From 4ad1d96e5d58801aca555a4e2f1b3fd6e3a6d4cf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 6 Apr 2026 20:20:30 +0100 Subject: [PATCH] fix(ci): repair typing drift on main --- extensions/elevenlabs/speech-provider.ts | 56 ++++++++++--------- extensions/openai/shared.ts | 13 ++++- .../bash-tools.exec-host-gateway.test.ts | 34 ++++++++--- src/agents/bash-tools.exec-host-node.test.ts | 34 ++++++++--- 4 files changed, 92 insertions(+), 45 deletions(-) diff --git a/extensions/elevenlabs/speech-provider.ts b/extensions/elevenlabs/speech-provider.ts index 29ae1bb1fab..e8184eac4da 100644 --- a/extensions/elevenlabs/speech-provider.ts +++ b/extensions/elevenlabs/speech-provider.ts @@ -348,9 +348,9 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { ...(trimToUndefined(talkProviderConfig.modelId) == null ? {} : { modelId: trimToUndefined(talkProviderConfig.modelId) }), - ...(asNumber(talkProviderConfig.seed) == null + ...(asFiniteNumber(talkProviderConfig.seed) == null ? {} - : { seed: asNumber(talkProviderConfig.seed) }), + : { seed: asFiniteNumber(talkProviderConfig.seed) }), ...(trimToUndefined(talkProviderConfig.applyTextNormalization) == null ? {} : { @@ -365,35 +365,37 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { }), voiceSettings: { ...base.voiceSettings, - ...(asNumber(talkVoiceSettings?.stability) == null + ...(asFiniteNumber(talkVoiceSettings?.stability) == null ? {} - : { stability: asNumber(talkVoiceSettings?.stability) }), - ...(asNumber(talkVoiceSettings?.similarityBoost) == null + : { stability: asFiniteNumber(talkVoiceSettings?.stability) }), + ...(asFiniteNumber(talkVoiceSettings?.similarityBoost) == null ? {} - : { similarityBoost: asNumber(talkVoiceSettings?.similarityBoost) }), - ...(asNumber(talkVoiceSettings?.style) == null + : { similarityBoost: asFiniteNumber(talkVoiceSettings?.similarityBoost) }), + ...(asFiniteNumber(talkVoiceSettings?.style) == null ? {} - : { style: asNumber(talkVoiceSettings?.style) }), + : { style: asFiniteNumber(talkVoiceSettings?.style) }), ...(asBoolean(talkVoiceSettings?.useSpeakerBoost) == null ? {} : { useSpeakerBoost: asBoolean(talkVoiceSettings?.useSpeakerBoost) }), - ...(asNumber(talkVoiceSettings?.speed) == null + ...(asFiniteNumber(talkVoiceSettings?.speed) == null ? {} - : { speed: asNumber(talkVoiceSettings?.speed) }), + : { speed: asFiniteNumber(talkVoiceSettings?.speed) }), }, }; }, resolveTalkOverrides: ({ params }) => { const normalize = trimToUndefined(params.normalize); const language = trimToUndefined(params.language)?.toLowerCase(); - const latencyTier = asNumber(params.latencyTier); + const latencyTier = asFiniteNumber(params.latencyTier); const voiceSettings = { - ...(asNumber(params.speed) == null ? {} : { speed: asNumber(params.speed) }), - ...(asNumber(params.stability) == null ? {} : { stability: asNumber(params.stability) }), - ...(asNumber(params.similarity) == null + ...(asFiniteNumber(params.speed) == null ? {} : { speed: asFiniteNumber(params.speed) }), + ...(asFiniteNumber(params.stability) == null ? {} - : { similarityBoost: asNumber(params.similarity) }), - ...(asNumber(params.style) == null ? {} : { style: asNumber(params.style) }), + : { stability: asFiniteNumber(params.stability) }), + ...(asFiniteNumber(params.similarity) == null + ? {} + : { similarityBoost: asFiniteNumber(params.similarity) }), + ...(asFiniteNumber(params.style) == null ? {} : { style: asFiniteNumber(params.style) }), ...(asBoolean(params.speakerBoost) == null ? {} : { useSpeakerBoost: asBoolean(params.speakerBoost) }), @@ -408,7 +410,7 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { ...(trimToUndefined(params.outputFormat) == null ? {} : { outputFormat: trimToUndefined(params.outputFormat) }), - ...(asNumber(params.seed) == null ? {} : { seed: asNumber(params.seed) }), + ...(asFiniteNumber(params.seed) == null ? {} : { seed: asFiniteNumber(params.seed) }), ...(normalize == null ? {} : { applyTextNormalization: normalizeApplyTextNormalization(normalize) }), @@ -452,7 +454,7 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { trimToUndefined(overrides.outputFormat) ?? (req.target === "voice-note" ? "opus_48000_64" : "mp3_44100_128"); const overrideVoiceSettings = asObject(overrides.voiceSettings); - const latencyTier = asNumber(overrides.latencyTier); + const latencyTier = asFiniteNumber(overrides.latencyTier); const audioBuffer = await elevenLabsTTS({ text: req.text, apiKey, @@ -460,7 +462,7 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { voiceId: trimToUndefined(overrides.voiceId) ?? config.voiceId, modelId: trimToUndefined(overrides.modelId) ?? config.modelId, outputFormat, - seed: asNumber(overrides.seed) ?? config.seed, + seed: asFiniteNumber(overrides.seed) ?? config.seed, applyTextNormalization: (trimToUndefined(overrides.applyTextNormalization) as | "auto" @@ -471,21 +473,21 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin { latencyTier, voiceSettings: { ...config.voiceSettings, - ...(asNumber(overrideVoiceSettings?.stability) == null + ...(asFiniteNumber(overrideVoiceSettings?.stability) == null ? {} - : { stability: asNumber(overrideVoiceSettings?.stability) }), - ...(asNumber(overrideVoiceSettings?.similarityBoost) == null + : { stability: asFiniteNumber(overrideVoiceSettings?.stability) }), + ...(asFiniteNumber(overrideVoiceSettings?.similarityBoost) == null ? {} - : { similarityBoost: asNumber(overrideVoiceSettings?.similarityBoost) }), - ...(asNumber(overrideVoiceSettings?.style) == null + : { similarityBoost: asFiniteNumber(overrideVoiceSettings?.similarityBoost) }), + ...(asFiniteNumber(overrideVoiceSettings?.style) == null ? {} - : { style: asNumber(overrideVoiceSettings?.style) }), + : { style: asFiniteNumber(overrideVoiceSettings?.style) }), ...(asBoolean(overrideVoiceSettings?.useSpeakerBoost) == null ? {} : { useSpeakerBoost: asBoolean(overrideVoiceSettings?.useSpeakerBoost) }), - ...(asNumber(overrideVoiceSettings?.speed) == null + ...(asFiniteNumber(overrideVoiceSettings?.speed) == null ? {} - : { speed: asNumber(overrideVoiceSettings?.speed) }), + : { speed: asFiniteNumber(overrideVoiceSettings?.speed) }), }, timeoutMs: req.timeoutMs, }); diff --git a/extensions/openai/shared.ts b/extensions/openai/shared.ts index 9cb764edab0..57f8898fe23 100644 --- a/extensions/openai/shared.ts +++ b/extensions/openai/shared.ts @@ -1,11 +1,20 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; -import type { ProviderRuntimeModel } from "openclaw/plugin-sdk/plugin-entry"; import { findCatalogTemplate } from "openclaw/plugin-sdk/provider-catalog-shared"; import { cloneFirstTemplateModel, matchesExactOrPrefix, } from "openclaw/plugin-sdk/provider-model-shared"; +type SyntheticOpenAIModelCatalogEntry = { + provider: string; + id: string; + name: string; + reasoning?: boolean; + input?: ("text" | "image")[]; + contextWindow?: number; + contextTokens?: number; +}; + export const OPENAI_API_BASE_URL = "https://api.openai.com/v1"; export function toOpenAIDataUrl(buffer: Buffer, mimeType: string): string { @@ -41,7 +50,7 @@ export function buildOpenAISyntheticCatalogEntry( contextWindow: number; contextTokens?: number; }, -): ProviderRuntimeModel | undefined { +): SyntheticOpenAIModelCatalogEntry | undefined { if (!template) { return undefined; } diff --git a/src/agents/bash-tools.exec-host-gateway.test.ts b/src/agents/bash-tools.exec-host-gateway.test.ts index 121d632b6e3..4ff2e0f6599 100644 --- a/src/agents/bash-tools.exec-host-gateway.test.ts +++ b/src/agents/bash-tools.exec-host-gateway.test.ts @@ -4,11 +4,17 @@ const createAndRegisterDefaultExecApprovalRequestMock = vi.hoisted(() => vi.fn() const buildExecApprovalPendingToolResultMock = vi.hoisted(() => vi.fn()); const buildExecApprovalFollowupTargetMock = vi.hoisted(() => vi.fn(() => null)); const createExecApprovalDecisionStateMock = vi.hoisted(() => - vi.fn(() => ({ - baseDecision: { timedOut: false }, - approvedByAsk: false, - deniedReason: "approval-required", - })), + vi.fn( + (): { + baseDecision: { timedOut: boolean }; + approvedByAsk: boolean; + deniedReason: string | null; + } => ({ + baseDecision: { timedOut: false }, + approvedByAsk: false, + deniedReason: "approval-required", + }), + ), ); const evaluateShellAllowlistMock = vi.hoisted(() => vi.fn(() => ({ @@ -27,7 +33,9 @@ const buildEnforcedShellCommandMock = vi.hoisted(() => })), ); const recordAllowlistMatchesUseMock = vi.hoisted(() => vi.fn()); -const resolveApprovalDecisionOrUndefinedMock = vi.hoisted(() => vi.fn(async () => undefined)); +const resolveApprovalDecisionOrUndefinedMock = vi.hoisted(() => + vi.fn(async (): Promise => undefined), +); const resolveExecHostApprovalContextMock = vi.hoisted(() => vi.fn(() => ({ approvals: { allowlist: [], file: { version: 1, agents: {} } }, @@ -39,9 +47,19 @@ const resolveExecHostApprovalContextMock = vi.hoisted(() => const runExecProcessMock = vi.hoisted(() => vi.fn()); const sendExecApprovalFollowupResultMock = vi.hoisted(() => vi.fn(async () => undefined)); const enforceStrictInlineEvalApprovalBoundaryMock = vi.hoisted(() => - vi.fn((value: { approvedByAsk: boolean; deniedReason: string | null }) => value), + vi.fn( + (value: { + approvedByAsk: boolean; + deniedReason: string | null; + }): { + approvedByAsk: boolean; + deniedReason: string | null; + } => value, + ), +); +const detectInterpreterInlineEvalArgvMock = vi.hoisted(() => + vi.fn((): { kind: string } | null => null), ); -const detectInterpreterInlineEvalArgvMock = vi.hoisted(() => vi.fn(() => null)); vi.mock("../infra/exec-approvals.js", () => ({ evaluateShellAllowlist: evaluateShellAllowlistMock, diff --git a/src/agents/bash-tools.exec-host-node.test.ts b/src/agents/bash-tools.exec-host-node.test.ts index 76469fce0b7..9af7b30b960 100644 --- a/src/agents/bash-tools.exec-host-node.test.ts +++ b/src/agents/bash-tools.exec-host-node.test.ts @@ -27,23 +27,41 @@ const resolveExecHostApprovalContextMock = vi.hoisted(() => })), ); const createAndRegisterDefaultExecApprovalRequestMock = vi.hoisted(() => vi.fn()); -const resolveApprovalDecisionOrUndefinedMock = vi.hoisted(() => vi.fn(async () => "allow-once")); +const resolveApprovalDecisionOrUndefinedMock = vi.hoisted(() => + vi.fn(async (): Promise => "allow-once"), +); const createExecApprovalDecisionStateMock = vi.hoisted(() => - vi.fn(() => ({ - baseDecision: { timedOut: false }, - approvedByAsk: false, - deniedReason: null, - })), + vi.fn( + (): { + baseDecision: { timedOut: boolean }; + approvedByAsk: boolean; + deniedReason: string | null; + } => ({ + baseDecision: { timedOut: false }, + approvedByAsk: false, + deniedReason: null, + }), + ), ); const buildExecApprovalPendingToolResultMock = vi.hoisted(() => vi.fn()); const sendExecApprovalFollowupResultMock = vi.hoisted(() => vi.fn(async () => undefined)); const enforceStrictInlineEvalApprovalBoundaryMock = vi.hoisted(() => - vi.fn((value: { approvedByAsk: boolean; deniedReason: string | null }) => value), + vi.fn( + (value: { + approvedByAsk: boolean; + deniedReason: string | null; + }): { + approvedByAsk: boolean; + deniedReason: string | null; + } => value, + ), ); const registerExecApprovalRequestForHostOrThrowMock = vi.hoisted(() => vi.fn(async () => undefined), ); -const detectInterpreterInlineEvalArgvMock = vi.hoisted(() => vi.fn(() => null)); +const detectInterpreterInlineEvalArgvMock = vi.hoisted(() => + vi.fn((): { kind: string } | null => null), +); vi.mock("../infra/exec-approvals.js", () => ({ evaluateShellAllowlist: vi.fn(() => ({