mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(plugin-sdk): share canonical replay hook families
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
readConfiguredProviderCatalogEntries,
|
||||
type ProviderCatalogContext,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
applyArceeConfig,
|
||||
@@ -20,9 +20,6 @@ import {
|
||||
} from "./provider-catalog.js";
|
||||
|
||||
const PROVIDER_ID = "arcee";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
const ARCEE_WIZARD_GROUP = {
|
||||
groupId: "arcee",
|
||||
groupLabel: "Arcee AI",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { ProviderResolveDynamicModelContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
cloneFirstTemplateModel,
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
normalizeModelCompat,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { isFireworksKimiModelId } from "./model-id.js";
|
||||
import { applyFireworksConfig, FIREWORKS_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
@@ -18,10 +18,6 @@ import {
|
||||
import { wrapFireworksProviderStream } from "./stream.js";
|
||||
|
||||
const PROVIDER_ID = "fireworks";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
|
||||
function resolveFireworksDynamicModel(ctx: ProviderResolveDynamicModelContext) {
|
||||
const modelId = ctx.modelId.trim();
|
||||
if (!modelId) {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { applyKilocodeConfig, KILOCODE_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
|
||||
|
||||
const PROVIDER_ID = "kilocode";
|
||||
const PASSTHROUGH_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
const KILOCODE_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("kilocode-thinking");
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { applyMoonshotNativeStreamingUsageCompat } from "./api.js";
|
||||
import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
||||
@@ -12,9 +12,6 @@ import { buildMoonshotProvider } from "./provider-catalog.js";
|
||||
import { createKimiWebSearchProvider } from "./src/kimi-web-search-provider.js";
|
||||
|
||||
const PROVIDER_ID = "moonshot";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
const MOONSHOT_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("moonshot-thinking");
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
type ProviderDiscoveryContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
type ModelProviderConfig,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
@@ -33,9 +33,6 @@ import { createOllamaWebSearchProvider } from "./src/web-search-provider.js";
|
||||
|
||||
const PROVIDER_ID = "ollama";
|
||||
const DEFAULT_API_KEY = "ollama-local";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
|
||||
type OllamaPluginConfig = {
|
||||
discovery?: {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyOpencodeGoConfig, OPENCODE_GO_DEFAULT_MODEL_REF } from "./api.js";
|
||||
|
||||
const PROVIDER_ID = "opencode-go";
|
||||
const PASSTHROUGH_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
|
||||
export default definePluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
name: "OpenCode Go Provider",
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
matchesExactOrPrefix,
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { applyOpencodeZenConfig, OPENCODE_ZEN_DEFAULT_MODEL } from "./api.js";
|
||||
|
||||
const PROVIDER_ID = "opencode";
|
||||
const MINIMAX_MODERN_MODEL_MATCHERS = ["minimax-m2.7"] as const;
|
||||
const PASSTHROUGH_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
|
||||
function isModernOpencodeModel(modelId: string): boolean {
|
||||
const lower = normalizeLowercaseStringOrEmpty(modelId);
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
getOpenRouterModelCapabilities,
|
||||
@@ -26,9 +26,6 @@ const OPENROUTER_CACHE_TTL_MODEL_PREFIXES = [
|
||||
"moonshotai/",
|
||||
"zai/",
|
||||
] as const;
|
||||
const PASSTHROUGH_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
|
||||
export default definePluginEntry({
|
||||
id: "openrouter",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { defaultToolStreamExtraParams } from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
import { jsonResult, readProviderEnvValue } from "openclaw/plugin-sdk/provider-web-search";
|
||||
import {
|
||||
@@ -24,10 +24,6 @@ import {
|
||||
} from "./x-search-tool-shared.js";
|
||||
|
||||
const PROVIDER_ID = "xai";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
|
||||
function hasResolvableXaiApiKey(config: unknown): boolean {
|
||||
return Boolean(
|
||||
resolveFallbackXaiAuth(config as never)?.apiKey || readProviderEnvValue(["XAI_API_KEY"]),
|
||||
|
||||
@@ -17,8 +17,8 @@ import {
|
||||
validateApiKeyInput,
|
||||
} from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
normalizeModelCompat,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { defaultToolStreamExtraParams } from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
@@ -32,9 +32,6 @@ import { applyZaiConfig, applyZaiProviderConfig, ZAI_DEFAULT_MODEL_REF } from ".
|
||||
const PROVIDER_ID = "zai";
|
||||
const GLM5_TEMPLATE_MODEL_ID = "glm-4.7";
|
||||
const PROFILE_ID = "zai:default";
|
||||
const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
const ZAI_TOOL_STREAM_HOOKS = buildProviderStreamFamilyHooks("tool-stream-default-on");
|
||||
|
||||
function resolveGlm5ForwardCompatModel(
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildProviderReplayFamilyHooks } from "./provider-model-shared.js";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
} from "./provider-model-shared.js";
|
||||
|
||||
describe("buildProviderReplayFamilyHooks", () => {
|
||||
it("covers the replay family matrix", async () => {
|
||||
@@ -171,4 +175,34 @@ describe("buildProviderReplayFamilyHooks", () => {
|
||||
} as never),
|
||||
).not.toHaveProperty("dropThinkingBlocks");
|
||||
});
|
||||
|
||||
it("exposes canonical replay hooks for reused provider families", () => {
|
||||
expect(
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS.buildReplayPolicy?.({
|
||||
provider: "xai",
|
||||
modelApi: "openai-completions",
|
||||
modelId: "grok-4",
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
sanitizeToolCallIds: true,
|
||||
applyAssistantFirstOrderingFix: true,
|
||||
validateGeminiTurns: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS.buildReplayPolicy?.({
|
||||
provider: "openrouter",
|
||||
modelApi: "openai-completions",
|
||||
modelId: "gemini-2.5-pro",
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
applyAssistantFirstOrderingFix: false,
|
||||
validateGeminiTurns: false,
|
||||
validateAnthropicTurns: false,
|
||||
sanitizeThoughtSignatures: {
|
||||
allowBase64Only: true,
|
||||
includeCamelCase: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -160,3 +160,11 @@ export function buildProviderReplayFamilyHooks(
|
||||
}
|
||||
throw new Error("Unsupported provider replay family");
|
||||
}
|
||||
|
||||
export const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "openai-compatible",
|
||||
});
|
||||
|
||||
export const PASSTHROUGH_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user