diff --git a/src/agents/auth-profiles.chutes.e2e.test.ts b/src/agents/auth-profiles.chutes.e2e.test.ts index c21f37ed1c..7af0f556c1 100644 --- a/src/agents/auth-profiles.chutes.e2e.test.ts +++ b/src/agents/auth-profiles.chutes.e2e.test.ts @@ -8,7 +8,7 @@ import { ensureAuthProfileStore, resolveApiKeyForProfile, } from "./auth-profiles.js"; -import { CHUTES_TOKEN_ENDPOINT, type ChutesStoredOAuth } from "./chutes-oauth.js"; +import { CHUTES_TOKEN_ENDPOINT } from "./chutes-oauth.js"; describe("auth-profiles (chutes)", () => { let envSnapshot: ReturnType | undefined; @@ -49,7 +49,7 @@ describe("auth-profiles (chutes)", () => { refresh: "rt_old", expires: Date.now() - 60_000, clientId: "cid_test", - } as unknown as ChutesStoredOAuth, + }, }, }; await fs.writeFile(authProfilePath, `${JSON.stringify(store)}\n`); diff --git a/src/agents/bash-tools.e2e.test.ts b/src/agents/bash-tools.e2e.test.ts index 2650f951ce..68c8e3e584 100644 --- a/src/agents/bash-tools.e2e.test.ts +++ b/src/agents/bash-tools.e2e.test.ts @@ -311,7 +311,8 @@ describe("exec tool backgrounding", () => { action: "poll", sessionId: sessionA, }); - expect(pollB.details.status).toBe("failed"); + const pollBDetails = pollB.details as { status?: string }; + expect(pollBDetails.status).toBe("failed"); }); }); @@ -335,9 +336,9 @@ describe("exec exit codes", () => { ? joinCommands(["Write-Output nope", "exit 1"]) : joinCommands(["echo nope", "exit 1"]); const result = await execTool.execute("call1", { command }); - - expect(result.details.status).toBe("completed"); - expect(result.details.exitCode).toBe(1); + const resultDetails = result.details as { status?: string; exitCode?: number | null }; + expect(resultDetails.status).toBe("completed"); + expect(resultDetails.exitCode).toBe(1); const text = normalizeText(result.content.find((c) => c.type === "text")?.text); expect(text).toContain("nope"); diff --git a/src/agents/bash-tools.exec.pty-fallback.e2e.test.ts b/src/agents/bash-tools.exec.pty-fallback.e2e.test.ts index 7ee383b5dc..7a7f53a535 100644 --- a/src/agents/bash-tools.exec.pty-fallback.e2e.test.ts +++ b/src/agents/bash-tools.exec.pty-fallback.e2e.test.ts @@ -23,7 +23,7 @@ test("exec falls back when PTY spawn fails", async () => { }); expect(result.details.status).toBe("completed"); - const text = result.content?.[0]?.text ?? ""; + const text = result.content?.find((item) => item.type === "text")?.text ?? ""; expect(text).toContain("ok"); expect(text).toContain("PTY spawn failed"); }); diff --git a/src/agents/bash-tools.exec.pty.e2e.test.ts b/src/agents/bash-tools.exec.pty.e2e.test.ts index 3db7e924d2..9acb22ea4d 100644 --- a/src/agents/bash-tools.exec.pty.e2e.test.ts +++ b/src/agents/bash-tools.exec.pty.e2e.test.ts @@ -14,6 +14,6 @@ test("exec supports pty output", async () => { }); expect(result.details.status).toBe("completed"); - const text = result.content?.[0]?.text ?? ""; + const text = result.content?.find((item) => item.type === "text")?.text ?? ""; expect(text).toContain("ok"); }); diff --git a/src/agents/bash-tools.process.send-keys.e2e.test.ts b/src/agents/bash-tools.process.send-keys.e2e.test.ts index 4034db49f8..2a5cb0bf91 100644 --- a/src/agents/bash-tools.process.send-keys.e2e.test.ts +++ b/src/agents/bash-tools.process.send-keys.e2e.test.ts @@ -18,7 +18,7 @@ async function startPtySession(command: string) { }); expect(result.details.status).toBe("running"); - const sessionId = result.details.sessionId; + const sessionId = (result.details as { sessionId: string }).sessionId; expect(sessionId).toBeTruthy(); return { processTool, sessionId }; } diff --git a/src/agents/claude-cli-runner.e2e.test.ts b/src/agents/claude-cli-runner.e2e.test.ts index afa353daba..9df19c7a9b 100644 --- a/src/agents/claude-cli-runner.e2e.test.ts +++ b/src/agents/claude-cli-runner.e2e.test.ts @@ -17,8 +17,8 @@ vi.mock("../process/supervisor/index.js", () => ({ })); function createDeferred() { - let resolve: (value: T) => void; - let reject: (error: unknown) => void; + let resolve: (value: T) => void = () => {}; + let reject: (error: unknown) => void = () => {}; const promise = new Promise((res, rej) => { resolve = res; reject = rej; diff --git a/src/agents/google-gemini-switch.live.test.ts b/src/agents/google-gemini-switch.live.test.ts index 76ca91762c..164bfd8677 100644 --- a/src/agents/google-gemini-switch.live.test.ts +++ b/src/agents/google-gemini-switch.live.test.ts @@ -1,4 +1,5 @@ import { completeSimple, getModel } from "@mariozechner/pi-ai"; +import { Type } from "@sinclair/typebox"; import { describe, expect, it } from "vitest"; import { isTruthyEnvValue } from "../infra/env.js"; @@ -57,13 +58,9 @@ describeLive("gemini live switch", () => { { name: "bash", description: "Run shell command", - parameters: { - type: "object", - properties: { - command: { type: "string" }, - }, - required: ["command"], - }, + parameters: Type.Object({ + command: Type.String(), + }), }, ], }, diff --git a/src/agents/model-compat.e2e.test.ts b/src/agents/model-compat.e2e.test.ts index ce6d12d4bd..95b4a0eb25 100644 --- a/src/agents/model-compat.e2e.test.ts +++ b/src/agents/model-compat.e2e.test.ts @@ -21,7 +21,9 @@ describe("normalizeModelCompat", () => { const model = baseModel(); delete (model as { compat?: unknown }).compat; const normalized = normalizeModelCompat(model); - expect(normalized.compat?.supportsDeveloperRole).toBe(false); + expect( + (normalized.compat as { supportsDeveloperRole?: boolean } | undefined)?.supportsDeveloperRole, + ).toBe(false); }); it("leaves non-zai models untouched", () => { @@ -39,6 +41,8 @@ describe("normalizeModelCompat", () => { const model = baseModel(); model.compat = { supportsDeveloperRole: false }; const normalized = normalizeModelCompat(model); - expect(normalized.compat?.supportsDeveloperRole).toBe(false); + expect( + (normalized.compat as { supportsDeveloperRole?: boolean } | undefined)?.supportsDeveloperRole, + ).toBe(false); }); }); diff --git a/src/agents/ollama-stream.test.ts b/src/agents/ollama-stream.test.ts index ff0a1796de..0a96258922 100644 --- a/src/agents/ollama-stream.test.ts +++ b/src/agents/ollama-stream.test.ts @@ -264,7 +264,7 @@ describe("createOllamaStreamFn", () => { try { const streamFn = createOllamaStreamFn("http://ollama-host:11434/v1/"); const signal = new AbortController().signal; - const stream = streamFn( + const stream = await streamFn( { id: "qwen3:32b", api: "ollama", @@ -321,7 +321,7 @@ describe("createOllamaStreamFn", () => { try { const streamFn = createOllamaStreamFn("http://ollama-host:11434"); - const stream = streamFn( + const stream = await streamFn( { id: "qwen3:32b", api: "ollama", diff --git a/src/agents/openclaw-tools.subagents.sessions-spawn.model.e2e.test.ts b/src/agents/openclaw-tools.subagents.sessions-spawn.model.e2e.test.ts index 5465285498..2b9df1b5a1 100644 --- a/src/agents/openclaw-tools.subagents.sessions-spawn.model.e2e.test.ts +++ b/src/agents/openclaw-tools.subagents.sessions-spawn.model.e2e.test.ts @@ -156,7 +156,8 @@ describe("openclaw-tools: subagents (sessions_spawn model + thinking)", () => { expect(result.details).toMatchObject({ status: "error", }); - expect(String(result.details?.error)).toMatch(/Invalid thinking level/i); + const errorDetails = result.details as { error?: unknown }; + expect(String(errorDetails.error)).toMatch(/Invalid thinking level/i); expect(calls).toHaveLength(0); }); diff --git a/src/agents/sandbox-agent-config.agent-specific-sandbox-config.e2e.test.ts b/src/agents/sandbox-agent-config.agent-specific-sandbox-config.e2e.test.ts index b112762260..4fca0e064a 100644 --- a/src/agents/sandbox-agent-config.agent-specific-sandbox-config.e2e.test.ts +++ b/src/agents/sandbox-agent-config.agent-specific-sandbox-config.e2e.test.ts @@ -21,6 +21,7 @@ vi.mock("node:child_process", async (importOriginal) => { stdout?: Readable; stderr?: Readable; on: (event: string, cb: (...args: unknown[]) => void) => void; + emit: (event: string, ...args: unknown[]) => boolean; }; child.stdout = new Readable({ read() {} }); child.stderr = new Readable({ read() {} }); @@ -40,8 +41,8 @@ vi.mock("node:child_process", async (importOriginal) => { }; }); -vi.mock("../skills.js", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("./skills.js", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, syncSkillsToWorkspace: vi.fn(async () => undefined), diff --git a/src/agents/sanitize-for-prompt.test.ts b/src/agents/sanitize-for-prompt.test.ts index 32a4ce3d86..b0cfa14703 100644 --- a/src/agents/sanitize-for-prompt.test.ts +++ b/src/agents/sanitize-for-prompt.test.ts @@ -39,7 +39,7 @@ describe("buildAgentSystemPrompt uses sanitized workspace/sandbox strings", () = enabled: true, containerWorkspaceDir: "/work\u2029space", workspaceDir: "/host\nspace", - workspaceAccess: "read-write", + workspaceAccess: "rw", agentWorkspaceMount: "/mnt\u2028mount", browserNoVncUrl: "http://example.test/\nui", }, diff --git a/src/agents/skills-status.e2e.test.ts b/src/agents/skills-status.e2e.test.ts index 5a53c27206..38fa50e82e 100644 --- a/src/agents/skills-status.e2e.test.ts +++ b/src/agents/skills-status.e2e.test.ts @@ -18,6 +18,7 @@ describe("buildWorkspaceSkillStatus", () => { source: "test", filePath: "/tmp/os-scoped", baseDir: "/tmp", + disableModelInvocation: false, }, frontmatter: {}, metadata: { diff --git a/src/agents/skills.resolveskillspromptforrun.e2e.test.ts b/src/agents/skills.resolveskillspromptforrun.e2e.test.ts index f07166e95f..305e11f2f4 100644 --- a/src/agents/skills.resolveskillspromptforrun.e2e.test.ts +++ b/src/agents/skills.resolveskillspromptforrun.e2e.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { resolveSkillsPromptForRun } from "./skills.js"; +import type { SkillEntry } from "./skills/types.js"; describe("resolveSkillsPromptForRun", () => { it("prefers snapshot prompt when available", () => { @@ -17,6 +18,7 @@ describe("resolveSkillsPromptForRun", () => { filePath: "/app/skills/demo-skill/SKILL.md", baseDir: "/app/skills/demo-skill", source: "openclaw-bundled", + disableModelInvocation: false, }, frontmatter: {}, }; diff --git a/src/agents/tool-loop-detection.test.ts b/src/agents/tool-loop-detection.test.ts index 1e405cbf23..eac09dc996 100644 --- a/src/agents/tool-loop-detection.test.ts +++ b/src/agents/tool-loop-detection.test.ts @@ -235,8 +235,8 @@ describe("tool-loop-detection", () => { expect(criticalResult.stuck).toBe(true); if (criticalResult.stuck) { expect(criticalResult.level).toBe("critical"); + expect(criticalResult.detector).toBe("known_poll_no_progress"); } - expect(criticalResult.detector).toBe("known_poll_no_progress"); }); it("can disable specific detectors", () => { diff --git a/src/agents/tools/discord-actions-presence.e2e.test.ts b/src/agents/tools/discord-actions-presence.e2e.test.ts index 3d930a4bbd..589373cdeb 100644 --- a/src/agents/tools/discord-actions-presence.e2e.test.ts +++ b/src/agents/tools/discord-actions-presence.e2e.test.ts @@ -33,7 +33,10 @@ describe("handleDiscordPresenceAction", () => { status: "online", afk: false, }); - const payload = JSON.parse(result.content[0].text ?? ""); + const textBlock = result.content.find((block) => block.type === "text"); + const payload = JSON.parse( + (textBlock as { type: "text"; text: string } | undefined)?.text ?? "{}", + ); expect(payload.ok).toBe(true); expect(payload.activities[0]).toEqual({ type: 0, name: "with fire" }); }); diff --git a/src/agents/tools/image-tool.e2e.test.ts b/src/agents/tools/image-tool.e2e.test.ts index cd2370d0f8..da96786914 100644 --- a/src/agents/tools/image-tool.e2e.test.ts +++ b/src/agents/tools/image-tool.e2e.test.ts @@ -183,6 +183,7 @@ describe("image tool implicit imageModel config", () => { models: { providers: { acme: { + baseUrl: "https://example.com", models: [ makeModelDefinition("text-1", ["text"]), makeModelDefinition("vision-1", ["text", "image"]), @@ -228,6 +229,7 @@ describe("image tool implicit imageModel config", () => { models: { providers: { acme: { + baseUrl: "https://example.com", models: [makeModelDefinition("vision-1", ["text", "image"])], }, }, diff --git a/src/agents/tools/message-tool.e2e.test.ts b/src/agents/tools/message-tool.e2e.test.ts index c8d4937913..f75eedf7c3 100644 --- a/src/agents/tools/message-tool.e2e.test.ts +++ b/src/agents/tools/message-tool.e2e.test.ts @@ -25,7 +25,7 @@ function mockSendResult(overrides: { channel?: string; to?: string } = {}) { kind: "send", action: "send", channel: overrides.channel ?? "telegram", - ...(overrides.to ? { to: overrides.to } : {}), + to: overrides.to ?? "telegram:123", handledBy: "plugin", payload: {}, dryRun: true, diff --git a/src/agents/tools/telegram-actions.e2e.test.ts b/src/agents/tools/telegram-actions.e2e.test.ts index 827cadb237..a93b64c8d3 100644 --- a/src/agents/tools/telegram-actions.e2e.test.ts +++ b/src/agents/tools/telegram-actions.e2e.test.ts @@ -76,7 +76,7 @@ describe("handleTelegramAction", () => { reactMessageTelegram.mockResolvedValueOnce({ ok: false, warning: "Reaction unavailable: ✅", - }); + } as unknown as Awaited>); const result = await handleTelegramAction(defaultReactionAction, reactionConfig("minimal")); const textPayload = result.content.find((item) => item.type === "text"); expect(textPayload?.type).toBe("text"); diff --git a/src/agents/tools/web-fetch.response-limit.test.ts b/src/agents/tools/web-fetch.response-limit.test.ts index 931e95b213..48e96b994b 100644 --- a/src/agents/tools/web-fetch.response-limit.test.ts +++ b/src/agents/tools/web-fetch.response-limit.test.ts @@ -27,7 +27,7 @@ describe("web_fetch response size limits", () => { const tool = createWebFetchTool(baseToolConfig); const result = await tool?.execute?.("call", { url: "https://example.com/stream" }); - - expect(result?.details?.warning).toContain("Response body truncated"); + const details = result?.details as { warning?: string } | undefined; + expect(details?.warning).toContain("Response body truncated"); }); });