fix(cycles): add remaining seam files

This commit is contained in:
Vincent Koc
2026-04-11 10:39:16 +01:00
parent 7308e72fac
commit 08ba5a72f7
20 changed files with 847 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
import type { CompactEmbeddedPiSessionParams } from "./compact.types.js";
import type { EmbeddedPiCompactResult } from "./types.js";
export type CompactEmbeddedPiSessionDirect = (
params: CompactEmbeddedPiSessionParams,
) => Promise<EmbeddedPiCompactResult>;

View File

@@ -0,0 +1,76 @@
import { type DeliveryContext, normalizeDeliveryContext } from "../utils/delivery-context.js";
import { subagentRuns } from "./subagent-registry-memory.js";
import {
countPendingDescendantRunsExcludingRunFromRuns,
countPendingDescendantRunsFromRuns,
findRunIdsByChildSessionKeyFromRuns,
listRunsForRequesterFromRuns,
resolveRequesterForChildSessionFromRuns,
shouldIgnorePostCompletionAnnounceForSessionFromRuns,
} from "./subagent-registry-queries.js";
import { getSubagentRunsSnapshotForRead } from "./subagent-registry-state.js";
import type { SubagentRunRecord } from "./subagent-registry.types.js";
export function resolveRequesterForChildSession(childSessionKey: string): {
requesterSessionKey: string;
requesterOrigin?: DeliveryContext;
} | null {
const resolved = resolveRequesterForChildSessionFromRuns(
getSubagentRunsSnapshotForRead(subagentRuns),
childSessionKey,
);
if (!resolved) {
return null;
}
return {
requesterSessionKey: resolved.requesterSessionKey,
requesterOrigin: normalizeDeliveryContext(resolved.requesterOrigin),
};
}
export function isSubagentSessionRunActive(childSessionKey: string): boolean {
const runIds = findRunIdsByChildSessionKeyFromRuns(subagentRuns, childSessionKey);
let latest: SubagentRunRecord | undefined;
for (const runId of runIds) {
const entry = subagentRuns.get(runId);
if (!entry) {
continue;
}
if (!latest || entry.createdAt > latest.createdAt) {
latest = entry;
}
}
return Boolean(latest && typeof latest.endedAt !== "number");
}
export function shouldIgnorePostCompletionAnnounceForSession(childSessionKey: string): boolean {
return shouldIgnorePostCompletionAnnounceForSessionFromRuns(
getSubagentRunsSnapshotForRead(subagentRuns),
childSessionKey,
);
}
export function listSubagentRunsForRequester(
requesterSessionKey: string,
options?: { requesterRunId?: string },
): SubagentRunRecord[] {
return listRunsForRequesterFromRuns(subagentRuns, requesterSessionKey, options);
}
export function countPendingDescendantRuns(rootSessionKey: string): number {
return countPendingDescendantRunsFromRuns(
getSubagentRunsSnapshotForRead(subagentRuns),
rootSessionKey,
);
}
export function countPendingDescendantRunsExcludingRun(
rootSessionKey: string,
excludeRunId: string,
): number {
return countPendingDescendantRunsExcludingRunFromRuns(
getSubagentRunsSnapshotForRead(subagentRuns),
rootSessionKey,
excludeRunId,
);
}

View File

@@ -0,0 +1,25 @@
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { FinalizedMsgContext } from "../templating.js";
import type { GetReplyOptions } from "../types.js";
import type { ReplyDispatcher, ReplyDispatchKind } from "./reply-dispatcher.js";
export type DispatchFromConfigResult = {
queuedFinal: boolean;
counts: Record<ReplyDispatchKind, number>;
};
export type DispatchFromConfigParams = {
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;
};
export type DispatchReplyFromConfig = (
params: DispatchFromConfigParams,
) => Promise<DispatchFromConfigResult>;

View File

@@ -0,0 +1,112 @@
import type { ReplyPayload } from "../../auto-reply/types.js";
import type { OpenClawConfig } from "../../config/types.openclaw.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 { OutboundMediaAccess } from "../../media/load-options.js";
import type {
ChannelOutboundTargetMode,
ChannelPollContext,
ChannelPollResult,
} from "./types.core.js";
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>;
};

View File

@@ -0,0 +1,6 @@
import type { ChannelId } from "../channel-id.types.js";
import type { ChannelOutboundAdapter } from "../outbound.types.js";
export type LoadChannelOutboundAdapter = (
id: ChannelId,
) => Promise<ChannelOutboundAdapter | undefined>;

View File

@@ -0,0 +1,13 @@
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { RuntimeEnv } from "../../runtime.js";
export type ChannelPairingAdapter = {
idLabel: string;
normalizeAllowEntry?: (entry: string) => string;
notifyApproval?: (params: {
cfg: OpenClawConfig;
id: string;
accountId?: string;
runtime?: RuntimeEnv;
}) => Promise<void>;
};

View File

@@ -0,0 +1,12 @@
import type { OpenClawConfig } from "./config.js";
import type { MarkdownTableMode } from "./types.base.js";
export type ResolveMarkdownTableModeParams = {
cfg?: Partial<OpenClawConfig>;
channel?: string | null;
accountId?: string | null;
};
export type ResolveMarkdownTableMode = (
params: ResolveMarkdownTableModeParams,
) => MarkdownTableMode;

View File

@@ -0,0 +1,22 @@
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;

View File

@@ -0,0 +1,40 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type {
GeneratedImageAsset,
ImageGenerationIgnoredOverride,
ImageGenerationNormalization,
ImageGenerationProvider,
ImageGenerationResolution,
ImageGenerationSourceImage,
} from "./types.js";
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 ListRuntimeImageGenerationProvidersParams = {
config?: OpenClawConfig;
};
export type RuntimeImageGenerationProvider = ImageGenerationProvider;

View File

@@ -0,0 +1,15 @@
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>;
};

View File

@@ -0,0 +1,41 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type {
GeneratedMusicAsset,
MusicGenerationIgnoredOverride,
MusicGenerationNormalization,
MusicGenerationOutputFormat,
MusicGenerationProvider,
MusicGenerationSourceImage,
} from "./types.js";
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 ListRuntimeMusicGenerationProvidersParams = {
config?: OpenClawConfig;
};
export type RuntimeMusicGenerationProvider = MusicGenerationProvider;

View File

@@ -0,0 +1,74 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
coreDrainPendingDeliveries: vi.fn(async () => {}),
deliverOutboundPayloads: vi.fn(async () => []),
}));
vi.mock("../infra/outbound/delivery-queue.js", () => ({
drainPendingDeliveries: mocks.coreDrainPendingDeliveries,
}));
vi.mock("../infra/outbound/deliver-runtime.js", () => ({
deliverOutboundPayloads: mocks.deliverOutboundPayloads,
}));
type InfraRuntimeModule = typeof import("./infra-runtime.js");
let drainPendingDeliveries: InfraRuntimeModule["drainPendingDeliveries"];
const log = {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
beforeAll(async () => {
({ drainPendingDeliveries } = await import("./infra-runtime.js"));
});
beforeEach(() => {
mocks.coreDrainPendingDeliveries.mockClear();
mocks.deliverOutboundPayloads.mockClear();
log.info.mockClear();
log.warn.mockClear();
log.error.mockClear();
});
describe("plugin-sdk drainPendingDeliveries", () => {
it("injects the lazy outbound deliver runtime when no deliver fn is provided", async () => {
await drainPendingDeliveries({
drainKey: "whatsapp:test",
logLabel: "WhatsApp reconnect drain",
cfg: {},
log,
selectEntry: () => ({ match: false }),
});
expect(mocks.coreDrainPendingDeliveries).toHaveBeenCalledWith(
expect.objectContaining({
deliver: mocks.deliverOutboundPayloads,
}),
);
});
it("preserves an explicit deliver fn without loading the lazy runtime", async () => {
const deliver = vi.fn(async () => []);
await drainPendingDeliveries({
drainKey: "whatsapp:test",
logLabel: "WhatsApp reconnect drain",
cfg: {},
log,
deliver,
selectEntry: () => ({ match: false }),
});
expect(mocks.coreDrainPendingDeliveries).toHaveBeenCalledWith(
expect.objectContaining({
deliver,
}),
);
expect(mocks.deliverOutboundPayloads).not.toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,56 @@
import type { ReplyPayload } from "../auto-reply/types.js";
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;
};
};
};

View File

@@ -0,0 +1,57 @@
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 PluginHookMessageReceivedEvent = {
from: string;
content: string;
timestamp?: number;
metadata?: Record<string, unknown>;
};
export type PluginHookMessageSendingEvent = {
to: string;
content: string;
metadata?: Record<string, unknown>;
};
export type PluginHookMessageSendingResult = {
content?: string;
cancel?: boolean;
};
export type PluginHookMessageSentEvent = {
to: string;
content: string;
success: boolean;
error?: string;
};

View File

@@ -0,0 +1 @@
export type PluginOrigin = "bundled" | "global" | "workspace" | "config";

View File

@@ -0,0 +1,34 @@
import type { AuthProfileStore, OAuthCredential } from "../agents/auth-profiles/types.js";
import type { ModelProviderAuthMode, ModelProviderConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
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;

50
src/plugins/tool-types.ts Normal file
View File

@@ -0,0 +1,50 @@
import type { ToolFsPolicy } from "../agents/tool-fs-policy.js";
import type { AnyAgentTool } from "../agents/tools/common.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { HookEntry } from "../hooks/types.js";
import type { DeliveryContext } from "../utils/delivery-context.js";
/** 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;
};

View File

@@ -0,0 +1,127 @@
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { RuntimeEnv } from "../runtime.js";
import type {
RuntimeWebFetchMetadata,
RuntimeWebSearchMetadata,
} from "../secrets/runtime-web-tools.types.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import type { SecretInputMode } from "./provider-auth-types.js";
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;
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;
credentialPath: string;
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;
applySelectionConfig?: (config: OpenClawConfig) => OpenClawConfig;
resolveRuntimeMetadata?: (
ctx: WebFetchRuntimeMetadataContext,
) => Partial<RuntimeWebFetchMetadata> | Promise<Partial<RuntimeWebFetchMetadata>>;
createTool: (ctx: WebFetchProviderContext) => WebFetchProviderToolDefinition | null;
};
export type PluginWebFetchProviderEntry = WebFetchProviderPlugin & {
pluginId: string;
};

View File

@@ -0,0 +1,43 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type {
GeneratedVideoAsset,
VideoGenerationIgnoredOverride,
VideoGenerationNormalization,
VideoGenerationProvider,
VideoGenerationResolution,
VideoGenerationSourceAsset,
} from "./types.js";
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[];
};
export type GenerateVideoRuntimeResult = {
videos: GeneratedVideoAsset[];
provider: string;
model: string;
attempts: FallbackAttempt[];
normalization?: VideoGenerationNormalization;
metadata?: Record<string, unknown>;
ignoredOverrides: VideoGenerationIgnoredOverride[];
};
export type ListRuntimeVideoGenerationProvidersParams = {
config?: OpenClawConfig;
};
export type RuntimeVideoGenerationProvider = VideoGenerationProvider;

View File

@@ -0,0 +1,37 @@
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type {
PluginWebSearchProviderEntry,
WebSearchProviderToolDefinition,
} from "../plugins/web-provider-types.js";
import type { RuntimeWebSearchMetadata } from "../secrets/runtime-web-tools.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 RunWebSearchResult = {
provider: string;
result: Record<string, unknown>;
};
export type ListWebSearchProvidersParams = {
config?: OpenClawConfig;
};
export type RuntimeWebSearchProviderEntry = PluginWebSearchProviderEntry;
export type RuntimeWebSearchToolDefinition = WebSearchProviderToolDefinition;
export type RuntimeWebSearchConfig = WebSearchConfig;