Skip to content

Commit da38041

Browse files
committed
Add tests for extractUserPromptsFromEvents
1 parent d6d1721 commit da38041

1 file changed

Lines changed: 131 additions & 1 deletion

File tree

apps/code/src/renderer/utils/session.test.ts

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import type { ContentBlock } from "@agentclientprotocol/sdk";
2+
import type { AcpMessage } from "@shared/types/session-events";
13
import { describe, expect, it } from "vitest";
24

3-
import { isFatalSessionError } from "./session";
5+
import { makeAttachmentUri } from "./promptContent";
6+
import { extractUserPromptsFromEvents, isFatalSessionError } from "./session";
47

58
describe("isFatalSessionError", () => {
69
it("detects fatal 'Internal error' pattern", () => {
@@ -37,3 +40,130 @@ describe("isFatalSessionError", () => {
3740
expect(isFatalSessionError("")).toBe(false);
3841
});
3942
});
43+
44+
function promptEvent(prompt: ContentBlock[], ts = 1): AcpMessage {
45+
return {
46+
type: "acp_message",
47+
ts,
48+
message: {
49+
jsonrpc: "2.0",
50+
id: ts,
51+
method: "session/prompt",
52+
params: { prompt },
53+
},
54+
};
55+
}
56+
57+
describe("extractUserPromptsFromEvents", () => {
58+
it("extracts text from a plain text prompt", () => {
59+
const events = [promptEvent([{ type: "text", text: "fix the bug" }])];
60+
expect(extractUserPromptsFromEvents(events)).toEqual(["fix the bug"]);
61+
});
62+
63+
it("skips hidden text blocks", () => {
64+
const events = [
65+
promptEvent([
66+
{
67+
type: "text",
68+
text: "hidden context",
69+
_meta: { ui: { hidden: true } },
70+
} as ContentBlock,
71+
{ type: "text", text: "visible prompt" },
72+
]),
73+
];
74+
expect(extractUserPromptsFromEvents(events)).toEqual(["visible prompt"]);
75+
});
76+
77+
it("returns attachment labels when prompt has no text", () => {
78+
const uri = makeAttachmentUri("/tmp/screenshot.png");
79+
const events = [
80+
promptEvent([
81+
{
82+
type: "resource",
83+
resource: { uri, text: "", mimeType: "image/png" },
84+
},
85+
]),
86+
];
87+
expect(extractUserPromptsFromEvents(events)).toEqual([
88+
"[Attached files: screenshot.png]",
89+
]);
90+
});
91+
92+
it("returns text when prompt has both text and attachments", () => {
93+
const uri = makeAttachmentUri("/tmp/data.csv");
94+
const events = [
95+
promptEvent([
96+
{ type: "text", text: "analyze this" },
97+
{ type: "resource", resource: { uri, text: "", mimeType: "text/csv" } },
98+
]),
99+
];
100+
expect(extractUserPromptsFromEvents(events)).toEqual(["analyze this"]);
101+
});
102+
103+
it("joins multiple attachment labels with commas", () => {
104+
const uri1 = makeAttachmentUri("/tmp/a.png");
105+
const uri2 = makeAttachmentUri("/tmp/b.pdf");
106+
const events = [
107+
promptEvent([
108+
{
109+
type: "resource",
110+
resource: { uri: uri1, text: "", mimeType: "image/png" },
111+
},
112+
{
113+
type: "resource",
114+
resource: { uri: uri2, text: "", mimeType: "application/pdf" },
115+
},
116+
]),
117+
];
118+
expect(extractUserPromptsFromEvents(events)).toEqual([
119+
"[Attached files: a.png, b.pdf]",
120+
]);
121+
});
122+
123+
it("falls back to attachment labels when all text blocks are hidden", () => {
124+
const uri = makeAttachmentUri("/tmp/report.md");
125+
const events = [
126+
promptEvent([
127+
{
128+
type: "text",
129+
text: "hidden",
130+
_meta: { ui: { hidden: true } },
131+
} as ContentBlock,
132+
{
133+
type: "resource",
134+
resource: { uri, text: "", mimeType: "text/markdown" },
135+
},
136+
]),
137+
];
138+
expect(extractUserPromptsFromEvents(events)).toEqual([
139+
"[Attached files: report.md]",
140+
]);
141+
});
142+
143+
it("skips events with empty prompt arrays", () => {
144+
const events = [promptEvent([])];
145+
expect(extractUserPromptsFromEvents(events)).toEqual([]);
146+
});
147+
148+
it("collects prompts from multiple events in order", () => {
149+
const uri = makeAttachmentUri("/tmp/logo.svg");
150+
const events = [
151+
promptEvent([{ type: "text", text: "first" }], 1),
152+
promptEvent(
153+
[
154+
{
155+
type: "resource",
156+
resource: { uri, text: "", mimeType: "image/svg+xml" },
157+
},
158+
],
159+
2,
160+
),
161+
promptEvent([{ type: "text", text: "third" }], 3),
162+
];
163+
expect(extractUserPromptsFromEvents(events)).toEqual([
164+
"first",
165+
"[Attached files: logo.svg]",
166+
"third",
167+
]);
168+
});
169+
});

0 commit comments

Comments
 (0)