From f2602a5d7b67877a202bb96717016514c2c33b9e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 05:06:40 +0100 Subject: [PATCH] fix: restore ci after dedupe refactors --- extensions/acpx/src/acpx-runtime-compat.d.ts | 56 ++++++++++++++++++++ extensions/diffs/src/tool.ts | 3 +- extensions/elevenlabs/doctor-contract.ts | 6 +-- extensions/telegram/src/thread-bindings.ts | 2 +- extensions/xai/code-execution.ts | 43 ++++++++------- extensions/xai/index.ts | 10 ++-- extensions/xai/model-definitions.ts | 4 +- extensions/xai/provider-models.ts | 6 +-- extensions/xai/video-generation-provider.ts | 19 ++++--- extensions/xai/web-search.ts | 11 ++-- extensions/xai/x-search.ts | 26 ++++----- src/agents/tools/sessions-list-tool.ts | 13 ++++- 12 files changed, 132 insertions(+), 67 deletions(-) create mode 100644 extensions/acpx/src/acpx-runtime-compat.d.ts diff --git a/extensions/acpx/src/acpx-runtime-compat.d.ts b/extensions/acpx/src/acpx-runtime-compat.d.ts new file mode 100644 index 00000000000..53ce43d6cfe --- /dev/null +++ b/extensions/acpx/src/acpx-runtime-compat.d.ts @@ -0,0 +1,56 @@ +declare module "acpx/dist/runtime.js" { + export const ACPX_BACKEND_ID: string; + + export type AcpRuntimeDoctorReport = import("../runtime-api.js").AcpRuntimeDoctorReport; + export type AcpRuntimeEnsureInput = import("../runtime-api.js").AcpRuntimeEnsureInput; + export type AcpRuntimeEvent = import("../runtime-api.js").AcpRuntimeEvent; + export type AcpRuntimeHandle = import("../runtime-api.js").AcpRuntimeHandle; + export type AcpRuntimeCapabilities = import("../runtime-api.js").AcpRuntimeCapabilities; + export type AcpRuntimeStatus = import("../runtime-api.js").AcpRuntimeStatus; + export type AcpRuntimeTurnInput = import("../runtime-api.js").AcpRuntimeTurnInput; + + export type AcpAgentRegistry = { + resolve(agent: string): string | undefined; + list(): string[]; + }; + + export type AcpSessionRecord = Record; + + export type AcpSessionStore = { + load(sessionId: string): Promise; + save(record: AcpSessionRecord): Promise; + }; + + export type AcpRuntimeOptions = { + cwd: string; + sessionStore: AcpSessionStore; + agentRegistry: AcpAgentRegistry; + mcpServers?: unknown; + permissionMode?: unknown; + nonInteractivePermissions?: unknown; + timeoutMs?: number; + }; + + export class AcpxRuntime { + constructor(options: AcpRuntimeOptions, testOptions?: unknown); + isHealthy(): boolean; + probeAvailability(): Promise; + doctor(): Promise; + ensureSession(input: AcpRuntimeEnsureInput): Promise; + runTurn(input: AcpRuntimeTurnInput): AsyncIterable; + getCapabilities(input?: { + handle?: AcpRuntimeHandle; + }): AcpRuntimeCapabilities | Promise; + getStatus(input: { handle: AcpRuntimeHandle; signal?: AbortSignal }): Promise; + setMode(input: { handle: AcpRuntimeHandle; mode: string }): Promise; + setConfigOption(input: { handle: AcpRuntimeHandle; key: string; value: string }): Promise; + cancel(input: { handle: AcpRuntimeHandle; reason?: string }): Promise; + close(input: { handle: AcpRuntimeHandle; reason?: string }): Promise; + } + + export function createAcpRuntime(...args: unknown[]): AcpxRuntime; + export function createAgentRegistry(params: { overrides?: unknown }): AcpAgentRegistry; + export function createFileSessionStore(params: { stateDir: string }): AcpSessionStore; + export function decodeAcpxRuntimeHandleState(...args: unknown[]): unknown; + export function encodeAcpxRuntimeHandleState(...args: unknown[]): unknown; +} diff --git a/extensions/diffs/src/tool.ts b/extensions/diffs/src/tool.ts index 525a20d0a46..ac043403533 100644 --- a/extensions/diffs/src/tool.ts +++ b/extensions/diffs/src/tool.ts @@ -301,8 +301,7 @@ export function createDiffsTool(params: { content: [ { type: "text", - text: - `Diff viewer ready.\n${viewerUrl}\n` + `File rendering failed: ${errorMessage}`, + text: `Diff viewer ready.\n${viewerUrl}\nFile rendering failed: ${errorMessage}`, }, ], details: { diff --git a/extensions/elevenlabs/doctor-contract.ts b/extensions/elevenlabs/doctor-contract.ts index 2676ee84a1d..d25632856ba 100644 --- a/extensions/elevenlabs/doctor-contract.ts +++ b/extensions/elevenlabs/doctor-contract.ts @@ -1,10 +1,8 @@ import type { ChannelDoctorLegacyConfigRule } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { ELEVENLABS_TALK_PROVIDER_ID, migrateElevenLabsLegacyTalkConfig } from "./config-compat.js"; - -function isRecord(value: unknown): value is Record { - return Boolean(value) && typeof value === "object" && !Array.isArray(value); -} +import { isRecord } from "openclaw/plugin-sdk/text-runtime"; +import { ELEVENLABS_TALK_PROVIDER_ID, migrateElevenLabsLegacyTalkConfig } from "./config-compat.js"; export function hasLegacyTalkFields(value: unknown): boolean { const talk = isRecord(value) ? value : null; diff --git a/extensions/telegram/src/thread-bindings.ts b/extensions/telegram/src/thread-bindings.ts index e49a31bc9f5..cade87b354e 100644 --- a/extensions/telegram/src/thread-bindings.ts +++ b/extensions/telegram/src/thread-bindings.ts @@ -3,7 +3,6 @@ import os from "node:os"; import path from "node:path"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { - formatErrorMessage, formatThreadBindingDurationLabel, registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, @@ -13,6 +12,7 @@ import { type SessionBindingAdapter, type SessionBindingRecord, } from "openclaw/plugin-sdk/conversation-runtime"; +import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; import { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store"; import { normalizeAccountId } from "openclaw/plugin-sdk/routing"; import { logVerbose } from "openclaw/plugin-sdk/runtime-env"; diff --git a/extensions/xai/code-execution.ts b/extensions/xai/code-execution.ts index 066af33b562..ea7d8f89c36 100644 --- a/extensions/xai/code-execution.ts +++ b/extensions/xai/code-execution.ts @@ -1,6 +1,6 @@ -import { getRuntimeConfigSnapshot, type OpenClawConfig } from "@openclaw/plugin-sdk/config-runtime"; -import { jsonResult, readStringParam } from "@openclaw/plugin-sdk/provider-web-search"; import { Type } from "@sinclair/typebox"; +import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/config-runtime"; +import { jsonResult, readStringParam } from "openclaw/plugin-sdk/provider-web-search"; import { buildXaiCodeExecutionPayload, requestXaiCodeExecution, @@ -9,14 +9,6 @@ import { } from "./src/code-execution-shared.js"; import { isXaiToolEnabled, resolveXaiToolApiKey } from "./src/tool-auth-shared.js"; -type _XaiPluginConfig = NonNullable< - NonNullable["entries"] ->["xai"] extends { - config?: infer Config; -} - ? Config - : undefined; - type CodeExecutionConfig = { enabled?: boolean; model?: string; @@ -30,12 +22,19 @@ function readCodeExecutionConfigRecord( return config && typeof config === "object" ? (config as Record) : undefined; } -function readPluginCodeExecutionConfig(cfg?: OpenClawConfig): CodeExecutionConfig | undefined { - const entries = cfg?.plugins?.entries; - if (!entries || typeof entries !== "object") { +function readPluginCodeExecutionConfig(cfg?: unknown): CodeExecutionConfig | undefined { + if (!cfg || typeof cfg !== "object") { return undefined; } - const xaiEntry = (entries as Record).xai; + const entries = (cfg as Record).plugins; + const pluginEntries = + entries && typeof entries === "object" + ? ((entries as Record).entries as Record | undefined) + : undefined; + if (!pluginEntries) { + return undefined; + } + const xaiEntry = pluginEntries.xai; if (!xaiEntry || typeof xaiEntry !== "object") { return undefined; } @@ -51,20 +50,20 @@ function readPluginCodeExecutionConfig(cfg?: OpenClawConfig): CodeExecutionConfi } function resolveCodeExecutionEnabled(params: { - sourceConfig?: OpenClawConfig; - runtimeConfig?: OpenClawConfig; + sourceConfig?: unknown; + runtimeConfig?: unknown; config?: CodeExecutionConfig; }): boolean { return isXaiToolEnabled({ enabled: readCodeExecutionConfigRecord(params.config)?.enabled as boolean | undefined, - runtimeConfig: params.runtimeConfig, - sourceConfig: params.sourceConfig, + runtimeConfig: params.runtimeConfig as never, + sourceConfig: params.sourceConfig as never, }); } export function createCodeExecutionTool(options?: { - config?: OpenClawConfig; - runtimeConfig?: OpenClawConfig | null; + config?: unknown; + runtimeConfig?: Record | null; }) { const runtimeConfig = options?.runtimeConfig ?? getRuntimeConfigSnapshot(); const codeExecutionConfig = @@ -93,8 +92,8 @@ export function createCodeExecutionTool(options?: { }), execute: async (_toolCallId: string, args: Record) => { const apiKey = resolveXaiToolApiKey({ - runtimeConfig: runtimeConfig ?? undefined, - sourceConfig: options?.config, + runtimeConfig: (runtimeConfig ?? undefined) as never, + sourceConfig: options?.config as never, }); if (!apiKey) { return jsonResult({ diff --git a/extensions/xai/index.ts b/extensions/xai/index.ts index d0ca2f9970f..c38774147ea 100644 --- a/extensions/xai/index.ts +++ b/extensions/xai/index.ts @@ -1,8 +1,7 @@ -import type { OpenClawConfig } from "@openclaw/plugin-sdk/config-runtime"; -import { defineSingleProviderPluginEntry } from "@openclaw/plugin-sdk/provider-entry"; -import { buildProviderReplayFamilyHooks } from "@openclaw/plugin-sdk/provider-model-shared"; -import { jsonResult, readProviderEnvValue } from "@openclaw/plugin-sdk/provider-web-search"; import { Type } from "@sinclair/typebox"; +import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry"; +import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; +import { jsonResult, readProviderEnvValue } from "openclaw/plugin-sdk/provider-web-search"; import { applyXaiModelCompat, normalizeXaiModelId, @@ -30,8 +29,7 @@ const OPENAI_COMPATIBLE_REPLAY_HOOKS = buildProviderReplayFamilyHooks({ function hasResolvableXaiApiKey(config: unknown): boolean { return Boolean( - resolveFallbackXaiAuth(config as OpenClawConfig | undefined)?.apiKey || - readProviderEnvValue(["XAI_API_KEY"]), + resolveFallbackXaiAuth(config as never)?.apiKey || readProviderEnvValue(["XAI_API_KEY"]), ); } diff --git a/extensions/xai/model-definitions.ts b/extensions/xai/model-definitions.ts index 3de78c5b741..951c0adca93 100644 --- a/extensions/xai/model-definitions.ts +++ b/extensions/xai/model-definitions.ts @@ -1,4 +1,4 @@ -import type { ModelDefinitionConfig } from "@openclaw/plugin-sdk/provider-model-shared"; +import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared"; export const XAI_BASE_URL = "https://api.x.ai/v1"; export const XAI_DEFAULT_MODEL_ID = "grok-4"; @@ -200,7 +200,7 @@ export function buildXaiCatalogModels(): ModelDefinitionConfig[] { return XAI_MODEL_CATALOG.map((entry) => toModelDefinition(entry)); } -export function resolveXaiCatalogEntry(modelId: string): ModelDefinitionConfig | undefined { +export function resolveXaiCatalogEntry(modelId: string) { const lower = modelId.trim().toLowerCase(); const exact = XAI_MODEL_CATALOG.find((entry) => entry.id.toLowerCase() === lower); if (exact) { diff --git a/extensions/xai/provider-models.ts b/extensions/xai/provider-models.ts index 214044bef39..829b41a7c3f 100644 --- a/extensions/xai/provider-models.ts +++ b/extensions/xai/provider-models.ts @@ -1,8 +1,8 @@ import type { ProviderResolveDynamicModelContext, ProviderRuntimeModel, -} from "@openclaw/plugin-sdk/plugin-entry"; -import { normalizeModelCompat } from "@openclaw/plugin-sdk/provider-model-shared"; +} from "openclaw/plugin-sdk/plugin-entry"; +import { normalizeModelCompat } from "openclaw/plugin-sdk/provider-model-shared"; import { applyXaiModelCompat } from "./api.js"; import { resolveXaiCatalogEntry, XAI_BASE_URL } from "./model-definitions.js"; @@ -19,7 +19,7 @@ export function isModernXaiModel(modelId: string): boolean { export function resolveXaiForwardCompatModel(params: { providerId: string; ctx: ProviderResolveDynamicModelContext; -}): ProviderRuntimeModel | undefined { +}) { const definition = resolveXaiCatalogEntry(params.ctx.modelId); if (!definition) { return undefined; diff --git a/extensions/xai/video-generation-provider.ts b/extensions/xai/video-generation-provider.ts index 42937edb9cb..a966e5f4e20 100644 --- a/extensions/xai/video-generation-provider.ts +++ b/extensions/xai/video-generation-provider.ts @@ -1,17 +1,16 @@ -import { isProviderApiKeyConfigured } from "@openclaw/plugin-sdk/provider-auth"; -import { resolveApiKeyForProvider } from "@openclaw/plugin-sdk/provider-auth-runtime"; +import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth"; +import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime"; import { assertOkOrThrowHttpError, fetchWithTimeout, postJsonRequest, resolveProviderHttpRequestConfig, -} from "@openclaw/plugin-sdk/provider-http"; +} from "openclaw/plugin-sdk/provider-http"; import type { GeneratedVideoAsset, VideoGenerationProvider, VideoGenerationRequest, - VideoGenerationSourceAsset, -} from "@openclaw/plugin-sdk/video-generation"; +} from "openclaw/plugin-sdk/video-generation"; const DEFAULT_XAI_VIDEO_BASE_URL = "https://api.x.ai/v1"; const DEFAULT_XAI_VIDEO_MODEL = "grok-imagine-video"; @@ -40,6 +39,12 @@ type XaiVideoStatusResponse = { } | null; }; +type VideoGenerationSourceInput = { + url?: string; + buffer?: Buffer; + mimeType?: string; +}; + function resolveXaiVideoBaseUrl(req: VideoGenerationRequest): string { return req.cfg?.models?.providers?.xai?.baseUrl?.trim() || DEFAULT_XAI_VIDEO_BASE_URL; } @@ -48,7 +53,7 @@ function toDataUrl(buffer: Buffer, mimeType: string): string { return `data:${mimeType};base64,${buffer.toString("base64")}`; } -function resolveImageUrl(input: VideoGenerationSourceAsset | undefined): string | undefined { +function resolveImageUrl(input: VideoGenerationSourceInput | undefined): string | undefined { if (!input) { return undefined; } @@ -61,7 +66,7 @@ function resolveImageUrl(input: VideoGenerationSourceAsset | undefined): string return toDataUrl(input.buffer, input.mimeType?.trim() || "image/png"); } -function resolveInputVideoUrl(input: VideoGenerationSourceAsset | undefined): string | undefined { +function resolveInputVideoUrl(input: VideoGenerationSourceInput | undefined): string | undefined { if (!input) { return undefined; } diff --git a/extensions/xai/web-search.ts b/extensions/xai/web-search.ts index 8b68f509f06..50c8ea022b2 100644 --- a/extensions/xai/web-search.ts +++ b/extensions/xai/web-search.ts @@ -1,3 +1,4 @@ +import { Type } from "@sinclair/typebox"; import { DEFAULT_CACHE_TTL_MINUTES, DEFAULT_TIMEOUT_SECONDS, @@ -14,12 +15,10 @@ import { resolveWebSearchProviderCredential, setProviderWebSearchPluginConfigValue, setScopedCredentialValue, - type SearchConfigRecord, type WebSearchProviderSetupContext, type WebSearchProviderPlugin, writeCache, -} from "@openclaw/plugin-sdk/provider-web-search"; -import { Type } from "@sinclair/typebox"; +} from "openclaw/plugin-sdk/provider-web-search"; import { buildXaiWebSearchPayload, extractXaiWebSearchContent, @@ -168,15 +167,15 @@ function runXaiWebSearch(params: { function resolveXaiToolSearchConfig(ctx: { config?: Record; searchConfig?: Record; -}): SearchConfigRecord | undefined { +}) { return mergeScopedSearchConfig( - ctx.searchConfig as SearchConfigRecord | undefined, + ctx.searchConfig, "grok", resolveProviderWebSearchPluginConfig(ctx.config, "xai"), ); } -function resolveXaiWebSearchCredential(searchConfig?: SearchConfigRecord): string | undefined { +function resolveXaiWebSearchCredential(searchConfig?: Record): string | undefined { return resolveWebSearchProviderCredential({ credentialValue: getScopedCredentialValue(searchConfig, "grok"), path: "tools.web.search.grok.apiKey", diff --git a/extensions/xai/x-search.ts b/extensions/xai/x-search.ts index 98eeb87f544..ff653ae49dd 100644 --- a/extensions/xai/x-search.ts +++ b/extensions/xai/x-search.ts @@ -1,4 +1,4 @@ -import { getRuntimeConfigSnapshot, type OpenClawConfig } from "@openclaw/plugin-sdk/config-runtime"; +import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/config-runtime"; import { jsonResult, readCache, @@ -7,7 +7,7 @@ import { resolveCacheTtlMs, resolveTimeoutSeconds, writeCache, -} from "@openclaw/plugin-sdk/provider-web-search"; +} from "openclaw/plugin-sdk/provider-web-search"; import { isXaiToolEnabled, resolveXaiToolApiKey } from "./src/tool-auth-shared.js"; import { resolveEffectiveXSearchConfig } from "./src/x-search-config.js"; import { @@ -51,27 +51,27 @@ function getSharedXSearchCache(): Map { const X_SEARCH_CACHE = getSharedXSearchCache(); -function resolveXSearchConfig(cfg?: OpenClawConfig): Record | undefined { - return resolveEffectiveXSearchConfig(cfg); +function resolveXSearchConfig(cfg?: unknown): Record | undefined { + return resolveEffectiveXSearchConfig(cfg as never); } function resolveXSearchEnabled(params: { - cfg?: OpenClawConfig; + cfg?: unknown; config?: Record; - runtimeConfig?: OpenClawConfig; + runtimeConfig?: unknown; }): boolean { return isXaiToolEnabled({ enabled: params.config?.enabled as boolean | undefined, - runtimeConfig: params.runtimeConfig, - sourceConfig: params.cfg, + runtimeConfig: params.runtimeConfig as never, + sourceConfig: params.cfg as never, }); } function resolveXSearchApiKey(params: { - sourceConfig?: OpenClawConfig; - runtimeConfig?: OpenClawConfig; + sourceConfig?: unknown; + runtimeConfig?: unknown; }): string | undefined { - return resolveXaiToolApiKey(params); + return resolveXaiToolApiKey(params as never); } function normalizeOptionalIsoDate(value: string | undefined, label: string): string | undefined { @@ -120,8 +120,8 @@ function buildXSearchCacheKey(params: { } export function createXSearchTool(options?: { - config?: OpenClawConfig; - runtimeConfig?: OpenClawConfig | null; + config?: unknown; + runtimeConfig?: Record | null; }) { const xSearchConfig = resolveXSearchConfig(options?.config); const runtimeConfig = options?.runtimeConfig ?? getRuntimeConfigSnapshot(); diff --git a/src/agents/tools/sessions-list-tool.ts b/src/agents/tools/sessions-list-tool.ts index 5ab9314f4d5..79407983294 100644 --- a/src/agents/tools/sessions-list-tool.ts +++ b/src/agents/tools/sessions-list-tool.ts @@ -25,6 +25,7 @@ import { resolveInternalSessionKey, resolveSandboxedSessionToolContext, type SessionListRow, + type SessionRunStatus, stripToolMessages, } from "./sessions-helpers.js"; @@ -37,6 +38,16 @@ const SessionsListToolSchema = Type.Object({ type GatewayCaller = typeof callGateway; +function readSessionRunStatus(value: unknown): SessionRunStatus | undefined { + return value === "running" || + value === "done" || + value === "failed" || + value === "killed" || + value === "timeout" + ? value + : undefined; +} + export function createSessionsListTool(opts?: { agentSessionKey?: string; sandboxed?: boolean; @@ -247,7 +258,7 @@ export function createSessionsListTool(opts?: { totalTokens: typeof entry.totalTokens === "number" ? entry.totalTokens : undefined, estimatedCostUsd: typeof entry.estimatedCostUsd === "number" ? entry.estimatedCostUsd : undefined, - status: readStringValue(entry.status), + status: readSessionRunStatus(entry.status), startedAt: typeof entry.startedAt === "number" ? entry.startedAt : undefined, endedAt: typeof entry.endedAt === "number" ? entry.endedAt : undefined, runtimeMs: typeof entry.runtimeMs === "number" ? entry.runtimeMs : undefined,