diff --git a/extensions/anthropic-vertex/index.ts b/extensions/anthropic-vertex/index.ts index 6c0452b6fd9..6e66ced2827 100644 --- a/extensions/anthropic-vertex/index.ts +++ b/extensions/anthropic-vertex/index.ts @@ -1,5 +1,5 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; -import { buildNativeAnthropicReplayPolicyForModel } from "openclaw/plugin-sdk/provider-model-shared"; +import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; import { mergeImplicitAnthropicVertexProvider, resolveAnthropicVertexConfigApiKey, @@ -7,6 +7,9 @@ import { } from "./api.js"; const PROVIDER_ID = "anthropic-vertex"; +const NATIVE_ANTHROPIC_REPLAY_HOOKS = buildProviderReplayFamilyHooks({ + family: "native-anthropic-by-model", +}); export default definePluginEntry({ id: PROVIDER_ID, @@ -36,7 +39,7 @@ export default definePluginEntry({ }, }, resolveConfigApiKey: ({ env }) => resolveAnthropicVertexConfigApiKey(env), - buildReplayPolicy: ({ modelId }) => buildNativeAnthropicReplayPolicyForModel(modelId), + ...NATIVE_ANTHROPIC_REPLAY_HOOKS, }); }, }); diff --git a/extensions/anthropic/replay-policy.ts b/extensions/anthropic/replay-policy.ts index 57b485d8d4d..f79847a9252 100644 --- a/extensions/anthropic/replay-policy.ts +++ b/extensions/anthropic/replay-policy.ts @@ -1,12 +1,11 @@ -import type { - ProviderReplayPolicy, - ProviderReplayPolicyContext, -} from "openclaw/plugin-sdk/plugin-entry"; -import { buildNativeAnthropicReplayPolicyForModel } from "openclaw/plugin-sdk/provider-model-shared"; +import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; -/** - * Returns the provider-owned replay policy for Anthropic transports. - */ -export function buildAnthropicReplayPolicy(ctx: ProviderReplayPolicyContext): ProviderReplayPolicy { - return buildNativeAnthropicReplayPolicyForModel(ctx.modelId); +const { buildReplayPolicy } = buildProviderReplayFamilyHooks({ + family: "native-anthropic-by-model", +}); + +if (!buildReplayPolicy) { + throw new Error("Expected native Anthropic replay hooks to expose buildReplayPolicy."); } + +export { buildReplayPolicy as buildAnthropicReplayPolicy }; diff --git a/src/plugin-sdk/provider-model-shared.test.ts b/src/plugin-sdk/provider-model-shared.test.ts index 3624e9f528a..8303f152bad 100644 --- a/src/plugin-sdk/provider-model-shared.test.ts +++ b/src/plugin-sdk/provider-model-shared.test.ts @@ -34,6 +34,25 @@ describe("buildProviderReplayFamilyHooks", () => { hasSanitizeReplayHistory: false, reasoningMode: undefined, }, + { + family: "native-anthropic-by-model" as const, + ctx: { + provider: "anthropic", + modelApi: "anthropic-messages", + modelId: "claude-sonnet-4-6", + }, + match: { + sanitizeMode: "full", + preserveNativeAnthropicToolUseIds: true, + preserveSignatures: true, + repairToolUseResultPairing: true, + validateAnthropicTurns: true, + allowSyntheticToolResults: true, + }, + absent: ["dropThinkingBlocks"], + hasSanitizeReplayHistory: false, + reasoningMode: undefined, + }, { family: "google-gemini" as const, ctx: { diff --git a/src/plugin-sdk/provider-model-shared.ts b/src/plugin-sdk/provider-model-shared.ts index 4364ed79175..40d1cdd18ff 100644 --- a/src/plugin-sdk/provider-model-shared.ts +++ b/src/plugin-sdk/provider-model-shared.ts @@ -97,6 +97,7 @@ export { export type ProviderReplayFamily = | "openai-compatible" | "anthropic-by-model" + | "native-anthropic-by-model" | "google-gemini" | "passthrough-gemini" | "hybrid-anthropic-openai"; @@ -109,6 +110,7 @@ type ProviderReplayFamilyHooks = Pick< type BuildProviderReplayFamilyHooksOptions = | { family: "openai-compatible" } | { family: "anthropic-by-model" } + | { family: "native-anthropic-by-model" } | { family: "google-gemini" } | { family: "passthrough-gemini" } | { @@ -130,6 +132,11 @@ export function buildProviderReplayFamilyHooks( buildReplayPolicy: ({ modelId }: ProviderReplayPolicyContext) => buildAnthropicReplayPolicyForModel(modelId), }; + case "native-anthropic-by-model": + return { + buildReplayPolicy: ({ modelId }: ProviderReplayPolicyContext) => + buildNativeAnthropicReplayPolicyForModel(modelId), + }; case "google-gemini": return { buildReplayPolicy: () => buildGoogleGeminiReplayPolicy(),