fix: restore ci after dedupe refactors

This commit is contained in:
Peter Steinberger
2026-04-07 05:06:40 +01:00
parent 4dbe8f9f66
commit f2602a5d7b
12 changed files with 132 additions and 67 deletions

View File

@@ -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<string, unknown>;
export type AcpSessionStore = {
load(sessionId: string): Promise<AcpSessionRecord | undefined>;
save(record: AcpSessionRecord): Promise<void>;
};
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<void>;
doctor(): Promise<AcpRuntimeDoctorReport>;
ensureSession(input: AcpRuntimeEnsureInput): Promise<AcpRuntimeHandle>;
runTurn(input: AcpRuntimeTurnInput): AsyncIterable<AcpRuntimeEvent>;
getCapabilities(input?: {
handle?: AcpRuntimeHandle;
}): AcpRuntimeCapabilities | Promise<AcpRuntimeCapabilities>;
getStatus(input: { handle: AcpRuntimeHandle; signal?: AbortSignal }): Promise<AcpRuntimeStatus>;
setMode(input: { handle: AcpRuntimeHandle; mode: string }): Promise<void>;
setConfigOption(input: { handle: AcpRuntimeHandle; key: string; value: string }): Promise<void>;
cancel(input: { handle: AcpRuntimeHandle; reason?: string }): Promise<void>;
close(input: { handle: AcpRuntimeHandle; reason?: string }): Promise<void>;
}
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;
}

View File

@@ -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: {

View File

@@ -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<string, unknown> {
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;

View File

@@ -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";

View File

@@ -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<OpenClawConfig["plugins"]>["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<string, unknown>) : 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<string, unknown>).xai;
const entries = (cfg as Record<string, unknown>).plugins;
const pluginEntries =
entries && typeof entries === "object"
? ((entries as Record<string, unknown>).entries as Record<string, unknown> | 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<string, unknown> | null;
}) {
const runtimeConfig = options?.runtimeConfig ?? getRuntimeConfigSnapshot();
const codeExecutionConfig =
@@ -93,8 +92,8 @@ export function createCodeExecutionTool(options?: {
}),
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
const apiKey = resolveXaiToolApiKey({
runtimeConfig: runtimeConfig ?? undefined,
sourceConfig: options?.config,
runtimeConfig: (runtimeConfig ?? undefined) as never,
sourceConfig: options?.config as never,
});
if (!apiKey) {
return jsonResult({

View File

@@ -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"]),
);
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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<string, unknown>;
searchConfig?: Record<string, unknown>;
}): 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, unknown>): string | undefined {
return resolveWebSearchProviderCredential({
credentialValue: getScopedCredentialValue(searchConfig, "grok"),
path: "tools.web.search.grok.apiKey",

View File

@@ -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<string, XSearchCacheEntry> {
const X_SEARCH_CACHE = getSharedXSearchCache();
function resolveXSearchConfig(cfg?: OpenClawConfig): Record<string, unknown> | undefined {
return resolveEffectiveXSearchConfig(cfg);
function resolveXSearchConfig(cfg?: unknown): Record<string, unknown> | undefined {
return resolveEffectiveXSearchConfig(cfg as never);
}
function resolveXSearchEnabled(params: {
cfg?: OpenClawConfig;
cfg?: unknown;
config?: Record<string, unknown>;
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<string, unknown> | null;
}) {
const xSearchConfig = resolveXSearchConfig(options?.config);
const runtimeConfig = options?.runtimeConfig ?? getRuntimeConfigSnapshot();

View File

@@ -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,