macro-agent 0.0.14 → 0.0.16
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.
- package/.claude/settings.local.json +59 -0
- package/dist/acp/index.d.ts +1 -1
- package/dist/acp/index.d.ts.map +1 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/macro-agent.d.ts +21 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +182 -0
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/types.d.ts +31 -2
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +10 -4
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/cli/acp.d.ts +6 -0
- package/dist/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +16 -2
- package/dist/cli/acp.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts +5 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +47 -4
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/utils/address-translation.d.ts +99 -0
- package/dist/map/utils/address-translation.d.ts.map +1 -0
- package/dist/map/utils/address-translation.js +285 -0
- package/dist/map/utils/address-translation.js.map +1 -0
- package/dist/map/utils/index.d.ts +7 -0
- package/dist/map/utils/index.d.ts.map +1 -0
- package/dist/map/utils/index.js +7 -0
- package/dist/map/utils/index.js.map +1 -0
- package/dist/store/event-store.js +9 -2
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +2 -0
- package/dist/store/types/agents.d.ts.map +1 -1
- package/package.json +4 -4
- package/references/acp-factory-ref/CHANGELOG.md +33 -0
- package/references/acp-factory-ref/LICENSE +21 -0
- package/references/acp-factory-ref/README.md +341 -0
- package/references/acp-factory-ref/package-lock.json +3102 -0
- package/references/acp-factory-ref/package.json +96 -0
- package/references/acp-factory-ref/python/CHANGELOG.md +33 -0
- package/references/acp-factory-ref/python/LICENSE +21 -0
- package/references/acp-factory-ref/python/Makefile +57 -0
- package/references/acp-factory-ref/python/README.md +253 -0
- package/references/acp-factory-ref/python/pyproject.toml +73 -0
- package/references/acp-factory-ref/python/tests/__init__.py +0 -0
- package/references/acp-factory-ref/python/tests/e2e/__init__.py +1 -0
- package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +349 -0
- package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +165 -0
- package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +296 -0
- package/references/acp-factory-ref/python/tests/test_client_handler.py +543 -0
- package/references/acp-factory-ref/python/tests/test_pushable.py +199 -0
- package/references/claude-code-acp/.github/workflows/ci.yml +45 -0
- package/references/claude-code-acp/.github/workflows/publish.yml +34 -0
- package/references/claude-code-acp/.prettierrc.json +4 -0
- package/references/claude-code-acp/CHANGELOG.md +249 -0
- package/references/claude-code-acp/LICENSE +222 -0
- package/references/claude-code-acp/README.md +53 -0
- package/references/claude-code-acp/docs/RELEASES.md +24 -0
- package/references/claude-code-acp/eslint.config.js +48 -0
- package/references/claude-code-acp/package-lock.json +4570 -0
- package/references/claude-code-acp/package.json +88 -0
- package/references/claude-code-acp/scripts/release.sh +119 -0
- package/references/claude-code-acp/src/acp-agent.ts +2079 -0
- package/references/claude-code-acp/src/index.ts +26 -0
- package/references/claude-code-acp/src/lib.ts +38 -0
- package/references/claude-code-acp/src/mcp-server.ts +911 -0
- package/references/claude-code-acp/src/settings.ts +522 -0
- package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +5 -0
- package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +6 -0
- package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +479 -0
- package/references/claude-code-acp/src/tests/acp-agent.test.ts +1502 -0
- package/references/claude-code-acp/src/tests/extract-lines.test.ts +103 -0
- package/references/claude-code-acp/src/tests/fork-session.test.ts +335 -0
- package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +334 -0
- package/references/claude-code-acp/src/tests/settings.test.ts +617 -0
- package/references/claude-code-acp/src/tests/skills-options.test.ts +187 -0
- package/references/claude-code-acp/src/tests/tools.test.ts +318 -0
- package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +558 -0
- package/references/claude-code-acp/src/tools.ts +819 -0
- package/references/claude-code-acp/src/utils.ts +171 -0
- package/references/claude-code-acp/tsconfig.json +18 -0
- package/references/claude-code-acp/vitest.config.ts +19 -0
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +111 -0
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +13 -0
- package/references/multi-agent-protocol/LICENSE +21 -0
- package/references/multi-agent-protocol/README.md +113 -0
- package/references/multi-agent-protocol/docs/00-design-specification.md +496 -0
- package/references/multi-agent-protocol/docs/01-open-questions.md +1050 -0
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +296 -0
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +252 -0
- package/references/multi-agent-protocol/docs/04-error-handling.md +231 -0
- package/references/multi-agent-protocol/docs/05-connection-model.md +244 -0
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +243 -0
- package/references/multi-agent-protocol/docs/07-federation.md +259 -0
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +253 -0
- package/references/multi-agent-protocol/docs/09-authentication.md +680 -0
- package/references/multi-agent-protocol/docs/10-mail-protocol.md +553 -0
- package/references/multi-agent-protocol/docs/agent-iam-integration.md +877 -0
- package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +459 -0
- package/references/multi-agent-protocol/docs/git-transport-draft.md +251 -0
- package/references/multi-agent-protocol/docs-site/Gemfile +22 -0
- package/references/multi-agent-protocol/docs-site/README.md +82 -0
- package/references/multi-agent-protocol/docs-site/_config.yml +91 -0
- package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +20 -0
- package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +42 -0
- package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +34 -0
- package/references/multi-agent-protocol/docs-site/examples/full-integration.md +510 -0
- package/references/multi-agent-protocol/docs-site/examples/index.md +138 -0
- package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +282 -0
- package/references/multi-agent-protocol/docs-site/examples/task-queue.md +399 -0
- package/references/multi-agent-protocol/docs-site/getting-started/index.md +98 -0
- package/references/multi-agent-protocol/docs-site/getting-started/installation.md +219 -0
- package/references/multi-agent-protocol/docs-site/getting-started/overview.md +172 -0
- package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +237 -0
- package/references/multi-agent-protocol/docs-site/index.md +136 -0
- package/references/multi-agent-protocol/docs-site/protocol/authentication.md +391 -0
- package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +376 -0
- package/references/multi-agent-protocol/docs-site/protocol/design.md +284 -0
- package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +312 -0
- package/references/multi-agent-protocol/docs-site/protocol/federation.md +449 -0
- package/references/multi-agent-protocol/docs-site/protocol/index.md +129 -0
- package/references/multi-agent-protocol/docs-site/protocol/permissions.md +398 -0
- package/references/multi-agent-protocol/docs-site/protocol/streaming.md +353 -0
- package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +369 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +357 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/client.md +380 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/index.md +62 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/server.md +453 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/types.md +468 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +375 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +405 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +352 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +89 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +360 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +446 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +363 -0
- package/references/multi-agent-protocol/docs-site/sdk/index.md +206 -0
- package/references/multi-agent-protocol/package-lock.json +3886 -0
- package/references/multi-agent-protocol/package.json +56 -0
- package/references/multi-agent-protocol/schema/meta.json +467 -0
- package/references/multi-agent-protocol/schema/schema.json +2558 -0
- package/src/acp/__tests__/history.test.ts +526 -0
- package/src/acp/__tests__/integration.test.ts +2 -1
- package/src/acp/index.ts +4 -0
- package/src/acp/macro-agent.ts +329 -85
- package/src/acp/types.ts +39 -2
- package/src/agent/__tests__/agent-manager.test.ts +67 -1
- package/src/agent/agent-manager.ts +10 -4
- package/src/cli/__tests__/stable-instance-id.test.ts +57 -0
- package/src/cli/acp.ts +17 -2
- package/src/map/adapter/acp-over-map.ts +57 -2
- package/src/store/event-store.ts +10 -3
- package/src/store/types/agents.ts +2 -0
package/src/acp/macro-agent.ts
CHANGED
|
@@ -63,6 +63,9 @@ import type {
|
|
|
63
63
|
CancelPermissionResponse,
|
|
64
64
|
ResumeAgentRequest,
|
|
65
65
|
ResumeAgentResponse,
|
|
66
|
+
GetHistoryRequest,
|
|
67
|
+
GetHistoryResponse,
|
|
68
|
+
HistoryTurn,
|
|
66
69
|
} from "./types.js";
|
|
67
70
|
import { ACPError } from "./types.js";
|
|
68
71
|
import type { PeerManager } from "../peer/peer-manager.js";
|
|
@@ -95,6 +98,7 @@ const SUPPORTED_EXTENSIONS: ACPExtensionMethod[] = [
|
|
|
95
98
|
"_macro/respondToPermission",
|
|
96
99
|
"_macro/cancelPermission",
|
|
97
100
|
"_macro/resume",
|
|
101
|
+
"_macro/getHistory",
|
|
98
102
|
];
|
|
99
103
|
|
|
100
104
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -150,6 +154,12 @@ export class MacroAgent implements Agent {
|
|
|
150
154
|
private cancellationControllers: Map<ACPSessionId, AbortController> =
|
|
151
155
|
new Map();
|
|
152
156
|
|
|
157
|
+
/** Accumulates assistant response parts during prompt streaming for history persistence */
|
|
158
|
+
private promptBuffers: Map<
|
|
159
|
+
ACPSessionId,
|
|
160
|
+
{ textChunks: string[]; toolCalls: Record<string, unknown>[] }
|
|
161
|
+
> = new Map();
|
|
162
|
+
|
|
153
163
|
constructor(connection: AgentSideConnection, config: MacroAgentConfig) {
|
|
154
164
|
this.connection = connection;
|
|
155
165
|
this.agentManager = config.agentManager;
|
|
@@ -165,7 +175,7 @@ export class MacroAgent implements Agent {
|
|
|
165
175
|
const recovered = this.sessionMapper.recoverFromStore();
|
|
166
176
|
if (recovered > 0) {
|
|
167
177
|
console.log(
|
|
168
|
-
`[MacroAgent] Recovered ${recovered} session(s) from EventStore
|
|
178
|
+
`[MacroAgent] Recovered ${recovered} session(s) from EventStore`,
|
|
169
179
|
);
|
|
170
180
|
}
|
|
171
181
|
}
|
|
@@ -231,6 +241,12 @@ export class MacroAgent implements Agent {
|
|
|
231
241
|
// Create abort controller for cancellation
|
|
232
242
|
this.cancellationControllers.set(acpSessionId, new AbortController());
|
|
233
243
|
|
|
244
|
+
// Create a conversation in EventStore for history tracking
|
|
245
|
+
this.ensureConversation(acpSessionId, spawned.id);
|
|
246
|
+
|
|
247
|
+
// Emit session_info_update so client has title/timestamps
|
|
248
|
+
await this.emitSessionInfo(acpSessionId);
|
|
249
|
+
|
|
234
250
|
return {
|
|
235
251
|
sessionId: acpSessionId,
|
|
236
252
|
};
|
|
@@ -255,7 +271,7 @@ export class MacroAgent implements Agent {
|
|
|
255
271
|
}
|
|
256
272
|
acpSessionId = agent.session_id;
|
|
257
273
|
console.log(
|
|
258
|
-
`[MacroAgent] loadSession: Resolved agentId ${metaAgentId} to session ${acpSessionId}
|
|
274
|
+
`[MacroAgent] loadSession: Resolved agentId ${metaAgentId} to session ${acpSessionId}`,
|
|
259
275
|
);
|
|
260
276
|
}
|
|
261
277
|
|
|
@@ -267,32 +283,36 @@ export class MacroAgent implements Agent {
|
|
|
267
283
|
// Check if the agent already has an active session
|
|
268
284
|
if (this.agentManager.hasActiveSession(existing.id)) {
|
|
269
285
|
console.log(
|
|
270
|
-
`[MacroAgent] loadSession: Agent ${existing.id} already has active session, reusing
|
|
286
|
+
`[MacroAgent] loadSession: Agent ${existing.id} already has active session, reusing`,
|
|
271
287
|
);
|
|
272
288
|
// Reuse the existing active session - just update mappings
|
|
273
289
|
this.sessionMapper.createMapping(acpSessionId, existing.id);
|
|
274
290
|
if (!this.cancellationControllers.has(acpSessionId)) {
|
|
275
291
|
this.cancellationControllers.set(acpSessionId, new AbortController());
|
|
276
292
|
}
|
|
293
|
+
this.ensureConversation(acpSessionId, existing.id);
|
|
294
|
+
await this.emitSessionInfo(acpSessionId);
|
|
277
295
|
return {};
|
|
278
296
|
}
|
|
279
297
|
|
|
280
298
|
// Agent exists but no active session - resume it
|
|
281
299
|
console.log(
|
|
282
|
-
`[MacroAgent] loadSession: Resuming stopped agent ${existing.id}
|
|
300
|
+
`[MacroAgent] loadSession: Resuming stopped agent ${existing.id}`,
|
|
283
301
|
);
|
|
284
302
|
const spawned = await this.agentManager.resume(existing.id);
|
|
285
303
|
|
|
286
304
|
// Create session mapping
|
|
287
305
|
this.sessionMapper.createMapping(acpSessionId, spawned.id);
|
|
288
306
|
this.cancellationControllers.set(acpSessionId, new AbortController());
|
|
307
|
+
this.ensureConversation(acpSessionId, spawned.id);
|
|
308
|
+
await this.emitSessionInfo(acpSessionId);
|
|
289
309
|
|
|
290
310
|
return {};
|
|
291
311
|
}
|
|
292
312
|
|
|
293
313
|
// No existing agent found - try to get or create with the specific session ID
|
|
294
314
|
console.log(
|
|
295
|
-
`[MacroAgent] loadSession: No existing agent for session ${acpSessionId}, creating new
|
|
315
|
+
`[MacroAgent] loadSession: No existing agent for session ${acpSessionId}, creating new`,
|
|
296
316
|
);
|
|
297
317
|
const spawned = await this.agentManager.getOrCreateHeadManager({
|
|
298
318
|
cwd,
|
|
@@ -302,6 +322,8 @@ export class MacroAgent implements Agent {
|
|
|
302
322
|
// Create session mapping
|
|
303
323
|
this.sessionMapper.createMapping(acpSessionId, spawned.id);
|
|
304
324
|
this.cancellationControllers.set(acpSessionId, new AbortController());
|
|
325
|
+
this.ensureConversation(acpSessionId, spawned.id);
|
|
326
|
+
await this.emitSessionInfo(acpSessionId);
|
|
305
327
|
|
|
306
328
|
return {};
|
|
307
329
|
}
|
|
@@ -310,7 +332,7 @@ export class MacroAgent implements Agent {
|
|
|
310
332
|
* Authenticate - macro-agent doesn't require authentication
|
|
311
333
|
*/
|
|
312
334
|
async authenticate(
|
|
313
|
-
_params: AuthenticateRequest
|
|
335
|
+
_params: AuthenticateRequest,
|
|
314
336
|
): Promise<AuthenticateResponse> {
|
|
315
337
|
// No authentication required
|
|
316
338
|
return {};
|
|
@@ -338,11 +360,14 @@ export class MacroAgent implements Agent {
|
|
|
338
360
|
// Mark session as processing (for health monitoring)
|
|
339
361
|
this.sessionMapper.setProcessing(acpSessionId, true);
|
|
340
362
|
|
|
363
|
+
// Initialize prompt buffer for history accumulation
|
|
364
|
+
this.promptBuffers.set(acpSessionId, { textChunks: [], toolCalls: [] });
|
|
365
|
+
|
|
341
366
|
try {
|
|
342
367
|
// Stream responses from the agent
|
|
343
368
|
for await (const update of this.agentManager.prompt(
|
|
344
369
|
agentId,
|
|
345
|
-
messageContent
|
|
370
|
+
messageContent,
|
|
346
371
|
)) {
|
|
347
372
|
// Check for cancellation
|
|
348
373
|
if (abortController.signal.aborted) {
|
|
@@ -355,6 +380,12 @@ export class MacroAgent implements Agent {
|
|
|
355
380
|
await this.forwardSessionUpdate(acpSessionId, update);
|
|
356
381
|
}
|
|
357
382
|
|
|
383
|
+
// Persist conversation turns for history
|
|
384
|
+
this.recordPromptTurns(acpSessionId, agentId, messageContent);
|
|
385
|
+
|
|
386
|
+
// Emit updated session info after prompt completes
|
|
387
|
+
await this.emitSessionInfo(acpSessionId);
|
|
388
|
+
|
|
358
389
|
return {
|
|
359
390
|
stopReason: "end_turn",
|
|
360
391
|
};
|
|
@@ -408,7 +439,7 @@ export class MacroAgent implements Agent {
|
|
|
408
439
|
// Agent may already be stopped - log but don't throw
|
|
409
440
|
console.warn(
|
|
410
441
|
`[MacroAgent] Error terminating agent ${agentId}:`,
|
|
411
|
-
error instanceof Error ? error.message : String(error)
|
|
442
|
+
error instanceof Error ? error.message : String(error),
|
|
412
443
|
);
|
|
413
444
|
}
|
|
414
445
|
|
|
@@ -426,97 +457,104 @@ export class MacroAgent implements Agent {
|
|
|
426
457
|
*/
|
|
427
458
|
async extMethod(
|
|
428
459
|
method: string,
|
|
429
|
-
params: Record<string, unknown
|
|
460
|
+
params: Record<string, unknown>,
|
|
430
461
|
): Promise<Record<string, unknown>> {
|
|
431
462
|
// Method may come with or without underscore prefix depending on caller
|
|
432
463
|
// SDK calls with full name (e.g., "_macro/spawnAgent"), direct calls may omit it
|
|
433
|
-
const fullMethod = (
|
|
464
|
+
const fullMethod = (
|
|
465
|
+
method.startsWith("_") ? method : `_${method}`
|
|
466
|
+
) as ACPExtensionMethod;
|
|
434
467
|
|
|
435
468
|
switch (fullMethod) {
|
|
436
469
|
case "_macro/spawnAgent":
|
|
437
470
|
return this.handleSpawnAgent(
|
|
438
|
-
params as unknown as SpawnAgentRequest
|
|
471
|
+
params as unknown as SpawnAgentRequest,
|
|
439
472
|
) as unknown as Record<string, unknown>;
|
|
440
473
|
|
|
441
474
|
case "_macro/getHierarchy":
|
|
442
475
|
return this.handleGetHierarchy(
|
|
443
|
-
params as unknown as GetHierarchyRequest
|
|
476
|
+
params as unknown as GetHierarchyRequest,
|
|
444
477
|
) as unknown as Record<string, unknown>;
|
|
445
478
|
|
|
446
479
|
case "_macro/getTask":
|
|
447
480
|
return this.handleGetTask(
|
|
448
|
-
params as unknown as GetTaskRequest
|
|
481
|
+
params as unknown as GetTaskRequest,
|
|
449
482
|
) as unknown as Record<string, unknown>;
|
|
450
483
|
|
|
451
484
|
case "_macro/mountAgent":
|
|
452
485
|
return this.handleMountAgent(
|
|
453
|
-
params as unknown as MountAgentRequest
|
|
486
|
+
params as unknown as MountAgentRequest,
|
|
454
487
|
) as unknown as Record<string, unknown>;
|
|
455
488
|
|
|
456
489
|
case "_macro/forkAgent":
|
|
457
490
|
return this.handleForkAgent(
|
|
458
|
-
params as unknown as ForkAgentRequest
|
|
491
|
+
params as unknown as ForkAgentRequest,
|
|
459
492
|
) as unknown as Record<string, unknown>;
|
|
460
493
|
|
|
461
494
|
case "_macro/sendPeerMessage":
|
|
462
495
|
return this.handleSendPeerMessage(
|
|
463
|
-
params as unknown as SendPeerMessageACPRequest
|
|
496
|
+
params as unknown as SendPeerMessageACPRequest,
|
|
464
497
|
) as unknown as Record<string, unknown>;
|
|
465
498
|
|
|
466
499
|
case "_macro/sendPeerRequest":
|
|
467
500
|
return this.handleSendPeerRequest(
|
|
468
|
-
params as unknown as SendPeerRequestACPRequest
|
|
501
|
+
params as unknown as SendPeerRequestACPRequest,
|
|
469
502
|
) as unknown as Record<string, unknown>;
|
|
470
503
|
|
|
471
504
|
case "_macro/deliverPeerMessage":
|
|
472
505
|
return this.handleDeliverPeerMessage(
|
|
473
|
-
params as unknown as DeliverPeerMessageRequest
|
|
506
|
+
params as unknown as DeliverPeerMessageRequest,
|
|
474
507
|
) as unknown as Record<string, unknown>;
|
|
475
508
|
|
|
476
509
|
case "_macro/deliverPeerRequest":
|
|
477
510
|
return this.handleDeliverPeerRequest(
|
|
478
|
-
params as unknown as DeliverPeerRequestRequest
|
|
511
|
+
params as unknown as DeliverPeerRequestRequest,
|
|
479
512
|
) as unknown as Record<string, unknown>;
|
|
480
513
|
|
|
481
514
|
case "_macro/grantCapability":
|
|
482
515
|
return this.handleGrantCapability(
|
|
483
|
-
params as unknown as GrantCapabilityRequest
|
|
516
|
+
params as unknown as GrantCapabilityRequest,
|
|
484
517
|
) as unknown as Record<string, unknown>;
|
|
485
518
|
|
|
486
519
|
case "_macro/revokeCapability":
|
|
487
520
|
return this.handleRevokeCapability(
|
|
488
|
-
params as unknown as RevokeCapabilityRequest
|
|
521
|
+
params as unknown as RevokeCapabilityRequest,
|
|
489
522
|
) as unknown as Record<string, unknown>;
|
|
490
523
|
|
|
491
524
|
case "_macro/getCapabilities":
|
|
492
525
|
return this.handleGetCapabilities(
|
|
493
|
-
params as unknown as GetCapabilitiesRequest
|
|
526
|
+
params as unknown as GetCapabilitiesRequest,
|
|
494
527
|
) as unknown as Record<string, unknown>;
|
|
495
528
|
|
|
496
529
|
case "_macro/checkCapability":
|
|
497
530
|
return this.handleCheckCapability(
|
|
498
|
-
params as unknown as CheckCapabilityRequest
|
|
531
|
+
params as unknown as CheckCapabilityRequest,
|
|
499
532
|
) as unknown as Record<string, unknown>;
|
|
500
533
|
|
|
501
534
|
case "_macro/respondToPermission":
|
|
502
535
|
return this.handleRespondToPermission(
|
|
503
|
-
params as unknown as RespondToPermissionRequest
|
|
536
|
+
params as unknown as RespondToPermissionRequest,
|
|
504
537
|
) as unknown as Record<string, unknown>;
|
|
505
538
|
|
|
506
539
|
case "_macro/cancelPermission":
|
|
507
540
|
return this.handleCancelPermission(
|
|
508
|
-
params as unknown as CancelPermissionRequest
|
|
541
|
+
params as unknown as CancelPermissionRequest,
|
|
509
542
|
) as unknown as Record<string, unknown>;
|
|
510
543
|
|
|
511
544
|
case "_macro/resume":
|
|
512
545
|
return this.handleResumeAgent(
|
|
513
|
-
params as unknown as ResumeAgentRequest
|
|
546
|
+
params as unknown as ResumeAgentRequest,
|
|
547
|
+
) as unknown as Record<string, unknown>;
|
|
548
|
+
|
|
549
|
+
case "_macro/getHistory":
|
|
550
|
+
return this.handleGetHistory(
|
|
551
|
+
params as unknown as GetHistoryRequest,
|
|
514
552
|
) as unknown as Record<string, unknown>;
|
|
515
553
|
|
|
516
554
|
default:
|
|
517
555
|
throw new ACPError(
|
|
518
556
|
`Unknown extension method: ${method}`,
|
|
519
|
-
"INVALID_EXTENSION"
|
|
557
|
+
"INVALID_EXTENSION",
|
|
520
558
|
);
|
|
521
559
|
}
|
|
522
560
|
}
|
|
@@ -529,7 +567,7 @@ export class MacroAgent implements Agent {
|
|
|
529
567
|
* Spawn a new child agent
|
|
530
568
|
*/
|
|
531
569
|
private async handleSpawnAgent(
|
|
532
|
-
params: SpawnAgentRequest
|
|
570
|
+
params: SpawnAgentRequest,
|
|
533
571
|
): Promise<SpawnAgentResponse> {
|
|
534
572
|
// Determine parent - use provided parentId or fall back to a session's mapped agent
|
|
535
573
|
let parentId = params.parentId;
|
|
@@ -563,7 +601,7 @@ export class MacroAgent implements Agent {
|
|
|
563
601
|
parentRole,
|
|
564
602
|
childRole,
|
|
565
603
|
requiredCapability,
|
|
566
|
-
}
|
|
604
|
+
},
|
|
567
605
|
);
|
|
568
606
|
}
|
|
569
607
|
}
|
|
@@ -572,7 +610,7 @@ export class MacroAgent implements Agent {
|
|
|
572
610
|
// Merge default config with per-spawn override
|
|
573
611
|
const mergedConfig = this.mergeSubAgentConfig(
|
|
574
612
|
this.initConfig.defaultSubAgentConfig,
|
|
575
|
-
params.config
|
|
613
|
+
params.config,
|
|
576
614
|
);
|
|
577
615
|
|
|
578
616
|
// Spawn the agent with merged config
|
|
@@ -624,7 +662,7 @@ export class MacroAgent implements Agent {
|
|
|
624
662
|
* Get the agent hierarchy tree
|
|
625
663
|
*/
|
|
626
664
|
private async handleGetHierarchy(
|
|
627
|
-
params: GetHierarchyRequest
|
|
665
|
+
params: GetHierarchyRequest,
|
|
628
666
|
): Promise<GetHierarchyResponse> {
|
|
629
667
|
let rootAgentId = params.rootAgentId;
|
|
630
668
|
|
|
@@ -665,7 +703,7 @@ export class MacroAgent implements Agent {
|
|
|
665
703
|
* Get task details by ID
|
|
666
704
|
*/
|
|
667
705
|
private async handleGetTask(
|
|
668
|
-
params: GetTaskRequest
|
|
706
|
+
params: GetTaskRequest,
|
|
669
707
|
): Promise<GetTaskResponse> {
|
|
670
708
|
const task = this.taskManager.get(params.taskId);
|
|
671
709
|
|
|
@@ -687,7 +725,7 @@ export class MacroAgent implements Agent {
|
|
|
687
725
|
* Subsequent prompts will go to the mounted agent.
|
|
688
726
|
*/
|
|
689
727
|
private async handleMountAgent(
|
|
690
|
-
params: MountAgentRequest
|
|
728
|
+
params: MountAgentRequest,
|
|
691
729
|
): Promise<MountAgentResponse> {
|
|
692
730
|
const { sessionId, agentId } = params;
|
|
693
731
|
|
|
@@ -705,7 +743,7 @@ export class MacroAgent implements Agent {
|
|
|
705
743
|
throw new ACPError(
|
|
706
744
|
`Session not found: ${sessionId}`,
|
|
707
745
|
"SESSION_NOT_FOUND",
|
|
708
|
-
{ sessionId }
|
|
746
|
+
{ sessionId },
|
|
709
747
|
);
|
|
710
748
|
}
|
|
711
749
|
|
|
@@ -729,7 +767,7 @@ export class MacroAgent implements Agent {
|
|
|
729
767
|
* Uses native fork if available, otherwise falls back to loadSession.
|
|
730
768
|
*/
|
|
731
769
|
private async handleForkAgent(
|
|
732
|
-
params: ForkAgentRequest
|
|
770
|
+
params: ForkAgentRequest,
|
|
733
771
|
): Promise<ForkAgentResponse> {
|
|
734
772
|
const { agentId, name } = params;
|
|
735
773
|
|
|
@@ -747,7 +785,7 @@ export class MacroAgent implements Agent {
|
|
|
747
785
|
throw new ACPError(
|
|
748
786
|
`Agent has no active session to fork: ${agentId}`,
|
|
749
787
|
"FORK_NOT_SUPPORTED",
|
|
750
|
-
{ agentId }
|
|
788
|
+
{ agentId },
|
|
751
789
|
);
|
|
752
790
|
}
|
|
753
791
|
|
|
@@ -789,12 +827,12 @@ export class MacroAgent implements Agent {
|
|
|
789
827
|
* Called by external clients to have an agent send a message to a peer.
|
|
790
828
|
*/
|
|
791
829
|
private async handleSendPeerMessage(
|
|
792
|
-
params: SendPeerMessageACPRequest
|
|
830
|
+
params: SendPeerMessageACPRequest,
|
|
793
831
|
): Promise<SendPeerMessageACPResponse> {
|
|
794
832
|
if (!this.peerManager) {
|
|
795
833
|
throw new ACPError(
|
|
796
834
|
"PeerManager not configured for this macro-agent",
|
|
797
|
-
"NO_PEER_MANAGER"
|
|
835
|
+
"NO_PEER_MANAGER",
|
|
798
836
|
);
|
|
799
837
|
}
|
|
800
838
|
|
|
@@ -803,7 +841,7 @@ export class MacroAgent implements Agent {
|
|
|
803
841
|
if (headManagers.length === 0) {
|
|
804
842
|
throw new ACPError(
|
|
805
843
|
"No agents available to send peer message",
|
|
806
|
-
"AGENT_NOT_FOUND"
|
|
844
|
+
"AGENT_NOT_FOUND",
|
|
807
845
|
);
|
|
808
846
|
}
|
|
809
847
|
const sendingAgentId = headManagers[0].id;
|
|
@@ -825,7 +863,7 @@ export class MacroAgent implements Agent {
|
|
|
825
863
|
throw new ACPError(
|
|
826
864
|
`Failed to send peer message: ${error instanceof Error ? error.message : String(error)}`,
|
|
827
865
|
"PEER_SEND_FAILED",
|
|
828
|
-
{ to: params.to, error }
|
|
866
|
+
{ to: params.to, error },
|
|
829
867
|
);
|
|
830
868
|
}
|
|
831
869
|
}
|
|
@@ -837,12 +875,12 @@ export class MacroAgent implements Agent {
|
|
|
837
875
|
* and wait for a response.
|
|
838
876
|
*/
|
|
839
877
|
private async handleSendPeerRequest(
|
|
840
|
-
params: SendPeerRequestACPRequest
|
|
878
|
+
params: SendPeerRequestACPRequest,
|
|
841
879
|
): Promise<SendPeerRequestACPResponse> {
|
|
842
880
|
if (!this.peerManager) {
|
|
843
881
|
throw new ACPError(
|
|
844
882
|
"PeerManager not configured for this macro-agent",
|
|
845
|
-
"NO_PEER_MANAGER"
|
|
883
|
+
"NO_PEER_MANAGER",
|
|
846
884
|
);
|
|
847
885
|
}
|
|
848
886
|
|
|
@@ -851,7 +889,7 @@ export class MacroAgent implements Agent {
|
|
|
851
889
|
if (headManagers.length === 0) {
|
|
852
890
|
throw new ACPError(
|
|
853
891
|
"No agents available to send peer request",
|
|
854
|
-
"AGENT_NOT_FOUND"
|
|
892
|
+
"AGENT_NOT_FOUND",
|
|
855
893
|
);
|
|
856
894
|
}
|
|
857
895
|
const sendingAgentId = headManagers[0].id;
|
|
@@ -864,7 +902,7 @@ export class MacroAgent implements Agent {
|
|
|
864
902
|
method: params.method,
|
|
865
903
|
params: params.params,
|
|
866
904
|
timeout: params.timeout,
|
|
867
|
-
}
|
|
905
|
+
},
|
|
868
906
|
);
|
|
869
907
|
|
|
870
908
|
return response;
|
|
@@ -872,7 +910,7 @@ export class MacroAgent implements Agent {
|
|
|
872
910
|
throw new ACPError(
|
|
873
911
|
`Failed to send peer request: ${error instanceof Error ? error.message : String(error)}`,
|
|
874
912
|
"PEER_SEND_FAILED",
|
|
875
|
-
{ to: params.to, error }
|
|
913
|
+
{ to: params.to, error },
|
|
876
914
|
);
|
|
877
915
|
}
|
|
878
916
|
}
|
|
@@ -884,12 +922,12 @@ export class MacroAgent implements Agent {
|
|
|
884
922
|
* to this macro-agent. The message is queued for the target agent.
|
|
885
923
|
*/
|
|
886
924
|
private async handleDeliverPeerMessage(
|
|
887
|
-
params: DeliverPeerMessageRequest
|
|
925
|
+
params: DeliverPeerMessageRequest,
|
|
888
926
|
): Promise<DeliverPeerMessageResponse> {
|
|
889
927
|
if (!this.peerManager) {
|
|
890
928
|
throw new ACPError(
|
|
891
929
|
"PeerManager not configured for this macro-agent",
|
|
892
|
-
"NO_PEER_MANAGER"
|
|
930
|
+
"NO_PEER_MANAGER",
|
|
893
931
|
);
|
|
894
932
|
}
|
|
895
933
|
|
|
@@ -903,7 +941,7 @@ export class MacroAgent implements Agent {
|
|
|
903
941
|
? { correlationId: params.correlationId }
|
|
904
942
|
: undefined,
|
|
905
943
|
},
|
|
906
|
-
params.targetAgentId
|
|
944
|
+
params.targetAgentId,
|
|
907
945
|
);
|
|
908
946
|
|
|
909
947
|
return {
|
|
@@ -920,12 +958,12 @@ export class MacroAgent implements Agent {
|
|
|
920
958
|
* internal agent to respond.
|
|
921
959
|
*/
|
|
922
960
|
private async handleDeliverPeerRequest(
|
|
923
|
-
params: DeliverPeerRequestRequest
|
|
961
|
+
params: DeliverPeerRequestRequest,
|
|
924
962
|
): Promise<DeliverPeerRequestResponse> {
|
|
925
963
|
if (!this.peerManager) {
|
|
926
964
|
throw new ACPError(
|
|
927
965
|
"PeerManager not configured for this macro-agent",
|
|
928
|
-
"NO_PEER_MANAGER"
|
|
966
|
+
"NO_PEER_MANAGER",
|
|
929
967
|
);
|
|
930
968
|
}
|
|
931
969
|
|
|
@@ -938,7 +976,7 @@ export class MacroAgent implements Agent {
|
|
|
938
976
|
params: params.params,
|
|
939
977
|
timeout: params.timeout,
|
|
940
978
|
},
|
|
941
|
-
params.targetAgentId
|
|
979
|
+
params.targetAgentId,
|
|
942
980
|
);
|
|
943
981
|
|
|
944
982
|
return response;
|
|
@@ -952,12 +990,12 @@ export class MacroAgent implements Agent {
|
|
|
952
990
|
* Grant capabilities to a peer
|
|
953
991
|
*/
|
|
954
992
|
private async handleGrantCapability(
|
|
955
|
-
params: GrantCapabilityRequest
|
|
993
|
+
params: GrantCapabilityRequest,
|
|
956
994
|
): Promise<GrantCapabilityResponse> {
|
|
957
995
|
if (!this.capabilityManager) {
|
|
958
996
|
throw new ACPError(
|
|
959
997
|
"CapabilityManager not configured for this macro-agent",
|
|
960
|
-
"NO_PEER_MANAGER"
|
|
998
|
+
"NO_PEER_MANAGER",
|
|
961
999
|
);
|
|
962
1000
|
}
|
|
963
1001
|
|
|
@@ -967,7 +1005,7 @@ export class MacroAgent implements Agent {
|
|
|
967
1005
|
{
|
|
968
1006
|
expiresIn: params.expiresIn,
|
|
969
1007
|
issuedBy: params.issuedBy,
|
|
970
|
-
}
|
|
1008
|
+
},
|
|
971
1009
|
);
|
|
972
1010
|
|
|
973
1011
|
return { capabilities };
|
|
@@ -977,12 +1015,12 @@ export class MacroAgent implements Agent {
|
|
|
977
1015
|
* Revoke capabilities from a peer
|
|
978
1016
|
*/
|
|
979
1017
|
private async handleRevokeCapability(
|
|
980
|
-
params: RevokeCapabilityRequest
|
|
1018
|
+
params: RevokeCapabilityRequest,
|
|
981
1019
|
): Promise<RevokeCapabilityResponse> {
|
|
982
1020
|
if (!this.capabilityManager) {
|
|
983
1021
|
throw new ACPError(
|
|
984
1022
|
"CapabilityManager not configured for this macro-agent",
|
|
985
|
-
"NO_PEER_MANAGER"
|
|
1023
|
+
"NO_PEER_MANAGER",
|
|
986
1024
|
);
|
|
987
1025
|
}
|
|
988
1026
|
|
|
@@ -991,7 +1029,7 @@ export class MacroAgent implements Agent {
|
|
|
991
1029
|
return {
|
|
992
1030
|
success: true,
|
|
993
1031
|
remainingCapabilities: this.capabilityManager.getCapabilities(
|
|
994
|
-
params.peerId
|
|
1032
|
+
params.peerId,
|
|
995
1033
|
),
|
|
996
1034
|
};
|
|
997
1035
|
}
|
|
@@ -1000,12 +1038,12 @@ export class MacroAgent implements Agent {
|
|
|
1000
1038
|
* Get capabilities for a peer or list all authorized peers
|
|
1001
1039
|
*/
|
|
1002
1040
|
private async handleGetCapabilities(
|
|
1003
|
-
params: GetCapabilitiesRequest
|
|
1041
|
+
params: GetCapabilitiesRequest,
|
|
1004
1042
|
): Promise<GetCapabilitiesResponse> {
|
|
1005
1043
|
if (!this.capabilityManager) {
|
|
1006
1044
|
throw new ACPError(
|
|
1007
1045
|
"CapabilityManager not configured for this macro-agent",
|
|
1008
|
-
"NO_PEER_MANAGER"
|
|
1046
|
+
"NO_PEER_MANAGER",
|
|
1009
1047
|
);
|
|
1010
1048
|
}
|
|
1011
1049
|
|
|
@@ -1024,19 +1062,19 @@ export class MacroAgent implements Agent {
|
|
|
1024
1062
|
* Check if a peer has a required capability
|
|
1025
1063
|
*/
|
|
1026
1064
|
private async handleCheckCapability(
|
|
1027
|
-
params: CheckCapabilityRequest
|
|
1065
|
+
params: CheckCapabilityRequest,
|
|
1028
1066
|
): Promise<CheckCapabilityResponse> {
|
|
1029
1067
|
if (!this.capabilityManager) {
|
|
1030
1068
|
throw new ACPError(
|
|
1031
1069
|
"CapabilityManager not configured for this macro-agent",
|
|
1032
|
-
"NO_PEER_MANAGER"
|
|
1070
|
+
"NO_PEER_MANAGER",
|
|
1033
1071
|
);
|
|
1034
1072
|
}
|
|
1035
1073
|
|
|
1036
1074
|
return {
|
|
1037
1075
|
hasCapability: this.capabilityManager.hasCapability(
|
|
1038
1076
|
params.peerId,
|
|
1039
|
-
params.required
|
|
1077
|
+
params.required,
|
|
1040
1078
|
),
|
|
1041
1079
|
};
|
|
1042
1080
|
}
|
|
@@ -1052,7 +1090,7 @@ export class MacroAgent implements Agent {
|
|
|
1052
1090
|
* then calls the agent manager to resolve the pending permission.
|
|
1053
1091
|
*/
|
|
1054
1092
|
private async handleRespondToPermission(
|
|
1055
|
-
params: RespondToPermissionRequest
|
|
1093
|
+
params: RespondToPermissionRequest,
|
|
1056
1094
|
): Promise<RespondToPermissionResponse> {
|
|
1057
1095
|
const { sessionId, requestId, optionId } = params;
|
|
1058
1096
|
|
|
@@ -1069,12 +1107,12 @@ export class MacroAgent implements Agent {
|
|
|
1069
1107
|
const success = this.agentManager.respondToPermission(
|
|
1070
1108
|
agentId,
|
|
1071
1109
|
requestId,
|
|
1072
|
-
optionId
|
|
1110
|
+
optionId,
|
|
1073
1111
|
);
|
|
1074
1112
|
|
|
1075
1113
|
if (success) {
|
|
1076
1114
|
console.log(
|
|
1077
|
-
`[MacroAgent] Responded to permission ${requestId} for session ${sessionId} with ${optionId}
|
|
1115
|
+
`[MacroAgent] Responded to permission ${requestId} for session ${sessionId} with ${optionId}`,
|
|
1078
1116
|
);
|
|
1079
1117
|
return { success: true };
|
|
1080
1118
|
} else {
|
|
@@ -1092,7 +1130,7 @@ export class MacroAgent implements Agent {
|
|
|
1092
1130
|
* then calls the agent manager to cancel the pending permission.
|
|
1093
1131
|
*/
|
|
1094
1132
|
private async handleCancelPermission(
|
|
1095
|
-
params: CancelPermissionRequest
|
|
1133
|
+
params: CancelPermissionRequest,
|
|
1096
1134
|
): Promise<CancelPermissionResponse> {
|
|
1097
1135
|
const { sessionId, requestId } = params;
|
|
1098
1136
|
|
|
@@ -1110,7 +1148,7 @@ export class MacroAgent implements Agent {
|
|
|
1110
1148
|
|
|
1111
1149
|
if (success) {
|
|
1112
1150
|
console.log(
|
|
1113
|
-
`[MacroAgent] Cancelled permission ${requestId} for session ${sessionId}
|
|
1151
|
+
`[MacroAgent] Cancelled permission ${requestId} for session ${sessionId}`,
|
|
1114
1152
|
);
|
|
1115
1153
|
return { success: true };
|
|
1116
1154
|
} else {
|
|
@@ -1125,7 +1163,7 @@ export class MacroAgent implements Agent {
|
|
|
1125
1163
|
* Resume a stopped/failed agent
|
|
1126
1164
|
*/
|
|
1127
1165
|
private async handleResumeAgent(
|
|
1128
|
-
params: ResumeAgentRequest
|
|
1166
|
+
params: ResumeAgentRequest,
|
|
1129
1167
|
): Promise<ResumeAgentResponse> {
|
|
1130
1168
|
const { agentId } = params;
|
|
1131
1169
|
|
|
@@ -1143,7 +1181,7 @@ export class MacroAgent implements Agent {
|
|
|
1143
1181
|
if (agent.state !== "stopped" && agent.state !== "failed") {
|
|
1144
1182
|
throw new ACPError(
|
|
1145
1183
|
`Agent ${agentId} is ${agent.state} — only stopped or failed agents can be resumed`,
|
|
1146
|
-
"INVALID_EXTENSION"
|
|
1184
|
+
"INVALID_EXTENSION",
|
|
1147
1185
|
);
|
|
1148
1186
|
}
|
|
1149
1187
|
|
|
@@ -1195,12 +1233,13 @@ export class MacroAgent implements Agent {
|
|
|
1195
1233
|
* - available_commands_update: Available slash commands
|
|
1196
1234
|
* - current_mode_update: Mode changes (code/plan/etc)
|
|
1197
1235
|
* - config_option_update: Configuration changes
|
|
1236
|
+
* - session_info_update: Session title and timestamps
|
|
1198
1237
|
*
|
|
1199
1238
|
* Permission requests are handled separately via the requestPermission RPC.
|
|
1200
1239
|
*/
|
|
1201
1240
|
private async forwardSessionUpdate(
|
|
1202
1241
|
acpSessionId: ACPSessionId,
|
|
1203
|
-
update: unknown
|
|
1242
|
+
update: unknown,
|
|
1204
1243
|
): Promise<void> {
|
|
1205
1244
|
const sessionUpdate = update as Record<string, unknown>;
|
|
1206
1245
|
|
|
@@ -1208,7 +1247,7 @@ export class MacroAgent implements Agent {
|
|
|
1208
1247
|
if (!("sessionUpdate" in sessionUpdate)) {
|
|
1209
1248
|
console.warn(
|
|
1210
1249
|
`[MacroAgent] Received update without sessionUpdate field:`,
|
|
1211
|
-
JSON.stringify(update).substring(0, 200)
|
|
1250
|
+
JSON.stringify(update).substring(0, 200),
|
|
1212
1251
|
);
|
|
1213
1252
|
return;
|
|
1214
1253
|
}
|
|
@@ -1226,7 +1265,7 @@ export class MacroAgent implements Agent {
|
|
|
1226
1265
|
const text = content?.text ?? "";
|
|
1227
1266
|
if (text) {
|
|
1228
1267
|
console.log(
|
|
1229
|
-
`[MacroAgent] Forwarding ${updateType} (${text.length} chars): "${text.substring(0, 80)}${text.length > 80 ? "..." : ""}"
|
|
1268
|
+
`[MacroAgent] Forwarding ${updateType} (${text.length} chars): "${text.substring(0, 80)}${text.length > 80 ? "..." : ""}"`,
|
|
1230
1269
|
);
|
|
1231
1270
|
}
|
|
1232
1271
|
break;
|
|
@@ -1237,7 +1276,7 @@ export class MacroAgent implements Agent {
|
|
|
1237
1276
|
const title = sessionUpdate.title as string;
|
|
1238
1277
|
const status = sessionUpdate.status as string;
|
|
1239
1278
|
console.log(
|
|
1240
|
-
`[MacroAgent] Forwarding tool_call: id=${toolCallId}, title="${title}", status=${status}
|
|
1279
|
+
`[MacroAgent] Forwarding tool_call: id=${toolCallId}, title="${title}", status=${status}`,
|
|
1241
1280
|
);
|
|
1242
1281
|
break;
|
|
1243
1282
|
}
|
|
@@ -1246,7 +1285,7 @@ export class MacroAgent implements Agent {
|
|
|
1246
1285
|
const toolCallId = sessionUpdate.toolCallId as string;
|
|
1247
1286
|
const status = sessionUpdate.status as string;
|
|
1248
1287
|
console.log(
|
|
1249
|
-
`[MacroAgent] Forwarding tool_call_update: id=${toolCallId}, status=${status}
|
|
1288
|
+
`[MacroAgent] Forwarding tool_call_update: id=${toolCallId}, status=${status}`,
|
|
1250
1289
|
);
|
|
1251
1290
|
break;
|
|
1252
1291
|
}
|
|
@@ -1276,7 +1315,7 @@ export class MacroAgent implements Agent {
|
|
|
1276
1315
|
const agentId = this.sessionMapper.getAgentId(permReq.sessionId);
|
|
1277
1316
|
if (!agentId) {
|
|
1278
1317
|
console.warn(
|
|
1279
|
-
`[MacroAgent] No agent found for session ${permReq.sessionId}, cannot forward permission request
|
|
1318
|
+
`[MacroAgent] No agent found for session ${permReq.sessionId}, cannot forward permission request`,
|
|
1280
1319
|
);
|
|
1281
1320
|
return;
|
|
1282
1321
|
}
|
|
@@ -1289,11 +1328,20 @@ export class MacroAgent implements Agent {
|
|
|
1289
1328
|
toolCall: {
|
|
1290
1329
|
toolCallId: permReq.toolCall.toolCallId,
|
|
1291
1330
|
title: permReq.toolCall.title,
|
|
1292
|
-
status: permReq.toolCall.status as
|
|
1331
|
+
status: permReq.toolCall.status as
|
|
1332
|
+
| "pending"
|
|
1333
|
+
| "in_progress"
|
|
1334
|
+
| "completed"
|
|
1335
|
+
| "failed"
|
|
1336
|
+
| undefined,
|
|
1293
1337
|
rawInput: permReq.toolCall.rawInput,
|
|
1294
1338
|
},
|
|
1295
1339
|
options: permReq.options as Array<{
|
|
1296
|
-
kind:
|
|
1340
|
+
kind:
|
|
1341
|
+
| "allow_once"
|
|
1342
|
+
| "allow_always"
|
|
1343
|
+
| "reject_once"
|
|
1344
|
+
| "reject_always";
|
|
1297
1345
|
name: string;
|
|
1298
1346
|
optionId: string;
|
|
1299
1347
|
}>,
|
|
@@ -1308,21 +1356,21 @@ export class MacroAgent implements Agent {
|
|
|
1308
1356
|
const success = this.agentManager.respondToPermission(
|
|
1309
1357
|
agentId,
|
|
1310
1358
|
permReq.requestId,
|
|
1311
|
-
response.outcome.optionId
|
|
1359
|
+
response.outcome.optionId,
|
|
1312
1360
|
);
|
|
1313
1361
|
if (!success) {
|
|
1314
1362
|
console.warn(
|
|
1315
|
-
`[MacroAgent] Failed to forward permission response to agent ${agentId}
|
|
1363
|
+
`[MacroAgent] Failed to forward permission response to agent ${agentId}`,
|
|
1316
1364
|
);
|
|
1317
1365
|
}
|
|
1318
1366
|
} else if (response.outcome.outcome === "cancelled") {
|
|
1319
1367
|
const success = this.agentManager.cancelPermission(
|
|
1320
1368
|
agentId,
|
|
1321
|
-
permReq.requestId
|
|
1369
|
+
permReq.requestId,
|
|
1322
1370
|
);
|
|
1323
1371
|
if (!success) {
|
|
1324
1372
|
console.warn(
|
|
1325
|
-
`[MacroAgent] Failed to cancel permission for agent ${agentId}
|
|
1373
|
+
`[MacroAgent] Failed to cancel permission for agent ${agentId}`,
|
|
1326
1374
|
);
|
|
1327
1375
|
}
|
|
1328
1376
|
}
|
|
@@ -1330,7 +1378,7 @@ export class MacroAgent implements Agent {
|
|
|
1330
1378
|
} catch (err) {
|
|
1331
1379
|
console.error(
|
|
1332
1380
|
`[MacroAgent] Failed to forward permission_request:`,
|
|
1333
|
-
err instanceof Error ? err.message : err
|
|
1381
|
+
err instanceof Error ? err.message : err,
|
|
1334
1382
|
);
|
|
1335
1383
|
// Cancel the permission request on error
|
|
1336
1384
|
try {
|
|
@@ -1348,16 +1396,77 @@ export class MacroAgent implements Agent {
|
|
|
1348
1396
|
console.log(`[MacroAgent] Forwarding ${updateType}`);
|
|
1349
1397
|
}
|
|
1350
1398
|
|
|
1399
|
+
// Accumulate content for history persistence
|
|
1400
|
+
const buffer = this.promptBuffers.get(acpSessionId);
|
|
1401
|
+
if (buffer) {
|
|
1402
|
+
if (updateType === "agent_message_chunk") {
|
|
1403
|
+
const content = sessionUpdate.content as
|
|
1404
|
+
| { type?: string; text?: string }
|
|
1405
|
+
| undefined;
|
|
1406
|
+
if (content?.text) {
|
|
1407
|
+
buffer.textChunks.push(content.text);
|
|
1408
|
+
}
|
|
1409
|
+
} else if (
|
|
1410
|
+
updateType === "tool_call" ||
|
|
1411
|
+
updateType === "tool_call_update"
|
|
1412
|
+
) {
|
|
1413
|
+
const status = sessionUpdate.status as string | undefined;
|
|
1414
|
+
if (
|
|
1415
|
+
status === "completed" ||
|
|
1416
|
+
(updateType === "tool_call" && status !== "running")
|
|
1417
|
+
) {
|
|
1418
|
+
buffer.toolCalls.push({
|
|
1419
|
+
toolCallId: sessionUpdate.toolCallId,
|
|
1420
|
+
title: sessionUpdate.title,
|
|
1421
|
+
status: sessionUpdate.status,
|
|
1422
|
+
input: sessionUpdate.rawInput,
|
|
1423
|
+
output: sessionUpdate.output,
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1351
1429
|
// Forward updates via sessionUpdate (except permission_request which is handled above)
|
|
1352
1430
|
try {
|
|
1353
1431
|
await this.connection.sessionUpdate({
|
|
1354
1432
|
sessionId: acpSessionId,
|
|
1355
|
-
update: sessionUpdate as Parameters<
|
|
1433
|
+
update: sessionUpdate as Parameters<
|
|
1434
|
+
AgentSideConnection["sessionUpdate"]
|
|
1435
|
+
>[0]["update"],
|
|
1356
1436
|
});
|
|
1357
1437
|
} catch (err) {
|
|
1358
1438
|
console.error(
|
|
1359
1439
|
`[MacroAgent] Failed to forward ${updateType}:`,
|
|
1360
|
-
err instanceof Error ? err.message : err
|
|
1440
|
+
err instanceof Error ? err.message : err,
|
|
1441
|
+
);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/**
|
|
1446
|
+
* Emit a session_info_update with title and timestamps.
|
|
1447
|
+
* Uses agent task as title and session mapping timestamps.
|
|
1448
|
+
*/
|
|
1449
|
+
private async emitSessionInfo(acpSessionId: ACPSessionId): Promise<void> {
|
|
1450
|
+
const mapping = this.sessionMapper.getMapping(acpSessionId);
|
|
1451
|
+
const agentId = mapping?.agentId;
|
|
1452
|
+
const agent = agentId ? this.eventStore.getAgent(agentId) : null;
|
|
1453
|
+
|
|
1454
|
+
const title = agent?.task ?? null;
|
|
1455
|
+
const updatedAt = new Date(mapping?.updatedAt ?? Date.now()).toISOString();
|
|
1456
|
+
|
|
1457
|
+
try {
|
|
1458
|
+
await this.connection.sessionUpdate({
|
|
1459
|
+
sessionId: acpSessionId,
|
|
1460
|
+
update: {
|
|
1461
|
+
sessionUpdate: "session_info_update",
|
|
1462
|
+
title,
|
|
1463
|
+
updatedAt,
|
|
1464
|
+
} as Parameters<AgentSideConnection["sessionUpdate"]>[0]["update"],
|
|
1465
|
+
});
|
|
1466
|
+
} catch (err) {
|
|
1467
|
+
console.warn(
|
|
1468
|
+
`[MacroAgent] Failed to send session_info_update:`,
|
|
1469
|
+
err instanceof Error ? err.message : err,
|
|
1361
1470
|
);
|
|
1362
1471
|
}
|
|
1363
1472
|
}
|
|
@@ -1391,7 +1500,7 @@ export class MacroAgent implements Agent {
|
|
|
1391
1500
|
*/
|
|
1392
1501
|
private mergeSubAgentConfig(
|
|
1393
1502
|
defaults?: SubAgentConfig,
|
|
1394
|
-
override?: SubAgentConfig
|
|
1503
|
+
override?: SubAgentConfig,
|
|
1395
1504
|
): SubAgentConfig | undefined {
|
|
1396
1505
|
if (!defaults && !override) {
|
|
1397
1506
|
return undefined;
|
|
@@ -1448,6 +1557,141 @@ export class MacroAgent implements Agent {
|
|
|
1448
1557
|
};
|
|
1449
1558
|
}
|
|
1450
1559
|
|
|
1560
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1561
|
+
// History Persistence Helpers
|
|
1562
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* Ensure a conversation exists in the EventStore for a session.
|
|
1566
|
+
* Uses the ACP session ID as the conversation ID for direct lookup.
|
|
1567
|
+
*/
|
|
1568
|
+
private ensureConversation(
|
|
1569
|
+
acpSessionId: ACPSessionId,
|
|
1570
|
+
agentId: AgentId,
|
|
1571
|
+
): void {
|
|
1572
|
+
// Guard: EventStore may not support conversations (e.g., in tests with mocks)
|
|
1573
|
+
if (typeof this.eventStore.getConversation !== "function") return;
|
|
1574
|
+
|
|
1575
|
+
// Check if conversation already exists
|
|
1576
|
+
const existing = this.eventStore.getConversation(acpSessionId);
|
|
1577
|
+
if (existing) return;
|
|
1578
|
+
|
|
1579
|
+
try {
|
|
1580
|
+
this.eventStore.emit({
|
|
1581
|
+
type: "conversation",
|
|
1582
|
+
source: { agent_id: agentId },
|
|
1583
|
+
payload: {
|
|
1584
|
+
action: "created",
|
|
1585
|
+
conversation_id: acpSessionId,
|
|
1586
|
+
conversation_type: "session",
|
|
1587
|
+
subject: `ACP session ${acpSessionId}`,
|
|
1588
|
+
},
|
|
1589
|
+
});
|
|
1590
|
+
} catch (error) {
|
|
1591
|
+
console.warn(
|
|
1592
|
+
`[MacroAgent] Failed to create conversation for session ${acpSessionId}:`,
|
|
1593
|
+
error instanceof Error ? error.message : String(error),
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
/**
|
|
1599
|
+
* Record user and assistant turns after a prompt completes.
|
|
1600
|
+
*/
|
|
1601
|
+
private recordPromptTurns(
|
|
1602
|
+
acpSessionId: ACPSessionId,
|
|
1603
|
+
agentId: AgentId,
|
|
1604
|
+
userMessage: string,
|
|
1605
|
+
): void {
|
|
1606
|
+
const buffer = this.promptBuffers.get(acpSessionId);
|
|
1607
|
+
if (!buffer) return;
|
|
1608
|
+
|
|
1609
|
+
const now = Date.now();
|
|
1610
|
+
|
|
1611
|
+
try {
|
|
1612
|
+
// Record user turn
|
|
1613
|
+
if (userMessage) {
|
|
1614
|
+
this.eventStore.emit({
|
|
1615
|
+
type: "turn",
|
|
1616
|
+
source: { agent_id: agentId },
|
|
1617
|
+
payload: {
|
|
1618
|
+
action: "recorded",
|
|
1619
|
+
turn_id: `turn_user_${now}_${Math.random().toString(36).slice(2, 8)}`,
|
|
1620
|
+
conversation_id: acpSessionId,
|
|
1621
|
+
participant: "user",
|
|
1622
|
+
timestamp: now,
|
|
1623
|
+
content_type: "user_prompt",
|
|
1624
|
+
content: userMessage,
|
|
1625
|
+
source_type: "explicit",
|
|
1626
|
+
},
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// Record assistant turn with accumulated content
|
|
1631
|
+
const assistantText = buffer.textChunks.join("");
|
|
1632
|
+
const parts: unknown[] = [];
|
|
1633
|
+
|
|
1634
|
+
if (assistantText) {
|
|
1635
|
+
parts.push({ type: "text", text: assistantText });
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
for (const tool of buffer.toolCalls) {
|
|
1639
|
+
parts.push({ type: "tool", ...tool });
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
if (parts.length > 0) {
|
|
1643
|
+
this.eventStore.emit({
|
|
1644
|
+
type: "turn",
|
|
1645
|
+
source: { agent_id: agentId },
|
|
1646
|
+
payload: {
|
|
1647
|
+
action: "recorded",
|
|
1648
|
+
turn_id: `turn_asst_${now}_${Math.random().toString(36).slice(2, 8)}`,
|
|
1649
|
+
conversation_id: acpSessionId,
|
|
1650
|
+
participant: agentId,
|
|
1651
|
+
timestamp: now + 1, // +1ms to ensure ordering after user turn
|
|
1652
|
+
content_type: "assistant_response",
|
|
1653
|
+
content: { parts },
|
|
1654
|
+
source_type: "explicit",
|
|
1655
|
+
},
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
} catch (error) {
|
|
1659
|
+
console.warn(
|
|
1660
|
+
`[MacroAgent] Failed to record turns for session ${acpSessionId}:`,
|
|
1661
|
+
error instanceof Error ? error.message : String(error),
|
|
1662
|
+
);
|
|
1663
|
+
} finally {
|
|
1664
|
+
// Clean up the buffer
|
|
1665
|
+
this.promptBuffers.delete(acpSessionId);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
/**
|
|
1670
|
+
* Handle _macro/getHistory extension — returns conversation turns for a session
|
|
1671
|
+
*/
|
|
1672
|
+
private handleGetHistory(params: GetHistoryRequest): GetHistoryResponse {
|
|
1673
|
+
const { sessionId, limit } = params;
|
|
1674
|
+
|
|
1675
|
+
// Query turns from EventStore (conversation ID = session ID)
|
|
1676
|
+
const turns = this.eventStore.listTurns({
|
|
1677
|
+
conversationId: sessionId,
|
|
1678
|
+
order: "asc",
|
|
1679
|
+
limit: limit ?? 200,
|
|
1680
|
+
});
|
|
1681
|
+
|
|
1682
|
+
// Convert to HistoryTurn format
|
|
1683
|
+
const historyTurns: HistoryTurn[] = turns.map((turn) => ({
|
|
1684
|
+
role:
|
|
1685
|
+
turn.contentType === "user_prompt"
|
|
1686
|
+
? ("user" as const)
|
|
1687
|
+
: ("assistant" as const),
|
|
1688
|
+
timestamp: turn.timestamp,
|
|
1689
|
+
content: turn.content,
|
|
1690
|
+
}));
|
|
1691
|
+
|
|
1692
|
+
return { turns: historyTurns };
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1451
1695
|
// ─────────────────────────────────────────────────────────────────
|
|
1452
1696
|
// Accessors
|
|
1453
1697
|
// ─────────────────────────────────────────────────────────────────
|