diff options
| author | Adam Malczewski <[email protected]> | 2026-06-05 21:20:34 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-05 21:20:34 +0900 |
| commit | 552c22d74e5df915088d9e9ff4a286c96c2a54d6 (patch) | |
| tree | 7d9db1052bab91ef994446d80efc3bfc38026cad /packages/cli/src/render.test.ts | |
| parent | 7fb3269c698ae583ea7997ce206c4ae252fd3218 (diff) | |
| download | dispatch-552c22d74e5df915088d9e9ff4a286c96c2a54d6.tar.gz dispatch-552c22d74e5df915088d9e9ff4a286c96c2a54d6.zip | |
feat(cli): one-shot terminal client (models, chat, --text/--file/--cwd/--conversation)
HTTP client of transport-contract; pure-core arg/render/ndjson + injected fetch/fs shell.
Docs: GLOSSARY (credential/key/model name/model catalog), tasks.md milestone, ORCHESTRATOR geography.
Diffstat (limited to 'packages/cli/src/render.test.ts')
| -rw-r--r-- | packages/cli/src/render.test.ts | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/packages/cli/src/render.test.ts b/packages/cli/src/render.test.ts new file mode 100644 index 0000000..bfdb791 --- /dev/null +++ b/packages/cli/src/render.test.ts @@ -0,0 +1,147 @@ +import type { AgentEvent } from "@dispatch/transport-contract"; +import { describe, expect, it } from "vitest"; +import { renderEvent } from "./render.js"; + +describe("renderEvent", () => { + const opts = { showReasoning: false }; + const optsReasoning = { showReasoning: true }; + + it("renders text-delta as stdout", () => { + const e: AgentEvent = { + type: "text-delta", + conversationId: "c", + turnId: "t", + delta: "hello", + }; + expect(renderEvent(e, opts)).toEqual({ stdout: "hello" }); + }); + + it("hides reasoning-delta by default", () => { + const e: AgentEvent = { + type: "reasoning-delta", + conversationId: "c", + turnId: "t", + delta: "thinking...", + }; + expect(renderEvent(e, opts)).toBeUndefined(); + }); + + it("shows reasoning-delta when showReasoning is true", () => { + const e: AgentEvent = { + type: "reasoning-delta", + conversationId: "c", + turnId: "t", + delta: "thinking...", + }; + expect(renderEvent(e, optsReasoning)).toEqual({ stdout: "thinking..." }); + }); + + it("renders tool-call with name and JSON input", () => { + const e: AgentEvent = { + type: "tool-call", + conversationId: "c", + turnId: "t", + toolCallId: "tc1", + toolName: "read_file", + input: { path: "/foo" }, + }; + const result = renderEvent(e, opts); + expect(result?.stdout).toContain("[tool] read_file"); + expect(result?.stdout).toContain('"/foo"'); + }); + + it("renders tool-output data as stdout", () => { + const e: AgentEvent = { + type: "tool-output", + conversationId: "c", + turnId: "t", + toolCallId: "tc1", + data: "some output", + stream: "stdout", + }; + expect(renderEvent(e, opts)).toEqual({ stdout: "some output" }); + }); + + it("renders tool-result without error", () => { + const e: AgentEvent = { + type: "tool-result", + conversationId: "c", + turnId: "t", + toolCallId: "tc1", + toolName: "read_file", + content: "file contents", + isError: false, + }; + expect(renderEvent(e, opts)).toEqual({ + stdout: "[tool:read_file] file contents\n", + }); + }); + + it("renders tool-result with error flag", () => { + const e: AgentEvent = { + type: "tool-result", + conversationId: "c", + turnId: "t", + toolCallId: "tc1", + toolName: "read_file", + content: "not found", + isError: true, + }; + expect(renderEvent(e, opts)).toEqual({ + stdout: "[tool:read_file] ERROR not found\n", + }); + }); + + it("renders usage event", () => { + const e: AgentEvent = { + type: "usage", + conversationId: "c", + turnId: "t", + usage: { inputTokens: 100, outputTokens: 50 }, + }; + expect(renderEvent(e, opts)).toEqual({ + stdout: "\n[usage] in=100 out=50\n", + }); + }); + + it("renders error event to stderr", () => { + const e: AgentEvent = { + type: "error", + conversationId: "c", + turnId: "t", + message: "something went wrong", + }; + expect(renderEvent(e, opts)).toEqual({ + stderr: "[error] something went wrong\n", + }); + }); + + it("returns undefined for status", () => { + const e: AgentEvent = { + type: "status", + conversationId: "c", + status: "running", + }; + expect(renderEvent(e, opts)).toBeUndefined(); + }); + + it("returns undefined for turn-start", () => { + const e: AgentEvent = { type: "turn-start", conversationId: "c", turnId: "t" }; + expect(renderEvent(e, opts)).toBeUndefined(); + }); + + it("returns undefined for turn-sealed", () => { + const e: AgentEvent = { type: "turn-sealed", conversationId: "c", turnId: "t" }; + expect(renderEvent(e, opts)).toBeUndefined(); + }); + + it("returns undefined for done", () => { + const e: AgentEvent = { + type: "done", + conversationId: "c", + turnId: "t", + reason: "completed", + }; + expect(renderEvent(e, opts)).toBeUndefined(); + }); +}); |
