diff --git a/extensions/amazon-bedrock/provider-policy-api.ts b/extensions/amazon-bedrock/provider-policy-api.ts index d9f56ad1bd49..db16b19cc154 100644 --- a/extensions/amazon-bedrock/provider-policy-api.ts +++ b/extensions/amazon-bedrock/provider-policy-api.ts @@ -2,7 +2,7 @@ * Provider-policy API for Amazon Bedrock. Core asks this plugin for thinking * profiles without importing provider registration or streaming code. */ -import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared"; +import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; import { resolveBedrockClaudeThinkingProfile } from "./thinking-policy.js"; /** Resolve the Bedrock thinking profile for a provider/model pair. */ diff --git a/extensions/anthropic-vertex/provider-policy-api.ts b/extensions/anthropic-vertex/provider-policy-api.ts index 278297448dba..69220a9c4680 100644 --- a/extensions/anthropic-vertex/provider-policy-api.ts +++ b/extensions/anthropic-vertex/provider-policy-api.ts @@ -2,7 +2,7 @@ * Provider-policy API for Anthropic Vertex. Core asks for thinking profiles * without importing the provider entry or stream runtime. */ -import { resolveClaudeThinkingProfile } from "openclaw/plugin-sdk/provider-model-shared"; +import { resolveClaudeThinkingProfile } from "openclaw/plugin-sdk/claude-model-runtime"; /** Resolve Anthropic Vertex thinking profile for a provider/model pair. */ export function resolveThinkingProfile(params: { diff --git a/extensions/anthropic/provider-policy-api.ts b/extensions/anthropic/provider-policy-api.ts index dca81eb88f0b..ff988e77e88d 100644 --- a/extensions/anthropic/provider-policy-api.ts +++ b/extensions/anthropic/provider-policy-api.ts @@ -6,7 +6,7 @@ import { resolveClaudeModelIdentity, resolveClaudeMythos5ModelIdentity, resolveClaudeThinkingProfile, -} from "openclaw/plugin-sdk/provider-model-shared"; +} from "openclaw/plugin-sdk/claude-model-runtime"; import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-types"; import { CLAUDE_CLI_OFF_THINKING_PROFILE, CLAUDE_CLI_PROFILE_ID } from "./cli-constants.js"; import { diff --git a/extensions/ollama/provider-policy-api.ts b/extensions/ollama/provider-policy-api.ts index 9c0e0e141457..02458a6f3a5e 100644 --- a/extensions/ollama/provider-policy-api.ts +++ b/extensions/ollama/provider-policy-api.ts @@ -1,10 +1,11 @@ +import { isCloudModelRef } from "@openclaw/model-catalog-core/model-catalog-refs"; +import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id"; // Ollama API module exposes the plugin public contract. import type { ProviderDefaultThinkingPolicyContext, ProviderNormalizeResolvedModelContext, ProviderThinkingProfile, } from "openclaw/plugin-sdk/plugin-entry"; -import { isCloudModelRef, normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared"; import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-types"; import { OLLAMA_CLOUD_PROVIDER_ID, OLLAMA_DEFAULT_BASE_URL } from "./src/defaults.js"; import { supportsOllamaCloudFullThinkingEffort } from "./src/model-reasoning.js"; diff --git a/extensions/opencode/provider-policy-api.ts b/extensions/opencode/provider-policy-api.ts index 20d468f3573b..5de30933539c 100644 --- a/extensions/opencode/provider-policy-api.ts +++ b/extensions/opencode/provider-policy-api.ts @@ -1,9 +1,9 @@ +import { resolveClaudeThinkingProfile } from "openclaw/plugin-sdk/claude-model-runtime"; // Opencode API module exposes the plugin public contract. import type { ProviderDefaultThinkingPolicyContext, ProviderThinkingProfile, } from "openclaw/plugin-sdk/plugin-entry"; -import { resolveClaudeThinkingProfile } from "openclaw/plugin-sdk/provider-model-shared"; const FIXED_REASONING_PROFILE = { levels: [{ id: "off", label: "always on" }], diff --git a/extensions/tsconfig.package-boundary.paths.json b/extensions/tsconfig.package-boundary.paths.json index 376aa4d1275a..38c09c26e52d 100644 --- a/extensions/tsconfig.package-boundary.paths.json +++ b/extensions/tsconfig.package-boundary.paths.json @@ -134,6 +134,9 @@ "openclaw/plugin-sdk/cli-backend": [ "../packages/plugin-sdk/dist/src/plugin-sdk/cli-backend.d.ts" ], + "openclaw/plugin-sdk/claude-model-runtime": [ + "../packages/plugin-sdk/dist/src/plugin-sdk/claude-model-runtime.d.ts" + ], "openclaw/plugin-sdk/codex-mcp-projection": [ "../packages/plugin-sdk/dist/src/plugin-sdk/codex-mcp-projection.d.ts" ], diff --git a/extensions/xai/tsconfig.json b/extensions/xai/tsconfig.json index 4662f1971ee7..b699a2ef9afe 100644 --- a/extensions/xai/tsconfig.json +++ b/extensions/xai/tsconfig.json @@ -128,6 +128,9 @@ "openclaw/plugin-sdk/cli-backend": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/cli-backend.d.ts" ], + "openclaw/plugin-sdk/claude-model-runtime": [ + "../../packages/plugin-sdk/dist/src/plugin-sdk/claude-model-runtime.d.ts" + ], "openclaw/plugin-sdk/codex-mcp-projection": [ "../../packages/plugin-sdk/dist/src/plugin-sdk/codex-mcp-projection.d.ts" ], diff --git a/package.json b/package.json index 918ca5f1041f..47a01e091600 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "!dist/plugin-sdk/channel-test-helpers.d.ts", "!dist/plugin-sdk/chat-channel-ids.d.ts", "!dist/plugin-sdk/cli-backend.d.ts", + "!dist/plugin-sdk/claude-model-runtime.d.ts", "!dist/plugin-sdk/cli-runtime.d.ts", "!dist/plugin-sdk/codex-mcp-projection.d.ts", "!dist/plugin-sdk/codex-session-transcript-runtime.d.ts", @@ -785,6 +786,9 @@ "./plugin-sdk/cli-backend": { "default": "./dist/plugin-sdk/cli-backend.js" }, + "./plugin-sdk/claude-model-runtime": { + "default": "./dist/plugin-sdk/claude-model-runtime.js" + }, "./plugin-sdk/codex-mcp-projection": { "default": "./dist/plugin-sdk/codex-mcp-projection.js" }, diff --git a/scripts/lib/plugin-sdk-entrypoints.json b/scripts/lib/plugin-sdk-entrypoints.json index 717aa626aeff..3b7b0ed3a394 100644 --- a/scripts/lib/plugin-sdk-entrypoints.json +++ b/scripts/lib/plugin-sdk-entrypoints.json @@ -111,6 +111,7 @@ "cli-argv", "cli-runtime", "cli-backend", + "claude-model-runtime", "codex-mcp-projection", "native-hook-relay-runtime", "codex-session-transcript-runtime", diff --git a/scripts/lib/plugin-sdk-private-local-only-subpaths.json b/scripts/lib/plugin-sdk-private-local-only-subpaths.json index dacdd4a760a3..909380cd03ee 100644 --- a/scripts/lib/plugin-sdk-private-local-only-subpaths.json +++ b/scripts/lib/plugin-sdk-private-local-only-subpaths.json @@ -28,6 +28,7 @@ "channel-targets", "channel-test-helpers", "chat-channel-ids", + "claude-model-runtime", "cli-backend", "cli-runtime", "codex-mcp-projection", diff --git a/src/agents/embedded-agent-runner/run.inherited-auth-owner.test.ts b/src/agents/embedded-agent-runner/run.inherited-auth-owner.test.ts index 13fd27a42766..9a1376b06870 100644 --- a/src/agents/embedded-agent-runner/run.inherited-auth-owner.test.ts +++ b/src/agents/embedded-agent-runner/run.inherited-auth-owner.test.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { listAgentIds } from "../agent-scope-config.js"; import { makeAttemptResult } from "./run.overflow-compaction.fixture.js"; @@ -10,7 +10,7 @@ import { mockedRunEmbeddedAttempt, overflowBaseRunParams, resetSharedRunIntegrationHarnessMocks, - warmRunOverflowCompactionHarness, + useOpenAIPlatformAuthFixture, } from "./run.overflow-compaction.harness.js"; const { runEmbeddedAgent } = await loadRunOverflowCompactionHarness(); @@ -29,12 +29,13 @@ function projectSetupExecutionConfig(source: OpenClawConfig): OpenClawConfig { } describe("embedded setup inference inherited auth owner", () => { - beforeAll(async () => { - await warmRunOverflowCompactionHarness(runEmbeddedAgent); + // Provider-pinned runs stay on the mocked plugin harness, so no host-route + // warmup is needed here; see overflowBaseRunParams for the route trap. + beforeEach(() => { + resetSharedRunIntegrationHarnessMocks(); + useOpenAIPlatformAuthFixture(); }); - beforeEach(resetSharedRunIntegrationHarnessMocks); - it.each([ { name: "a pre-roster config", source: {} }, { name: "a sole-agent config", source: { agents: { entries: { main: {} } } } }, @@ -49,6 +50,11 @@ describe("embedded setup inference inherited auth owner", () => { await runEmbeddedAgent({ ...overflowBaseRunParams, + // Auth-owner resolution is provider-agnostic. Route through the mocked + // plugin harness so this shard does not compile the bundled Anthropic + // provider policy from source just to assert an agent directory. + provider: "openai", + model: "gpt-5.6-luna", agentId: "main", config, runId: `run-setup-inference-owner-${name}`, @@ -60,6 +66,11 @@ describe("embedded setup inference inherited auth owner", () => { value.endsWith(path.join("agents", "main", "agent")), ); expect(mockedRunEmbeddedAttempt).toHaveBeenCalledOnce(); + // A silent fall-back to the built-in host harness would still pass the + // auth-owner assertions; fail loudly on the route instead. + expect(mockedRunEmbeddedAttempt).toHaveBeenCalledWith( + expect.objectContaining({ agentHarnessId: "codex" }), + ); }, ); }); diff --git a/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts b/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts index 777bdabc7818..135156bc4593 100644 --- a/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts +++ b/src/agents/embedded-agent-runner/run.overflow-compaction.harness.ts @@ -442,6 +442,10 @@ const mockedHasUsableCustomProviderApiKey = vi.fn(() => false); const mockedMarkAuthProfileSuccess = vi.fn(async () => {}); const mockedShouldPreferExplicitConfigApiKeyAuth = vi.fn(() => false); +// No provider here means model resolution defaults to anthropic/test-model, which +// the mocked codex harness does not claim: such runs select the built-in openclaw +// host harness and pay its one-time source-compile cost. Suites proving plugin +// harness behavior must pin provider "openai" (see run.session-permissions.test.ts). export const overflowBaseRunParams = { agentId: "main", sessionId: "test-session", diff --git a/src/plugin-sdk/claude-model-runtime.ts b/src/plugin-sdk/claude-model-runtime.ts new file mode 100644 index 000000000000..b3a5e71daf11 --- /dev/null +++ b/src/plugin-sdk/claude-model-runtime.ts @@ -0,0 +1,11 @@ +/** + * Claude model-family policy helpers for provider policy artifacts. + * + * Provider policy artifacts (`provider-policy-api.js`) load eagerly whenever a + * provider is resolved, so their module graph must stay leaf-light. This + * subpath re-exports the Claude identity and thinking helpers from their leaf + * owners; importing them through `provider-model-shared` drags the transport + * and compat graph into every policy load (~60s under jiti in source checkouts). + */ +export { resolveClaudeModelIdentity, resolveClaudeMythos5ModelIdentity } from "@openclaw/llm-core"; +export { resolveClaudeThinkingProfile } from "../plugins/provider-claude-thinking.js";