diff --git a/src/agents/pi-embedded-helpers.buildbootstrapcontextfiles.e2e.test.ts b/src/agents/pi-embedded-helpers.buildbootstrapcontextfiles.e2e.test.ts index 805f4fa53f..46f861ce1a 100644 --- a/src/agents/pi-embedded-helpers.buildbootstrapcontextfiles.e2e.test.ts +++ b/src/agents/pi-embedded-helpers.buildbootstrapcontextfiles.e2e.test.ts @@ -8,6 +8,7 @@ import { resolveBootstrapTotalMaxChars, } from "./pi-embedded-helpers.js"; import { DEFAULT_AGENTS_FILENAME } from "./workspace.js"; +import type { WorkspaceBootstrapFile } from "./workspace.js"; const makeFile = (overrides: Partial): WorkspaceBootstrapFile => ({ name: DEFAULT_AGENTS_FILENAME, diff --git a/src/agents/pi-embedded-runner.e2e.test.ts b/src/agents/pi-embedded-runner.e2e.test.ts index 2255af5589..5617af016f 100644 --- a/src/agents/pi-embedded-runner.e2e.test.ts +++ b/src/agents/pi-embedded-runner.e2e.test.ts @@ -35,7 +35,7 @@ vi.mock("@mariozechner/pi-ai", async () => { const buildAssistantErrorMessage = (model: { api: string; provider: string; id: string }) => ({ role: "assistant" as const, - content: [] as const, + content: [], stopReason: "error" as const, errorMessage: "boom", api: model.api, diff --git a/src/agents/pi-embedded-runner.openai-tool-id-preservation.e2e.test.ts b/src/agents/pi-embedded-runner.openai-tool-id-preservation.e2e.test.ts index 115d0a22b6..5d3a86eec2 100644 --- a/src/agents/pi-embedded-runner.openai-tool-id-preservation.e2e.test.ts +++ b/src/agents/pi-embedded-runner.openai-tool-id-preservation.e2e.test.ts @@ -21,7 +21,7 @@ describe("sanitizeSessionHistory openai tool id preservation", () => { { role: "assistant", content: [{ type: "toolCall", id: "call_123|fc_123", name: "noop", arguments: {} }], - }, + } as unknown as AgentMessage, { role: "toolResult", toolCallId: "call_123|fc_123", diff --git a/src/agents/pi-embedded-runner.sanitize-session-history.e2e.test.ts b/src/agents/pi-embedded-runner.sanitize-session-history.e2e.test.ts index 58d40a608d..1e4c8badfc 100644 --- a/src/agents/pi-embedded-runner.sanitize-session-history.e2e.test.ts +++ b/src/agents/pi-embedded-runner.sanitize-session-history.e2e.test.ts @@ -9,8 +9,7 @@ import { sanitizeWithOpenAIResponses, } from "./pi-embedded-runner.sanitize-session-history.test-harness.js"; -type SanitizeSessionHistory = - typeof import("./pi-embedded-runner/google.js").sanitizeSessionHistory; +type SanitizeSessionHistory = Awaited>; let sanitizeSessionHistory: SanitizeSessionHistory; vi.mock("./pi-embedded-helpers.js", async () => { diff --git a/src/agents/pi-embedded-runner/usage-reporting.test.ts b/src/agents/pi-embedded-runner/usage-reporting.test.ts index 52c72e25d2..ed8d122722 100644 --- a/src/agents/pi-embedded-runner/usage-reporting.test.ts +++ b/src/agents/pi-embedded-runner/usage-reporting.test.ts @@ -51,7 +51,7 @@ describe("runEmbeddedPiAgent usage reporting", () => { }); // Check usage in meta - const usage = result.meta.agentMeta.usage; + const usage = result.meta.agentMeta?.usage; expect(usage).toBeDefined(); // Check if total matches the last turn's total (200) diff --git a/src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.e2e.test.ts b/src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.e2e.test.ts index 05f5bd12fe..c5455dcd2a 100644 --- a/src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.e2e.test.ts +++ b/src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.e2e.test.ts @@ -1,3 +1,4 @@ +import type { AssistantMessage } from "@mariozechner/pi-ai"; import { describe, expect, it, vi } from "vitest"; import { createStubSessionHarness, diff --git a/src/agents/pi-embedded-utils.e2e.test.ts b/src/agents/pi-embedded-utils.e2e.test.ts index fa8865abe1..ecb8dace5a 100644 --- a/src/agents/pi-embedded-utils.e2e.test.ts +++ b/src/agents/pi-embedded-utils.e2e.test.ts @@ -14,7 +14,14 @@ function makeAssistantMessage( api: "responses", provider: "openai", model: "gpt-5", - usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: 0 }, + usage: { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 0, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, + }, stopReason: "stop", ...message, }; diff --git a/src/agents/pi-extensions/compaction-safeguard.e2e.test.ts b/src/agents/pi-extensions/compaction-safeguard.e2e.test.ts index 8a7c00a5a4..3d5fab422a 100644 --- a/src/agents/pi-extensions/compaction-safeguard.e2e.test.ts +++ b/src/agents/pi-extensions/compaction-safeguard.e2e.test.ts @@ -119,7 +119,7 @@ describe("computeAdaptiveChunkRatio", () => { role: "assistant", content: [{ type: "text", text: "y".repeat(1000) }], timestamp: Date.now(), - }, + } as unknown as AgentMessage, ]; const ratio = computeAdaptiveChunkRatio(messages, CONTEXT_WINDOW); @@ -134,7 +134,7 @@ describe("computeAdaptiveChunkRatio", () => { role: "assistant", content: [{ type: "text", text: "y".repeat(50_000 * 4) }], timestamp: Date.now(), - }, + } as unknown as AgentMessage, ]; const ratio = computeAdaptiveChunkRatio(messages, CONTEXT_WINDOW); diff --git a/src/agents/pi-extensions/context-pruning.e2e.test.ts b/src/agents/pi-extensions/context-pruning.e2e.test.ts index d269e98abc..09bc3d2f8a 100644 --- a/src/agents/pi-extensions/context-pruning.e2e.test.ts +++ b/src/agents/pi-extensions/context-pruning.e2e.test.ts @@ -68,7 +68,14 @@ function makeAssistant(text: string): AgentMessage { api: "openai-responses", provider: "openai", model: "fake", - usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, total: 2 }, + usage: { + input: 1, + output: 1, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 2, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, + }, stopReason: "stop", timestamp: Date.now(), }; diff --git a/src/agents/pi-tool-definition-adapter.after-tool-call.e2e.test.ts b/src/agents/pi-tool-definition-adapter.after-tool-call.e2e.test.ts index 9d54b7de4c..5d442fc672 100644 --- a/src/agents/pi-tool-definition-adapter.after-tool-call.e2e.test.ts +++ b/src/agents/pi-tool-definition-adapter.after-tool-call.e2e.test.ts @@ -37,7 +37,7 @@ function createReadTool() { } type ToolExecute = ReturnType[number]["execute"]; -const extensionContext = {} as Parameters[3]; +const extensionContext = {} as Parameters[4]; function enableAfterToolCallHook() { hookMocks.runner.hasHooks.mockImplementation((name: string) => name === "after_tool_call"); @@ -45,14 +45,12 @@ function enableAfterToolCallHook() { async function executeReadTool(callId: string) { const defs = toToolDefinitions([createReadTool()]); - const args: Parameters<(typeof defs)[number]["execute"]> = [ - callId, - { path: "/tmp/file" }, - undefined, - extensionContext, - undefined, - ]; - return await defs[0].execute(...args); + const def = defs[0]; + if (!def) { + throw new Error("missing tool definition"); + } + const execute = (...args: Parameters<(typeof defs)[0]["execute"]>) => def.execute(...args); + return await execute(callId, { path: "/tmp/file" }, undefined, undefined, extensionContext); } function expectReadAfterToolCallPayload(result: Awaited>) { @@ -119,14 +117,12 @@ describe("pi tool definition adapter after_tool_call", () => { } satisfies AgentTool; const defs = toToolDefinitions([tool]); - const args: Parameters<(typeof defs)[number]["execute"]> = [ - "call-err", - { cmd: "ls" }, - undefined, - extensionContext, - undefined, - ]; - const result = await defs[0].execute(...args); + const def = defs[0]; + if (!def) { + throw new Error("missing tool definition"); + } + const execute = (...args: Parameters<(typeof defs)[0]["execute"]>) => def.execute(...args); + const result = await execute("call-err", { cmd: "ls" }, undefined, undefined, extensionContext); expect(result.details).toMatchObject({ status: "error", diff --git a/src/agents/pi-tool-definition-adapter.e2e.test.ts b/src/agents/pi-tool-definition-adapter.e2e.test.ts index 362e9fbca0..cc15e71e1f 100644 --- a/src/agents/pi-tool-definition-adapter.e2e.test.ts +++ b/src/agents/pi-tool-definition-adapter.e2e.test.ts @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; import { toToolDefinitions } from "./pi-tool-definition-adapter.js"; type ToolExecute = ReturnType[number]["execute"]; -const extensionContext = {} as Parameters[3]; +const extensionContext = {} as Parameters[4]; describe("pi tool definition adapter", () => { it("wraps tool errors into a tool result", async () => { @@ -19,14 +19,12 @@ describe("pi tool definition adapter", () => { } satisfies AgentTool; const defs = toToolDefinitions([tool]); - const args: Parameters<(typeof defs)[number]["execute"]> = [ - "call1", - {}, - undefined, - extensionContext, - undefined, - ]; - const result = await defs[0].execute(...args); + const def = defs[0]; + if (!def) { + throw new Error("missing tool definition"); + } + const execute = (...args: Parameters<(typeof defs)[0]["execute"]>) => def.execute(...args); + const result = await execute("call1", {}, undefined, undefined, extensionContext); expect(result.details).toMatchObject({ status: "error", @@ -48,14 +46,12 @@ describe("pi tool definition adapter", () => { } satisfies AgentTool; const defs = toToolDefinitions([tool]); - const args: Parameters<(typeof defs)[number]["execute"]> = [ - "call2", - {}, - undefined, - extensionContext, - undefined, - ]; - const result = await defs[0].execute(...args); + const def = defs[0]; + if (!def) { + throw new Error("missing tool definition"); + } + const execute = (...args: Parameters<(typeof defs)[0]["execute"]>) => def.execute(...args); + const result = await execute("call2", {}, undefined, undefined, extensionContext); expect(result.details).toMatchObject({ status: "error", diff --git a/src/agents/pi-tools-agent-config.e2e.test.ts b/src/agents/pi-tools-agent-config.e2e.test.ts index d8f9a1c866..cd3f79cb63 100644 --- a/src/agents/pi-tools-agent-config.e2e.test.ts +++ b/src/agents/pi-tools-agent-config.e2e.test.ts @@ -618,7 +618,8 @@ describe("Agent-specific tool filtering", () => { yieldMs: 10, }); - expect(result?.details.status).toBe("completed"); + const resultDetails = result?.details as { status?: string } | undefined; + expect(resultDetails?.status).toBe("completed"); }); it("should apply agent-specific exec host defaults over global defaults", async () => { @@ -673,6 +674,7 @@ describe("Agent-specific tool filtering", () => { host: "sandbox", yieldMs: 1000, }); - expect(helperResult?.details.status).toBe("completed"); + const helperDetails = helperResult?.details as { status?: string } | undefined; + expect(helperDetails?.status).toBe("completed"); }); }); diff --git a/src/agents/pi-tools.before-tool-call.e2e.test.ts b/src/agents/pi-tools.before-tool-call.e2e.test.ts index e364d1f9a9..4734ddeb32 100644 --- a/src/agents/pi-tools.before-tool-call.e2e.test.ts +++ b/src/agents/pi-tools.before-tool-call.e2e.test.ts @@ -151,16 +151,14 @@ describe("before_tool_call hook deduplication (#15502)", () => { sessionKey: "main", }); const [def] = toToolDefinitions([wrapped]); - const extensionContext = {} as Parameters[3]; - - const args: Parameters = [ + const extensionContext = {} as Parameters[4]; + await def.execute( "call-dedup", { url: "https://example.com" }, undefined, - extensionContext, undefined, - ]; - await def.execute(...args); + extensionContext, + ); expect(hookRunner.runBeforeToolCall).toHaveBeenCalledTimes(1); }); @@ -200,16 +198,8 @@ describe("before_tool_call hook integration for client tools", () => { onClientToolCall, { agentId: "main", sessionKey: "main" }, ); - const extensionContext = {} as Parameters[3]; - - const args: Parameters = [ - "client-call-1", - { value: "ok" }, - undefined, - extensionContext, - undefined, - ]; - await tool.execute(...args); + const extensionContext = {} as Parameters[4]; + await tool.execute("client-call-1", { value: "ok" }, undefined, undefined, extensionContext); expect(onClientToolCall).toHaveBeenCalledWith("client_tool", { value: "ok", diff --git a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.e2e.test.ts b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.e2e.test.ts index 3437e6253e..ee071861c8 100644 --- a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.e2e.test.ts +++ b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.e2e.test.ts @@ -79,7 +79,7 @@ describe("createOpenClawCodingTools", () => { sessionKey: "sandbox:test", workspaceDir: sandboxDir, agentWorkspaceDir: path.join(os.tmpdir(), "moltbot-workspace"), - workspaceAccess: "none", + workspaceAccess: "none" as const, containerName: "openclaw-sbx-test", containerWorkdir: "/workspace", fsBridge: createHostSandboxFsBridge(sandboxDir), @@ -112,7 +112,7 @@ describe("createOpenClawCodingTools", () => { sessionKey: "sandbox:test", workspaceDir: sandboxDir, agentWorkspaceDir: path.join(os.tmpdir(), "moltbot-workspace"), - workspaceAccess: "ro", + workspaceAccess: "ro" as const, containerName: "openclaw-sbx-test", containerWorkdir: "/workspace", fsBridge: createHostSandboxFsBridge(sandboxDir), diff --git a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts index f580f04c2b..baa05b7f60 100644 --- a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts +++ b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts @@ -2,6 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import type { AgentTool } from "@mariozechner/pi-agent-core"; +import { Type } from "@sinclair/typebox"; import { describe, expect, it, vi } from "vitest"; import "./test-helpers/fast-coding-tools.js"; import { createOpenClawTools } from "./openclaw-tools.js"; @@ -62,15 +63,12 @@ describe("createOpenClawCodingTools", () => { it("adds Claude-style aliases to schemas without dropping metadata", () => { const base: AgentTool = { name: "write", + label: "write", description: "test", - parameters: { - type: "object", - required: ["path", "content"], - properties: { - path: { type: "string", description: "Path" }, - content: { type: "string", description: "Body" }, - }, - }, + parameters: Type.Object({ + path: Type.String({ description: "Path" }), + content: Type.String({ description: "Body" }), + }), execute: vi.fn(), }; @@ -90,15 +88,12 @@ describe("createOpenClawCodingTools", () => { const execute = vi.fn(async (_id, args) => args); const tool: AgentTool = { name: "write", + label: "write", description: "test", - parameters: { - type: "object", - required: ["path", "content"], - properties: { - path: { type: "string" }, - content: { type: "string" }, - }, - }, + parameters: Type.Object({ + path: Type.String(), + content: Type.String(), + }), execute, }; diff --git a/src/agents/pi-tools.policy.e2e.test.ts b/src/agents/pi-tools.policy.e2e.test.ts index 819768be14..6a8d0e70f5 100644 --- a/src/agents/pi-tools.policy.e2e.test.ts +++ b/src/agents/pi-tools.policy.e2e.test.ts @@ -1,4 +1,5 @@ import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; +import { Type } from "@sinclair/typebox"; import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { @@ -7,12 +8,12 @@ import { resolveSubagentToolPolicy, } from "./pi-tools.policy.js"; -function createStubTool(name: string): AgentTool { +function createStubTool(name: string): AgentTool { return { name, label: name, description: "", - parameters: {}, + parameters: Type.Object({}), execute: async () => ({}) as AgentToolResult, }; } diff --git a/src/agents/pi-tools.safe-bins.e2e.test.ts b/src/agents/pi-tools.safe-bins.e2e.test.ts index f022a84abc..6e8c3747bc 100644 --- a/src/agents/pi-tools.safe-bins.e2e.test.ts +++ b/src/agents/pi-tools.safe-bins.e2e.test.ts @@ -110,7 +110,8 @@ describe("createOpenClawCodingTools safeBins", () => { })(); const text = result.content.find((content) => content.type === "text")?.text ?? ""; - expect(result.details.status).toBe("completed"); + const resultDetails = result.details as { status?: string }; + expect(resultDetails.status).toBe("completed"); expect(text).toContain(marker); }); @@ -152,7 +153,8 @@ describe("createOpenClawCodingTools safeBins", () => { }); const text = result.content.find((content) => content.type === "text")?.text ?? ""; - expect(result.details.status).toBe("completed"); + const blockedResultDetails = result.details as { status?: string }; + expect(blockedResultDetails.status).toBe("completed"); expect(text).not.toContain(secret); }); }); diff --git a/src/agents/pi-tools.workspace-paths.e2e.test.ts b/src/agents/pi-tools.workspace-paths.e2e.test.ts index eb58b58a11..bef983e59d 100644 --- a/src/agents/pi-tools.workspace-paths.e2e.test.ts +++ b/src/agents/pi-tools.workspace-paths.e2e.test.ts @@ -162,7 +162,7 @@ describe("sandboxed workspace paths", () => { sessionKey: "sandbox:test", workspaceDir: sandboxDir, agentWorkspaceDir: workspaceDir, - workspaceAccess: "rw", + workspaceAccess: "rw" as const, containerName: "openclaw-sbx-test", containerWorkdir: "/workspace", fsBridge: createHostSandboxFsBridge(sandboxDir),