fix(cycles): continue seam extraction

This commit is contained in:
Vincent Koc
2026-04-11 10:36:01 +01:00
parent 688327311c
commit 7308e72fac
76 changed files with 325 additions and 763 deletions

View File

@@ -1,6 +1,6 @@
import type { OpenClawConfig } from "../../config/config.js";
import { buildProviderAuthDoctorHintWithPlugin } from "../../plugins/provider-runtime.runtime.js";
import { normalizeProviderId } from "../model-selection.js";
import { normalizeProviderId } from "../model-selection-normalize.js";
import type { AuthProfileStore } from "./types.js";
/**

View File

@@ -1,5 +1,5 @@
import type { ProviderExternalAuthProfile } from "../../plugins/provider-external-auth.types.js";
import { resolveExternalAuthProfilesWithPlugins } from "../../plugins/provider-runtime.js";
import type { ProviderExternalAuthProfile } from "../../plugins/types.js";
import type { AuthProfileStore, OAuthCredential } from "./types.js";
type ExternalAuthProfileMap = Map<string, ProviderExternalAuthProfile>;

View File

@@ -23,7 +23,7 @@ type DiscoveredModel = {
input?: ModelInputType[];
};
type PiSdkModule = typeof import("./pi-model-discovery.js");
type PiSdkModule = typeof import("./pi-model-discovery-runtime.js");
type PiRegistryInstance =
| Array<DiscoveredModel>
| {

View File

@@ -21,7 +21,7 @@ import {
} from "./agent-scope.js";
import { resolveConfiguredProviderFallback } from "./configured-provider-fallback.js";
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
import type { ModelCatalogEntry } from "./model-catalog.js";
import type { ModelCatalogEntry } from "./model-catalog.types.js";
import { splitTrailingAuthProfile } from "./model-ref-profile.js";
import {
type ModelRef,

View File

@@ -1,6 +1,6 @@
import { normalizeOptionalString } from "../shared/string-coerce.js";
import type { AuthProfileCredential, AuthProfileStore } from "./auth-profiles.js";
import { normalizeProviderId } from "./model-selection.js";
import { normalizeProviderId } from "./provider-id.js";
export type PiApiKeyCredential = { type: "api_key"; key: string };
export type PiOAuthCredential = {

View File

@@ -1,9 +1,15 @@
import { compactEmbeddedPiSessionDirect as compactEmbeddedPiSessionDirectImpl } from "./compact.js";
import type { CompactEmbeddedPiSessionDirect } from "./compact.runtime.types.js";
type CompactEmbeddedPiSessionDirect = typeof import("./compact.js").compactEmbeddedPiSessionDirect;
let compactRuntimePromise: Promise<typeof import("./compact.js")> | null = null;
export function compactEmbeddedPiSessionDirect(
function loadCompactRuntime() {
compactRuntimePromise ??= import("./compact.js");
return compactRuntimePromise;
}
export async function compactEmbeddedPiSessionDirect(
...args: Parameters<CompactEmbeddedPiSessionDirect>
): ReturnType<CompactEmbeddedPiSessionDirect> {
return compactEmbeddedPiSessionDirectImpl(...args);
const { compactEmbeddedPiSessionDirect } = await loadCompactRuntime();
return compactEmbeddedPiSessionDirect(...args);
}

View File

@@ -14,9 +14,8 @@ import {
resolveProviderSyntheticAuthWithPlugin,
} from "../plugins/provider-runtime.js";
import { resolveRuntimeSyntheticAuthProviderRefs } from "../plugins/synthetic-auth.runtime.js";
import type { ProviderRuntimeModel } from "../plugins/types.js";
import { isRecord } from "../utils.js";
import { ensureAuthProfileStore } from "./auth-profiles.js";
import { ensureAuthProfileStore } from "./auth-profiles/store.js";
import { resolveProviderEnvApiKeyCandidates } from "./model-auth-env-vars.js";
import { resolveEnvApiKey } from "./model-auth-env.js";
import { resolvePiCredentialMapFromStore, type PiCredentialMap } from "./pi-auth-credentials.js";
@@ -26,6 +25,10 @@ const PiModelRegistryClass = PiCodingAgent.ModelRegistry;
export { PiAuthStorageClass as AuthStorage, PiModelRegistryClass as ModelRegistry };
type ProviderRuntimeModelLike = Model<Api> & {
contextTokens?: number;
};
type InMemoryAuthStorageBackendLike = {
withLock<T>(
update: (current: string) => {
@@ -67,7 +70,7 @@ export function normalizeDiscoveredPiModel<T>(value: T, agentDir: string): T {
) {
return value;
}
const model = value as unknown as ProviderRuntimeModel;
const model = value as unknown as ProviderRuntimeModelLike;
const pluginNormalized =
normalizeProviderResolvedModelWithPlugin({
provider: model.provider,

View File

@@ -1,8 +1,8 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { normalizePluginsConfig, resolveEffectiveEnableState } from "../plugins/config-state.js";
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
import type { PluginOrigin } from "../plugins/types.js";
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
import { normalizeProviderId } from "./provider-id.js";
export type ProviderAuthAliasLookupParams = {

View File

@@ -1,11 +1,13 @@
export {
countActiveDescendantRuns,
getLatestSubagentRunByChildSessionKey,
} from "./subagent-registry-read.js";
export {
countPendingDescendantRuns,
countPendingDescendantRunsExcludingRun,
getLatestSubagentRunByChildSessionKey,
isSubagentSessionRunActive,
listSubagentRunsForRequester,
replaceSubagentRunAfterSteer,
resolveRequesterForChildSession,
shouldIgnorePostCompletionAnnounceForSession,
} from "./subagent-registry.js";
} from "./subagent-registry-announce-read.js";
export { replaceSubagentRunAfterSteer } from "./subagent-registry-steer-runtime.js";

View File

@@ -1,6 +1,6 @@
import type { OpenClawConfig } from "../config/config.js";
import type { DispatchFromConfigResult } from "./reply/dispatch-from-config.js";
import { dispatchReplyFromConfig } from "./reply/dispatch-from-config.js";
import type { DispatchFromConfigResult } from "./reply/dispatch-from-config.types.js";
import { finalizeInboundContext } from "./reply/inbound-context.js";
import {
createReplyDispatcher,

View File

@@ -50,12 +50,7 @@ import {
import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js";
import type { FinalizedMsgContext } from "../templating.js";
import { normalizeVerboseLevel } from "../thinking.js";
import {
getReplyPayloadMetadata,
type BlockReplyContext,
type GetReplyOptions,
type ReplyPayload,
} from "../types.js";
import { getReplyPayloadMetadata, type BlockReplyContext, type ReplyPayload } from "../types.js";
import {
createInternalHookEvent,
loadSessionStore,
@@ -63,8 +58,11 @@ import {
resolveStorePath,
triggerInternalHook,
} from "./dispatch-from-config.runtime.js";
import type {
DispatchFromConfigParams,
DispatchFromConfigResult,
} from "./dispatch-from-config.types.js";
import { shouldSkipDuplicateInbound } from "./inbound-dedupe.js";
import type { ReplyDispatcher, ReplyDispatchKind } from "./reply-dispatcher.js";
import { resolveReplyRoutingDecision } from "./routing-policy.js";
import { resolveRunTypingPolicy } from "./typing-policy.js";
@@ -194,23 +192,14 @@ const createShouldEmitVerboseProgress = (params: {
return params.fallbackLevel !== "off";
};
};
export type {
DispatchFromConfigParams,
DispatchFromConfigResult,
} from "./dispatch-from-config.types.js";
export type DispatchFromConfigResult = {
queuedFinal: boolean;
counts: Record<ReplyDispatchKind, number>;
};
export async function dispatchReplyFromConfig(params: {
ctx: FinalizedMsgContext;
cfg: OpenClawConfig;
dispatcher: ReplyDispatcher;
replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
replyResolver?: typeof import("./get-reply-from-config.runtime.js").getReplyFromConfig;
fastAbortResolver?: typeof import("./abort.runtime.js").tryFastAbortFromMessage;
formatAbortReplyTextResolver?: typeof import("./abort.runtime.js").formatAbortReplyText;
/** Optional config override passed to getReplyFromConfig (e.g. per-sender timezone). */
configOverride?: OpenClawConfig;
}): Promise<DispatchFromConfigResult> {
export async function dispatchReplyFromConfig(
params: DispatchFromConfigParams,
): Promise<DispatchFromConfigResult> {
const { ctx, cfg, dispatcher } = params;
const diagnosticsEnabled = isDiagnosticsEnabled(cfg);
const channel = normalizeLowercaseStringOrEmpty(ctx.Surface ?? ctx.Provider ?? "unknown");

View File

@@ -1,6 +1,6 @@
import { resolveAgentConfig } from "../../agents/agent-scope.js";
import type { ChannelId } from "../../channels/plugins/channel-id.types.js";
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
import type { ChannelId } from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import { compileConfigRegexes, type ConfigRegexRejectReason } from "../../security/config-regex.js";

View File

@@ -1,5 +1,7 @@
import type { ChannelId } from "../channel-id.types.js";
import type { ChannelOutboundAdapter } from "../outbound.types.js";
import { createChannelRegistryLoader } from "../registry-loader.js";
import type { ChannelId, ChannelOutboundAdapter } from "../types.js";
import type { LoadChannelOutboundAdapter } from "./load.types.js";
// Channel docking: outbound sends should stay cheap to import.
//
@@ -15,3 +17,5 @@ export async function loadChannelOutboundAdapter(
): Promise<ChannelOutboundAdapter | undefined> {
return loadOutboundAdapterFromRegistry(id);
}
export type { LoadChannelOutboundAdapter };

View File

@@ -1,6 +1,6 @@
import type { PluginChannelRegistration, PluginRegistry } from "../../plugins/registry.js";
import type { PluginChannelRegistration, PluginRegistry } from "../../plugins/registry-types.js";
import { getActivePluginChannelRegistry } from "../../plugins/runtime.js";
import type { ChannelId } from "./types.js";
import type { ChannelId } from "./channel-id.types.js";
type ChannelRegistryValueResolver<TValue> = (
entry: PluginChannelRegistration,

View File

@@ -6,20 +6,24 @@ import type { GroupToolPolicyConfig } from "../../config/types.tools.js";
import type { ChannelApprovalNativeRuntimeAdapter } from "../../infra/approval-handler-runtime-types.js";
import type { ChannelApprovalKind } from "../../infra/approval-types.js";
import type { ExecApprovalRequest, ExecApprovalResolved } from "../../infra/exec-approvals.js";
import type { OutboundDeliveryResult } from "../../infra/outbound/deliver-types.js";
import type { OutboundIdentity } from "../../infra/outbound/identity-types.js";
import type { OutboundSendDeps } from "../../infra/outbound/send-deps.js";
import type {
PluginApprovalRequest,
PluginApprovalResolved,
} from "../../infra/plugin-approvals.js";
import type { OutboundMediaAccess } from "../../media/load-options.js";
import type { PluginRuntime } from "../../plugins/runtime/types.js";
import type { RuntimeEnv } from "../../runtime.js";
import type { ResolverContext, SecretDefaults } from "../../secrets/runtime-shared.js";
import type { SecretTargetRegistryEntry } from "../../secrets/target-registry-types.js";
import type { ChannelApprovalNativeAdapter } from "./approval-native.types.js";
import type { ConfigWriteTarget } from "./config-writes.js";
export type {
ChannelOutboundAdapter,
ChannelOutboundContext,
ChannelOutboundFormattedContext,
ChannelOutboundPayloadContext,
ChannelOutboundPayloadHint,
ChannelOutboundTargetRef,
} from "./outbound.types.js";
import type {
ChannelAccountSnapshot,
ChannelAccountState,
@@ -28,14 +32,12 @@ import type {
ChannelHeartbeatDeps,
ChannelLegacyStateMigrationPlan,
ChannelLogSink,
ChannelOutboundTargetMode,
ChannelPollContext,
ChannelPollResult,
ChannelSecurityContext,
ChannelSecurityDmPolicy,
ChannelSetupInput,
ChannelStatusIssue,
} from "./types.core.js";
export type { ChannelPairingAdapter } from "./pairing.types.js";
type ConfiguredBindingRule = AgentBinding;
export type { ChannelApprovalKind } from "../../infra/approval-types.js";
@@ -168,107 +170,6 @@ export type ChannelGroupAdapter = {
resolveToolPolicy?: (params: ChannelGroupContext) => GroupToolPolicyConfig | undefined;
};
export type ChannelOutboundContext = {
cfg: OpenClawConfig;
to: string;
text: string;
mediaUrl?: string;
audioAsVoice?: boolean;
mediaAccess?: OutboundMediaAccess;
mediaLocalRoots?: readonly string[];
mediaReadFile?: (filePath: string) => Promise<Buffer>;
gifPlayback?: boolean;
/** Send image as document to avoid Telegram compression. */
forceDocument?: boolean;
replyToId?: string | null;
threadId?: string | number | null;
accountId?: string | null;
identity?: OutboundIdentity;
deps?: OutboundSendDeps;
silent?: boolean;
gatewayClientScopes?: readonly string[];
};
export type ChannelOutboundPayloadContext = ChannelOutboundContext & {
payload: ReplyPayload;
};
export type ChannelOutboundPayloadHint =
| { kind: "approval-pending"; approvalKind: "exec" | "plugin" }
| { kind: "approval-resolved"; approvalKind: "exec" | "plugin" };
export type ChannelOutboundTargetRef = {
channel: string;
to: string;
accountId?: string | null;
threadId?: string | number | null;
};
export type ChannelOutboundFormattedContext = ChannelOutboundContext & {
abortSignal?: AbortSignal;
};
export type ChannelOutboundAdapter = {
deliveryMode: "direct" | "gateway" | "hybrid";
chunker?: ((text: string, limit: number) => string[]) | null;
chunkerMode?: "text" | "markdown";
textChunkLimit?: number;
sanitizeText?: (params: { text: string; payload: ReplyPayload }) => string;
pollMaxOptions?: number;
supportsPollDurationSeconds?: boolean;
supportsAnonymousPolls?: boolean;
normalizePayload?: (params: { payload: ReplyPayload }) => ReplyPayload | null;
shouldSkipPlainTextSanitization?: (params: { payload: ReplyPayload }) => boolean;
resolveEffectiveTextChunkLimit?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
fallbackLimit?: number;
}) => number | undefined;
shouldSuppressLocalPayloadPrompt?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
payload: ReplyPayload;
hint?: ChannelOutboundPayloadHint;
}) => boolean;
beforeDeliverPayload?: (params: {
cfg: OpenClawConfig;
target: ChannelOutboundTargetRef;
payload: ReplyPayload;
hint?: ChannelOutboundPayloadHint;
}) => Promise<void> | void;
/**
* @deprecated Use shouldTreatDeliveredTextAsVisible instead.
*/
shouldTreatRoutedTextAsVisible?: (params: {
kind: "tool" | "block" | "final";
text?: string;
}) => boolean;
shouldTreatDeliveredTextAsVisible?: (params: {
kind: "tool" | "block" | "final";
text?: string;
}) => boolean;
targetsMatchForReplySuppression?: (params: {
originTarget: string;
targetKey: string;
targetThreadId?: string;
}) => boolean;
resolveTarget?: (params: {
cfg?: OpenClawConfig;
to?: string;
allowFrom?: string[];
accountId?: string | null;
mode?: ChannelOutboundTargetMode;
}) => { ok: true; to: string } | { ok: false; error: Error };
sendPayload?: (ctx: ChannelOutboundPayloadContext) => Promise<OutboundDeliveryResult>;
sendFormattedText?: (ctx: ChannelOutboundFormattedContext) => Promise<OutboundDeliveryResult[]>;
sendFormattedMedia?: (
ctx: ChannelOutboundFormattedContext & { mediaUrl: string },
) => Promise<OutboundDeliveryResult>;
sendText?: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;
sendMedia?: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;
sendPoll?: (ctx: ChannelPollContext) => Promise<ChannelPollResult>;
};
export type ChannelStatusAdapter<ResolvedAccount, Probe = unknown, Audit = unknown> = {
defaultRuntime?: ChannelAccountSnapshot;
skipStaleSocketHealthCheck?: boolean;
@@ -431,17 +332,6 @@ export type ChannelLogoutContext<ResolvedAccount = unknown> = {
log?: ChannelLogSink;
};
export type ChannelPairingAdapter = {
idLabel: string;
normalizeAllowEntry?: (entry: string) => string;
notifyApproval?: (params: {
cfg: OpenClawConfig;
id: string;
accountId?: string;
runtime?: RuntimeEnv;
}) => Promise<void>;
};
export type ChannelGatewayAdapter<ResolvedAccount = unknown> = {
startAccount?: (ctx: ChannelGatewayContext<ResolvedAccount>) => Promise<unknown>;
stopAccount?: (ctx: ChannelGatewayContext<ResolvedAccount>) => Promise<void>;

View File

@@ -1,4 +1,4 @@
import type { OutboundSendDeps } from "../infra/outbound/deliver.js";
import type { OutboundSendDeps } from "../infra/outbound/send-deps.js";
import {
createOutboundSendDepsFromCliSource,
type CliOutboundSendSource,

View File

@@ -1,5 +1,5 @@
import { normalizeAnyChannelId } from "../channels/registry.js";
import type { OutboundSendDeps } from "../infra/outbound/deliver.js";
import type { OutboundSendDeps } from "../infra/outbound/send-deps.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
/**

View File

@@ -1,5 +1,5 @@
import { normalizeChatChannelId } from "../../../channels/ids.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { readChannelAllowFromStore } from "../../../pairing/pairing-store.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
import { normalizeOptionalLowercaseString } from "../../../shared/string-coerce.js";

View File

@@ -1,6 +1,6 @@
import path from "node:path";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../../agents/agent-scope.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { resolveBundledPluginSources } from "../../../plugins/bundled-sources.js";
import { sanitizeForLog } from "../../../terminal/ansi.js";
import { resolveUserPath } from "../../../utils.js";

View File

@@ -9,7 +9,7 @@ import type {
ChannelDoctorEmptyAllowlistAccountContext,
ChannelDoctorSequenceResult,
} from "../../../channels/plugins/types.adapters.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
type ChannelDoctorEntry = {
channelId: string;

View File

@@ -1,5 +1,5 @@
import { listPotentialConfiguredChannelIds } from "../../../channels/config-presence.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import {
normalizePluginsConfig,
resolveEffectivePluginActivationState,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
export type DoctorConfigMutationState = {
cfg: OpenClawConfig;

View File

@@ -1,6 +1,6 @@
import { normalizeChatChannelId } from "../../../channels/ids.js";
import { listRouteBindings } from "../../../config/bindings.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import {
formatChannelAccountsDefaultPath,
formatSetExplicitDefaultInstruction,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import type { DoctorAccountRecord, DoctorAllowFromList } from "../types.js";
import { collectEmptyAllowlistPolicyWarningsForAccount } from "./empty-allowlist-policy.js";
import { asObjectRecord } from "./object.js";

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { resolveCommandResolutionFromArgv } from "../../../infra/exec-command-resolution.js";
import {
listInterpreterLikeSafeBins,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/types.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { runPluginSetupConfigMigrations } from "../../../plugins/setup-registry.js";
import { collectChannelDoctorCompatibilityMutations } from "./channel-doctor.js";
import {

View File

@@ -1,9 +1,9 @@
import { isDeepStrictEqual } from "node:util";
import { normalizeProviderId } from "../../../agents/model-selection.js";
import { resolveSingleAccountKeysToMove } from "../../../channels/plugins/setup-helpers.js";
import type { OpenClawConfig } from "../../../config/config.js";
import { resolveNormalizedProviderModelMaxTokens } from "../../../config/defaults.js";
import { normalizeTalkSection } from "../../../config/talk.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { DEFAULT_GOOGLE_API_BASE_URL } from "../../../infra/google-api-base-url.js";
import { DEFAULT_ACCOUNT_ID } from "../../../routing/session-key.js";
import {

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { parseToolsBySenderTypedKey } from "../../../config/types.tools.js";
import { sanitizeForLog } from "../../../terminal/ansi.js";
import { formatConfigPath, resolveConfigPathTarget } from "../../doctor-config-analysis.js";

View File

@@ -1,5 +1,5 @@
import type { OpenClawConfig } from "../../../config/config.js";
import { mergeMissing } from "../../../config/legacy.shared.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import {
cloneRecord,
ensureRecord,

View File

@@ -1,5 +1,5 @@
import type { OpenClawConfig } from "../../../config/config.js";
import { mergeMissing } from "../../../config/legacy.shared.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import {
loadPluginManifestRegistry,
resolveManifestContractOwnerPluginId,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { normalizeOptionalString } from "../../../shared/string-coerce.js";
import { sanitizeForLog } from "../../../terminal/ansi.js";
import { resolveAllowFromMode, type AllowFromMode } from "./allow-from-mode.js";

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { sanitizeForLog } from "../../../terminal/ansi.js";
import {
collectBundledPluginLoadPathWarnings,

View File

@@ -1,5 +1,5 @@
import { isDeepStrictEqual } from "node:util";
import type { OpenClawConfig } from "../../../config/types.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { applyLegacyDoctorMigrations } from "./legacy-config-compat.js";
import { normalizeCompatibilityConfigValues } from "./legacy-config-core-migrate.js";

View File

@@ -1,5 +1,5 @@
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../../agents/agent-scope.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
import { normalizePluginId } from "../../../plugins/config-state.js";
import { loadPluginManifestRegistry } from "../../../plugins/manifest-registry.js";
import { sanitizeForLog } from "../../../terminal/ansi.js";

View File

@@ -1,5 +1,5 @@
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
import type { PluginOrigin } from "../plugins/types.js";
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
import type { ChannelUiMetadata, PluginUiMetadata } from "./schema.js";
type ChannelMetadataRecord = ChannelUiMetadata & {

View File

@@ -6,8 +6,8 @@ import {
normalizeProviderConfigForConfigDefaults,
} from "./provider-policy.js";
import { normalizeTalkConfig } from "./talk.js";
import type { OpenClawConfig } from "./types.js";
import type { ModelDefinitionConfig } from "./types.models.js";
import type { OpenClawConfig } from "./types.openclaw.js";
type WarnState = { warned: boolean };

View File

@@ -1,4 +1,4 @@
import type { ChannelId } from "../channels/plugins/types.js";
import type { ChannelId } from "../channels/plugins/channel-id.types.js";
import { resolveAccountEntry } from "../routing/account-lookup.js";
import { normalizeAccountId } from "../routing/session-key.js";
import {

View File

@@ -3,7 +3,7 @@ import { listChannelPlugins } from "../channels/plugins/registry.js";
import { getActivePluginChannelRegistryVersion } from "../plugins/runtime.js";
import { resolveAccountEntry } from "../routing/account-lookup.js";
import { normalizeAccountId } from "../routing/session-key.js";
import type { OpenClawConfig } from "./config.js";
import type { ResolveMarkdownTableModeParams } from "./markdown-tables.types.js";
import type { MarkdownTableMode } from "./types.base.js";
type MarkdownConfigEntry = {
@@ -80,11 +80,14 @@ function resolveMarkdownModeFromSection(
return isMarkdownTableMode(sectionMode) ? sectionMode : undefined;
}
export function resolveMarkdownTableMode(params: {
cfg?: Partial<OpenClawConfig>;
channel?: string | null;
accountId?: string | null;
}): MarkdownTableMode {
export type {
ResolveMarkdownTableMode,
ResolveMarkdownTableModeParams,
} from "./markdown-tables.types.js";
export function resolveMarkdownTableMode(
params: ResolveMarkdownTableModeParams,
): MarkdownTableMode {
const channel = normalizeChannelId(params.channel);
const defaultMode = channel ? (getDefaultTableModes().get(channel) ?? "code") : "code";
if (!channel || !params.cfg) {

View File

@@ -6,7 +6,7 @@ import type {
TalkConfigResponse,
TalkProviderConfig,
} from "./types.gateway.js";
import type { OpenClawConfig } from "./types.js";
import type { OpenClawConfig } from "./types.openclaw.js";
import { coerceSecretRef } from "./types.secrets.js";
function normalizeTalkSecretInput(value: unknown): TalkProviderConfig["apiKey"] | undefined {

View File

@@ -5,6 +5,12 @@ import {
READ_SCOPE,
WRITE_SCOPE,
} from "./method-scopes.js";
import type {
GatewayBroadcastFn,
GatewayBroadcastOpts,
GatewayBroadcastStateVersion,
GatewayBroadcastToConnIdsFn,
} from "./server-broadcast-types.js";
import { MAX_BUFFERED_BYTES } from "./server-constants.js";
import type { GatewayWsClient } from "./server/ws-types.js";
import { logWs, shouldLogWs, summarizeAgentEventForWsLog } from "./ws-log.js";
@@ -23,28 +29,12 @@ const EVENT_SCOPE_GUARDS: Record<string, string[]> = {
"session.tool": [READ_SCOPE],
};
export type GatewayBroadcastStateVersion = {
presence?: number;
health?: number;
};
export type GatewayBroadcastOpts = {
dropIfSlow?: boolean;
stateVersion?: GatewayBroadcastStateVersion;
};
export type GatewayBroadcastFn = (
event: string,
payload: unknown,
opts?: GatewayBroadcastOpts,
) => void;
export type GatewayBroadcastToConnIdsFn = (
event: string,
payload: unknown,
connIds: ReadonlySet<string>,
opts?: GatewayBroadcastOpts,
) => void;
export type {
GatewayBroadcastFn,
GatewayBroadcastOpts,
GatewayBroadcastStateVersion,
GatewayBroadcastToConnIdsFn,
} from "./server-broadcast-types.js";
function hasEventScope(client: GatewayWsClient, event: string): boolean {
const required = EVENT_SCOPE_GUARDS[event];

View File

@@ -10,7 +10,7 @@ import type { ChatAbortControllerEntry } from "../chat-abort.js";
import type { ExecApprovalManager } from "../exec-approval-manager.js";
import type { NodeRegistry } from "../node-registry.js";
import type { ConnectParams, ErrorShape, RequestFrame } from "../protocol/index.js";
import type { GatewayBroadcastFn, GatewayBroadcastToConnIdsFn } from "../server-broadcast.js";
import type { GatewayBroadcastFn, GatewayBroadcastToConnIdsFn } from "../server-broadcast-types.js";
import type { ChannelRuntimeSnapshot } from "../server-channels.js";
import type { DedupeEntry } from "../server-shared.js";

View File

@@ -19,11 +19,8 @@ import type { ChatAbortControllerEntry } from "./chat-abort.js";
import type { ControlUiRootState } from "./control-ui.js";
import type { HooksConfigResolved } from "./hooks.js";
import { isLoopbackHost, resolveGatewayListenHosts } from "./net.js";
import {
createGatewayBroadcaster,
type GatewayBroadcastFn,
type GatewayBroadcastToConnIdsFn,
} from "./server-broadcast.js";
import type { GatewayBroadcastFn, GatewayBroadcastToConnIdsFn } from "./server-broadcast-types.js";
import { createGatewayBroadcaster } from "./server-broadcast.js";
import {
type ChatRunEntry,
createChatRunState,

View File

@@ -1,6 +1,6 @@
import type { SessionLifecycleEvent } from "../sessions/session-lifecycle-events.js";
import type { SessionTranscriptUpdate } from "../sessions/transcript-events.js";
import type { GatewayBroadcastToConnIdsFn } from "./server-broadcast.js";
import type { GatewayBroadcastToConnIdsFn } from "./server-broadcast-types.js";
import type {
SessionEventSubscriberRegistry,
SessionMessageSubscriberRegistry,

View File

@@ -1,5 +1,5 @@
import { listSystemPresence } from "../../infra/system-presence.js";
import type { GatewayBroadcastFn } from "../server-broadcast.js";
import type { GatewayBroadcastFn } from "../server-broadcast-types.js";
export function broadcastPresenceSnapshot(params: {
broadcast: GatewayBroadcastFn;

View File

@@ -6,9 +6,9 @@
*/
import type { WorkspaceBootstrapFile } from "../agents/workspace.js";
import type { CliDeps } from "../cli/deps.js";
import type { OpenClawConfig } from "../config/config.js";
import type { CliDeps } from "../cli/outbound-send-deps.js";
import type { SessionEntry } from "../config/sessions.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { SessionsPatchParams } from "../gateway/protocol/index.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";

View File

@@ -7,7 +7,7 @@ import type {
PluginHookMessageContext,
PluginHookMessageReceivedEvent,
PluginHookMessageSentEvent,
} from "../plugins/types.js";
} from "../plugins/hook-message.types.js";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,

View File

@@ -1,7 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import { describeFailoverError, isFailoverError } from "../agents/failover-error.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {
@@ -13,39 +12,12 @@ import {
import { parseImageGenerationModelRef } from "./model-ref.js";
import { resolveImageGenerationOverrides } from "./normalization.js";
import { getImageGenerationProvider, listImageGenerationProviders } from "./provider-registry.js";
import type {
GeneratedImageAsset,
ImageGenerationIgnoredOverride,
ImageGenerationNormalization,
ImageGenerationResolution,
ImageGenerationResult,
ImageGenerationSourceImage,
} from "./types.js";
import type { GenerateImageParams, GenerateImageRuntimeResult } from "./runtime-types.js";
import type { ImageGenerationResult } from "./types.js";
const log = createSubsystemLogger("image-generation");
export type GenerateImageParams = {
cfg: OpenClawConfig;
prompt: string;
agentDir?: string;
authStore?: AuthProfileStore;
modelOverride?: string;
count?: number;
size?: string;
aspectRatio?: string;
resolution?: ImageGenerationResolution;
inputImages?: ImageGenerationSourceImage[];
};
export type GenerateImageRuntimeResult = {
images: GeneratedImageAsset[];
provider: string;
model: string;
attempts: FallbackAttempt[];
normalization?: ImageGenerationNormalization;
metadata?: Record<string, unknown>;
ignoredOverrides: ImageGenerationIgnoredOverride[];
};
export type { GenerateImageParams, GenerateImageRuntimeResult } from "./runtime-types.js";
function buildNoImageGenerationModelConfiguredMessage(cfg: OpenClawConfig): string {
return buildNoCapabilityModelConfiguredMessage({

View File

@@ -1,6 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
import type { MediaNormalizationEntry } from "../media-generation/runtime-shared.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { MediaNormalizationEntry } from "../media-generation/normalization.types.js";
export type GeneratedImageAsset = {
buffer: Buffer;

View File

@@ -1,4 +1,4 @@
import type { ChannelId } from "../channels/plugins/types.js";
import type { ChannelId } from "../channels/plugins/channel-id.types.js";
export type ChannelDirection = "inbound" | "outbound";
type ActivityEntry = {

View File

@@ -1,7 +1,7 @@
import type { OutboundChannel } from "./targets.js";
import type { ChannelId } from "../../channels/plugins/channel-id.types.js";
export type OutboundDeliveryResult = {
channel: Exclude<OutboundChannel, "none">;
channel: Exclude<ChannelId, "none">;
messageId: string;
chatId?: string;
channelId?: string;

View File

@@ -63,15 +63,6 @@ const PERMANENT_ERROR_PATTERNS: readonly RegExp[] = [
const drainInProgress = new Map<string, boolean>();
const entriesInProgress = new Set<string>();
type DeliverRuntimeModule = typeof import("./deliver-runtime.js");
let deliverRuntimePromise: Promise<DeliverRuntimeModule> | null = null;
function loadDeliverRuntime() {
deliverRuntimePromise ??= import("./deliver-runtime.js");
return deliverRuntimePromise;
}
function getErrnoCode(err: unknown): string | null {
return err && typeof err === "object" && "code" in err
? String((err as { code?: unknown }).code)
@@ -225,7 +216,7 @@ export async function drainPendingDeliveries(opts: {
cfg: OpenClawConfig;
log: RecoveryLogger;
stateDir?: string;
deliver?: DeliverFn;
deliver: DeliverFn;
selectEntry: (entry: QueuedDelivery, now: number) => PendingDeliveryDrainDecision;
}): Promise<void> {
if (drainInProgress.get(opts.drainKey)) {
@@ -236,7 +227,7 @@ export async function drainPendingDeliveries(opts: {
drainInProgress.set(opts.drainKey, true);
try {
const now = Date.now();
const deliver = opts.deliver ?? (await loadDeliverRuntime()).deliverOutboundPayloads;
const deliver = opts.deliver;
const matchingEntries = (await loadPendingDeliveries(opts.stateDir))
.map((entry) => ({
entry,

View File

@@ -1,6 +1,6 @@
import { mapAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
import { normalizeChatType, type ChatType } from "../../channels/chat-type.js";
import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.js";
import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.core.js";
import type { OpenClawConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js";
import type { AgentDefaultsConfig } from "../../config/types.agent-defaults.js";

View File

@@ -11,27 +11,21 @@ import type { AgentModelConfig } from "../config/types.agents-shared.js";
import type { OpenClawConfig } from "../config/types.js";
import { getProviderEnvVars } from "../secrets/provider-env-vars.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import type {
MediaGenerationNormalizationMetadataInput,
MediaNormalizationEntry,
MediaNormalizationValue,
} from "./normalization.types.js";
export type ParsedProviderModelRef = {
provider: string;
model: string;
};
export type MediaNormalizationValue = string | number | boolean;
export type MediaNormalizationEntry<TValue extends MediaNormalizationValue> = {
requested?: TValue;
applied?: TValue;
derivedFrom?: string;
supportedValues?: readonly TValue[];
};
export type MediaGenerationNormalizationMetadataInput = {
size?: MediaNormalizationEntry<string>;
aspectRatio?: MediaNormalizationEntry<string>;
resolution?: MediaNormalizationEntry<string>;
durationSeconds?: MediaNormalizationEntry<number>;
};
export type {
MediaGenerationNormalizationMetadataInput,
MediaNormalizationEntry,
MediaNormalizationValue,
} from "./normalization.types.js";
export function hasMediaNormalizationEntry<TValue extends MediaNormalizationValue>(
entry: MediaNormalizationEntry<TValue> | undefined,

View File

@@ -1,7 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import { describeFailoverError, isFailoverError } from "../agents/failover-error.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {
@@ -13,40 +12,12 @@ import {
import { parseMusicGenerationModelRef } from "./model-ref.js";
import { resolveMusicGenerationOverrides } from "./normalization.js";
import { getMusicGenerationProvider, listMusicGenerationProviders } from "./provider-registry.js";
import type {
GeneratedMusicAsset,
MusicGenerationIgnoredOverride,
MusicGenerationNormalization,
MusicGenerationOutputFormat,
MusicGenerationResult,
MusicGenerationSourceImage,
} from "./types.js";
import type { GenerateMusicParams, GenerateMusicRuntimeResult } from "./runtime-types.js";
import type { MusicGenerationResult } from "./types.js";
const log = createSubsystemLogger("music-generation");
export type GenerateMusicParams = {
cfg: OpenClawConfig;
prompt: string;
agentDir?: string;
authStore?: AuthProfileStore;
modelOverride?: string;
lyrics?: string;
instrumental?: boolean;
durationSeconds?: number;
format?: MusicGenerationOutputFormat;
inputImages?: MusicGenerationSourceImage[];
};
export type GenerateMusicRuntimeResult = {
tracks: GeneratedMusicAsset[];
provider: string;
model: string;
attempts: FallbackAttempt[];
lyrics?: string[];
normalization?: MusicGenerationNormalization;
metadata?: Record<string, unknown>;
ignoredOverrides: MusicGenerationIgnoredOverride[];
};
export type { GenerateMusicParams, GenerateMusicRuntimeResult } from "./runtime-types.js";
export function listRuntimeMusicGenerationProviders(params?: { config?: OpenClawConfig }) {
return listMusicGenerationProviders(params?.config);

View File

@@ -1,6 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/types.js";
import type { MediaNormalizationEntry } from "../media-generation/runtime-shared.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { MediaNormalizationEntry } from "../media-generation/normalization.types.js";
export type MusicGenerationOutputFormat = "mp3" | "wav";

View File

@@ -2,8 +2,9 @@ import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import type { ChannelId } from "../channels/plugins/channel-id.types.js";
import { getPairingAdapter } from "../channels/plugins/pairing.js";
import type { ChannelId, ChannelPairingAdapter } from "../channels/plugins/types.js";
import type { ChannelPairingAdapter } from "../channels/plugins/pairing.types.js";
import { resolveOAuthDir, resolveStateDir } from "../config/paths.js";
import { withFileLock as withPathLock } from "../infra/file-lock.js";
import { resolveRequiredHomeDir } from "../infra/home-dir.js";

View File

@@ -1,6 +1,6 @@
import type { OpenClawConfig } from "../config/config.js";
import {
drainPendingDeliveries,
drainPendingDeliveries as coreDrainPendingDeliveries,
type DeliverFn,
type RecoveryLogger,
} from "../infra/outbound/delivery-queue.js";
@@ -13,6 +13,29 @@ function normalizeWhatsAppReconnectAccountId(accountId?: string): string {
const WHATSAPP_NO_LISTENER_ERROR_RE = /No active WhatsApp Web listener/i;
type OutboundDeliverRuntimeModule = typeof import("../infra/outbound/deliver-runtime.js");
type DrainPendingDeliveriesOptions = Omit<
Parameters<typeof coreDrainPendingDeliveries>[0],
"deliver"
> & {
deliver?: DeliverFn;
};
let outboundDeliverRuntimePromise: Promise<OutboundDeliverRuntimeModule> | null = null;
async function loadOutboundDeliverRuntime(): Promise<OutboundDeliverRuntimeModule> {
outboundDeliverRuntimePromise ??= import("../infra/outbound/deliver-runtime.js");
return await outboundDeliverRuntimePromise;
}
export async function drainPendingDeliveries(opts: DrainPendingDeliveriesOptions): Promise<void> {
const deliver = opts.deliver ?? (await loadOutboundDeliverRuntime()).deliverOutboundPayloads;
await coreDrainPendingDeliveries({
...opts,
deliver,
});
}
/**
* @deprecated Prefer plugin-owned reconnect policy wired through
* `drainPendingDeliveries(...)`. This compatibility shim preserves the
@@ -76,7 +99,6 @@ export * from "../infra/net/proxy-env.js";
export * from "../infra/net/proxy-fetch.js";
export * from "../infra/net/undici-global-dispatcher.js";
export * from "../infra/net/ssrf.js";
export { drainPendingDeliveries };
export * from "../infra/outbound/identity.js";
export * from "../infra/outbound/sanitize-text.js";
export * from "../infra/parse-finite-number.js";

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import {
normalizeOptionalLowercaseString,
normalizeOptionalString,
@@ -15,7 +15,7 @@ import {
type NormalizedPluginsConfig as SharedNormalizedPluginsConfig,
} from "./config-normalization-shared.js";
import { loadPluginManifestRegistry } from "./manifest-registry.js";
import type { PluginOrigin } from "./types.js";
import type { PluginOrigin } from "./plugin-origin.types.js";
export type PluginActivationSource = "disabled" | "explicit" | "auto" | "default";

View File

@@ -18,14 +18,14 @@ import {
normalizeOptionalLowercaseString,
normalizeOptionalString,
} from "../shared/string-coerce.js";
import { getActivePluginRegistry } from "./runtime.js";
import type {
PluginConversationBinding,
PluginConversationBindingResolvedEvent,
PluginConversationBindingResolutionDecision,
PluginConversationBindingRequestParams,
PluginConversationBindingRequestResult,
} from "./types.js";
} from "./conversation-binding.types.js";
import { getActivePluginRegistry } from "./runtime.js";
const log = createSubsystemLogger("plugins/binding");

View File

@@ -8,7 +8,7 @@
import { createSubsystemLogger } from "../logging/subsystem.js";
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
import { createHookRunner, type HookRunner } from "./hooks.js";
import type { PluginRegistry } from "./registry.js";
import type { PluginRegistry } from "./registry-types.js";
import type { PluginHookGatewayContext, PluginHookGatewayStopEvent } from "./types.js";
type HookRunnerGlobalState = {

View File

@@ -64,7 +64,7 @@ import {
recordImportedPluginId,
setActivePluginRegistry,
} from "./runtime.js";
import type { CreatePluginRuntimeOptions } from "./runtime/index.js";
import type { CreatePluginRuntimeOptions } from "./runtime/types.js";
import type { PluginRuntime } from "./runtime/types.js";
import { validateJsonSchemaValue } from "./schema-validator.js";
import {

View File

@@ -26,6 +26,7 @@ import {
} from "./manifest.js";
import { checkMinHostVersion } from "./min-host-version.js";
import { isPathInside, safeRealpathSync } from "./path-safety.js";
import type { PluginOrigin } from "./plugin-origin.types.js";
import { resolvePluginCacheInputs } from "./roots.js";
import type {
PluginBundleFormat,
@@ -33,7 +34,6 @@ import type {
PluginDiagnostic,
PluginFormat,
PluginKind,
PluginOrigin,
} from "./types.js";
type PluginManifestContractListKey =

View File

@@ -1,5 +1,5 @@
import { createEmptyPluginRegistry } from "./registry-empty.js";
import type { PluginRegistry } from "./registry.js";
import type { PluginRegistry } from "./registry-types.js";
import {
PLUGIN_REGISTRY_STATE,
type RegistryState,

View File

@@ -30,7 +30,9 @@ import { createRuntimeMedia } from "./runtime-media.js";
import { createRuntimeSystem } from "./runtime-system.js";
import { createRuntimeTaskFlow } from "./runtime-taskflow.js";
import { createRuntimeTasks } from "./runtime-tasks.js";
import type { PluginRuntime } from "./types.js";
import type { CreatePluginRuntimeOptions, PluginRuntime } from "./types.js";
export type { CreatePluginRuntimeOptions } from "./types.js";
const loadTtsRuntime = createLazyRuntimeModule(() => import("../../tts/tts.js"));
const loadMediaUnderstandingRuntime = createLazyRuntimeModule(
@@ -198,11 +200,6 @@ function createLateBindingSubagent(
});
}
export type CreatePluginRuntimeOptions = {
subagent?: PluginRuntime["subagent"];
allowGatewaySubagentBinding?: boolean;
};
export function createPluginRuntime(_options: CreatePluginRuntimeOptions = {}): PluginRuntime {
const mediaUnderstanding = createRuntimeMediaUnderstandingFacade();
const taskFlow = createRuntimeTaskFlow();

View File

@@ -29,7 +29,7 @@ import type {
TaskRuntime,
} from "../../tasks/task-registry.types.js";
import { normalizeDeliveryContext } from "../../utils/delivery-context.js";
import type { OpenClawPluginToolContext } from "../types.js";
import type { OpenClawPluginToolContext } from "../tool-types.js";
export type ManagedTaskFlowRecord = TaskFlowRecord & {
syncMode: "managed";

View File

@@ -21,7 +21,7 @@ import {
resolveTaskForLookupTokenForOwner,
} from "../../tasks/task-owner-access.js";
import { normalizeDeliveryContext } from "../../utils/delivery-context.js";
import type { OpenClawPluginToolContext } from "../types.js";
import type { OpenClawPluginToolContext } from "../tool-types.js";
import type { PluginRuntimeTaskFlow } from "./runtime-taskflow.js";
import type {
TaskFlowDetail,

View File

@@ -71,7 +71,7 @@ export type PluginRuntimeChannel = {
resolveChunkMode: typeof import("../../auto-reply/chunk.js").resolveChunkMode;
resolveTextChunkLimit: typeof import("../../auto-reply/chunk.js").resolveTextChunkLimit;
hasControlCommand: typeof import("../../auto-reply/command-detection.js").hasControlCommand;
resolveMarkdownTableMode: typeof import("../../config/markdown-tables.js").resolveMarkdownTableMode;
resolveMarkdownTableMode: import("../../config/markdown-tables.types.js").ResolveMarkdownTableMode;
convertMarkdownTables: typeof import("../../markdown/tables.js").convertMarkdownTables;
};
reply: {
@@ -79,7 +79,7 @@ export type PluginRuntimeChannel = {
createReplyDispatcherWithTyping: typeof import("../../auto-reply/reply/reply-dispatcher.js").createReplyDispatcherWithTyping;
resolveEffectiveMessagesConfig: typeof import("../../agents/identity.js").resolveEffectiveMessagesConfig;
resolveHumanDelayConfig: typeof import("../../agents/identity.js").resolveHumanDelayConfig;
dispatchReplyFromConfig: typeof import("../../auto-reply/reply/dispatch-from-config.js").dispatchReplyFromConfig;
dispatchReplyFromConfig: import("../../auto-reply/reply/dispatch-from-config.types.js").DispatchReplyFromConfig;
withReplyDispatcher: typeof import("../../auto-reply/dispatch.js").withReplyDispatcher;
finalizeInboundContext: typeof import("../../auto-reply/reply/inbound-context.js").finalizeInboundContext;
formatAgentEnvelope: typeof import("../../auto-reply/envelope.js").formatAgentEnvelope;
@@ -137,7 +137,7 @@ export type PluginRuntimeChannel = {
shouldHandleTextCommands: typeof import("../../auto-reply/commands-registry.js").shouldHandleTextCommands;
};
outbound: {
loadAdapter: typeof import("../../channels/plugins/outbound/load.js").loadChannelOutboundAdapter;
loadAdapter: import("../../channels/plugins/outbound/load.types.js").LoadChannelOutboundAdapter;
};
threadBindings: {
setIdleTimeoutBySessionKey: (params: {

View File

@@ -34,7 +34,12 @@ export type PluginRuntimeCore = {
resolveAgentDir: typeof import("../../agents/agent-scope.js").resolveAgentDir;
resolveAgentWorkspaceDir: typeof import("../../agents/agent-scope.js").resolveAgentWorkspaceDir;
resolveAgentIdentity: typeof import("../../agents/identity.js").resolveAgentIdentity;
resolveThinkingDefault: typeof import("../../agents/model-selection.js").resolveThinkingDefault;
resolveThinkingDefault: (params: {
cfg: import("../../config/types.openclaw.js").OpenClawConfig;
provider: string;
model: string;
catalog?: import("../../agents/model-catalog.types.js").ModelCatalogEntry[];
}) => import("../../auto-reply/thinking.js").ThinkLevel;
runEmbeddedAgent: typeof import("../../agents/embedded-agent.js").runEmbeddedAgent;
runEmbeddedPiAgent: typeof import("../../agents/pi-embedded.js").runEmbeddedPiAgent;
resolveAgentTimeoutMs: typeof import("../../agents/timeout.js").resolveAgentTimeoutMs;
@@ -80,20 +85,36 @@ export type PluginRuntimeCore = {
transcribeAudioFile: typeof import("../../media-understanding/runtime.js").transcribeAudioFile;
};
imageGeneration: {
generate: typeof import("../../image-generation/runtime.js").generateImage;
listProviders: typeof import("../../image-generation/runtime.js").listRuntimeImageGenerationProviders;
generate: (
params: import("../../image-generation/runtime-types.js").GenerateImageParams,
) => Promise<import("../../image-generation/runtime-types.js").GenerateImageRuntimeResult>;
listProviders: (
params?: import("../../image-generation/runtime-types.js").ListRuntimeImageGenerationProvidersParams,
) => import("../../image-generation/runtime-types.js").RuntimeImageGenerationProvider[];
};
videoGeneration: {
generate: typeof import("../../video-generation/runtime.js").generateVideo;
listProviders: typeof import("../../video-generation/runtime.js").listRuntimeVideoGenerationProviders;
generate: (
params: import("../../video-generation/runtime-types.js").GenerateVideoParams,
) => Promise<import("../../video-generation/runtime-types.js").GenerateVideoRuntimeResult>;
listProviders: (
params?: import("../../video-generation/runtime-types.js").ListRuntimeVideoGenerationProvidersParams,
) => import("../../video-generation/runtime-types.js").RuntimeVideoGenerationProvider[];
};
musicGeneration: {
generate: typeof import("../../music-generation/runtime.js").generateMusic;
listProviders: typeof import("../../music-generation/runtime.js").listRuntimeMusicGenerationProviders;
generate: (
params: import("../../music-generation/runtime-types.js").GenerateMusicParams,
) => Promise<import("../../music-generation/runtime-types.js").GenerateMusicRuntimeResult>;
listProviders: (
params?: import("../../music-generation/runtime-types.js").ListRuntimeMusicGenerationProvidersParams,
) => import("../../music-generation/runtime-types.js").RuntimeMusicGenerationProvider[];
};
webSearch: {
listProviders: typeof import("../../web-search/runtime.js").listWebSearchProviders;
search: typeof import("../../web-search/runtime.js").runWebSearch;
listProviders: (
params?: import("../../web-search/runtime-types.js").ListWebSearchProvidersParams,
) => import("../../web-search/runtime-types.js").RuntimeWebSearchProviderEntry[];
search: (
params: import("../../web-search/runtime-types.js").RunWebSearchParams,
) => Promise<import("../../web-search/runtime-types.js").RunWebSearchResult>;
};
stt: {
transcribeAudioFile: typeof import("../../media-understanding/transcribe-audio.js").transcribeAudioFile;
@@ -125,7 +146,7 @@ export type PluginRuntimeCore = {
getApiKeyForModel: (params: {
model: import("@mariozechner/pi-ai").Model<import("@mariozechner/pi-ai").Api>;
cfg?: import("../../config/config.js").OpenClawConfig;
}) => Promise<import("../../agents/model-auth.js").ResolvedProviderAuth>;
}) => Promise<import("../../agents/model-auth-runtime-shared.js").ResolvedProviderAuth>;
/** Resolve request-ready auth for a model, including provider runtime exchanges. */
getRuntimeAuthForModel: (params: {
model: import("@mariozechner/pi-ai").Model<import("@mariozechner/pi-ai").Api>;
@@ -136,6 +157,6 @@ export type PluginRuntimeCore = {
resolveApiKeyForProvider: (params: {
provider: string;
cfg?: import("../../config/config.js").OpenClawConfig;
}) => Promise<import("../../agents/model-auth.js").ResolvedProviderAuth>;
}) => Promise<import("../../agents/model-auth-runtime-shared.js").ResolvedProviderAuth>;
};
};

View File

@@ -64,3 +64,8 @@ export type PluginRuntime = PluginRuntimeCore & {
};
channel: PluginRuntimeChannel;
};
export type CreatePluginRuntimeOptions = {
subagent?: PluginRuntime["subagent"];
allowGatewaySubagentBinding?: boolean;
};

View File

@@ -16,25 +16,19 @@ import type { FailoverReason } from "../agents/pi-embedded-helpers/types.js";
import type { ModelProviderRequestTransportOverrides } from "../agents/provider-request-config.js";
import type { ProviderSystemPromptContribution } from "../agents/system-prompt-contribution.js";
import type { PromptMode } from "../agents/system-prompt.js";
import type { ToolFsPolicy } from "../agents/tool-fs-policy.js";
import type { AnyAgentTool } from "../agents/tools/common.js";
import type { ReplyDispatchKind, ReplyDispatcher } from "../auto-reply/reply/reply-dispatcher.js";
import type { FinalizedMsgContext } from "../auto-reply/templating.js";
import type { ThinkLevel } from "../auto-reply/thinking.js";
import type { ReplyPayload } from "../auto-reply/types.js";
import type { ChannelId, ChannelPlugin } from "../channels/plugins/types.js";
import type {
CliBackendConfig,
ModelProviderAuthMode,
ModelProviderConfig,
} from "../config/types.js";
import type { CliBackendConfig, ModelProviderConfig } from "../config/types.js";
import type { ModelCompatConfig } from "../config/types.models.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { TtsAutoMode } from "../config/types.tts.js";
import type { OperatorScope } from "../gateway/operator-scopes.js";
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
import type { InternalHookHandler } from "../hooks/internal-hooks.js";
import type { HookEntry } from "../hooks/types.js";
import type { ImageGenerationProvider } from "../image-generation/types.js";
import type { ProviderUsageSnapshot } from "../infra/provider-usage.types.js";
import type { MediaUnderstandingProvider } from "../media-understanding/types.js";
@@ -56,10 +50,6 @@ import type {
RealtimeVoiceProviderResolveConfigContext,
} from "../realtime-voice/provider-types.js";
import type { RuntimeEnv } from "../runtime.js";
import type {
RuntimeWebFetchMetadata,
RuntimeWebSearchMetadata,
} from "../secrets/runtime-web-tools.types.js";
import type { SecurityAuditFinding } from "../security/audit.types.js";
import type {
SpeechDirectiveTokenParseContext,
@@ -77,9 +67,15 @@ import type {
SpeechTelephonySynthesisResult,
SpeechVoiceOption,
} from "../tts/provider-types.js";
import type { DeliveryContext } from "../utils/delivery-context.js";
import type { VideoGenerationProvider } from "../video-generation/types.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import type {
PluginConversationBinding,
PluginConversationBindingRequestParams,
PluginConversationBindingRequestResult,
PluginConversationBindingResolvedEvent,
PluginConversationBindingResolutionDecision,
} from "./conversation-binding.types.js";
import {
PLUGIN_PROMPT_MUTATION_RESULT_FIELDS,
stripPromptMutationFieldsFromLegacyHookResult,
@@ -92,16 +88,48 @@ import type {
PluginHookBeforePromptBuildEvent,
PluginHookBeforePromptBuildResult,
} from "./hook-before-agent-start.types.js";
import type {
PluginHookInboundClaimContext,
PluginHookInboundClaimEvent,
PluginHookMessageContext,
PluginHookMessageReceivedEvent,
PluginHookMessageSendingEvent,
PluginHookMessageSendingResult,
PluginHookMessageSentEvent,
} from "./hook-message.types.js";
import type { PluginKind } from "./plugin-kind.types.js";
import type { PluginOrigin } from "./plugin-origin.types.js";
import type { SecretInputMode } from "./provider-auth-types.js";
import type {
ProviderExternalAuthProfile,
ProviderExternalOAuthProfile,
ProviderResolveExternalAuthProfilesContext,
ProviderResolveExternalOAuthProfilesContext,
ProviderResolveSyntheticAuthContext,
ProviderSyntheticAuthResult,
} from "./provider-external-auth.types.js";
import type { createVpsAwareOAuthHandlers } from "./provider-oauth-flow.js";
import type {
ProviderDefaultThinkingPolicyContext,
ProviderThinkingPolicyContext,
} from "./provider-thinking.types.js";
import type { PluginRuntime } from "./runtime/types.js";
import type {
OpenClawPluginHookOptions,
OpenClawPluginToolContext,
OpenClawPluginToolFactory,
OpenClawPluginToolOptions,
} from "./tool-types.js";
import type { WebFetchProviderPlugin, WebSearchProviderPlugin } from "./web-provider-types.js";
export type { PluginRuntime } from "./runtime/types.js";
export type { PluginOrigin } from "./plugin-origin.types.js";
export type {
OpenClawPluginHookOptions,
OpenClawPluginToolContext,
OpenClawPluginToolFactory,
OpenClawPluginToolOptions,
} from "./tool-types.js";
export type { AnyAgentTool } from "../agents/tools/common.js";
export type { AgentHarness } from "../agents/harness/types.js";
export type {
@@ -117,6 +145,13 @@ export {
PLUGIN_PROMPT_MUTATION_RESULT_FIELDS,
stripPromptMutationFieldsFromLegacyHookResult,
} from "./hook-before-agent-start.types.js";
export type {
PluginConversationBinding,
PluginConversationBindingRequestParams,
PluginConversationBindingRequestResult,
PluginConversationBindingResolvedEvent,
PluginConversationBindingResolutionDecision,
} from "./conversation-binding.types.js";
export type ProviderAuthOptionBag = {
token?: string;
@@ -143,6 +178,40 @@ export type PluginConfigUiHint = {
};
export type { PluginKind } from "./plugin-kind.types.js";
export type {
PluginHookInboundClaimContext,
PluginHookInboundClaimEvent,
PluginHookMessageContext,
PluginHookMessageReceivedEvent,
PluginHookMessageSendingEvent,
PluginHookMessageSendingResult,
PluginHookMessageSentEvent,
} from "./hook-message.types.js";
export type {
ProviderExternalAuthProfile,
ProviderExternalOAuthProfile,
ProviderResolveExternalAuthProfilesContext,
ProviderResolveExternalOAuthProfilesContext,
ProviderResolveSyntheticAuthContext,
ProviderSyntheticAuthResult,
} from "./provider-external-auth.types.js";
export type {
PluginWebFetchProviderEntry,
PluginWebSearchProviderEntry,
WebFetchCredentialResolutionSource,
WebFetchProviderContext,
WebFetchProviderId,
WebFetchProviderPlugin,
WebFetchProviderToolDefinition,
WebFetchRuntimeMetadataContext,
WebSearchCredentialResolutionSource,
WebSearchProviderContext,
WebSearchProviderId,
WebSearchProviderPlugin,
WebSearchProviderSetupContext,
WebSearchProviderToolDefinition,
WebSearchRuntimeMetadataContext,
} from "./web-provider-types.js";
export type PluginConfigValidation =
| { ok: true; value?: unknown }
@@ -169,51 +238,6 @@ export type OpenClawPluginConfigSchema = {
jsonSchema?: Record<string, unknown>;
};
/** Trusted execution context passed to plugin-owned agent tool factories. */
export type OpenClawPluginToolContext = {
config?: OpenClawConfig;
/** Active runtime-resolved config snapshot when one is available. */
runtimeConfig?: OpenClawConfig;
/** Effective filesystem policy for the active tool run. */
fsPolicy?: ToolFsPolicy;
workspaceDir?: string;
agentDir?: string;
agentId?: string;
sessionKey?: string;
/** Ephemeral session UUID - regenerated on /new and /reset. Use for per-conversation isolation. */
sessionId?: string;
browser?: {
sandboxBridgeUrl?: string;
allowHostControl?: boolean;
};
messageChannel?: string;
agentAccountId?: string;
/** Trusted ambient delivery route for the active agent/session. */
deliveryContext?: DeliveryContext;
/** Trusted sender id from inbound context (runtime-provided, not tool args). */
requesterSenderId?: string;
/** Whether the trusted sender is an owner. */
senderIsOwner?: boolean;
sandboxed?: boolean;
};
export type OpenClawPluginToolFactory = (
ctx: OpenClawPluginToolContext,
) => AnyAgentTool | AnyAgentTool[] | null | undefined;
export type OpenClawPluginToolOptions = {
name?: string;
names?: string[];
optional?: boolean;
};
export type OpenClawPluginHookOptions = {
entry?: HookEntry;
name?: string;
description?: string;
register?: boolean;
};
export type ProviderAuthKind = "oauth" | "api_key" | "token" | "device_code" | "custom";
/** Standard result payload returned by provider auth methods. */
@@ -1059,35 +1083,6 @@ export type ProviderModelSelectedContext = {
workspaceDir?: string;
};
export type ProviderResolveSyntheticAuthContext = {
config?: OpenClawConfig;
provider: string;
providerConfig?: ModelProviderConfig;
};
export type ProviderSyntheticAuthResult = {
apiKey: string;
source: string;
mode: Exclude<ModelProviderAuthMode, "aws-sdk">;
};
export type ProviderResolveExternalOAuthProfilesContext = {
config?: OpenClawConfig;
agentDir?: string;
workspaceDir?: string;
env: NodeJS.ProcessEnv;
store: AuthProfileStore;
};
export type ProviderResolveExternalAuthProfilesContext =
ProviderResolveExternalOAuthProfilesContext;
export type ProviderExternalOAuthProfile = {
profileId: string;
credential: OAuthCredential;
persistence?: "runtime-only" | "persisted";
};
export type ProviderExternalAuthProfile = ProviderExternalOAuthProfile;
export type ProviderDeferSyntheticProfileAuthContext = {
config?: OpenClawConfig;
provider: string;
@@ -1644,140 +1639,6 @@ export type ProviderPlugin = {
onModelSelected?: (ctx: ProviderModelSelectedContext) => Promise<void>;
};
export type WebSearchProviderId = string;
export type WebFetchProviderId = string;
export type WebSearchProviderToolDefinition = {
description: string;
parameters: Record<string, unknown>;
execute: (args: Record<string, unknown>) => Promise<Record<string, unknown>>;
};
export type WebFetchProviderToolDefinition = {
description: string;
parameters: Record<string, unknown>;
execute: (args: Record<string, unknown>) => Promise<Record<string, unknown>>;
};
export type WebSearchProviderContext = {
config?: OpenClawConfig;
searchConfig?: Record<string, unknown>;
runtimeMetadata?: RuntimeWebSearchMetadata;
};
export type WebFetchProviderContext = {
config?: OpenClawConfig;
fetchConfig?: Record<string, unknown>;
runtimeMetadata?: RuntimeWebFetchMetadata;
};
export type WebSearchCredentialResolutionSource = "config" | "secretRef" | "env" | "missing";
export type WebSearchRuntimeMetadataContext = {
config?: OpenClawConfig;
searchConfig?: Record<string, unknown>;
runtimeMetadata?: RuntimeWebSearchMetadata;
resolvedCredential?: {
value?: string;
source: WebSearchCredentialResolutionSource;
fallbackEnvVar?: string;
};
};
export type WebSearchProviderSetupContext = {
config: OpenClawConfig;
runtime: RuntimeEnv;
prompter: WizardPrompter;
quickstartDefaults?: boolean;
secretInputMode?: SecretInputMode;
};
export type WebFetchCredentialResolutionSource = "config" | "secretRef" | "env" | "missing";
export type WebFetchRuntimeMetadataContext = {
config?: OpenClawConfig;
fetchConfig?: Record<string, unknown>;
runtimeMetadata?: RuntimeWebFetchMetadata;
resolvedCredential?: {
value?: string;
source: WebFetchCredentialResolutionSource;
fallbackEnvVar?: string;
};
};
export type WebSearchProviderPlugin = {
id: WebSearchProviderId;
label: string;
hint: string;
/**
* Interactive onboarding surfaces where this search provider should appear
* when OpenClaw has no config-aware runtime context yet.
*
* Unlike provider auth, search setup historically exposed only a curated
* quickstart subset. Keep this plugin-owned so core does not hardcode the
* default bundled provider list.
*/
onboardingScopes?: Array<"text-inference">;
requiresCredential?: boolean;
credentialLabel?: string;
envVars: string[];
placeholder: string;
signupUrl: string;
docsUrl?: string;
autoDetectOrder?: number;
credentialPath: string;
inactiveSecretPaths?: string[];
getCredentialValue: (searchConfig?: Record<string, unknown>) => unknown;
setCredentialValue: (searchConfigTarget: Record<string, unknown>, value: unknown) => void;
getConfiguredCredentialValue?: (config?: OpenClawConfig) => unknown;
setConfiguredCredentialValue?: (configTarget: OpenClawConfig, value: unknown) => void;
applySelectionConfig?: (config: OpenClawConfig) => OpenClawConfig;
runSetup?: (ctx: WebSearchProviderSetupContext) => OpenClawConfig | Promise<OpenClawConfig>;
resolveRuntimeMetadata?: (
ctx: WebSearchRuntimeMetadataContext,
) => Partial<RuntimeWebSearchMetadata> | Promise<Partial<RuntimeWebSearchMetadata>>;
createTool: (ctx: WebSearchProviderContext) => WebSearchProviderToolDefinition | null;
};
export type PluginWebSearchProviderEntry = WebSearchProviderPlugin & {
pluginId: string;
};
export type WebFetchProviderPlugin = {
id: WebFetchProviderId;
label: string;
hint: string;
requiresCredential?: boolean;
credentialLabel?: string;
envVars: string[];
placeholder: string;
signupUrl: string;
docsUrl?: string;
autoDetectOrder?: number;
/** Canonical plugin-owned config path for this provider's primary fetch credential. */
credentialPath: string;
/**
* Legacy or inactive credential paths that should warn but not activate this provider.
* Include credentialPath here when overriding the list, because runtime classification
* treats inactiveSecretPaths as the full inactive surface for this provider.
*/
inactiveSecretPaths?: string[];
getCredentialValue: (fetchConfig?: Record<string, unknown>) => unknown;
setCredentialValue: (fetchConfigTarget: Record<string, unknown>, value: unknown) => void;
getConfiguredCredentialValue?: (config?: OpenClawConfig) => unknown;
setConfiguredCredentialValue?: (configTarget: OpenClawConfig, value: unknown) => void;
/** Apply the minimal config needed to select this provider without scattering plugin config writes in core. */
applySelectionConfig?: (config: OpenClawConfig) => OpenClawConfig;
resolveRuntimeMetadata?: (
ctx: WebFetchRuntimeMetadataContext,
) => Partial<RuntimeWebFetchMetadata> | Promise<Partial<RuntimeWebFetchMetadata>>;
createTool: (ctx: WebFetchProviderContext) => WebFetchProviderToolDefinition | null;
};
export type PluginWebFetchProviderEntry = WebFetchProviderPlugin & {
pluginId: string;
};
/** Speech capability registered by a plugin. */
export type SpeechProviderPlugin = {
id: SpeechProviderId;
@@ -1893,61 +1754,6 @@ export type PluginCommandContext = {
getCurrentConversationBinding: () => Promise<PluginConversationBinding | null>;
};
export type PluginConversationBindingRequestParams = {
summary?: string;
detachHint?: string;
};
export type PluginConversationBindingResolutionDecision = "allow-once" | "allow-always" | "deny";
export type PluginConversationBinding = {
bindingId: string;
pluginId: string;
pluginName?: string;
pluginRoot: string;
channel: string;
accountId: string;
conversationId: string;
parentConversationId?: string;
threadId?: string | number;
boundAt: number;
summary?: string;
detachHint?: string;
};
export type PluginConversationBindingRequestResult =
| {
status: "bound";
binding: PluginConversationBinding;
}
| {
status: "pending";
approvalId: string;
reply: ReplyPayload;
}
| {
status: "error";
message: string;
};
export type PluginConversationBindingResolvedEvent = {
status: "approved" | "denied";
binding?: PluginConversationBinding;
decision: PluginConversationBindingResolutionDecision;
request: {
summary?: string;
detachHint?: string;
requestedBySenderId?: string;
conversation: {
channel: string;
accountId: string;
conversationId: string;
parentConversationId?: string;
threadId?: string | number;
};
};
};
/**
* Result returned by a plugin command handler.
*/
@@ -2356,8 +2162,6 @@ export type OpenClawPluginApi = {
) => void;
};
export type PluginOrigin = "bundled" | "global" | "workspace" | "config";
export type PluginFormat = "openclaw" | "bundle";
export type PluginBundleFormat = "codex" | "claude" | "cursor";
@@ -2560,40 +2364,6 @@ export type PluginHookAfterCompactionEvent = {
sessionFile?: string;
};
// Message context
export type PluginHookMessageContext = {
channelId: string;
accountId?: string;
conversationId?: string;
};
export type PluginHookInboundClaimContext = PluginHookMessageContext & {
parentConversationId?: string;
senderId?: string;
messageId?: string;
};
export type PluginHookInboundClaimEvent = {
content: string;
body?: string;
bodyForAgent?: string;
transcript?: string;
timestamp?: number;
channel: string;
accountId?: string;
conversationId?: string;
parentConversationId?: string;
senderId?: string;
senderName?: string;
senderUsername?: string;
threadId?: string | number;
messageId?: string;
isGroup: boolean;
commandAuthorized?: boolean;
wasMentioned?: boolean;
metadata?: Record<string, unknown>;
};
export type PluginHookInboundClaimResult = {
handled: boolean;
};
@@ -2669,34 +2439,6 @@ export type PluginHookReplyDispatchResult = {
counts: Record<ReplyDispatchKind, number>;
};
// message_received hook
export type PluginHookMessageReceivedEvent = {
from: string;
content: string;
timestamp?: number;
metadata?: Record<string, unknown>;
};
// message_sending hook
export type PluginHookMessageSendingEvent = {
to: string;
content: string;
metadata?: Record<string, unknown>;
};
export type PluginHookMessageSendingResult = {
content?: string;
cancel?: boolean;
};
// message_sent hook
export type PluginHookMessageSentEvent = {
to: string;
content: string;
success: boolean;
error?: string;
};
// Tool context
export type PluginHookToolContext = {
agentId?: string;

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
export type RealtimeTranscriptionProviderId = string;

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
export type RealtimeVoiceProviderId = string;

View File

@@ -1,7 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import { describeFailoverError, isFailoverError } from "../agents/failover-error.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {
@@ -16,16 +15,14 @@ import { parseVideoGenerationModelRef } from "./model-ref.js";
import { resolveVideoGenerationOverrides } from "./normalization.js";
import { getVideoGenerationProvider, listVideoGenerationProviders } from "./provider-registry.js";
import type {
GeneratedVideoAsset,
VideoGenerationIgnoredOverride,
VideoGenerationNormalization,
VideoGenerationProviderOptionType,
VideoGenerationResolution,
VideoGenerationResult,
VideoGenerationSourceAsset,
} from "./types.js";
import type { GenerateVideoParams, GenerateVideoRuntimeResult } from "./runtime-types.js";
const log = createSubsystemLogger("video-generation");
export type { GenerateVideoParams, GenerateVideoRuntimeResult } from "./runtime-types.js";
/**
* Validate agent-supplied providerOptions against the candidate's declared
@@ -38,7 +35,7 @@ const log = createSubsystemLogger("video-generation");
* the safe default for legacy / not-yet-migrated providers.
* - Provider explicitly declares an empty schema ({}): rejects any options.
* This is the opt-in signal that the provider has been audited and truly
* supports no provider-specific options.
* supports no options.
* - Provider declares a typed schema: validates each key name and value type,
* skipping the candidate on any mismatch.
*/
@@ -53,11 +50,9 @@ function validateProviderOptionsAgainstDeclaration(params: {
if (keys.length === 0) {
return undefined;
}
// Undeclared schema: pass through for backward compatibility.
if (declaration === undefined) {
return undefined;
}
// Explicitly declared empty schema: provider accepts no options.
if (Object.keys(declaration).length === 0) {
return `${providerId}/${model} does not accept providerOptions (caller supplied: ${keys.join(", ")}); skipping`;
}
@@ -83,35 +78,6 @@ function validateProviderOptionsAgainstDeclaration(params: {
return undefined;
}
export type GenerateVideoParams = {
cfg: OpenClawConfig;
prompt: string;
agentDir?: string;
authStore?: AuthProfileStore;
modelOverride?: string;
size?: string;
aspectRatio?: string;
resolution?: VideoGenerationResolution;
durationSeconds?: number;
audio?: boolean;
watermark?: boolean;
inputImages?: VideoGenerationSourceAsset[];
inputVideos?: VideoGenerationSourceAsset[];
inputAudios?: VideoGenerationSourceAsset[];
/** Arbitrary provider-specific options forwarded as-is to provider.generateVideo. Core does not validate or log the contents. */
providerOptions?: Record<string, unknown>;
};
export type GenerateVideoRuntimeResult = {
videos: GeneratedVideoAsset[];
provider: string;
model: string;
attempts: FallbackAttempt[];
normalization?: VideoGenerationNormalization;
metadata?: Record<string, unknown>;
ignoredOverrides: VideoGenerationIgnoredOverride[];
};
function buildNoVideoGenerationModelConfiguredMessage(cfg: OpenClawConfig): string {
return buildNoCapabilityModelConfiguredMessage({
capabilityLabel: "video-generation",

View File

@@ -1,6 +1,6 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/types.js";
import type { MediaNormalizationEntry } from "../media-generation/runtime-shared.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { MediaNormalizationEntry } from "../media-generation/normalization.types.js";
export type GeneratedVideoAsset = {
buffer: Buffer;

View File

@@ -1,6 +1,6 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { PluginWebSearchProviderEntry } from "../plugins/types.js";
import type { PluginWebSearchProviderEntry } from "../plugins/web-provider-types.js";
import {
createWebSearchTestProvider,
type WebSearchTestProviderParams,

View File

@@ -1,9 +1,9 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { logVerbose } from "../globals.js";
import type {
PluginWebSearchProviderEntry,
WebSearchProviderToolDefinition,
} from "../plugins/types.js";
} from "../plugins/web-provider-types.js";
import { resolvePluginWebSearchProviders } from "../plugins/web-search-providers.runtime.js";
import { resolveRuntimeWebSearchProviders } from "../plugins/web-search-providers.runtime.js";
import { sortWebSearchProvidersForAutoDetect } from "../plugins/web-search-providers.shared.js";
@@ -20,24 +20,22 @@ import {
resolveWebProviderConfig,
resolveWebProviderDefinition,
} from "../web/provider-runtime-shared.js";
import type {
ResolveWebSearchDefinitionParams,
RunWebSearchParams,
RunWebSearchResult,
RuntimeWebSearchConfig as WebSearchConfig,
} from "./runtime-types.js";
type WebSearchConfig = NonNullable<OpenClawConfig["tools"]>["web"] extends infer Web
? Web extends { search?: infer Search }
? Search
: undefined
: undefined;
export type ResolveWebSearchDefinitionParams = {
config?: OpenClawConfig;
sandboxed?: boolean;
runtimeWebSearch?: RuntimeWebSearchMetadata;
providerId?: string;
preferRuntimeProviders?: boolean;
};
export type RunWebSearchParams = ResolveWebSearchDefinitionParams & {
args: Record<string, unknown>;
};
export type {
ListWebSearchProvidersParams,
ResolveWebSearchDefinitionParams,
RunWebSearchParams,
RunWebSearchResult,
RuntimeWebSearchConfig,
RuntimeWebSearchProviderEntry,
RuntimeWebSearchToolDefinition,
} from "./runtime-types.js";
function resolveSearchConfig(cfg?: OpenClawConfig): WebSearchConfig {
return resolveWebProviderConfig<"search", NonNullable<WebSearchConfig>>(cfg, "search");
@@ -296,9 +294,7 @@ function hasExplicitWebSearchSelection(params: {
return false;
}
export async function runWebSearch(
params: RunWebSearchParams,
): Promise<{ provider: string; result: Record<string, unknown> }> {
export async function runWebSearch(params: RunWebSearchParams): Promise<RunWebSearchResult> {
const search = resolveSearchConfig(params.config);
const runtimeWebSearch = params.runtimeWebSearch ?? getActiveRuntimeWebToolsMetadata()?.search;
const candidates = resolveWebSearchCandidates({