import { normalizeXaiModelId } from "openclaw/plugin-sdk/provider-models"; import { postTrustedWebToolsJson } from "openclaw/plugin-sdk/provider-web-search"; import { extractXaiWebSearchContent, type XaiWebSearchResponse } from "./web-search-shared.js"; export const XAI_CODE_EXECUTION_ENDPOINT = "https://api.x.ai/v1/responses"; export const XAI_DEFAULT_CODE_EXECUTION_MODEL = "grok-4-1-fast"; export type XaiCodeExecutionConfig = { apiKey?: unknown; model?: unknown; maxTurns?: unknown; }; export type XaiCodeExecutionResponse = XaiWebSearchResponse & { output?: Array<{ type?: string; }>; }; export type XaiCodeExecutionResult = { content: string; citations: string[]; usedCodeExecution: boolean; outputTypes: string[]; }; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } export function resolveXaiCodeExecutionConfig( config?: Record, ): XaiCodeExecutionConfig { return isRecord(config) ? (config as XaiCodeExecutionConfig) : {}; } export function resolveXaiCodeExecutionModel(config?: Record): string { const resolved = resolveXaiCodeExecutionConfig(config); return typeof resolved.model === "string" && resolved.model.trim() ? normalizeXaiModelId(resolved.model.trim()) : XAI_DEFAULT_CODE_EXECUTION_MODEL; } export function resolveXaiCodeExecutionMaxTurns( config?: Record, ): number | undefined { const raw = resolveXaiCodeExecutionConfig(config).maxTurns; if (typeof raw !== "number" || !Number.isFinite(raw)) { return undefined; } const normalized = Math.trunc(raw); return normalized > 0 ? normalized : undefined; } export function buildXaiCodeExecutionPayload(params: { task: string; model: string; tookMs: number; content: string; citations: string[]; usedCodeExecution: boolean; outputTypes: string[]; }): Record { return { task: params.task, provider: "xai", model: params.model, tookMs: params.tookMs, content: params.content, citations: params.citations, usedCodeExecution: params.usedCodeExecution, outputTypes: params.outputTypes, }; } export async function requestXaiCodeExecution(params: { apiKey: string; model: string; timeoutSeconds: number; maxTurns?: number; task: string; }): Promise { return await postTrustedWebToolsJson( { url: XAI_CODE_EXECUTION_ENDPOINT, timeoutSeconds: params.timeoutSeconds, apiKey: params.apiKey, body: { model: params.model, input: [{ role: "user", content: params.task }], tools: [{ type: "code_interpreter" }], ...(params.maxTurns ? { max_turns: params.maxTurns } : {}), }, errorLabel: "xAI", }, async (response) => { const data = (await response.json()) as XaiCodeExecutionResponse; const { text, annotationCitations } = extractXaiWebSearchContent(data); const outputTypes = Array.isArray(data.output) ? [ ...new Set( data.output .map((entry) => entry?.type) .filter((value): value is string => Boolean(value)), ), ] : []; const citations = Array.isArray(data.citations) && data.citations.length > 0 ? data.citations : annotationCitations; return { content: text ?? "No response", citations, usedCodeExecution: outputTypes.includes("code_interpreter_call"), outputTypes, }; }, ); } export const __testing = { buildXaiCodeExecutionPayload, requestXaiCodeExecution, resolveXaiCodeExecutionConfig, resolveXaiCodeExecutionMaxTurns, resolveXaiCodeExecutionModel, XAI_DEFAULT_CODE_EXECUTION_MODEL, } as const;