fix(plugin-sdk): share canonical stream hook families

This commit is contained in:
Vincent Koc
2026-04-14 17:13:16 +01:00
parent 0bf3b84669
commit eea7ba5345
9 changed files with 46 additions and 23 deletions

View File

@@ -1,2 +1,2 @@
57ae55ced0f486941716dcfc569af480e964421ae50f0304665bd6ce2fa77521 plugin-sdk-api-baseline.json
6b3e30a125af7d4ae061c288c8f7bc268b676c1dcd602dec56fbd66bfef2ca72 plugin-sdk-api-baseline.jsonl
a1e765cf426077085975f1f00847026b71f301cad35cb9168713e2b6249c4a47 plugin-sdk-api-baseline.json
9f1cdbe8d9bfbd582edb671729c4c09e578fb1940e787cfd6aa82dee0bdf5de7 plugin-sdk-api-baseline.jsonl

View File

@@ -1,9 +1,9 @@
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { GOOGLE_THINKING_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
export const GOOGLE_GEMINI_PROVIDER_HOOKS = {
...buildProviderReplayFamilyHooks({
family: "google-gemini",
}),
...buildProviderStreamFamilyHooks("google-thinking"),
...GOOGLE_THINKING_STREAM_HOOKS,
};

View File

@@ -1,12 +1,11 @@
import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { KILOCODE_THINKING_STREAM_HOOKS } 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 KILOCODE_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("kilocode-thinking");
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,

View File

@@ -13,7 +13,7 @@ import {
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { MINIMAX_FAST_MODE_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
import { fetchMinimaxUsage } from "openclaw/plugin-sdk/provider-usage";
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
import { isMiniMaxModernModelId, MINIMAX_DEFAULT_MODEL_ID } from "./api.js";
@@ -42,7 +42,6 @@ const HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
family: "hybrid-anthropic-openai",
anthropicModelDropThinkingBlocks: true,
});
const MINIMAX_FAST_MODE_STREAM_HOOKS = buildProviderStreamFamilyHooks("minimax-fast-mode");
const MINIMAX_PROVIDER_HOOKS = {
...HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS,
...MINIMAX_FAST_MODE_STREAM_HOOKS,

View File

@@ -1,6 +1,6 @@
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { MOONSHOT_THINKING_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
import { applyMoonshotNativeStreamingUsageCompat } from "./api.js";
import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js";
import {
@@ -12,7 +12,6 @@ import { buildMoonshotProvider } from "./provider-catalog.js";
import { createKimiWebSearchProvider } from "./src/kimi-web-search-provider.js";
const PROVIDER_ID = "moonshot";
const MOONSHOT_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("moonshot-thinking");
export default defineSingleProviderPluginEntry({
id: PROVIDER_ID,

View File

@@ -1,8 +1,6 @@
import type { StreamFn } from "@mariozechner/pi-agent-core";
import type { ProviderWrapStreamFnContext } from "openclaw/plugin-sdk/plugin-entry";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
const OPENROUTER_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("openrouter-thinking");
import { OPENROUTER_THINKING_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
function injectOpenRouterRouting(
baseStreamFn: StreamFn | undefined,

View File

@@ -20,7 +20,7 @@ import {
normalizeModelCompat,
OPENAI_COMPATIBLE_REPLAY_HOOKS,
} from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { TOOL_STREAM_DEFAULT_ON_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
import { defaultToolStreamExtraParams } from "openclaw/plugin-sdk/provider-stream-shared";
import { fetchZaiUsage, resolveLegacyPiAgentAccessToken } from "openclaw/plugin-sdk/provider-usage";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
@@ -32,7 +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 ZAI_TOOL_STREAM_HOOKS = buildProviderStreamFamilyHooks("tool-stream-default-on");
function resolveGlm5ForwardCompatModel(
ctx: ProviderResolveDynamicModelContext,
@@ -280,7 +279,7 @@ export default definePluginEntry({
resolveDynamicModel: (ctx) => resolveGlm5ForwardCompatModel(ctx),
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
prepareExtraParams: (ctx) => defaultToolStreamExtraParams(ctx.extraParams),
...ZAI_TOOL_STREAM_HOOKS,
...TOOL_STREAM_DEFAULT_ON_HOOKS,
isBinaryThinking: () => true,
isModernModelRef: ({ modelId }) => {
const lower = normalizeLowercaseStringOrEmpty(modelId);

View File

@@ -10,6 +10,13 @@ import {
composeProviderStreamWrappers,
createMoonshotThinkingWrapper,
createToolStreamWrapper,
GOOGLE_THINKING_STREAM_HOOKS,
KILOCODE_THINKING_STREAM_HOOKS,
MINIMAX_FAST_MODE_STREAM_HOOKS,
MOONSHOT_THINKING_STREAM_HOOKS,
OPENAI_RESPONSES_STREAM_HOOKS,
OPENROUTER_THINKING_STREAM_HOOKS,
TOOL_STREAM_DEFAULT_ON_HOOKS,
} from "./provider-stream.js";
function requireWrapStreamFn(
@@ -89,7 +96,7 @@ describe("buildProviderStreamFamilyHooks", () => {
return {} as never;
};
const googleHooks = buildProviderStreamFamilyHooks("google-thinking");
const googleHooks = GOOGLE_THINKING_STREAM_HOOKS;
const googleStream = requireStreamFn(
requireWrapStreamFn(googleHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -109,7 +116,7 @@ describe("buildProviderStreamFamilyHooks", () => {
).thinkingConfig as Record<string, unknown>;
expect(googleThinkingConfig).not.toHaveProperty("thinkingBudget");
const minimaxHooks = buildProviderStreamFamilyHooks("minimax-fast-mode");
const minimaxHooks = MINIMAX_FAST_MODE_STREAM_HOOKS;
const minimaxStream = requireStreamFn(
requireWrapStreamFn(minimaxHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -127,7 +134,7 @@ describe("buildProviderStreamFamilyHooks", () => {
);
expect(capturedModelId).toBe("MiniMax-M2.7-highspeed");
const kilocodeHooks = buildProviderStreamFamilyHooks("kilocode-thinking");
const kilocodeHooks = KILOCODE_THINKING_STREAM_HOOKS;
void requireStreamFn(
requireWrapStreamFn(kilocodeHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -152,7 +159,7 @@ describe("buildProviderStreamFamilyHooks", () => {
});
expect(capturedPayload).not.toHaveProperty("reasoning");
const moonshotHooks = buildProviderStreamFamilyHooks("moonshot-thinking");
const moonshotHooks = MOONSHOT_THINKING_STREAM_HOOKS;
const moonshotStream = requireStreamFn(
requireWrapStreamFn(moonshotHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -165,7 +172,7 @@ describe("buildProviderStreamFamilyHooks", () => {
thinking: { type: "disabled" },
});
const openAiHooks = buildProviderStreamFamilyHooks("openai-responses-defaults");
const openAiHooks = OPENAI_RESPONSES_STREAM_HOOKS;
void requireStreamFn(
requireWrapStreamFn(openAiHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -189,7 +196,7 @@ describe("buildProviderStreamFamilyHooks", () => {
});
expect(capturedHeaders).toBeDefined();
const openRouterHooks = buildProviderStreamFamilyHooks("openrouter-thinking");
const openRouterHooks = OPENROUTER_THINKING_STREAM_HOOKS;
void requireStreamFn(
requireWrapStreamFn(openRouterHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -214,7 +221,7 @@ describe("buildProviderStreamFamilyHooks", () => {
});
expect(capturedPayload).not.toHaveProperty("reasoning");
const toolStreamHooks = buildProviderStreamFamilyHooks("tool-stream-default-on");
const toolStreamHooks = TOOL_STREAM_DEFAULT_ON_HOOKS;
const toolStreamDefault = requireStreamFn(
requireWrapStreamFn(toolStreamHooks.wrapStreamFn)({
streamFn: baseStreamFn,
@@ -239,4 +246,14 @@ describe("buildProviderStreamFamilyHooks", () => {
});
expect(capturedPayload).not.toHaveProperty("tool_stream");
});
it("exposes canonical stream hook constants for reused families", () => {
expect(GOOGLE_THINKING_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(KILOCODE_THINKING_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(MINIMAX_FAST_MODE_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(MOONSHOT_THINKING_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(OPENAI_RESPONSES_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(OPENROUTER_THINKING_STREAM_HOOKS.wrapStreamFn).toBeTypeOf("function");
expect(TOOL_STREAM_DEFAULT_ON_HOOKS.wrapStreamFn).toBeTypeOf("function");
});
});

View File

@@ -139,6 +139,18 @@ export function buildProviderStreamFamilyHooks(
throw new Error("Unsupported provider stream family");
}
export const GOOGLE_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("google-thinking");
export const KILOCODE_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("kilocode-thinking");
export const MOONSHOT_THINKING_STREAM_HOOKS = buildProviderStreamFamilyHooks("moonshot-thinking");
export const MINIMAX_FAST_MODE_STREAM_HOOKS = buildProviderStreamFamilyHooks("minimax-fast-mode");
export const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks(
"openai-responses-defaults",
);
export const OPENROUTER_THINKING_STREAM_HOOKS =
buildProviderStreamFamilyHooks("openrouter-thinking");
export const TOOL_STREAM_DEFAULT_ON_HOOKS =
buildProviderStreamFamilyHooks("tool-stream-default-on");
// Public stream-wrapper helpers for provider plugins.
export {