mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-06 06:41:08 +00:00
refactor(amazon-bedrock): lazy-load provider registration
This commit is contained in:
@@ -1,97 +1,11 @@
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { buildAnthropicReplayPolicyForModel } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
createBedrockNoCacheWrapper,
|
||||
isAnthropicBedrockModel,
|
||||
streamWithPayloadPatch,
|
||||
} from "openclaw/plugin-sdk/provider-stream";
|
||||
import {
|
||||
mergeImplicitBedrockProvider,
|
||||
resolveBedrockConfigApiKey,
|
||||
resolveImplicitBedrockProvider,
|
||||
} from "./api.js";
|
||||
|
||||
type GuardrailConfig = {
|
||||
guardrailIdentifier: string;
|
||||
guardrailVersion: string;
|
||||
streamProcessingMode?: "sync" | "async";
|
||||
trace?: "enabled" | "disabled" | "enabled_full";
|
||||
};
|
||||
|
||||
function createGuardrailWrapStreamFn(
|
||||
innerWrapStreamFn: (ctx: { modelId: string; streamFn?: StreamFn }) => StreamFn | null | undefined,
|
||||
guardrailConfig: GuardrailConfig,
|
||||
): (ctx: { modelId: string; streamFn?: StreamFn }) => StreamFn | null | undefined {
|
||||
return (ctx) => {
|
||||
const inner = innerWrapStreamFn(ctx);
|
||||
if (!inner) return inner;
|
||||
return (model, context, options) => {
|
||||
return streamWithPayloadPatch(inner, model, context, options, (payload) => {
|
||||
const gc: Record<string, unknown> = {
|
||||
guardrailIdentifier: guardrailConfig.guardrailIdentifier,
|
||||
guardrailVersion: guardrailConfig.guardrailVersion,
|
||||
};
|
||||
if (guardrailConfig.streamProcessingMode) {
|
||||
gc.streamProcessingMode = guardrailConfig.streamProcessingMode;
|
||||
}
|
||||
if (guardrailConfig.trace) {
|
||||
gc.trace = guardrailConfig.trace;
|
||||
}
|
||||
payload.guardrailConfig = gc;
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const PROVIDER_ID = "amazon-bedrock";
|
||||
const CLAUDE_46_MODEL_RE = /claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i;
|
||||
|
||||
export default definePluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
id: "amazon-bedrock",
|
||||
name: "Amazon Bedrock Provider",
|
||||
description: "Bundled Amazon Bedrock provider policy plugin",
|
||||
register(api) {
|
||||
const guardrail = (api.pluginConfig as Record<string, unknown> | undefined)?.guardrail as
|
||||
| GuardrailConfig
|
||||
| undefined;
|
||||
|
||||
const baseWrapStreamFn = ({ modelId, streamFn }: { modelId: string; streamFn?: StreamFn }) =>
|
||||
isAnthropicBedrockModel(modelId) ? streamFn : createBedrockNoCacheWrapper(streamFn);
|
||||
|
||||
const wrapStreamFn =
|
||||
guardrail?.guardrailIdentifier && guardrail?.guardrailVersion
|
||||
? createGuardrailWrapStreamFn(baseWrapStreamFn, guardrail)
|
||||
: baseWrapStreamFn;
|
||||
|
||||
api.registerProvider({
|
||||
id: PROVIDER_ID,
|
||||
label: "Amazon Bedrock",
|
||||
docsPath: "/providers/models",
|
||||
auth: [],
|
||||
catalog: {
|
||||
order: "simple",
|
||||
run: async (ctx) => {
|
||||
const implicit = await resolveImplicitBedrockProvider({
|
||||
config: ctx.config,
|
||||
env: ctx.env,
|
||||
});
|
||||
if (!implicit) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
provider: mergeImplicitBedrockProvider({
|
||||
existing: ctx.config.models?.providers?.[PROVIDER_ID],
|
||||
implicit,
|
||||
}),
|
||||
};
|
||||
},
|
||||
},
|
||||
resolveConfigApiKey: ({ env }) => resolveBedrockConfigApiKey(env),
|
||||
buildReplayPolicy: ({ modelId }) => buildAnthropicReplayPolicyForModel(modelId),
|
||||
wrapStreamFn,
|
||||
resolveDefaultThinkingLevel: ({ modelId }) =>
|
||||
CLAUDE_46_MODEL_RE.test(modelId.trim()) ? "adaptive" : undefined,
|
||||
});
|
||||
async register(api) {
|
||||
const { registerAmazonBedrockPlugin } = await import("./register.runtime.js");
|
||||
await registerAmazonBedrockPlugin(api);
|
||||
},
|
||||
});
|
||||
|
||||
92
extensions/amazon-bedrock/register.runtime.ts
Normal file
92
extensions/amazon-bedrock/register.runtime.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { buildAnthropicReplayPolicyForModel } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
createBedrockNoCacheWrapper,
|
||||
isAnthropicBedrockModel,
|
||||
streamWithPayloadPatch,
|
||||
} from "openclaw/plugin-sdk/provider-stream";
|
||||
import {
|
||||
mergeImplicitBedrockProvider,
|
||||
resolveBedrockConfigApiKey,
|
||||
resolveImplicitBedrockProvider,
|
||||
} from "./api.js";
|
||||
|
||||
type GuardrailConfig = {
|
||||
guardrailIdentifier: string;
|
||||
guardrailVersion: string;
|
||||
streamProcessingMode?: "sync" | "async";
|
||||
trace?: "enabled" | "disabled" | "enabled_full";
|
||||
};
|
||||
|
||||
function createGuardrailWrapStreamFn(
|
||||
innerWrapStreamFn: (ctx: { modelId: string; streamFn?: StreamFn }) => StreamFn | null | undefined,
|
||||
guardrailConfig: GuardrailConfig,
|
||||
): (ctx: { modelId: string; streamFn?: StreamFn }) => StreamFn | null | undefined {
|
||||
return (ctx) => {
|
||||
const inner = innerWrapStreamFn(ctx);
|
||||
if (!inner) return inner;
|
||||
return (model, context, options) => {
|
||||
return streamWithPayloadPatch(inner, model, context, options, (payload) => {
|
||||
const gc: Record<string, unknown> = {
|
||||
guardrailIdentifier: guardrailConfig.guardrailIdentifier,
|
||||
guardrailVersion: guardrailConfig.guardrailVersion,
|
||||
};
|
||||
if (guardrailConfig.streamProcessingMode) {
|
||||
gc.streamProcessingMode = guardrailConfig.streamProcessingMode;
|
||||
}
|
||||
if (guardrailConfig.trace) {
|
||||
gc.trace = guardrailConfig.trace;
|
||||
}
|
||||
payload.guardrailConfig = gc;
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const PROVIDER_ID = "amazon-bedrock";
|
||||
const CLAUDE_46_MODEL_RE = /claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i;
|
||||
|
||||
export async function registerAmazonBedrockPlugin(api: OpenClawPluginApi): Promise<void> {
|
||||
const guardrail = (api.pluginConfig as Record<string, unknown> | undefined)?.guardrail as
|
||||
| GuardrailConfig
|
||||
| undefined;
|
||||
|
||||
const baseWrapStreamFn = ({ modelId, streamFn }: { modelId: string; streamFn?: StreamFn }) =>
|
||||
isAnthropicBedrockModel(modelId) ? streamFn : createBedrockNoCacheWrapper(streamFn);
|
||||
|
||||
const wrapStreamFn =
|
||||
guardrail?.guardrailIdentifier && guardrail?.guardrailVersion
|
||||
? createGuardrailWrapStreamFn(baseWrapStreamFn, guardrail)
|
||||
: baseWrapStreamFn;
|
||||
|
||||
api.registerProvider({
|
||||
id: PROVIDER_ID,
|
||||
label: "Amazon Bedrock",
|
||||
docsPath: "/providers/models",
|
||||
auth: [],
|
||||
catalog: {
|
||||
order: "simple",
|
||||
run: async (ctx) => {
|
||||
const implicit = await resolveImplicitBedrockProvider({
|
||||
config: ctx.config,
|
||||
env: ctx.env,
|
||||
});
|
||||
if (!implicit) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
provider: mergeImplicitBedrockProvider({
|
||||
existing: ctx.config.models?.providers?.[PROVIDER_ID],
|
||||
implicit,
|
||||
}),
|
||||
};
|
||||
},
|
||||
},
|
||||
resolveConfigApiKey: ({ env }) => resolveBedrockConfigApiKey(env),
|
||||
buildReplayPolicy: ({ modelId }) => buildAnthropicReplayPolicyForModel(modelId),
|
||||
wrapStreamFn,
|
||||
resolveDefaultThinkingLevel: ({ modelId }) =>
|
||||
CLAUDE_46_MODEL_RE.test(modelId.trim()) ? "adaptive" : undefined,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user