refactor(providers): add family replay and tool hooks

This commit is contained in:
Vincent Koc
2026-04-04 19:27:36 +09:00
parent 4e099689c0
commit 39d2a719c9
20 changed files with 273 additions and 85 deletions

View File

@@ -2,12 +2,15 @@ import type {
OpenClawPluginApi,
ProviderAuthContext,
ProviderFetchUsageSnapshotContext,
ProviderWrapStreamFnContext,
} from "openclaw/plugin-sdk/plugin-entry";
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth-result";
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
import { createGoogleThinkingPayloadWrapper } from "openclaw/plugin-sdk/provider-stream";
import { buildProviderToolCompatFamilyHooks } from "openclaw/plugin-sdk/provider-tools";
import { fetchGeminiUsage } from "openclaw/plugin-sdk/provider-usage";
import { formatGoogleOauthApiKey, parseGoogleUsageToken } from "./oauth-token-shared.js";
import { isModernGoogleModel, resolveGoogle31ForwardCompatModel } from "./provider-models.js";
import { buildGoogleGeminiProviderHooks } from "./replay-policy.js";
const PROVIDER_ID = "google-gemini-cli";
const PROVIDER_LABEL = "Gemini CLI OAuth";
@@ -19,9 +22,12 @@ const ENV_VARS = [
"GEMINI_CLI_OAUTH_CLIENT_SECRET",
];
const GOOGLE_GEMINI_CLI_PROVIDER_HOOKS = buildGoogleGeminiProviderHooks({
includeToolSchemaCompat: true,
});
const GOOGLE_GEMINI_CLI_PROVIDER_HOOKS = {
...buildProviderReplayFamilyHooks({ family: "google-gemini" }),
wrapStreamFn: (ctx: ProviderWrapStreamFnContext) =>
createGoogleThinkingPayloadWrapper(ctx.streamFn, ctx.thinkingLevel),
...buildProviderToolCompatFamilyHooks("gemini"),
};
async function fetchGeminiCliUsage(ctx: ProviderFetchUsageSnapshotContext) {
return await fetchGeminiUsage(ctx.token, ctx.timeoutMs, ctx.fetchFn, PROVIDER_ID);

View File

@@ -5,9 +5,13 @@ import {
type OpenClawPluginApi,
type ProviderAuthContext,
type ProviderFetchUsageSnapshotContext,
type ProviderWrapStreamFnContext,
} from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
import { createGoogleThinkingPayloadWrapper } from "openclaw/plugin-sdk/provider-stream";
import { buildProviderToolCompatFamilyHooks } from "openclaw/plugin-sdk/provider-tools";
import {
GOOGLE_GEMINI_DEFAULT_MODEL,
applyGoogleGeminiModelDefault,
@@ -18,7 +22,6 @@ import {
import { buildGoogleGeminiCliBackend } from "./cli-backend.js";
import { formatGoogleOauthApiKey } from "./oauth-token-shared.js";
import { isModernGoogleModel, resolveGoogle31ForwardCompatModel } from "./provider-models.js";
import { buildGoogleGeminiProviderHooks } from "./replay-policy.js";
import { createGeminiWebSearchProvider } from "./src/gemini-web-search-provider.js";
const GOOGLE_GEMINI_CLI_PROVIDER_ID = "google-gemini-cli";
@@ -42,10 +45,18 @@ type GoogleMediaUnderstandingProvider = MediaUnderstandingProvider & {
describeVideo: NonNullable<MediaUnderstandingProvider["describeVideo"]>;
};
const GOOGLE_GEMINI_PROVIDER_HOOKS = buildGoogleGeminiProviderHooks();
const GOOGLE_GEMINI_PROVIDER_HOOKS_WITH_TOOL_COMPAT = buildGoogleGeminiProviderHooks({
includeToolSchemaCompat: true,
const GOOGLE_GEMINI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
family: "google-gemini",
});
const GOOGLE_GEMINI_PROVIDER_HOOKS = {
...GOOGLE_GEMINI_REPLAY_HOOKS,
wrapStreamFn: (ctx: ProviderWrapStreamFnContext) =>
createGoogleThinkingPayloadWrapper(ctx.streamFn, ctx.thinkingLevel),
};
const GOOGLE_GEMINI_PROVIDER_HOOKS_WITH_TOOL_COMPAT = {
...GOOGLE_GEMINI_PROVIDER_HOOKS,
...buildProviderToolCompatFamilyHooks("gemini"),
};
async function loadGoogleGeminiCliProvider(): Promise<ProviderPlugin> {
if (!googleGeminiCliProviderPromise) {

View File

@@ -1,38 +0,0 @@
import type {
ProviderNormalizeToolSchemasContext,
ProviderSanitizeReplayHistoryContext,
ProviderWrapStreamFnContext,
} from "openclaw/plugin-sdk/plugin-entry";
import {
buildGoogleGeminiReplayPolicy,
resolveTaggedReasoningOutputMode,
sanitizeGoogleGeminiReplayHistory,
} from "openclaw/plugin-sdk/provider-model-shared";
import { createGoogleThinkingPayloadWrapper } from "openclaw/plugin-sdk/provider-stream";
import {
inspectGeminiToolSchemas,
normalizeGeminiToolSchemas,
} from "openclaw/plugin-sdk/provider-tools";
type GoogleGeminiHookOptions = {
includeToolSchemaCompat?: boolean;
};
export function buildGoogleGeminiProviderHooks(options: GoogleGeminiHookOptions = {}) {
return {
buildReplayPolicy: () => buildGoogleGeminiReplayPolicy(),
wrapStreamFn: (ctx: ProviderWrapStreamFnContext) =>
createGoogleThinkingPayloadWrapper(ctx.streamFn, ctx.thinkingLevel),
sanitizeReplayHistory: (ctx: ProviderSanitizeReplayHistoryContext) =>
sanitizeGoogleGeminiReplayHistory(ctx),
resolveReasoningOutputMode: () => resolveTaggedReasoningOutputMode(),
...(options.includeToolSchemaCompat
? {
normalizeToolSchemas: (ctx: ProviderNormalizeToolSchemasContext) =>
normalizeGeminiToolSchemas(ctx),
inspectToolSchemas: (ctx: ProviderNormalizeToolSchemasContext) =>
inspectGeminiToolSchemas(ctx),
}
: {}),
};
}