diff --git a/src/agents/schema-normalization-runtime-contract.test.ts b/src/agents/schema-normalization-runtime-contract.test.ts index 3832a5dc5c4d..66c6144e890c 100644 --- a/src/agents/schema-normalization-runtime-contract.test.ts +++ b/src/agents/schema-normalization-runtime-contract.test.ts @@ -1,3 +1,4 @@ +// Verifies OpenAI tool schema normalization remains stable across runtime paths. import type { StreamFn } from "openclaw/plugin-sdk/agent-core"; import { createNativeOpenAIResponsesModel, @@ -56,6 +57,7 @@ describe("OpenAI transport schema normalization runtime contract", () => { }); it("passes prepared executable schemas through compaction-triggered Responses requests", () => { + // Server-side compaction must not strip provider-prepared strict tool schemas. const hooks = buildProviderToolCompatFamilyHooks("openai"); const tools = hooks.normalizeToolSchemas({ provider: "openai", diff --git a/src/agents/session-suspension.test.ts b/src/agents/session-suspension.test.ts index e602d6619f2b..14774bcf7e50 100644 --- a/src/agents/session-suspension.test.ts +++ b/src/agents/session-suspension.test.ts @@ -1,3 +1,4 @@ +// Verifies quota suspension persists lane state and auto-resumes safely. import { afterEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_CRON_MAX_CONCURRENT_RUNS } from "../config/cron-limits.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -24,6 +25,7 @@ vi.mock("./command/session.js", () => ({ })); async function suspendLane(ttlMs: number, cfg: OpenClawConfig, laneId: CommandLane) { + // All cases exercise the public suspendSession path with fixed failure metadata. const { suspendSession } = await import("./session-suspension.js"); await suspendSession({ cfg, @@ -104,6 +106,7 @@ describe("session suspension", () => { }); it("clamps oversized suspension TTLs for timers and persisted resume time", async () => { + // Persisted expectedResumeBy must match the clamped timer, not MAX_SAFE_INTEGER. vi.useFakeTimers(); vi.setSystemTime(1_000); const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout"); diff --git a/src/agents/session-tool-result-guard.test.ts b/src/agents/session-tool-result-guard.test.ts index 870e08223e33..54ab4041d741 100644 --- a/src/agents/session-tool-result-guard.test.ts +++ b/src/agents/session-tool-result-guard.test.ts @@ -1,3 +1,4 @@ +// Verifies session tool-result guard inserts, truncates, and repairs tool results. import type { AgentMessage } from "openclaw/plugin-sdk/agent-core"; import { SessionManager } from "openclaw/plugin-sdk/agent-sessions"; import { describe, expect, it } from "vitest"; @@ -32,6 +33,7 @@ function appendAssistantToolCall( sm: SessionManager, params: { id: string; name: string; withArguments?: boolean }, ) { + // Builds pending tool calls with optional missing arguments for repair cases. const toolCall: { type: "toolCall"; id: string; @@ -61,6 +63,7 @@ function getPersistedMessages(sm: SessionManager): AgentMessage[] { } function expectPersistedRoles(sm: SessionManager, expectedRoles: AgentMessage["role"][]) { + // Role-order assertions prove where synthetic toolResult messages were inserted. const messages = getPersistedMessages(sm); expect(messages.map((message) => message.role)).toEqual(expectedRoles); return messages; @@ -387,9 +390,7 @@ describe("installSessionToolResultGuard", () => { ); const messages = expectPersistedRoles(sm, ["assistant", "assistant", "toolResult"]); - expect((messages[2] as { toolCallId?: string; isError?: boolean }).toolCallId).toBe( - "call_1", - ); + expect((messages[2] as { toolCallId?: string; isError?: boolean }).toolCallId).toBe("call_1"); expect((messages[2] as { isError?: boolean }).isError).toBe(false); expect(JSON.stringify(messages)).not.toContain("missing tool result"); expect(guard.getPendingIds()).toStrictEqual(["call_2"]); diff --git a/src/agents/session-tool-result-guard.tool-result-persist-hook.test.ts b/src/agents/session-tool-result-guard.tool-result-persist-hook.test.ts index 8a553c02639f..51bb57424161 100644 --- a/src/agents/session-tool-result-guard.tool-result-persist-hook.test.ts +++ b/src/agents/session-tool-result-guard.tool-result-persist-hook.test.ts @@ -1,3 +1,4 @@ +// Verifies persisted tool results are redacted/capped and can be transformed by hooks. import fs from "node:fs"; import os from "node:os"; import path from "node:path"; @@ -17,6 +18,7 @@ const originalConfigPath = process.env.OPENCLAW_CONFIG_PATH; let tempDirs: string[] = []; function writeTempPlugin(params: { dir: string; id: string; body: string }): string { + // Temp plugin manifests allow testing real hook loading without bundled plugins. const pluginDir = path.join(params.dir, params.id); fs.mkdirSync(pluginDir, { recursive: true }); const file = path.join(pluginDir, `${params.id}.mjs`); @@ -99,6 +101,7 @@ function expectPersistedToolResultTextCapped(sm: ReturnType) { + // Large details are summarized before persistence to keep transcript files bounded. const toolResult = requirePersistedToolResult(sm); const details = toolResult.details as Record; expect(details.persistedDetailsTruncated).toBe(true); diff --git a/src/agents/session-tool-result-guard.transcript-events.test.ts b/src/agents/session-tool-result-guard.transcript-events.test.ts index 49968f577c9f..c7c7d1d14a51 100644 --- a/src/agents/session-tool-result-guard.transcript-events.test.ts +++ b/src/agents/session-tool-result-guard.transcript-events.test.ts @@ -1,3 +1,4 @@ +// Verifies guarded session managers emit transcript update events with stable sequence ids. import type { AgentMessage } from "openclaw/plugin-sdk/agent-core"; import { SessionManager } from "openclaw/plugin-sdk/agent-sessions"; import { afterEach, describe, expect, it, vi } from "vitest"; @@ -10,6 +11,7 @@ import { guardSessionManager } from "./session-tool-result-guard-wrapper.js"; const listeners: Array<() => void> = []; afterEach(() => { + // Remove all transcript listeners between tests to avoid duplicate broadcasts. while (listeners.length > 0) { listeners.pop()?.(); } @@ -124,6 +126,7 @@ describe("guardSessionManager transcript updates", () => { }); it("caches real tool result sequence before final assistant messages", () => { + // Tool results are persisted but not broadcast, so later visible messages must skip their seq. const updates: SessionTranscriptUpdate[] = []; listeners.push(onSessionTranscriptUpdate((update) => updates.push(update))); diff --git a/src/agents/session-transcript-repair.attachments.test.ts b/src/agents/session-transcript-repair.attachments.test.ts index ba756435e989..bc6035a6ea8f 100644 --- a/src/agents/session-transcript-repair.attachments.test.ts +++ b/src/agents/session-transcript-repair.attachments.test.ts @@ -1,9 +1,11 @@ +// Verifies transcript repair preserves sessions_spawn attachments and ACP routing fields. import type { AgentMessage } from "openclaw/plugin-sdk/agent-core"; import { describe, it, expect } from "vitest"; import { sanitizeToolCallInputs } from "./session-transcript-repair.js"; import { castAgentMessage, castAgentMessages } from "./test-helpers/agent-message-fixtures.js"; function mkSessionsSpawnToolCall(content: string): AgentMessage { + // sessions_spawn attachments are transcript-owned payloads, not redaction targets. return castAgentMessage({ role: "assistant", content: [