fix(cycles): split residual shared type seams

This commit is contained in:
Vincent Koc
2026-04-11 00:47:42 +01:00
parent 707cc315cc
commit 95bc417944
81 changed files with 214 additions and 428 deletions

View File

@@ -1,9 +1,9 @@
import fs from "node:fs";
import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import { resolveAgentModelFallbackValues } from "../config/model-input.js";
import { resolveStateDir } from "../config/paths.js";
import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js";
import type { OpenClawConfig } from "../config/types.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {
DEFAULT_AGENT_ID,

View File

@@ -6,22 +6,13 @@ import {
normalizeOptionalString,
} from "../shared/string-coerce.js";
import { resolveOpenClawAgentDir } from "./agent-paths.js";
import type { ModelCatalogEntry, ModelInputType } from "./model-catalog.types.js";
import { ensureOpenClawModelsJson } from "./models-config.js";
import { normalizeProviderId } from "./provider-id.js";
const log = createSubsystemLogger("model-catalog");
export type ModelInputType = "text" | "image" | "document";
export type ModelCatalogEntry = {
id: string;
name: string;
provider: string;
alias?: string;
contextWindow?: number;
reasoning?: boolean;
input?: ModelInputType[];
};
export type { ModelCatalogEntry, ModelInputType } from "./model-catalog.types.js";
type DiscoveredModel = {
id: string;

View File

@@ -0,0 +1,11 @@
export type ModelInputType = "text" | "image" | "document";
export type ModelCatalogEntry = {
id: string;
name: string;
provider: string;
alias?: string;
contextWindow?: number;
reasoning?: boolean;
input?: ModelInputType[];
};

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../../config/config.js";
import type { OpenClawConfig } from "../../config/types.js";
import { normalizeAgentId } from "../../routing/session-key.js";
import { normalizeSkillFilter } from "./filter.js";

View File

@@ -0,0 +1,3 @@
import type { ChatChannelId } from "../ids.js";
export type ChannelId = ChatChannelId | (string & {});

View File

@@ -12,9 +12,9 @@ import {
type ConfigWriteTargetLike,
} from "./config-write-policy-shared.js";
import type { ChannelId } from "./types.core.js";
export type ConfigWriteScope = ConfigWriteScopeLike;
export type ConfigWriteTarget = ConfigWriteTargetLike;
export type ConfigWriteAuthorizationResult = ConfigWriteAuthorizationResultLike;
export type ConfigWriteScope = ConfigWriteScopeLike<ChannelId>;
export type ConfigWriteTarget = ConfigWriteTargetLike<ChannelId>;
export type ConfigWriteAuthorizationResult = ConfigWriteAuthorizationResultLike<ChannelId>;
function isInternalConfigWriteMessageChannel(channel?: string | null): boolean {
return normalizeLowercaseStringOrEmpty(channel) === "webchat";

View File

@@ -18,269 +18,7 @@ export type ChannelSetupPlugin = {
config: ChannelConfigAdapter<unknown>;
setup?: ChannelSetupAdapter;
setupWizard?: ChannelSetupWizard | ChannelSetupWizardAdapter;
};
export type ChannelSetupWizardStatus = {
configuredLabel: string;
unconfiguredLabel: string;
configuredHint?: string;
unconfiguredHint?: string;
configuredScore?: number;
unconfiguredScore?: number;
resolveConfigured: (params: {
cfg: OpenClawConfig;
accountId?: string;
}) => boolean | Promise<boolean>;
resolveStatusLines?: (params: {
cfg: OpenClawConfig;
accountId?: string;
configured: boolean;
}) => string[] | Promise<string[]>;
resolveSelectionHint?: (params: {
cfg: OpenClawConfig;
accountId?: string;
configured: boolean;
}) => string | undefined | Promise<string | undefined>;
resolveQuickstartScore?: (params: {
cfg: OpenClawConfig;
accountId?: string;
configured: boolean;
}) => number | undefined | Promise<number | undefined>;
};
export type ChannelSetupWizardCredentialState = {
accountConfigured: boolean;
hasConfiguredValue: boolean;
resolvedValue?: string;
envValue?: string;
};
export type ChannelSetupWizardCredentialValues = Partial<Record<string, string>>;
export type ChannelSetupWizardNote = {
title: string;
lines: string[];
shouldShow?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
}) => boolean | Promise<boolean>;
};
export type ChannelSetupWizardEnvShortcut = {
prompt: string;
preferredEnvVar?: string;
isAvailable: (params: { cfg: OpenClawConfig; accountId: string }) => boolean;
apply: (params: {
cfg: OpenClawConfig;
accountId: string;
}) => OpenClawConfig | Promise<OpenClawConfig>;
};
export type ChannelSetupWizardCredential = {
inputKey: keyof ChannelSetupInput;
providerHint: string;
credentialLabel: string;
preferredEnvVar?: string;
helpTitle?: string;
helpLines?: string[];
envPrompt: string;
keepPrompt: string;
inputPrompt: string;
allowEnv?: (params: { cfg: OpenClawConfig; accountId: string }) => boolean;
inspect: (params: {
cfg: OpenClawConfig;
accountId: string;
}) => ChannelSetupWizardCredentialState;
shouldPrompt?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
currentValue?: string;
state: ChannelSetupWizardCredentialState;
}) => boolean | Promise<boolean>;
applyUseEnv?: (params: {
cfg: OpenClawConfig;
accountId: string;
}) => OpenClawConfig | Promise<OpenClawConfig>;
applySet?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
value: unknown;
resolvedValue: string;
}) => OpenClawConfig | Promise<OpenClawConfig>;
};
export type ChannelSetupWizardTextInput = {
inputKey: keyof ChannelSetupInput;
message: string;
placeholder?: string;
required?: boolean;
applyEmptyValue?: boolean;
helpTitle?: string;
helpLines?: string[];
confirmCurrentValue?: boolean;
keepPrompt?: string | ((value: string) => string);
currentValue?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
}) => string | undefined | Promise<string | undefined>;
initialValue?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
}) => string | undefined | Promise<string | undefined>;
shouldPrompt?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
currentValue?: string;
}) => boolean | Promise<boolean>;
applyCurrentValue?: boolean;
validate?: (params: {
value: string;
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
}) => string | undefined;
normalizeValue?: (params: {
value: string;
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
}) => string;
applySet?: (params: {
cfg: OpenClawConfig;
accountId: string;
value: string;
}) => OpenClawConfig | Promise<OpenClawConfig>;
};
export type ChannelSetupWizardAllowFromEntry = {
input: string;
resolved: boolean;
id: string | null;
};
export type ChannelSetupWizardAllowFrom = {
helpTitle?: string;
helpLines?: string[];
credentialInputKey?: keyof ChannelSetupInput;
message: string;
placeholder: string;
invalidWithoutCredentialNote: string;
parseInputs?: (raw: string) => string[];
parseId: (raw: string) => string | null;
resolveEntries: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
entries: string[];
}) => Promise<ChannelSetupWizardAllowFromEntry[]>;
apply: (params: {
cfg: OpenClawConfig;
accountId: string;
allowFrom: string[];
}) => OpenClawConfig | Promise<OpenClawConfig>;
};
export type ChannelSetupWizardGroupAccess = {
label: string;
placeholder: string;
helpTitle?: string;
helpLines?: string[];
skipAllowlistEntries?: boolean;
currentPolicy: (params: { cfg: OpenClawConfig; accountId: string }) => ChannelAccessPolicy;
currentEntries: (params: { cfg: OpenClawConfig; accountId: string }) => string[];
updatePrompt: (params: { cfg: OpenClawConfig; accountId: string }) => boolean;
setPolicy: (params: {
cfg: OpenClawConfig;
accountId: string;
policy: ChannelAccessPolicy;
}) => OpenClawConfig;
resolveAllowlist?: (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
entries: string[];
prompter: Pick<WizardPrompter, "note">;
}) => Promise<unknown>;
applyAllowlist?: (params: {
cfg: OpenClawConfig;
accountId: string;
resolved: unknown;
}) => OpenClawConfig;
};
export type ChannelSetupWizardPrepare = (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
runtime: ChannelSetupConfigureContext["runtime"];
prompter: WizardPrompter;
options?: ChannelSetupConfigureContext["options"];
}) =>
| {
cfg?: OpenClawConfig;
credentialValues?: ChannelSetupWizardCredentialValues;
}
| void
| Promise<{
cfg?: OpenClawConfig;
credentialValues?: ChannelSetupWizardCredentialValues;
} | void>;
export type ChannelSetupWizardFinalize = (params: {
cfg: OpenClawConfig;
accountId: string;
credentialValues: ChannelSetupWizardCredentialValues;
runtime: ChannelSetupConfigureContext["runtime"];
prompter: WizardPrompter;
options?: ChannelSetupConfigureContext["options"];
forceAllowFrom: boolean;
}) =>
| {
cfg?: OpenClawConfig;
credentialValues?: ChannelSetupWizardCredentialValues;
}
| void
| Promise<{
cfg?: OpenClawConfig;
credentialValues?: ChannelSetupWizardCredentialValues;
} | void>;
export type ChannelSetupWizard = {
channel: string;
status: ChannelSetupWizardStatus;
introNote?: ChannelSetupWizardNote;
envShortcut?: ChannelSetupWizardEnvShortcut;
resolveAccountIdForConfigure?: (params: {
cfg: OpenClawConfig;
prompter: WizardPrompter;
options?: ChannelSetupConfigureContext["options"];
accountOverride?: string;
shouldPromptAccountIds: boolean;
listAccountIds: ChannelSetupPlugin["config"]["listAccountIds"];
defaultAccountId: string;
}) => string | Promise<string>;
resolveShouldPromptAccountIds?: (params: {
cfg: OpenClawConfig;
options?: ChannelSetupConfigureContext["options"];
shouldPromptAccountIds: boolean;
}) => boolean;
prepare?: ChannelSetupWizardPrepare;
stepOrder?: "credentials-first" | "text-first";
credentials: ChannelSetupWizardCredential[];
textInputs?: ChannelSetupWizardTextInput[];
finalize?: ChannelSetupWizardFinalize;
completionNote?: ChannelSetupWizardNote;
dmPolicy?: ChannelSetupDmPolicy;
allowFrom?: ChannelSetupWizardAllowFrom;
groupAccess?: ChannelSetupWizardGroupAccess;
disable?: (cfg: OpenClawConfig) => OpenClawConfig;
onAccountRecorded?: ChannelSetupWizardAdapter["onAccountRecorded"];
setupWizard?: ChannelSetupWizard | ChannelSetupWizardAdapter;
};
export type SetupChannelsOptions = {

View File

@@ -36,6 +36,7 @@ import type {
} from "./types.core.js";
type ConfiguredBindingRule = AgentBinding;
export type { ChannelApprovalKind } from "../../infra/approval-handler-runtime-types.js";
export type ChannelActionAvailabilityState =
| { kind: "enabled" }
@@ -666,8 +667,7 @@ export type ChannelApprovalDeliveryAdapter = {
request: ExecApprovalRequest;
}) => boolean;
};
export type ChannelApprovalKind = "exec" | "plugin";
export type { ChannelApprovalKind } from "../../infra/approval-handler-runtime-types.js";
export type ChannelApproveCommandBehavior =
| { kind: "allow" }

View File

@@ -8,10 +8,11 @@ import type { GatewayClientMode, GatewayClientName } from "../../gateway/protoco
import type { OutboundMediaAccess } from "../../media/load-options.js";
import type { PollInput } from "../../polls.js";
import type { ChatType } from "../chat-type.js";
import type { ChannelId } from "./channel-id.types.js";
import type { ChannelMessageActionName as ChannelMessageActionNameFromList } from "./message-action-names.js";
import type { ChannelMessageCapability } from "./message-capabilities.js";
export type ChannelId = string & { readonly __openclawChannelIdBrand?: never };
export type { ChannelId } from "./channel-id.types.js";
export type ChannelExposure = {
configured?: boolean;

View File

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

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { defaultSlotIdForKey } from "../plugins/slots.js";
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
import type { ContextEngine } from "./types.js";

View File

@@ -60,6 +60,8 @@ export {
createLazyChannelApprovalNativeRuntimeAdapter,
};
export type {
ApprovalRequest,
ApprovalResolved,
ChannelApprovalCapabilityHandlerContext,
ChannelApprovalKind,
ChannelApprovalNativeAvailabilityAdapter,

View File

@@ -14,7 +14,7 @@ import type {
SessionBindingCapabilities,
SessionBindingRecord,
SessionBindingUnbindInput,
} from "./session-binding-service.js";
} from "./session-binding.types.js";
type PersistedCurrentConversationBindingsFile = {
version: 1;

View File

@@ -13,7 +13,7 @@ import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load
import type {
ChannelOutboundAdapter,
ChannelOutboundContext,
} from "../../channels/plugins/types.js";
} from "../../channels/plugins/types.adapters.js";
import { resolveMirroredTranscriptText } from "../../config/sessions/transcript-mirror.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import { fireAndForgetHook } from "../../hooks/fire-and-forget.js";
@@ -39,7 +39,6 @@ import type { NormalizedOutboundPayload } from "./payloads.js";
import { normalizeReplyPayloadsForDelivery } from "./payloads.js";
import { resolveOutboundSendDep, type OutboundSendDeps } from "./send-deps.js";
import type { OutboundSessionContext } from "./session-context.js";
import type { OutboundChannel } from "./targets.js";
export type { OutboundDeliveryResult } from "./deliver-types.js";
export type { NormalizedOutboundPayload } from "./payloads.js";

View File

@@ -12,54 +12,27 @@ import {
buildChannelAccountKey,
normalizeConversationRef,
} from "./session-binding-normalization.js";
import type {
ConversationRef,
SessionBindingBindInput,
SessionBindingCapabilities,
SessionBindingErrorCode,
SessionBindingPlacement,
SessionBindingRecord,
SessionBindingUnbindInput,
} from "./session-binding.types.js";
export type BindingTargetKind = "subagent" | "session";
export type BindingStatus = "active" | "ending" | "ended";
export type SessionBindingPlacement = "current" | "child";
export type SessionBindingErrorCode =
| "BINDING_ADAPTER_UNAVAILABLE"
| "BINDING_CAPABILITY_UNSUPPORTED"
| "BINDING_CREATE_FAILED";
export type ConversationRef = {
channel: string;
accountId: string;
conversationId: string;
parentConversationId?: string;
};
export type SessionBindingRecord = {
bindingId: string;
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
status: BindingStatus;
boundAt: number;
expiresAt?: number;
metadata?: Record<string, unknown>;
};
export type SessionBindingBindInput = {
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
placement?: SessionBindingPlacement;
metadata?: Record<string, unknown>;
ttlMs?: number;
};
export type SessionBindingUnbindInput = {
bindingId?: string;
targetSessionKey?: string;
reason: string;
};
export type SessionBindingCapabilities = {
adapterAvailable: boolean;
bindSupported: boolean;
unbindSupported: boolean;
placements: SessionBindingPlacement[];
};
export type {
BindingStatus,
BindingTargetKind,
ConversationRef,
SessionBindingBindInput,
SessionBindingCapabilities,
SessionBindingErrorCode,
SessionBindingPlacement,
SessionBindingRecord,
SessionBindingUnbindInput,
} from "./session-binding.types.js";
export class SessionBindingError extends Error {
constructor(

View File

@@ -0,0 +1,47 @@
export type BindingTargetKind = "subagent" | "session";
export type BindingStatus = "active" | "ending" | "ended";
export type SessionBindingPlacement = "current" | "child";
export type SessionBindingErrorCode =
| "BINDING_ADAPTER_UNAVAILABLE"
| "BINDING_CAPABILITY_UNSUPPORTED"
| "BINDING_CREATE_FAILED";
export type ConversationRef = {
channel: string;
accountId: string;
conversationId: string;
parentConversationId?: string;
};
export type SessionBindingRecord = {
bindingId: string;
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
status: BindingStatus;
boundAt: number;
expiresAt?: number;
metadata?: Record<string, unknown>;
};
export type SessionBindingBindInput = {
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
placement?: SessionBindingPlacement;
metadata?: Record<string, unknown>;
ttlMs?: number;
};
export type SessionBindingUnbindInput = {
bindingId?: string;
targetSessionKey?: string;
reason: string;
};
export type SessionBindingCapabilities = {
adapterAvailable: boolean;
bindSupported: boolean;
unbindSupported: boolean;
placements: SessionBindingPlacement[];
};

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
deriveAspectRatioFromSize,
normalizeDurationToClosestMax,

View File

@@ -3,12 +3,12 @@ import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
import { DEFAULT_PROVIDER } from "../agents/defaults.js";
import { resolveEnvApiKey } from "../agents/model-auth-env.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/config.js";
import {
resolveAgentModelFallbackValues,
resolveAgentModelPrimaryValue,
} from "../config/model-input.js";
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";

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { createSafeAudioFixtureBuffer } from "./runner.test-utils.js";
import type { MediaUnderstandingProvider } from "./types.js";

View File

@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { withEnvAsync } from "../test-utils/env.js";
import { createSafeAudioFixtureBuffer } from "./runner.test-utils.js";

View File

@@ -1,7 +1,7 @@
import path from "node:path";
import { finalizeInboundContext } from "../auto-reply/reply/inbound-context.js";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { logVerbose, shouldLogVerbose } from "../globals.js";
import { renderFileContextBlock } from "../media/file-context.js";
import {

View File

@@ -1,5 +1,5 @@
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { logVerbose, shouldLogVerbose } from "../globals.js";
import { isAudioAttachment } from "./attachments.js";
import { runAudioTranscription } from "./audio-transcription-runner.js";

View File

@@ -1,5 +1,5 @@
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
type ActiveMediaModel,
buildProviderRegistry,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import {
bundledProviderSupportsNativePdfDocument,

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
const mockDeliverOutboundPayloads = vi.hoisted(() => vi.fn());

View File

@@ -1,5 +1,5 @@
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { logVerbose, shouldLogVerbose } from "../globals.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { isDeliverableMessageChannel } from "../utils/message-channel.js";

View File

@@ -1,5 +1,5 @@
import { beforeAll, describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
createEmptyProviderRegistryAllowlistFallbackRegistry,
getProviderRegistryAllowlistMocks,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolvePluginCapabilityProviders } from "../plugins/capability-provider-runtime.js";
import { describeImageWithModel, describeImagesWithModel } from "./image-runtime.js";
import { normalizeMediaProviderId } from "./provider-id.js";

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolveEntriesWithActiveFallback, resolveModelEntries } from "./resolve.js";
import type { MediaUnderstandingCapability } from "./types.js";

View File

@@ -1,5 +1,5 @@
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type {
MediaUnderstandingConfig,
MediaUnderstandingModelConfig,

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { withEnvAsync } from "../test-utils/env.js";
import { runCapability } from "./runner.js";
import { withAudioFixture } from "./runner.test-utils.js";

View File

@@ -1,5 +1,5 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { withAudioFixture } from "./runner.test-utils.js";
const runExecMock = vi.hoisted(() => vi.fn());

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { buildProviderRegistry, runCapability } from "./runner.js";
import { withAudioFixture } from "./runner.test-utils.js";

View File

@@ -11,7 +11,7 @@ import {
} from "../agents/provider-request-config.js";
import type { MsgContext } from "../auto-reply/templating.js";
import { applyTemplate } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type {
MediaUnderstandingConfig,
MediaUnderstandingModelConfig,

View File

@@ -1,5 +1,5 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { withAudioFixture, withVideoFixture } from "./runner.test-utils.js";
import type { AudioTranscriptionRequest, VideoDescriptionRequest } from "./types.js";

View File

@@ -3,7 +3,7 @@ import os from "node:os";
import path from "node:path";
import { describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { MIN_AUDIO_FILE_BYTES } from "./defaults.js";
import { createMediaAttachmentCache, normalizeMediaAttachments } from "./runner.attachments.js";
import { buildProviderRegistry, runCapability } from "./runner.js";

View File

@@ -10,11 +10,11 @@ import {
} from "../agents/model-catalog.js";
import { findNormalizedProviderValue } from "../agents/provider-id.js";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import {
resolveAgentModelFallbackValues,
resolveAgentModelPrimaryValue,
} from "../config/model-input.js";
import type { OpenClawConfig } from "../config/types.js";
import type {
MediaUnderstandingConfig,
MediaUnderstandingModelConfig,

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { withTempDir } from "../test-helpers/temp-dir.js";
import { withEnvAsync } from "../test-utils/env.js";
import { runCapability } from "./runner.js";

View File

@@ -1,6 +1,6 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
withBundledPluginAllowlistCompat,
withBundledPluginEnablementCompat,

View File

@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { MediaAttachment, MediaUnderstandingOutput } from "../media-understanding/types.js";
import { describeImageFile, runMediaUnderstandingFile } from "./runtime.js";

View File

@@ -1,6 +1,6 @@
import fs from "node:fs/promises";
import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
buildProviderRegistry,
createMediaAttachmentCache,

View File

@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
const { transcribeAudioFileFromRuntime } = vi.hoisted(() => {
const transcribeAudioFileFromRuntime = vi.fn();

View File

@@ -4,7 +4,7 @@ import {
resolveIMessageAttachmentRoots,
resolveIMessageRemoteAttachmentRoots,
} from "../../test/helpers/channels/channel-media-roots-contract.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
describe("channel-inbound-roots contract", () => {
function expectResolvedRootsCase(resolve: () => string[], expected: readonly string[]) {

View File

@@ -1,6 +1,6 @@
import type { MsgContext } from "../auto-reply/templating.js";
import { getBootstrapChannelPlugin } from "../channels/plugins/bootstrap-registry.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
function findChannelMessagingAdapter(channelId?: string | null) {

View File

@@ -1,7 +1,7 @@
import path from "node:path";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import type { OpenClawConfig } from "../config/config.js";
import { resolveStateDir } from "../config/paths.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { resolveConfigDir } from "../utils.js";

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolveAgentScopedOutboundMediaAccess } from "./read-capability.js";
describe("resolveAgentScopedOutboundMediaAccess", () => {

View File

@@ -4,7 +4,7 @@ import { resolveGroupToolPolicy } from "../agents/pi-tools.policy.js";
import { resolveEffectiveToolFsRootExpansionAllowed } from "../agents/tool-fs-policy.js";
import { isToolAllowedByPolicies } from "../agents/tool-policy-match.js";
import { resolveWorkspaceRoot } from "../agents/workspace-dir.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { readLocalFileSafely } from "../infra/fs-safe.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import type { OutboundMediaAccess, OutboundMediaReadFile } from "./load-options.js";

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
parseLiveCsvFilter,
parseProviderModelMap,

View File

@@ -1,5 +1,5 @@
import { normalizeProviderId } from "../agents/model-selection.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import { resolvePluginCapabilityProviders } from "../plugins/capability-provider-runtime.js";
import type { MusicGenerationProviderPlugin } from "../plugins/types.js";

View File

@@ -3,7 +3,7 @@ import {
getMediaGenerationRuntimeMocks,
resetMusicGenerationRuntimeMocks,
} from "../../test/helpers/media-generation/runtime-module-mocks.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { generateMusic, listRuntimeMusicGenerationProviders } from "./runtime.js";
import type { MusicGenerationProvider } from "./types.js";

View File

@@ -1,7 +1,7 @@
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.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {

View File

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

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
normalizeOptionalLowercaseString,
normalizeOptionalString,

View File

@@ -11,7 +11,7 @@ import {
} from "./dependency-denylist.js";
import { getGlobalHookRunner } from "./hook-runner-global.js";
import { createBeforeInstallHookPayload } from "./install-policy-context.js";
import type { InstallSafetyOverrides } from "./install-security-scan.js";
import type { InstallSafetyOverrides } from "./install-security-scan.types.js";
type InstallScanLogger = {
warn?: (message: string) => void;

View File

@@ -2,9 +2,8 @@ type InstallScanLogger = {
warn?: (message: string) => void;
};
export type InstallSafetyOverrides = {
dangerouslyForceUnsafeInstall?: boolean;
};
export type { InstallSafetyOverrides } from "./install-security-scan.types.js";
import type { InstallSafetyOverrides } from "./install-security-scan.types.js";
export type InstallSecurityScanResult = {
blocked?: {

View File

@@ -0,0 +1,3 @@
export type InstallSafetyOverrides = {
dangerouslyForceUnsafeInstall?: boolean;
};

View File

@@ -1,6 +1,6 @@
import fs from "node:fs";
import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
normalizeOptionalLowercaseString,
normalizeOptionalString,

View File

@@ -1,6 +1,6 @@
import type { OpenClawConfig } from "../config/config.js";
import type { SecretInput } from "../config/types.secrets.js";
import type { EmbeddingInput } from "../memory-host-sdk/engine-embeddings.js";
import type { EmbeddingInput } from "../memory-host-sdk/host/embedding-inputs.js";
export type MemoryEmbeddingBatchChunk = {
text: string;

View File

@@ -0,0 +1 @@
export type PluginKind = "memory" | "context-engine";

View File

@@ -1,12 +1,21 @@
import { normalizeProviderId } from "../agents/provider-id.js";
import { getActivePluginRegistry } from "./runtime.js";
import type {
ProviderDefaultThinkingPolicyContext,
ProviderPlugin,
ProviderThinkingPolicyContext,
} from "./types.js";
} from "./provider-thinking.types.js";
import { getActivePluginRegistry } from "./runtime.js";
function matchesProviderId(provider: ProviderPlugin, providerId: string): boolean {
type ThinkingProviderPlugin = {
id: string;
aliases?: string[];
isBinaryThinking?: (ctx: ProviderThinkingPolicyContext) => boolean | undefined;
supportsXHighThinking?: (ctx: ProviderThinkingPolicyContext) => boolean | undefined;
resolveDefaultThinkingLevel?: (
ctx: ProviderDefaultThinkingPolicyContext,
) => "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "adaptive" | null | undefined;
};
function matchesProviderId(provider: ThinkingProviderPlugin, providerId: string): boolean {
const normalized = normalizeProviderId(providerId);
if (!normalized) {
return false;
@@ -17,7 +26,7 @@ function matchesProviderId(provider: ProviderPlugin, providerId: string): boolea
return (provider.aliases ?? []).some((alias) => normalizeProviderId(alias) === normalized);
}
function resolveActiveThinkingProvider(providerId: string): ProviderPlugin | undefined {
function resolveActiveThinkingProvider(providerId: string): ThinkingProviderPlugin | undefined {
return getActivePluginRegistry()?.providers.find((entry) => {
return matchesProviderId(entry.provider, providerId);
})?.provider;

View File

@@ -0,0 +1,22 @@
/**
* Provider-owned thinking policy input.
*
* Used by shared `/think`, ACP controls, and directive parsing to ask a
* provider whether a model supports special reasoning UX such as xhigh or a
* binary on/off toggle.
*/
export type ProviderThinkingPolicyContext = {
provider: string;
modelId: string;
};
/**
* Provider-owned default thinking policy input.
*
* `reasoning` is the merged catalog hint for the selected model when one is
* available. Providers can use it to keep "reasoning model => low" behavior
* without re-reading the catalog themselves.
*/
export type ProviderDefaultThinkingPolicyContext = ProviderThinkingPolicyContext & {
reasoning?: boolean;
};

View File

@@ -1,6 +1,6 @@
import type { AgentHarness } from "../agents/harness/types.js";
import type { ChannelPlugin } from "../channels/plugins/types.js";
import type { OperatorScope } from "../gateway/method-scopes.js";
import type { OperatorScope } from "../gateway/operator-scopes.js";
import type { GatewayRequestHandlers } from "../gateway/server-methods/types.js";
import type { HookEntry } from "../hooks/types.js";
import type { PluginActivationSource } from "./config-state.js";

View File

@@ -7,7 +7,7 @@ import type { AgentHarness } from "../agents/harness/types.js";
import type { AnyAgentTool } from "../agents/tools/common.js";
import type { ChannelPlugin } from "../channels/plugins/types.js";
import { registerContextEngineForOwner } from "../context-engine/registry.js";
import type { OperatorScope } from "../gateway/method-scopes.js";
import type { OperatorScope } from "../gateway/operator-scopes.js";
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
import { registerInternalHook, unregisterInternalHook } from "../hooks/internal-hooks.js";
import type { HookEntry } from "../hooks/types.js";

View File

@@ -1,6 +1,6 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { PluginSlotsConfig } from "../config/types.plugins.js";
import type { PluginKind } from "./types.js";
import type { PluginKind } from "./plugin-kind.types.js";
export type PluginSlotKey = keyof PluginSlotsConfig;

View File

@@ -11,7 +11,8 @@ import type {
AuthProfileStore,
} from "../agents/auth-profiles/types.js";
import type { AgentHarness } from "../agents/harness/types.js";
import type { ModelCatalogEntry } from "../agents/model-catalog.js";
import type { ModelCatalogEntry } from "../agents/model-catalog.types.js";
import type { AgentHarness } from "../agents/harness/types.js";
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";
@@ -31,7 +32,7 @@ import type {
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/method-scopes.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";
@@ -80,8 +81,13 @@ import type {
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 { PluginKind } from "./plugin-kind.types.js";
import type { SecretInputMode } from "./provider-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";
export type { PluginRuntime } from "./runtime/types.js";
@@ -112,7 +118,7 @@ export type PluginConfigUiHint = {
placeholder?: string;
};
export type PluginKind = "memory" | "context-engine";
export type { PluginKind } from "./plugin-kind.types.js";
export type PluginConfigValidation =
| { ok: true; value?: unknown }
@@ -901,28 +907,10 @@ export type ProviderBuiltInModelSuppressionResult = {
errorMessage?: string;
};
/**
* Provider-owned thinking policy input.
*
* Used by shared `/think`, ACP controls, and directive parsing to ask a
* provider whether a model supports special reasoning UX such as xhigh or a
* binary on/off toggle.
*/
export type ProviderThinkingPolicyContext = {
provider: string;
modelId: string;
};
/**
* Provider-owned default thinking policy input.
*
* `reasoning` is the merged catalog hint for the selected model when one is
* available. Providers can use it to keep "reasoning model => low" behavior
* without re-reading the catalog themselves.
*/
export type ProviderDefaultThinkingPolicyContext = ProviderThinkingPolicyContext & {
reasoning?: boolean;
};
export type {
ProviderDefaultThinkingPolicyContext,
ProviderThinkingPolicyContext,
} from "./provider-thinking.types.js";
/**
* Provider-owned "modern model" policy input.

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { SpeechProviderPlugin } from "../plugins/types.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { listSpeechProviders } from "./provider-registry.js";

View File

@@ -1,5 +1,5 @@
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
import type { SpeechProviderPlugin } from "../plugins/types.js";

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolvePluginCapabilityProviders } from "../plugins/capability-provider-runtime.js";
import {
buildCapabilityProviderMaps,

View File

@@ -1,5 +1,5 @@
import type { OpenClawConfig } from "../config/config.js";
import type { TalkProviderConfig } from "../config/types.gateway.js";
import type { OpenClawConfig } from "../config/types.js";
export type SpeechProviderId = string;

View File

@@ -2,7 +2,7 @@ import fs from "node:fs";
import path from "node:path";
import { describe, expect, it, vi } from "vitest";
import { withTempHome } from "../../test/helpers/temp-home.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolveStatusTtsSnapshot } from "./status-config.js";
describe("resolveStatusTtsSnapshot", () => {

View File

@@ -1,6 +1,6 @@
import fs from "node:fs";
import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { TtsAutoMode, TtsConfig, TtsProvider } from "../config/types.tts.js";
import {
normalizeOptionalLowercaseString,

View File

@@ -1,9 +1,8 @@
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { TtsAutoMode, TtsMode } from "../config/types.tts.js";
import { resolveConfigDir, resolveUserPath } from "../utils.js";
import { normalizeTtsAutoMode } from "./tts-auto-mode.js";
export { normalizeTtsAutoMode } from "./tts-auto-mode.js";
export function resolveConfiguredTtsMode(cfg: OpenClawConfig): TtsMode {

View File

@@ -9,7 +9,7 @@ import {
} from "../agents/model-selection.js";
import { resolveModelAsync } from "../agents/pi-embedded-runner/model.js";
import { prepareModelForSimpleCompletion } from "../agents/simple-completion-transport.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
normalizeOptionalLowercaseString,
normalizeOptionalString,

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
canRunBufferBackedImageToVideoLiveLane,
canRunBufferBackedVideoToVideoLiveLane,

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import {
parseLiveCsvFilter,
parseProviderModelMap,

View File

@@ -1,5 +1,5 @@
import { normalizeProviderId } from "../agents/model-selection.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import { resolvePluginCapabilityProviders } from "../plugins/capability-provider-runtime.js";
import type { VideoGenerationProviderPlugin } from "../plugins/types.js";

View File

@@ -3,7 +3,7 @@ import {
getMediaGenerationRuntimeMocks,
resetVideoGenerationRuntimeMocks,
} from "../../test/helpers/media-generation/runtime-module-mocks.js";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { generateVideo, listRuntimeVideoGenerationProviders } from "./runtime.js";
import type { VideoGenerationProvider } from "./types.js";

View File

@@ -1,7 +1,7 @@
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.js";
import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {

View File

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

View File

@@ -1,5 +1,5 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import type { PluginWebFetchProviderEntry } from "../plugins/types.js";
import type { RuntimeWebFetchMetadata } from "../secrets/runtime-web-tools.types.js";
import {

View File

@@ -1,4 +1,4 @@
import type { OpenClawConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { logVerbose } from "../globals.js";
import type {
PluginWebFetchProviderEntry,