macro-agent 0.0.15 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/acp/index.d.ts +1 -1
  2. package/dist/acp/index.d.ts.map +1 -1
  3. package/dist/acp/index.js.map +1 -1
  4. package/dist/acp/macro-agent.d.ts +21 -0
  5. package/dist/acp/macro-agent.d.ts.map +1 -1
  6. package/dist/acp/macro-agent.js +182 -0
  7. package/dist/acp/macro-agent.js.map +1 -1
  8. package/dist/acp/types.d.ts +31 -2
  9. package/dist/acp/types.d.ts.map +1 -1
  10. package/dist/acp/types.js.map +1 -1
  11. package/dist/agent/agent-manager.d.ts.map +1 -1
  12. package/dist/agent/agent-manager.js +23 -5
  13. package/dist/agent/agent-manager.js.map +1 -1
  14. package/dist/map/adapter/acp-over-map.d.ts +15 -0
  15. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  16. package/dist/map/adapter/acp-over-map.js +204 -9
  17. package/dist/map/adapter/acp-over-map.js.map +1 -1
  18. package/dist/store/event-store.d.ts.map +1 -1
  19. package/dist/store/event-store.js +92 -53
  20. package/dist/store/event-store.js.map +1 -1
  21. package/dist/store/instance.d.ts +0 -2
  22. package/dist/store/instance.d.ts.map +1 -1
  23. package/dist/store/instance.js +1 -24
  24. package/dist/store/instance.js.map +1 -1
  25. package/package.json +3 -3
  26. package/references/acp-factory-ref/package-lock.json +2 -2
  27. package/references/acp-factory-ref/package.json +2 -2
  28. package/references/claude-code-acp/package-lock.json +2 -2
  29. package/references/claude-code-acp/package.json +1 -1
  30. package/references/claude-code-acp/src/acp-agent.ts +3 -6
  31. package/src/acp/__tests__/history.test.ts +526 -0
  32. package/src/acp/__tests__/integration.test.ts +2 -1
  33. package/src/acp/index.ts +4 -0
  34. package/src/acp/macro-agent.ts +329 -85
  35. package/src/acp/types.ts +39 -2
  36. package/src/agent/__tests__/agent-manager.test.ts +4 -6
  37. package/src/agent/agent-manager.ts +24 -5
  38. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +664 -0
  39. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +440 -0
  40. package/src/map/adapter/acp-over-map.ts +246 -7
  41. package/src/store/__tests__/event-store.test.ts +4 -12
  42. package/src/store/__tests__/instance.test.ts +5 -7
  43. package/src/store/event-store.ts +115 -57
  44. package/src/store/instance.ts +1 -29
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sudocode-ai/claude-code-acp",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sudocode-ai/claude-code-acp",
9
- "version": "0.13.8",
9
+ "version": "0.13.9",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@agentclientprotocol/sdk": "0.13.1",
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.13.8",
6
+ "version": "0.13.9",
7
7
  "description": "An ACP-compatible coding agent powered by the Claude Code SDK (TypeScript)",
8
8
  "main": "dist/lib.js",
9
9
  "types": "dist/lib.d.ts",
@@ -1635,7 +1635,7 @@ export class ClaudeAcpAgent implements Agent {
1635
1635
 
1636
1636
  // Fetch commands and models in the background to avoid blocking session creation.
1637
1637
  // These calls wait for the Claude Code subprocess to initialize, which can be slow.
1638
- // Results are sent via sessionUpdate notifications when ready.
1638
+ // Results are sent via sessionUpdate; models via extension notification (_model_state_update).
1639
1639
  void (async () => {
1640
1640
  try {
1641
1641
  const [availableCommands, models] = await Promise.all([
@@ -1649,12 +1649,9 @@ export class ClaudeAcpAgent implements Agent {
1649
1649
  availableCommands,
1650
1650
  },
1651
1651
  });
1652
- this.client.sessionUpdate({
1652
+ this.client.extNotification("_model_state_update", {
1653
1653
  sessionId,
1654
- update: {
1655
- sessionUpdate: "model_state_update",
1656
- models,
1657
- },
1654
+ models,
1658
1655
  });
1659
1656
  } catch (e) {
1660
1657
  this.logger.error("Failed to fetch session metadata:", e);
@@ -0,0 +1,526 @@
1
+ /**
2
+ * History persistence and retrieval tests
3
+ *
4
+ * Tests the _macro/getHistory extension method and the underlying
5
+ * conversation/turn persistence that records prompt interactions.
6
+ *
7
+ * Uses a real in-memory EventStore to verify the full flow:
8
+ * ensureConversation → recordPromptTurns → handleGetHistory
9
+ */
10
+
11
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
12
+ import { MacroAgent } from "../macro-agent.js";
13
+ import { createEventStore, type EventStore } from "../../store/event-store.js";
14
+ import type { AgentSideConnection } from "@agentclientprotocol/sdk";
15
+ import type { AgentManager } from "../../agent/agent-manager.js";
16
+ import type { TaskManager } from "../../task/task-manager.js";
17
+ import type { Agent, Task } from "../../store/types/index.js";
18
+
19
+ // ─────────────────────────────────────────────────────────────────
20
+ // Helpers
21
+ // ─────────────────────────────────────────────────────────────────
22
+
23
+ function createMockAgent(overrides: Partial<Agent> = {}): Agent {
24
+ return {
25
+ id: "agent-1",
26
+ session_id: "session-1",
27
+ state: "running",
28
+ task: "Test task",
29
+ task_id: "task-1",
30
+ parent: null,
31
+ lineage: [],
32
+ config: {},
33
+ cwd: "/test/cwd",
34
+ created_at: Date.now(),
35
+ started_at: Date.now(),
36
+ ...overrides,
37
+ };
38
+ }
39
+
40
+ function createMockTask(overrides: Partial<Task> = {}): Task {
41
+ return {
42
+ id: "task-1",
43
+ description: "Test task",
44
+ status: "in_progress",
45
+ created_by: "agent-1",
46
+ created_at: Date.now(),
47
+ ...overrides,
48
+ };
49
+ }
50
+
51
+ function createMockConnection(): AgentSideConnection {
52
+ return {
53
+ sessionUpdate: vi.fn().mockResolvedValue(undefined),
54
+ requestPermission: vi.fn().mockResolvedValue({ outcome: "allow_once" }),
55
+ closed: Promise.resolve(),
56
+ } as unknown as AgentSideConnection;
57
+ }
58
+
59
+ /**
60
+ * Create a mock AgentManager that yields the given streaming updates
61
+ * from its `prompt()` method.
62
+ */
63
+ function createMockAgentManager(
64
+ promptUpdates: unknown[] = []
65
+ ): AgentManager {
66
+ const mockAgent = createMockAgent();
67
+
68
+ return {
69
+ spawn: vi.fn().mockResolvedValue({
70
+ id: "agent-new",
71
+ session_id: "session-new",
72
+ agent: createMockAgent({ id: "agent-new", session_id: "session-new" }),
73
+ session: {},
74
+ }),
75
+ get: vi.fn().mockReturnValue(mockAgent),
76
+ list: vi.fn().mockReturnValue([mockAgent]),
77
+ listHeadManagers: vi.fn().mockReturnValue([mockAgent]),
78
+ getChildren: vi.fn().mockReturnValue([]),
79
+ getHierarchy: vi.fn().mockReturnValue({
80
+ root: { agent: mockAgent, children: [] },
81
+ depth: 1,
82
+ totalAgents: 1,
83
+ }),
84
+ getOrCreateHeadManager: vi.fn().mockResolvedValue({
85
+ id: "agent-1",
86
+ session_id: "session-1",
87
+ agent: mockAgent,
88
+ session: {},
89
+ }),
90
+ hasActiveSession: vi.fn().mockReturnValue(true),
91
+ resume: vi.fn().mockResolvedValue({
92
+ id: "agent-1",
93
+ session_id: "session-1",
94
+ agent: mockAgent,
95
+ session: {},
96
+ }),
97
+ terminate: vi.fn().mockResolvedValue(undefined),
98
+ prompt: vi.fn().mockReturnValue({
99
+ [Symbol.asyncIterator]: async function* () {
100
+ for (const update of promptUpdates) {
101
+ yield update;
102
+ }
103
+ },
104
+ }),
105
+ getSession: vi.fn().mockReturnValue(null),
106
+ onLifecycleEvent: vi.fn().mockReturnValue(() => {}),
107
+ close: vi.fn().mockResolvedValue(undefined),
108
+ respondToPermission: vi.fn().mockReturnValue(true),
109
+ cancelPermission: vi.fn().mockReturnValue(true),
110
+ } as unknown as AgentManager;
111
+ }
112
+
113
+ function createMockTaskManager(): TaskManager {
114
+ return {
115
+ get: vi.fn().mockReturnValue(createMockTask()),
116
+ list: vi.fn().mockReturnValue([createMockTask()]),
117
+ create: vi.fn().mockReturnValue(createMockTask()),
118
+ } as unknown as TaskManager;
119
+ }
120
+
121
+ // ─────────────────────────────────────────────────────────────────
122
+ // Tests
123
+ // ─────────────────────────────────────────────────────────────────
124
+
125
+ describe("_macro/getHistory", () => {
126
+ let eventStore: EventStore;
127
+ let macroAgent: MacroAgent;
128
+ let mockConnection: AgentSideConnection;
129
+
130
+ afterEach(async () => {
131
+ await eventStore.close();
132
+ });
133
+
134
+ /**
135
+ * Helper to set up a MacroAgent with given prompt streaming updates.
136
+ */
137
+ async function setup(promptUpdates: unknown[] = []) {
138
+ eventStore = await createEventStore({ inMemory: true });
139
+ mockConnection = createMockConnection();
140
+
141
+ const agentManager = createMockAgentManager(promptUpdates);
142
+ const taskManager = createMockTaskManager();
143
+
144
+ macroAgent = new MacroAgent(mockConnection, {
145
+ agentManager,
146
+ eventStore,
147
+ taskManager,
148
+ defaultCwd: "/test/cwd",
149
+ });
150
+
151
+ await macroAgent.initialize({
152
+ protocolVersion: 1,
153
+ clientCapabilities: {},
154
+ });
155
+
156
+ return { agentManager, taskManager };
157
+ }
158
+
159
+ it("should return empty turns for a session with no history", async () => {
160
+ await setup();
161
+
162
+ // Create a session so it has a conversation
163
+ await macroAgent.newSession({ cwd: "/test" });
164
+ const sessionId =
165
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
166
+
167
+ const response = await macroAgent.extMethod("_macro/getHistory", {
168
+ sessionId,
169
+ });
170
+
171
+ expect(response).toHaveProperty("turns");
172
+ expect((response as { turns: unknown[] }).turns).toEqual([]);
173
+ });
174
+
175
+ it("should record and return user + assistant text turns after prompt", async () => {
176
+ await setup([
177
+ {
178
+ sessionUpdate: "agent_message_chunk",
179
+ content: { type: "text", text: "Hello " },
180
+ },
181
+ {
182
+ sessionUpdate: "agent_message_chunk",
183
+ content: { type: "text", text: "world!" },
184
+ },
185
+ ]);
186
+
187
+ // Create session
188
+ await macroAgent.newSession({ cwd: "/test" });
189
+ const sessionId =
190
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
191
+
192
+ // Send a prompt — this triggers recording
193
+ await macroAgent.prompt({
194
+ sessionId,
195
+ prompt: [{ type: "text", text: "Say hello" }],
196
+ });
197
+
198
+ // Retrieve history
199
+ const response = await macroAgent.extMethod("_macro/getHistory", {
200
+ sessionId,
201
+ });
202
+
203
+ const turns = (response as { turns: { role: string; content: unknown }[] })
204
+ .turns;
205
+
206
+ expect(turns).toHaveLength(2);
207
+
208
+ // User turn
209
+ expect(turns[0].role).toBe("user");
210
+ expect(turns[0].content).toBe("Say hello");
211
+
212
+ // Assistant turn — accumulated text chunks
213
+ expect(turns[1].role).toBe("assistant");
214
+ const content = turns[1].content as { parts: { type: string; text?: string }[] };
215
+ expect(content.parts[0].type).toBe("text");
216
+ expect(content.parts[0].text).toBe("Hello world!");
217
+ });
218
+
219
+ it("should record tool calls in assistant turns", async () => {
220
+ await setup([
221
+ {
222
+ sessionUpdate: "agent_message_chunk",
223
+ content: { type: "text", text: "Let me check that." },
224
+ },
225
+ {
226
+ sessionUpdate: "tool_call",
227
+ toolCallId: "tc-1",
228
+ title: "Read file",
229
+ status: "completed",
230
+ rawInput: { path: "/test.txt" },
231
+ output: "file contents here",
232
+ },
233
+ {
234
+ sessionUpdate: "agent_message_chunk",
235
+ content: { type: "text", text: " Done!" },
236
+ },
237
+ ]);
238
+
239
+ await macroAgent.newSession({ cwd: "/test" });
240
+ const sessionId =
241
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
242
+
243
+ await macroAgent.prompt({
244
+ sessionId,
245
+ prompt: [{ type: "text", text: "Read test.txt" }],
246
+ });
247
+
248
+ const response = await macroAgent.extMethod("_macro/getHistory", {
249
+ sessionId,
250
+ });
251
+
252
+ const turns = (response as { turns: { role: string; content: unknown }[] })
253
+ .turns;
254
+
255
+ expect(turns).toHaveLength(2);
256
+
257
+ // Assistant turn should have text + tool parts
258
+ const assistantContent = turns[1].content as {
259
+ parts: { type: string; text?: string; toolCallId?: string; title?: string; output?: unknown }[];
260
+ };
261
+ expect(assistantContent.parts).toHaveLength(2);
262
+ expect(assistantContent.parts[0]).toEqual({
263
+ type: "text",
264
+ text: "Let me check that. Done!",
265
+ });
266
+ expect(assistantContent.parts[1]).toMatchObject({
267
+ type: "tool",
268
+ toolCallId: "tc-1",
269
+ title: "Read file",
270
+ status: "completed",
271
+ output: "file contents here",
272
+ });
273
+ });
274
+
275
+ it("should accumulate history across multiple prompts", async () => {
276
+ // First prompt returns "Hello"
277
+ const { agentManager } = await setup([
278
+ {
279
+ sessionUpdate: "agent_message_chunk",
280
+ content: { type: "text", text: "Hello" },
281
+ },
282
+ ]);
283
+
284
+ await macroAgent.newSession({ cwd: "/test" });
285
+ const sessionId =
286
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
287
+
288
+ // First prompt
289
+ await macroAgent.prompt({
290
+ sessionId,
291
+ prompt: [{ type: "text", text: "Hi" }],
292
+ });
293
+
294
+ // Second prompt — update mock to return different content
295
+ vi.mocked(agentManager.prompt).mockReturnValue({
296
+ [Symbol.asyncIterator]: async function* () {
297
+ yield {
298
+ sessionUpdate: "agent_message_chunk",
299
+ content: { type: "text", text: "Goodbye" },
300
+ };
301
+ },
302
+ } as any);
303
+
304
+ await macroAgent.prompt({
305
+ sessionId,
306
+ prompt: [{ type: "text", text: "Bye" }],
307
+ });
308
+
309
+ const response = await macroAgent.extMethod("_macro/getHistory", {
310
+ sessionId,
311
+ });
312
+
313
+ const turns = (response as { turns: { role: string; content: unknown }[] })
314
+ .turns;
315
+
316
+ // 2 prompts × 2 turns each = 4 turns total
317
+ expect(turns).toHaveLength(4);
318
+ expect(turns[0].role).toBe("user");
319
+ expect(turns[0].content).toBe("Hi");
320
+ expect(turns[1].role).toBe("assistant");
321
+ expect(turns[2].role).toBe("user");
322
+ expect(turns[2].content).toBe("Bye");
323
+ expect(turns[3].role).toBe("assistant");
324
+ });
325
+
326
+ it("should respect the limit parameter", async () => {
327
+ const { agentManager } = await setup([
328
+ {
329
+ sessionUpdate: "agent_message_chunk",
330
+ content: { type: "text", text: "Response 1" },
331
+ },
332
+ ]);
333
+
334
+ await macroAgent.newSession({ cwd: "/test" });
335
+ const sessionId =
336
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
337
+
338
+ // Send 3 prompts
339
+ for (let i = 0; i < 3; i++) {
340
+ vi.mocked(agentManager.prompt).mockReturnValue({
341
+ [Symbol.asyncIterator]: async function* () {
342
+ yield {
343
+ sessionUpdate: "agent_message_chunk",
344
+ content: { type: "text", text: `Response ${i + 1}` },
345
+ };
346
+ },
347
+ } as any);
348
+
349
+ await macroAgent.prompt({
350
+ sessionId,
351
+ prompt: [{ type: "text", text: `Message ${i + 1}` }],
352
+ });
353
+ }
354
+
355
+ // Request only 2 turns
356
+ const response = await macroAgent.extMethod("_macro/getHistory", {
357
+ sessionId,
358
+ limit: 2,
359
+ });
360
+
361
+ const turns = (response as { turns: unknown[] }).turns;
362
+ expect(turns).toHaveLength(2);
363
+ });
364
+
365
+ it("should not record turns when prompt has no text content", async () => {
366
+ await setup([
367
+ {
368
+ sessionUpdate: "agent_message_chunk",
369
+ content: { type: "text", text: "Response" },
370
+ },
371
+ ]);
372
+
373
+ await macroAgent.newSession({ cwd: "/test" });
374
+ const sessionId =
375
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
376
+
377
+ // Empty prompt — no text blocks
378
+ await macroAgent.prompt({
379
+ sessionId,
380
+ prompt: [],
381
+ });
382
+
383
+ const response = await macroAgent.extMethod("_macro/getHistory", {
384
+ sessionId,
385
+ });
386
+
387
+ const turns = (response as { turns: { role: string }[] }).turns;
388
+
389
+ // Should only have the assistant turn (no user turn since message was empty)
390
+ expect(turns).toHaveLength(1);
391
+ expect(turns[0].role).toBe("assistant");
392
+ });
393
+
394
+ it("should only record completed tool calls, not running ones", async () => {
395
+ await setup([
396
+ {
397
+ sessionUpdate: "tool_call",
398
+ toolCallId: "tc-running",
399
+ title: "Running tool",
400
+ status: "running",
401
+ rawInput: {},
402
+ },
403
+ {
404
+ sessionUpdate: "tool_call",
405
+ toolCallId: "tc-done",
406
+ title: "Done tool",
407
+ status: "completed",
408
+ rawInput: { x: 1 },
409
+ output: "result",
410
+ },
411
+ ]);
412
+
413
+ await macroAgent.newSession({ cwd: "/test" });
414
+ const sessionId =
415
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
416
+
417
+ await macroAgent.prompt({
418
+ sessionId,
419
+ prompt: [{ type: "text", text: "Run tools" }],
420
+ });
421
+
422
+ const response = await macroAgent.extMethod("_macro/getHistory", {
423
+ sessionId,
424
+ });
425
+
426
+ const turns = (response as { turns: { role: string; content: unknown }[] })
427
+ .turns;
428
+
429
+ const assistantContent = turns[1].content as {
430
+ parts: { type: string; toolCallId?: string }[];
431
+ };
432
+
433
+ // Only the completed tool call should be recorded
434
+ const toolParts = assistantContent.parts.filter((p) => p.type === "tool");
435
+ expect(toolParts).toHaveLength(1);
436
+ expect(toolParts[0].toolCallId).toBe("tc-done");
437
+ });
438
+
439
+ it("should return turns ordered by timestamp (ascending)", async () => {
440
+ const { agentManager } = await setup([
441
+ {
442
+ sessionUpdate: "agent_message_chunk",
443
+ content: { type: "text", text: "First" },
444
+ },
445
+ ]);
446
+
447
+ await macroAgent.newSession({ cwd: "/test" });
448
+ const sessionId =
449
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
450
+
451
+ await macroAgent.prompt({
452
+ sessionId,
453
+ prompt: [{ type: "text", text: "Q1" }],
454
+ });
455
+
456
+ // Small delay to ensure distinct timestamps
457
+ await new Promise((r) => setTimeout(r, 5));
458
+
459
+ vi.mocked(agentManager.prompt).mockReturnValue({
460
+ [Symbol.asyncIterator]: async function* () {
461
+ yield {
462
+ sessionUpdate: "agent_message_chunk",
463
+ content: { type: "text", text: "Second" },
464
+ };
465
+ },
466
+ } as any);
467
+
468
+ await macroAgent.prompt({
469
+ sessionId,
470
+ prompt: [{ type: "text", text: "Q2" }],
471
+ });
472
+
473
+ const response = await macroAgent.extMethod("_macro/getHistory", {
474
+ sessionId,
475
+ });
476
+
477
+ const turns = (
478
+ response as { turns: { timestamp: number; content: unknown }[] }
479
+ ).turns;
480
+
481
+ // Verify timestamps are in ascending order
482
+ for (let i = 1; i < turns.length; i++) {
483
+ expect(turns[i].timestamp).toBeGreaterThanOrEqual(turns[i - 1].timestamp);
484
+ }
485
+ });
486
+
487
+ it("should isolate history between different sessions", async () => {
488
+ await setup([
489
+ {
490
+ sessionUpdate: "agent_message_chunk",
491
+ content: { type: "text", text: "Session 1 response" },
492
+ },
493
+ ]);
494
+
495
+ // Create first session and prompt
496
+ await macroAgent.newSession({ cwd: "/test" });
497
+ const session1Id =
498
+ macroAgent.getSessionMapper().getAllMappings()[0]?.acpSessionId;
499
+
500
+ await macroAgent.prompt({
501
+ sessionId: session1Id,
502
+ prompt: [{ type: "text", text: "Session 1 message" }],
503
+ });
504
+
505
+ // Create second session
506
+ await macroAgent.newSession({ cwd: "/test2" });
507
+ const allMappings = macroAgent.getSessionMapper().getAllMappings();
508
+ const session2Id = allMappings.find(
509
+ (m) => m.acpSessionId !== session1Id
510
+ )?.acpSessionId;
511
+
512
+ // Session 2 should have no history
513
+ const response = await macroAgent.extMethod("_macro/getHistory", {
514
+ sessionId: session2Id,
515
+ });
516
+
517
+ const turns = (response as { turns: unknown[] }).turns;
518
+ expect(turns).toHaveLength(0);
519
+
520
+ // Session 1 should still have its history
521
+ const response1 = await macroAgent.extMethod("_macro/getHistory", {
522
+ sessionId: session1Id,
523
+ });
524
+ expect((response1 as { turns: unknown[] }).turns).toHaveLength(2);
525
+ });
526
+ });
@@ -372,7 +372,8 @@ describe("ACP Mode Integration", () => {
372
372
  expect(extensions).toContain("_macro/respondToPermission");
373
373
  expect(extensions).toContain("_macro/cancelPermission");
374
374
  expect(extensions).toContain("_macro/resume");
375
- expect(extensions?.length).toBe(16);
375
+ expect(extensions).toContain("_macro/getHistory");
376
+ expect(extensions?.length).toBe(17);
376
377
 
377
378
  expect(initResponse.agentCapabilities?._meta?.agentType).toBe(
378
379
  "macro-agent"
package/src/acp/index.ts CHANGED
@@ -95,6 +95,10 @@ export type {
95
95
  MountAgentResponse,
96
96
  ForkAgentRequest,
97
97
  ForkAgentResponse,
98
+ // History types
99
+ HistoryTurn,
100
+ GetHistoryRequest,
101
+ GetHistoryResponse,
98
102
  // Union types
99
103
  ACPExtensionMethod,
100
104
  ACPExtensionRequests,