chore: Fix types in tests 26/N.

This commit is contained in:
cpojer
2026-02-17 14:31:40 +09:00
parent 6e5df1dc0f
commit 4235435309
14 changed files with 57 additions and 45 deletions

View File

@@ -1,6 +1,5 @@
import type { StreamFn } from "@mariozechner/pi-agent-core"; import type { StreamFn } from "@mariozechner/pi-agent-core";
import type { Context, Model, SimpleStreamOptions } from "@mariozechner/pi-ai"; import type { Context, Model, SimpleStreamOptions } from "@mariozechner/pi-ai";
import { AssistantMessageEventStream } from "@mariozechner/pi-ai";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { applyExtraParamsToAgent, resolveExtraParams } from "./pi-embedded-runner.js"; import { applyExtraParamsToAgent, resolveExtraParams } from "./pi-embedded-runner.js";
@@ -77,7 +76,7 @@ describe("applyExtraParamsToAgent", () => {
const payload = { store: false }; const payload = { store: false };
const baseStreamFn: StreamFn = (_model, _context, options) => { const baseStreamFn: StreamFn = (_model, _context, options) => {
options?.onPayload?.(payload); options?.onPayload?.(payload);
return new AssistantMessageEventStream(); return {} as ReturnType<StreamFn>;
}; };
const agent = { streamFn: baseStreamFn }; const agent = { streamFn: baseStreamFn };
applyExtraParamsToAgent(agent, undefined, params.applyProvider, params.applyModelId); applyExtraParamsToAgent(agent, undefined, params.applyProvider, params.applyModelId);
@@ -90,7 +89,7 @@ describe("applyExtraParamsToAgent", () => {
const calls: Array<SimpleStreamOptions | undefined> = []; const calls: Array<SimpleStreamOptions | undefined> = [];
const baseStreamFn: StreamFn = (_model, _context, options) => { const baseStreamFn: StreamFn = (_model, _context, options) => {
calls.push(options); calls.push(options);
return new AssistantMessageEventStream(); return {} as ReturnType<StreamFn>;
}; };
const agent = { streamFn: baseStreamFn }; const agent = { streamFn: baseStreamFn };
@@ -159,7 +158,7 @@ describe("applyExtraParamsToAgent", () => {
const payload = { store: false }; const payload = { store: false };
const baseStreamFn: StreamFn = (_model, _context, options) => { const baseStreamFn: StreamFn = (_model, _context, options) => {
options?.onPayload?.(payload); options?.onPayload?.(payload);
return new AssistantMessageEventStream(); return {} as ReturnType<StreamFn>;
}; };
const agent = { streamFn: baseStreamFn }; const agent = { streamFn: baseStreamFn };

View File

@@ -12,7 +12,7 @@ const describeLive = LIVE && OPENAI_KEY ? describe : describe.skip;
describeLive("pi embedded extra params (live)", () => { describeLive("pi embedded extra params (live)", () => {
it("applies config maxTokens to openai streamFn", async () => { it("applies config maxTokens to openai streamFn", async () => {
const model = getModel("openai", "gpt-5.2") as Model<"openai-completions">; const model = getModel("openai", "gpt-5.2") as unknown as Model<"openai-completions">;
const cfg: OpenClawConfig = { const cfg: OpenClawConfig = {
agents: { agents: {

View File

@@ -4,13 +4,12 @@ import { describe, expect, it, vi } from "vitest";
import { applyGoogleTurnOrderingFix } from "./pi-embedded-runner.js"; import { applyGoogleTurnOrderingFix } from "./pi-embedded-runner.js";
describe("applyGoogleTurnOrderingFix", () => { describe("applyGoogleTurnOrderingFix", () => {
const makeAssistantFirst = () => const makeAssistantFirst = (): AgentMessage[] => [
[ {
{ role: "assistant",
role: "assistant", content: [{ type: "toolCall", id: "call_1", name: "exec", arguments: {} }],
content: [{ type: "toolCall", id: "call_1", name: "exec", arguments: {} }], } as unknown as AgentMessage,
}, ];
] satisfies AgentMessage[];
it("prepends a bootstrap once and records a marker for Google models", () => { it("prepends a bootstrap once and records a marker for Google models", () => {
const sessionManager = SessionManager.inMemory(); const sessionManager = SessionManager.inMemory();

View File

@@ -14,9 +14,10 @@ function assistantToolCall(id: string): AgentMessage {
describe("guardSessionManager integration", () => { describe("guardSessionManager integration", () => {
it("persists synthetic toolResult before subsequent assistant message", () => { it("persists synthetic toolResult before subsequent assistant message", () => {
const sm = guardSessionManager(SessionManager.inMemory()); const sm = guardSessionManager(SessionManager.inMemory());
const appendMessage = sm.appendMessage.bind(sm) as unknown as (message: AgentMessage) => void;
sm.appendMessage(assistantToolCall("call_1")); appendMessage(assistantToolCall("call_1"));
sm.appendMessage({ appendMessage({
role: "assistant", role: "assistant",
content: [{ type: "text", text: "followup" }], content: [{ type: "text", text: "followup" }],
} as AgentMessage); } as AgentMessage);

View File

@@ -43,10 +43,11 @@ describe("flushPendingToolResultsAfterIdle", () => {
it("waits for idle so real tool results can land before flush", async () => { it("waits for idle so real tool results can land before flush", async () => {
const sm = guardSessionManager(SessionManager.inMemory()); const sm = guardSessionManager(SessionManager.inMemory());
const appendMessage = sm.appendMessage.bind(sm) as unknown as (message: AgentMessage) => void;
const idle = deferred<void>(); const idle = deferred<void>();
const agent = { waitForIdle: () => idle.promise }; const agent = { waitForIdle: () => idle.promise };
sm.appendMessage(assistantToolCall("call_retry_1")); appendMessage(assistantToolCall("call_retry_1"));
const flushPromise = flushPendingToolResultsAfterIdle({ const flushPromise = flushPendingToolResultsAfterIdle({
agent, agent,
sessionManager: sm, sessionManager: sm,
@@ -58,7 +59,7 @@ describe("flushPendingToolResultsAfterIdle", () => {
expect(getMessages(sm).map((m) => m.role)).toEqual(["assistant"]); expect(getMessages(sm).map((m) => m.role)).toEqual(["assistant"]);
// Tool completes before idle wait finishes. // Tool completes before idle wait finishes.
sm.appendMessage(toolResult("call_retry_1", "command output here")); appendMessage(toolResult("call_retry_1", "command output here"));
idle.resolve(); idle.resolve();
await flushPromise; await flushPromise;
@@ -72,10 +73,11 @@ describe("flushPendingToolResultsAfterIdle", () => {
it("flushes pending tool call after timeout when idle never resolves", async () => { it("flushes pending tool call after timeout when idle never resolves", async () => {
const sm = guardSessionManager(SessionManager.inMemory()); const sm = guardSessionManager(SessionManager.inMemory());
const appendMessage = sm.appendMessage.bind(sm) as unknown as (message: AgentMessage) => void;
vi.useFakeTimers(); vi.useFakeTimers();
const agent = { waitForIdle: () => new Promise<void>(() => {}) }; const agent = { waitForIdle: () => new Promise<void>(() => {}) };
sm.appendMessage(assistantToolCall("call_orphan_1")); appendMessage(assistantToolCall("call_orphan_1"));
const flushPromise = flushPendingToolResultsAfterIdle({ const flushPromise = flushPendingToolResultsAfterIdle({
agent, agent,

View File

@@ -1,13 +1,14 @@
import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core";
import { Type } from "@sinclair/typebox";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { splitSdkTools } from "./pi-embedded-runner.js"; import { splitSdkTools } from "./pi-embedded-runner.js";
function createStubTool(name: string): AgentTool<unknown, unknown> { function createStubTool(name: string): AgentTool {
return { return {
name, name,
label: name, label: name,
description: "", description: "",
parameters: {}, parameters: Type.Object({}),
execute: async () => ({}) as AgentToolResult<unknown>, execute: async () => ({}) as AgentToolResult<unknown>,
}; };
} }

View File

@@ -1,11 +1,12 @@
import { vi } from "vitest"; import { vi } from "vitest";
import type { ModelDefinitionConfig } from "../../config/types.js";
import { discoverModels } from "../pi-model-discovery.js"; import { discoverModels } from "../pi-model-discovery.js";
export const makeModel = (id: string) => ({ export const makeModel = (id: string): ModelDefinitionConfig => ({
id, id,
name: id, name: id,
reasoning: false, reasoning: false,
input: ["text"] as const, input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1, contextWindow: 1,
maxTokens: 1, maxTokens: 1,

View File

@@ -62,7 +62,7 @@ function expectUnknownModelError(provider: string, id: string) {
describe("buildInlineProviderModels", () => { describe("buildInlineProviderModels", () => {
it("attaches provider ids to inline models", () => { it("attaches provider ids to inline models", () => {
const providers = { const providers: Parameters<typeof buildInlineProviderModels>[0] = {
" alpha ": { baseUrl: "http://alpha.local", models: [makeModel("alpha-model")] }, " alpha ": { baseUrl: "http://alpha.local", models: [makeModel("alpha-model")] },
beta: { baseUrl: "http://beta.local", models: [makeModel("beta-model")] }, beta: { baseUrl: "http://beta.local", models: [makeModel("beta-model")] },
}; };
@@ -86,7 +86,7 @@ describe("buildInlineProviderModels", () => {
}); });
it("inherits baseUrl from provider when model does not specify it", () => { it("inherits baseUrl from provider when model does not specify it", () => {
const providers = { const providers: Parameters<typeof buildInlineProviderModels>[0] = {
custom: { custom: {
baseUrl: "http://localhost:8000", baseUrl: "http://localhost:8000",
models: [makeModel("custom-model")], models: [makeModel("custom-model")],
@@ -100,7 +100,7 @@ describe("buildInlineProviderModels", () => {
}); });
it("inherits api from provider when model does not specify it", () => { it("inherits api from provider when model does not specify it", () => {
const providers = { const providers: Parameters<typeof buildInlineProviderModels>[0] = {
custom: { custom: {
baseUrl: "http://localhost:8000", baseUrl: "http://localhost:8000",
api: "anthropic-messages", api: "anthropic-messages",
@@ -115,7 +115,7 @@ describe("buildInlineProviderModels", () => {
}); });
it("model-level api takes precedence over provider-level api", () => { it("model-level api takes precedence over provider-level api", () => {
const providers = { const providers: Parameters<typeof buildInlineProviderModels>[0] = {
custom: { custom: {
baseUrl: "http://localhost:8000", baseUrl: "http://localhost:8000",
api: "openai-responses", api: "openai-responses",
@@ -130,7 +130,7 @@ describe("buildInlineProviderModels", () => {
}); });
it("inherits both baseUrl and api from provider config", () => { it("inherits both baseUrl and api from provider config", () => {
const providers = { const providers: Parameters<typeof buildInlineProviderModels>[0] = {
custom: { custom: {
baseUrl: "http://localhost:10000", baseUrl: "http://localhost:10000",
api: "anthropic-messages", api: "anthropic-messages",
@@ -327,7 +327,7 @@ describe("resolveModel", () => {
}, },
}, },
}, },
} as OpenClawConfig; } as unknown as OpenClawConfig;
expectResolvedForwardCompatFallback({ expectResolvedForwardCompatFallback({
provider: "openai-codex", provider: "openai-codex",

View File

@@ -52,6 +52,7 @@ import { log } from "./logger.js";
import { runEmbeddedPiAgent } from "./run.js"; import { runEmbeddedPiAgent } from "./run.js";
import { makeAttemptResult } from "./run.overflow-compaction.fixture.js"; import { makeAttemptResult } from "./run.overflow-compaction.fixture.js";
import { runEmbeddedAttempt } from "./run/attempt.js"; import { runEmbeddedAttempt } from "./run/attempt.js";
import type { EmbeddedRunAttemptResult } from "./run/types.js";
import { import {
sessionLikelyHasOversizedToolResults, sessionLikelyHasOversizedToolResults,
truncateOversizedToolResultsInSession, truncateOversizedToolResultsInSession,
@@ -171,7 +172,12 @@ describe("overflow compaction in run loop", () => {
.mockResolvedValueOnce( .mockResolvedValueOnce(
makeAttemptResult({ makeAttemptResult({
promptError: overflowError, promptError: overflowError,
messagesSnapshot: [{ role: "assistant", content: "big tool output" }], messagesSnapshot: [
{
role: "assistant",
content: "big tool output",
} as unknown as EmbeddedRunAttemptResult["messagesSnapshot"][number],
],
}), }),
) )
.mockResolvedValueOnce(makeAttemptResult({ promptError: null })); .mockResolvedValueOnce(makeAttemptResult({ promptError: null }));
@@ -362,7 +368,7 @@ describe("overflow compaction in run loop", () => {
cacheWrite: 0, cacheWrite: 0,
total: 2_000, total: 2_000,
}, },
} as EmbeddedRunAttemptResult["lastAssistant"], } as unknown as EmbeddedRunAttemptResult["lastAssistant"],
}), }),
); );

View File

@@ -17,8 +17,9 @@ describe("injectHistoryImagesIntoMessages", () => {
const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[0, [image]]])); const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[0, [image]]]));
expect(didMutate).toBe(true); expect(didMutate).toBe(true);
expect(Array.isArray(messages[0]?.content)).toBe(true); const firstUser = messages[0] as Extract<AgentMessage, { role: "user" }> | undefined;
const content = messages[0]?.content as Array<{ type: string; text?: string; data?: string }>; expect(Array.isArray(firstUser?.content)).toBe(true);
const content = firstUser?.content as Array<{ type: string; text?: string; data?: string }>;
expect(content).toHaveLength(2); expect(content).toHaveLength(2);
expect(content[0]?.type).toBe("text"); expect(content[0]?.type).toBe("text");
expect(content[1]).toMatchObject({ type: "image", data: "abc" }); expect(content[1]).toMatchObject({ type: "image", data: "abc" });
@@ -35,7 +36,7 @@ describe("injectHistoryImagesIntoMessages", () => {
const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[0, [image]]])); const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[0, [image]]]));
expect(didMutate).toBe(false); expect(didMutate).toBe(false);
const first = messages[0]; const first = messages[0] as Extract<AgentMessage, { role: "user" }> | undefined;
if (!first || !Array.isArray(first.content)) { if (!first || !Array.isArray(first.content)) {
throw new Error("expected array content"); throw new Error("expected array content");
} }
@@ -47,12 +48,13 @@ describe("injectHistoryImagesIntoMessages", () => {
{ {
role: "assistant", role: "assistant",
content: "noop", content: "noop",
} as AgentMessage, } as unknown as AgentMessage,
]; ];
const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[1, [image]]])); const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[1, [image]]]));
expect(didMutate).toBe(false); expect(didMutate).toBe(false);
expect(messages[0]?.content).toBe("noop"); const firstAssistant = messages[0] as Extract<AgentMessage, { role: "assistant" }> | undefined;
expect(firstAssistant?.content).toBe("noop");
}); });
}); });

View File

@@ -1,3 +1,4 @@
import type { AgentMessage } from "@mariozechner/pi-agent-core";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { import {
selectCompactionTimeoutSnapshot, selectCompactionTimeoutSnapshot,
@@ -31,8 +32,8 @@ describe("compaction-timeout helpers", () => {
}); });
it("uses pre-compaction snapshot when compaction timeout occurs", () => { it("uses pre-compaction snapshot when compaction timeout occurs", () => {
const pre = [{ role: "assistant", content: "pre" }] as const; const pre = [{ role: "assistant", content: "pre" } as unknown as AgentMessage] as const;
const current = [{ role: "assistant", content: "current" }] as const; const current = [{ role: "assistant", content: "current" } as unknown as AgentMessage] as const;
const selected = selectCompactionTimeoutSnapshot({ const selected = selectCompactionTimeoutSnapshot({
timedOutDuringCompaction: true, timedOutDuringCompaction: true,
preCompactionSnapshot: [...pre], preCompactionSnapshot: [...pre],
@@ -46,7 +47,7 @@ describe("compaction-timeout helpers", () => {
}); });
it("falls back to current snapshot when pre-compaction snapshot is unavailable", () => { it("falls back to current snapshot when pre-compaction snapshot is unavailable", () => {
const current = [{ role: "assistant", content: "current" }] as const; const current = [{ role: "assistant", content: "current" } as unknown as AgentMessage] as const;
const selected = selectCompactionTimeoutSnapshot({ const selected = selectCompactionTimeoutSnapshot({
timedOutDuringCompaction: true, timedOutDuringCompaction: true,
preCompactionSnapshot: null, preCompactionSnapshot: null,

View File

@@ -274,7 +274,7 @@ describe("buildEmbeddedRunPayloads", () => {
it("shows mutating tool errors even when assistant output exists", () => { it("shows mutating tool errors even when assistant output exists", () => {
const payloads = buildPayloads({ const payloads = buildPayloads({
assistantTexts: ["Done."], assistantTexts: ["Done."],
lastAssistant: { stopReason: "end_turn" } as AssistantMessage, lastAssistant: { stopReason: "end_turn" } as unknown as AssistantMessage,
lastToolError: { toolName: "write", error: "file missing" }, lastToolError: { toolName: "write", error: "file missing" },
}); });
@@ -287,7 +287,7 @@ describe("buildEmbeddedRunPayloads", () => {
it("does not treat session_status read failures as mutating when explicitly flagged", () => { it("does not treat session_status read failures as mutating when explicitly flagged", () => {
const payloads = buildPayloads({ const payloads = buildPayloads({
assistantTexts: ["Status loaded."], assistantTexts: ["Status loaded."],
lastAssistant: { stopReason: "end_turn" } as AssistantMessage, lastAssistant: { stopReason: "end_turn" } as unknown as AssistantMessage,
lastToolError: { lastToolError: {
toolName: "session_status", toolName: "session_status",
error: "model required", error: "model required",
@@ -312,7 +312,7 @@ describe("buildEmbeddedRunPayloads", () => {
const payloads = buildPayloads({ const payloads = buildPayloads({
assistantTexts: [warningText ?? ""], assistantTexts: [warningText ?? ""],
lastAssistant: { stopReason: "end_turn" } as AssistantMessage, lastAssistant: { stopReason: "end_turn" } as unknown as AssistantMessage,
lastToolError: { lastToolError: {
toolName: "write", toolName: "write",
error: "file missing", error: "file missing",

View File

@@ -12,7 +12,7 @@ describe("sanitizeSessionHistory toolResult details stripping", () => {
role: "assistant", role: "assistant",
content: [{ type: "toolUse", id: "call_1", name: "web_fetch", input: { url: "x" } }], content: [{ type: "toolUse", id: "call_1", name: "web_fetch", input: { url: "x" } }],
timestamp: 1, timestamp: 1,
} as AgentMessage, } as unknown as AgentMessage,
{ {
role: "toolResult", role: "toolResult",
toolCallId: "call_1", toolCallId: "call_1",
@@ -29,7 +29,7 @@ describe("sanitizeSessionHistory toolResult details stripping", () => {
role: "user", role: "user",
content: "continue", content: "continue",
timestamp: 3, timestamp: 3,
} as AgentMessage, } as unknown as AgentMessage,
]; ];
const sanitized = await sanitizeSessionHistory({ const sanitized = await sanitizeSessionHistory({

View File

@@ -17,7 +17,7 @@ function makeToolResult(text: string, toolCallId = "call_1"): AgentMessage {
content: [{ type: "text", text }], content: [{ type: "text", text }],
isError: false, isError: false,
timestamp: Date.now(), timestamp: Date.now(),
} as AgentMessage; } as unknown as AgentMessage;
} }
function makeUserMessage(text: string): AgentMessage { function makeUserMessage(text: string): AgentMessage {
@@ -25,7 +25,7 @@ function makeUserMessage(text: string): AgentMessage {
role: "user", role: "user",
content: text, content: text,
timestamp: Date.now(), timestamp: Date.now(),
} as AgentMessage; } as unknown as AgentMessage;
} }
function makeAssistantMessage(text: string): AgentMessage { function makeAssistantMessage(text: string): AgentMessage {
@@ -43,7 +43,7 @@ function makeAssistantMessage(text: string): AgentMessage {
}, },
stopReason: "end_turn", stopReason: "end_turn",
timestamp: Date.now(), timestamp: Date.now(),
} as AgentMessage; } as unknown as AgentMessage;
} }
describe("truncateToolResultText", () => { describe("truncateToolResultText", () => {