fix(coding-agent): tracked acp tool args by session for replay

- Tracked ACP tool-call inputs per session and replayed them via `toolArgsById`/`getToolArgs` plumbing.
- Merged ACP tool execution end content from start and result events so command output replay preserves original args.
- Scoped ACP async-job draining by session `ownerId` and `agentId` with in-flight tracking and permission-gated deferred turns.
- Refactored compaction telemetry and async tests with per-test telemetry setup and asynchronous teardown resets.
This commit is contained in:
can1357
2026-05-17 13:15:07 +02:00
parent 189b9a6d35
commit bfae4d46c3
12 changed files with 573 additions and 111 deletions
@@ -732,6 +732,7 @@ export class AgentSession {
#planReferenceSent = false;
#planReferencePath = "local://PLAN.md";
#clientBridge: ClientBridge | undefined;
#allowAcpAgentInitiatedTurns = false;
/** Per-session memory of allow_always / reject_always decisions for gated tools. */
#acpPermissionDecisions: Map<string, "allow_always" | "reject_always"> = new Map();
@@ -2777,9 +2778,15 @@ export class AgentSession {
const ownerFilter = this.#agentId ? { ownerId: this.#agentId } : undefined;
const before = manager.getDeliveryState(ownerFilter);
if (before.queued === 0 && !before.delivering) return false;
const drained = await manager.drainDeliveries({ timeoutMs: options?.timeoutMs, filter: ownerFilter });
const after = manager.getDeliveryState(ownerFilter);
return drained && (before.queued !== after.queued || before.delivering !== after.delivering);
const previousAllowAcpAgentInitiatedTurns = this.#allowAcpAgentInitiatedTurns;
this.#allowAcpAgentInitiatedTurns = true;
try {
const drained = await manager.drainDeliveries({ timeoutMs: options?.timeoutMs, filter: ownerFilter });
const after = manager.getDeliveryState(ownerFilter);
return drained && (before.queued !== after.queued || before.delivering !== after.delivering);
} finally {
this.#allowAcpAgentInitiatedTurns = previousAllowAcpAgentInitiatedTurns;
}
}
/** Most recent assistant message in agent state. */
@@ -4419,7 +4426,7 @@ export class AgentSession {
if (options?.deliverAs === "nextTurn") {
if (options?.triggerTurn) {
if (this.#clientBridge?.deferAgentInitiatedTurns) {
if (this.#clientBridge?.deferAgentInitiatedTurns && !this.#allowAcpAgentInitiatedTurns) {
this.#queueHiddenNextTurnMessage(appMessage, false);
return;
}
@@ -4438,7 +4445,7 @@ export class AgentSession {
}
if (options?.triggerTurn) {
if (this.#clientBridge?.deferAgentInitiatedTurns) {
if (this.#clientBridge?.deferAgentInitiatedTurns && !this.#allowAcpAgentInitiatedTurns) {
this.#queueHiddenNextTurnMessage(appMessage, false);
return;
}