Download src/agents/cli-runner/cli-run-settlement.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 6.94 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/cli-runner/cli-run-settlement.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/agents/cli-runner/cli-run-settlement.test.ts
-
curl -L -o cli-run-settlement.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/cli-runner/cli-run-settlement.test.ts
6.94 kB
| /** Tests native CLI continuity projection and bounded transcript-flush probing. */ | |
| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | |
| import type { SessionEntry } from "../../config/sessions.js"; | |
| import { | |
| isCliBindingFlushed, | |
| restoreCliRunnerTestDeps, | |
| setCliRunnerTestDeps, | |
| } from "../cli-runner.js"; | |
| import { buildPreparedCliRunContext } from "../cli-runner.test-helpers.js"; | |
| import { applyCliSessionBindingResult, getCliSessionBinding } from "../cli-session.js"; | |
| import { buildBlockedCliRunResult, buildCliRunResult } from "./cli-run-settlement.js"; | |
| describe("isCliBindingFlushed", () => { | |
| const workspaceDir = "/tmp/openclaw-workspace"; | |
| beforeEach(() => { | |
| vi.useRealTimers(); | |
| restoreCliRunnerTestDeps(); | |
| }); | |
| afterEach(() => { | |
| vi.clearAllTimers(); | |
| vi.useRealTimers(); | |
| restoreCliRunnerTestDeps(); | |
| }); | |
| it("returns false when no sessionId is provided", async () => { | |
| const probe = vi.fn(async () => true); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect(await isCliBindingFlushed(undefined, "claude-cli")).toBe(false); | |
| expect(probe).not.toHaveBeenCalled(); | |
| }); | |
| it("returns true when the transcript has content on the first probe", async () => { | |
| const probe = vi.fn(async () => true); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect(await isCliBindingFlushed("sid-fresh", "claude-cli", workspaceDir)).toBe(true); | |
| expect(probe).toHaveBeenCalledTimes(1); | |
| expect(probe).toHaveBeenCalledWith({ sessionId: "sid-fresh", workspaceDir }); | |
| }); | |
| it("retries up to three times before giving up", async () => { | |
| const delay = vi.fn(async () => undefined); | |
| const probe = vi.fn(async () => false); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe, delay }); | |
| expect(await isCliBindingFlushed("sid-cold", "claude-cli", workspaceDir)).toBe(false); | |
| expect(probe).toHaveBeenCalledTimes(3); | |
| expect(delay).toHaveBeenCalledTimes(2); | |
| expect(delay).toHaveBeenNthCalledWith(1, 50); | |
| expect(delay).toHaveBeenNthCalledWith(2, 150); | |
| }); | |
| it("succeeds when the transcript becomes visible on a later retry", async () => { | |
| const delay = vi.fn(async () => undefined); | |
| let calls = 0; | |
| const probe = vi.fn(async () => { | |
| calls += 1; | |
| return calls >= 2; | |
| }); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe, delay }); | |
| expect(await isCliBindingFlushed("sid-late", "claude-cli", workspaceDir)).toBe(true); | |
| expect(probe).toHaveBeenCalledTimes(2); | |
| expect(delay).toHaveBeenCalledExactlyOnceWith(50); | |
| }); | |
| it("schedules at most 0 + 50 + 150ms of delay across the bounded retry", async () => { | |
| vi.useFakeTimers(); | |
| try { | |
| // Fake timers enforce the retry contract without introducing wall-clock | |
| // sleeps into this import-heavy agent test. | |
| const probe = vi.fn(async () => false); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| const settled = vi.fn(); | |
| const errored = vi.fn(); | |
| isCliBindingFlushed("sid-bounded", "claude-cli", workspaceDir).then(settled, errored); | |
| await vi.advanceTimersByTimeAsync(0); | |
| await vi.advanceTimersByTimeAsync(50); | |
| await vi.advanceTimersByTimeAsync(150); | |
| expect(settled).toHaveBeenCalledTimes(1); | |
| expect(settled.mock.calls[0]?.[0]).toBe(false); | |
| expect(errored).not.toHaveBeenCalled(); | |
| expect(probe).toHaveBeenCalledTimes(3); | |
| } finally { | |
| vi.clearAllTimers(); | |
| vi.useRealTimers(); | |
| } | |
| }); | |
| it("returns true without probing for non-claude-cli providers", async () => { | |
| const probe = vi.fn(async () => false); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect(await isCliBindingFlushed("sid-codex", "codex-cli")).toBe(true); | |
| expect(await isCliBindingFlushed("sid-anthropic", "anthropic")).toBe(true); | |
| expect(await isCliBindingFlushed("sid-openai", "openai")).toBe(true); | |
| expect(probe).not.toHaveBeenCalled(); | |
| }); | |
| it("returns true without probing when provider is undefined", async () => { | |
| const probe = vi.fn(async () => false); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect(await isCliBindingFlushed("sid-x", undefined)).toBe(true); | |
| expect(probe).not.toHaveBeenCalled(); | |
| }); | |
| it("returns true without probing when the caller owns continuity outside native transcripts", async () => { | |
| const probe = vi.fn(async () => false); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect( | |
| await isCliBindingFlushed("sid-warm", "claude-cli", workspaceDir, { | |
| skipTranscriptProbe: true, | |
| }), | |
| ).toBe(true); | |
| expect(probe).not.toHaveBeenCalled(); | |
| }); | |
| it("still probes when transcript-probe skipping is disabled", async () => { | |
| const probe = vi.fn(async () => true); | |
| setCliRunnerTestDeps({ claudeCliSessionTranscriptHasContent: probe }); | |
| expect( | |
| await isCliBindingFlushed("sid-probe", "claude-cli", workspaceDir, { | |
| skipTranscriptProbe: false, | |
| }), | |
| ).toBe(true); | |
| expect(probe).toHaveBeenCalledTimes(1); | |
| }); | |
| }); | |
| describe("CLI native continuity projection", () => { | |
| it.each(["blocked", "no-native-id", "native", "stateless"])( | |
| "projects only explicit native continuity from a %s result", | |
| (kind) => { | |
| const context = buildPreparedCliRunContext({ provider: "claude-cli" }); | |
| const result = | |
| kind === "blocked" | |
| ? buildBlockedCliRunResult({ | |
| context, | |
| message: "Blocked by the test policy", | |
| preparedContextAgentMeta: {}, | |
| sessionBindingDisabled: false, | |
| }) | |
| : buildCliRunResult({ | |
| context, | |
| output: { text: "done" }, | |
| effectiveCliSessionId: kind === "native" ? "next-native-session" : undefined, | |
| bindingFlushOk: kind !== "no-native-id", | |
| usedHistoryPrompt: false, | |
| userTurnHandled: true, | |
| sessionBindingDisabled: kind === "stateless", | |
| preparedContextAgentMeta: {}, | |
| }); | |
| const entry: SessionEntry = { | |
| sessionId: context.params.sessionId, | |
| updatedAt: 1, | |
| cliSessionBindings: { "claude-cli": { sessionId: "previous-native-session" } }, | |
| }; | |
| applyCliSessionBindingResult(entry, "claude-cli", result.meta.agentMeta); | |
| expect(entry.sessionId).toBe(context.params.sessionId); | |
| expect(result.meta.agentMeta?.sessionId).toBe( | |
| kind === "native" ? "next-native-session" : context.params.sessionId, | |
| ); | |
| expect(getCliSessionBinding(entry, "claude-cli")?.sessionId).toBe( | |
| kind === "native" | |
| ? "next-native-session" | |
| : kind === "stateless" | |
| ? undefined | |
| : "previous-native-session", | |
| ); | |
| }, | |
| ); | |
| }); | |