@autohq/cli 0.1.195 → 0.1.197
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/dist/agent-bridge.js +127 -3
- package/dist/index.js +127 -3
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -26640,7 +26640,7 @@ Object.assign(lookup, {
|
|
|
26640
26640
|
// package.json
|
|
26641
26641
|
var package_default = {
|
|
26642
26642
|
name: "@autohq/cli",
|
|
26643
|
-
version: "0.1.
|
|
26643
|
+
version: "0.1.197",
|
|
26644
26644
|
license: "SEE LICENSE IN README.md",
|
|
26645
26645
|
publishConfig: {
|
|
26646
26646
|
access: "public"
|
|
@@ -27109,13 +27109,14 @@ var ClaudeCodeProjector = class {
|
|
|
27109
27109
|
}
|
|
27110
27110
|
};
|
|
27111
27111
|
function projectClaudeCodeResult(result) {
|
|
27112
|
+
const failedButRecoverable = isRecoverableToolUseDiagnostic(result);
|
|
27112
27113
|
return {
|
|
27113
27114
|
type: "entry",
|
|
27114
27115
|
entry: {
|
|
27115
27116
|
role: "system",
|
|
27116
27117
|
kind: "status",
|
|
27117
27118
|
status: result.isError ? "failed" : "completed",
|
|
27118
|
-
sessionStatusAfter: result.isError ? "failed" : "awaiting",
|
|
27119
|
+
sessionStatusAfter: result.isError && !failedButRecoverable ? "failed" : "awaiting",
|
|
27119
27120
|
content: {
|
|
27120
27121
|
parts: [
|
|
27121
27122
|
{
|
|
@@ -27127,6 +27128,13 @@ function projectClaudeCodeResult(result) {
|
|
|
27127
27128
|
}
|
|
27128
27129
|
};
|
|
27129
27130
|
}
|
|
27131
|
+
function isRecoverableToolUseDiagnostic(result) {
|
|
27132
|
+
if (!result.isError) {
|
|
27133
|
+
return false;
|
|
27134
|
+
}
|
|
27135
|
+
const message = result.errorMessage ?? "";
|
|
27136
|
+
return message.startsWith("[ede_diagnostic]") && message.includes("stop_reason=tool_use");
|
|
27137
|
+
}
|
|
27130
27138
|
function anthropicMessageIdFromStreamStart(message) {
|
|
27131
27139
|
const event = message.event;
|
|
27132
27140
|
if (event.type !== "message_start") {
|
|
@@ -46955,6 +46963,7 @@ function withClaudeStderrDiagnosticsPointer(error51, capturedStderr) {
|
|
|
46955
46963
|
|
|
46956
46964
|
// src/commands/agent-bridge/harness/claude-code/session.ts
|
|
46957
46965
|
var CLAUDE_AGENT_STARTUP_TIMEOUT_MS = 3e4;
|
|
46966
|
+
var CLAUDE_INTERRUPT_SETTLE_TIMEOUT_MS = 1e4;
|
|
46958
46967
|
var CLAUDE_STARTUP_PROFILE_HOOK_EVENTS = [
|
|
46959
46968
|
"Setup",
|
|
46960
46969
|
"SessionStart",
|
|
@@ -46991,6 +47000,17 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
46991
47000
|
// held here instead of injected mid-turn (which would reject a pending
|
|
46992
47001
|
// tool_use) and flushed once the turn ends and the session is idle.
|
|
46993
47002
|
deferredMessages = [];
|
|
47003
|
+
// tool_use ids the assistant has emitted whose tool_result has not yet been
|
|
47004
|
+
// observed. A non-empty set means a tool call is in flight, so an immediate
|
|
47005
|
+
// interrupt would append the new user message after an unresolved
|
|
47006
|
+
// stop_reason=tool_use — the invalid transcript that trips Claude Code's
|
|
47007
|
+
// ede_diagnostic and auto-restarts the session (FRA-3049).
|
|
47008
|
+
pendingToolUseIds = /* @__PURE__ */ new Set();
|
|
47009
|
+
// Incremented on every turn-terminal `result`. An interrupt that aborts an
|
|
47010
|
+
// in-flight tool call waits for this to advance before injecting, so the
|
|
47011
|
+
// message lands only once the interrupted turn has settled its tool_use.
|
|
47012
|
+
turnResultCount = 0;
|
|
47013
|
+
turnSettlementWaiters = /* @__PURE__ */ new Set();
|
|
46994
47014
|
constructor(input) {
|
|
46995
47015
|
const optionsStartedAt = Date.now();
|
|
46996
47016
|
this.input = input;
|
|
@@ -47052,6 +47072,8 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47052
47072
|
}
|
|
47053
47073
|
this.state = { kind: "closed" };
|
|
47054
47074
|
this.activeTurnCount = 0;
|
|
47075
|
+
this.pendingToolUseIds.clear();
|
|
47076
|
+
this.resolveTurnSettlement(false);
|
|
47055
47077
|
if (this.deferredMessages.length > 0) {
|
|
47056
47078
|
this.input.writeOutput?.(
|
|
47057
47079
|
`agent_bridge_claude_deferred_dropped count=${this.deferredMessages.length} reason=session_closed`
|
|
@@ -47140,8 +47162,12 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47140
47162
|
void (async () => {
|
|
47141
47163
|
try {
|
|
47142
47164
|
for await (const message of query) {
|
|
47165
|
+
this.trackToolUseLifecycle(message);
|
|
47143
47166
|
if (isClaudeAgentTurnResult(message)) {
|
|
47144
47167
|
this.activeTurnCount = Math.max(0, this.activeTurnCount - 1);
|
|
47168
|
+
this.pendingToolUseIds.clear();
|
|
47169
|
+
this.turnResultCount += 1;
|
|
47170
|
+
this.resolveTurnSettlement(true);
|
|
47145
47171
|
if (this.activeTurnCount === 0) {
|
|
47146
47172
|
this.flushDeferredMessages();
|
|
47147
47173
|
}
|
|
@@ -47168,6 +47194,8 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47168
47194
|
}
|
|
47169
47195
|
} finally {
|
|
47170
47196
|
this.activeTurnCount = 0;
|
|
47197
|
+
this.pendingToolUseIds.clear();
|
|
47198
|
+
this.resolveTurnSettlement(false);
|
|
47171
47199
|
this.state = { kind: "closed" };
|
|
47172
47200
|
this.reportExit();
|
|
47173
47201
|
}
|
|
@@ -47189,6 +47217,65 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47189
47217
|
hasInterruptibleTurn() {
|
|
47190
47218
|
return this.activeTurnCount > 0 && this.state.kind === "running";
|
|
47191
47219
|
}
|
|
47220
|
+
// True while the assistant has an emitted tool_use with no matching
|
|
47221
|
+
// tool_result yet — the window where an immediate interrupt would strand an
|
|
47222
|
+
// unresolved stop_reason=tool_use ahead of the injected user message.
|
|
47223
|
+
hasInFlightToolUse() {
|
|
47224
|
+
return this.pendingToolUseIds.size > 0;
|
|
47225
|
+
}
|
|
47226
|
+
// Track tool_use/tool_result pairs as they stream so hasInFlightToolUse()
|
|
47227
|
+
// reflects the live transcript. A tool_use may appear first as a streaming
|
|
47228
|
+
// content block before the full assistant message is available; the matching
|
|
47229
|
+
// tool_result closes it; the turn's terminal result clears any remainder.
|
|
47230
|
+
trackToolUseLifecycle(message) {
|
|
47231
|
+
for (const id of toolUseIds(message)) {
|
|
47232
|
+
this.pendingToolUseIds.add(id);
|
|
47233
|
+
}
|
|
47234
|
+
for (const id of toolResultIds(message)) {
|
|
47235
|
+
this.pendingToolUseIds.delete(id);
|
|
47236
|
+
}
|
|
47237
|
+
}
|
|
47238
|
+
// Resolve once the interrupted turn emits its terminal `result` (turnResultCount
|
|
47239
|
+
// advances past the pre-interrupt baseline), bounded so a tool that never
|
|
47240
|
+
// returns after interrupt cannot wedge delivery. On timeout the caller falls
|
|
47241
|
+
// back to immediate injection rather than hanging or dropping the message.
|
|
47242
|
+
awaitTurnSettlement(baseline, startedAt) {
|
|
47243
|
+
if (this.turnResultCount > baseline) {
|
|
47244
|
+
return Promise.resolve();
|
|
47245
|
+
}
|
|
47246
|
+
return new Promise((resolve) => {
|
|
47247
|
+
let done = false;
|
|
47248
|
+
const finish = (outcome) => {
|
|
47249
|
+
if (done) {
|
|
47250
|
+
return;
|
|
47251
|
+
}
|
|
47252
|
+
done = true;
|
|
47253
|
+
clearTimeout(timer);
|
|
47254
|
+
this.turnSettlementWaiters.delete(waiter);
|
|
47255
|
+
this.input.writeOutput?.(
|
|
47256
|
+
`agent_bridge_claude_interrupt_settle_${outcome} duration_ms=${Date.now() - startedAt}`
|
|
47257
|
+
);
|
|
47258
|
+
resolve();
|
|
47259
|
+
};
|
|
47260
|
+
const waiter = (settled) => finish(settled ? "ready" : "aborted");
|
|
47261
|
+
const timer = setTimeout(
|
|
47262
|
+
() => finish("timeout"),
|
|
47263
|
+
CLAUDE_INTERRUPT_SETTLE_TIMEOUT_MS
|
|
47264
|
+
);
|
|
47265
|
+
timer.unref?.();
|
|
47266
|
+
this.turnSettlementWaiters.add(waiter);
|
|
47267
|
+
});
|
|
47268
|
+
}
|
|
47269
|
+
resolveTurnSettlement(settled) {
|
|
47270
|
+
if (this.turnSettlementWaiters.size === 0) {
|
|
47271
|
+
return;
|
|
47272
|
+
}
|
|
47273
|
+
const waiters = [...this.turnSettlementWaiters];
|
|
47274
|
+
this.turnSettlementWaiters.clear();
|
|
47275
|
+
for (const waiter of waiters) {
|
|
47276
|
+
waiter(settled);
|
|
47277
|
+
}
|
|
47278
|
+
}
|
|
47192
47279
|
flushDeferredMessages() {
|
|
47193
47280
|
if (this.deferredMessages.length === 0) {
|
|
47194
47281
|
return;
|
|
@@ -47213,9 +47300,11 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47213
47300
|
return;
|
|
47214
47301
|
}
|
|
47215
47302
|
const query = this.state.query;
|
|
47303
|
+
const hadInFlightToolUse = this.hasInFlightToolUse();
|
|
47304
|
+
const settlementBaseline = this.turnResultCount;
|
|
47216
47305
|
const startedAt = Date.now();
|
|
47217
47306
|
this.input.writeOutput?.(
|
|
47218
|
-
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()}`
|
|
47307
|
+
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()} in_flight_tool_use=${hadInFlightToolUse}`
|
|
47219
47308
|
);
|
|
47220
47309
|
const interruptPromise = (async () => {
|
|
47221
47310
|
try {
|
|
@@ -47228,6 +47317,9 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
47228
47317
|
`agent_bridge_claude_mid_turn_interrupt_failed duration_ms=${Date.now() - startedAt} error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
47229
47318
|
);
|
|
47230
47319
|
}
|
|
47320
|
+
if (hadInFlightToolUse) {
|
|
47321
|
+
await this.awaitTurnSettlement(settlementBaseline, startedAt);
|
|
47322
|
+
}
|
|
47231
47323
|
})();
|
|
47232
47324
|
this.interruptInFlight = interruptPromise;
|
|
47233
47325
|
try {
|
|
@@ -47385,6 +47477,38 @@ function claudeAgentUserMessage(message) {
|
|
|
47385
47477
|
function isClaudeAgentTurnResult(message) {
|
|
47386
47478
|
return message.type === "result";
|
|
47387
47479
|
}
|
|
47480
|
+
function toolUseIds(message) {
|
|
47481
|
+
if (message.type === "assistant") {
|
|
47482
|
+
return contentBlocks(message.message.content).flatMap(
|
|
47483
|
+
(block2) => block2.type === "tool_use" && typeof block2.id === "string" ? [block2.id] : []
|
|
47484
|
+
);
|
|
47485
|
+
}
|
|
47486
|
+
if (message.type !== "stream_event") {
|
|
47487
|
+
return [];
|
|
47488
|
+
}
|
|
47489
|
+
const event = message.event;
|
|
47490
|
+
if (event.type !== "content_block_start") {
|
|
47491
|
+
return [];
|
|
47492
|
+
}
|
|
47493
|
+
const block = event.content_block;
|
|
47494
|
+
return block.type === "tool_use" && typeof block.id === "string" ? [block.id] : [];
|
|
47495
|
+
}
|
|
47496
|
+
function toolResultIds(message) {
|
|
47497
|
+
if (message.type !== "user") {
|
|
47498
|
+
return [];
|
|
47499
|
+
}
|
|
47500
|
+
return contentBlocks(message.message.content).flatMap(
|
|
47501
|
+
(block) => block.type === "tool_result" && typeof block.tool_use_id === "string" ? [block.tool_use_id] : []
|
|
47502
|
+
);
|
|
47503
|
+
}
|
|
47504
|
+
function contentBlocks(content) {
|
|
47505
|
+
if (!Array.isArray(content)) {
|
|
47506
|
+
return [];
|
|
47507
|
+
}
|
|
47508
|
+
return content.filter(
|
|
47509
|
+
(block) => typeof block === "object" && block !== null
|
|
47510
|
+
);
|
|
47511
|
+
}
|
|
47388
47512
|
|
|
47389
47513
|
// src/commands/agent-bridge/harness/claude-code/index.ts
|
|
47390
47514
|
async function runAgentBridgeClaudeCode(options) {
|
package/dist/index.js
CHANGED
|
@@ -21623,7 +21623,7 @@ var init_package = __esm({
|
|
|
21623
21623
|
"package.json"() {
|
|
21624
21624
|
package_default = {
|
|
21625
21625
|
name: "@autohq/cli",
|
|
21626
|
-
version: "0.1.
|
|
21626
|
+
version: "0.1.197",
|
|
21627
21627
|
license: "SEE LICENSE IN README.md",
|
|
21628
21628
|
publishConfig: {
|
|
21629
21629
|
access: "public"
|
|
@@ -31701,13 +31701,14 @@ var ClaudeCodeProjector = class {
|
|
|
31701
31701
|
}
|
|
31702
31702
|
};
|
|
31703
31703
|
function projectClaudeCodeResult(result) {
|
|
31704
|
+
const failedButRecoverable = isRecoverableToolUseDiagnostic(result);
|
|
31704
31705
|
return {
|
|
31705
31706
|
type: "entry",
|
|
31706
31707
|
entry: {
|
|
31707
31708
|
role: "system",
|
|
31708
31709
|
kind: "status",
|
|
31709
31710
|
status: result.isError ? "failed" : "completed",
|
|
31710
|
-
sessionStatusAfter: result.isError ? "failed" : "awaiting",
|
|
31711
|
+
sessionStatusAfter: result.isError && !failedButRecoverable ? "failed" : "awaiting",
|
|
31711
31712
|
content: {
|
|
31712
31713
|
parts: [
|
|
31713
31714
|
{
|
|
@@ -31719,6 +31720,13 @@ function projectClaudeCodeResult(result) {
|
|
|
31719
31720
|
}
|
|
31720
31721
|
};
|
|
31721
31722
|
}
|
|
31723
|
+
function isRecoverableToolUseDiagnostic(result) {
|
|
31724
|
+
if (!result.isError) {
|
|
31725
|
+
return false;
|
|
31726
|
+
}
|
|
31727
|
+
const message = result.errorMessage ?? "";
|
|
31728
|
+
return message.startsWith("[ede_diagnostic]") && message.includes("stop_reason=tool_use");
|
|
31729
|
+
}
|
|
31722
31730
|
function anthropicMessageIdFromStreamStart(message) {
|
|
31723
31731
|
const event = message.event;
|
|
31724
31732
|
if (event.type !== "message_start") {
|
|
@@ -31975,6 +31983,7 @@ function withClaudeStderrDiagnosticsPointer(error51, capturedStderr) {
|
|
|
31975
31983
|
|
|
31976
31984
|
// src/commands/agent-bridge/harness/claude-code/session.ts
|
|
31977
31985
|
var CLAUDE_AGENT_STARTUP_TIMEOUT_MS = 3e4;
|
|
31986
|
+
var CLAUDE_INTERRUPT_SETTLE_TIMEOUT_MS = 1e4;
|
|
31978
31987
|
var CLAUDE_STARTUP_PROFILE_HOOK_EVENTS = [
|
|
31979
31988
|
"Setup",
|
|
31980
31989
|
"SessionStart",
|
|
@@ -32011,6 +32020,17 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32011
32020
|
// held here instead of injected mid-turn (which would reject a pending
|
|
32012
32021
|
// tool_use) and flushed once the turn ends and the session is idle.
|
|
32013
32022
|
deferredMessages = [];
|
|
32023
|
+
// tool_use ids the assistant has emitted whose tool_result has not yet been
|
|
32024
|
+
// observed. A non-empty set means a tool call is in flight, so an immediate
|
|
32025
|
+
// interrupt would append the new user message after an unresolved
|
|
32026
|
+
// stop_reason=tool_use — the invalid transcript that trips Claude Code's
|
|
32027
|
+
// ede_diagnostic and auto-restarts the session (FRA-3049).
|
|
32028
|
+
pendingToolUseIds = /* @__PURE__ */ new Set();
|
|
32029
|
+
// Incremented on every turn-terminal `result`. An interrupt that aborts an
|
|
32030
|
+
// in-flight tool call waits for this to advance before injecting, so the
|
|
32031
|
+
// message lands only once the interrupted turn has settled its tool_use.
|
|
32032
|
+
turnResultCount = 0;
|
|
32033
|
+
turnSettlementWaiters = /* @__PURE__ */ new Set();
|
|
32014
32034
|
constructor(input) {
|
|
32015
32035
|
const optionsStartedAt = Date.now();
|
|
32016
32036
|
this.input = input;
|
|
@@ -32072,6 +32092,8 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32072
32092
|
}
|
|
32073
32093
|
this.state = { kind: "closed" };
|
|
32074
32094
|
this.activeTurnCount = 0;
|
|
32095
|
+
this.pendingToolUseIds.clear();
|
|
32096
|
+
this.resolveTurnSettlement(false);
|
|
32075
32097
|
if (this.deferredMessages.length > 0) {
|
|
32076
32098
|
this.input.writeOutput?.(
|
|
32077
32099
|
`agent_bridge_claude_deferred_dropped count=${this.deferredMessages.length} reason=session_closed`
|
|
@@ -32160,8 +32182,12 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32160
32182
|
void (async () => {
|
|
32161
32183
|
try {
|
|
32162
32184
|
for await (const message of query) {
|
|
32185
|
+
this.trackToolUseLifecycle(message);
|
|
32163
32186
|
if (isClaudeAgentTurnResult(message)) {
|
|
32164
32187
|
this.activeTurnCount = Math.max(0, this.activeTurnCount - 1);
|
|
32188
|
+
this.pendingToolUseIds.clear();
|
|
32189
|
+
this.turnResultCount += 1;
|
|
32190
|
+
this.resolveTurnSettlement(true);
|
|
32165
32191
|
if (this.activeTurnCount === 0) {
|
|
32166
32192
|
this.flushDeferredMessages();
|
|
32167
32193
|
}
|
|
@@ -32188,6 +32214,8 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32188
32214
|
}
|
|
32189
32215
|
} finally {
|
|
32190
32216
|
this.activeTurnCount = 0;
|
|
32217
|
+
this.pendingToolUseIds.clear();
|
|
32218
|
+
this.resolveTurnSettlement(false);
|
|
32191
32219
|
this.state = { kind: "closed" };
|
|
32192
32220
|
this.reportExit();
|
|
32193
32221
|
}
|
|
@@ -32209,6 +32237,65 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32209
32237
|
hasInterruptibleTurn() {
|
|
32210
32238
|
return this.activeTurnCount > 0 && this.state.kind === "running";
|
|
32211
32239
|
}
|
|
32240
|
+
// True while the assistant has an emitted tool_use with no matching
|
|
32241
|
+
// tool_result yet — the window where an immediate interrupt would strand an
|
|
32242
|
+
// unresolved stop_reason=tool_use ahead of the injected user message.
|
|
32243
|
+
hasInFlightToolUse() {
|
|
32244
|
+
return this.pendingToolUseIds.size > 0;
|
|
32245
|
+
}
|
|
32246
|
+
// Track tool_use/tool_result pairs as they stream so hasInFlightToolUse()
|
|
32247
|
+
// reflects the live transcript. A tool_use may appear first as a streaming
|
|
32248
|
+
// content block before the full assistant message is available; the matching
|
|
32249
|
+
// tool_result closes it; the turn's terminal result clears any remainder.
|
|
32250
|
+
trackToolUseLifecycle(message) {
|
|
32251
|
+
for (const id of toolUseIds(message)) {
|
|
32252
|
+
this.pendingToolUseIds.add(id);
|
|
32253
|
+
}
|
|
32254
|
+
for (const id of toolResultIds(message)) {
|
|
32255
|
+
this.pendingToolUseIds.delete(id);
|
|
32256
|
+
}
|
|
32257
|
+
}
|
|
32258
|
+
// Resolve once the interrupted turn emits its terminal `result` (turnResultCount
|
|
32259
|
+
// advances past the pre-interrupt baseline), bounded so a tool that never
|
|
32260
|
+
// returns after interrupt cannot wedge delivery. On timeout the caller falls
|
|
32261
|
+
// back to immediate injection rather than hanging or dropping the message.
|
|
32262
|
+
awaitTurnSettlement(baseline, startedAt) {
|
|
32263
|
+
if (this.turnResultCount > baseline) {
|
|
32264
|
+
return Promise.resolve();
|
|
32265
|
+
}
|
|
32266
|
+
return new Promise((resolve4) => {
|
|
32267
|
+
let done = false;
|
|
32268
|
+
const finish = (outcome) => {
|
|
32269
|
+
if (done) {
|
|
32270
|
+
return;
|
|
32271
|
+
}
|
|
32272
|
+
done = true;
|
|
32273
|
+
clearTimeout(timer);
|
|
32274
|
+
this.turnSettlementWaiters.delete(waiter);
|
|
32275
|
+
this.input.writeOutput?.(
|
|
32276
|
+
`agent_bridge_claude_interrupt_settle_${outcome} duration_ms=${Date.now() - startedAt}`
|
|
32277
|
+
);
|
|
32278
|
+
resolve4();
|
|
32279
|
+
};
|
|
32280
|
+
const waiter = (settled) => finish(settled ? "ready" : "aborted");
|
|
32281
|
+
const timer = setTimeout(
|
|
32282
|
+
() => finish("timeout"),
|
|
32283
|
+
CLAUDE_INTERRUPT_SETTLE_TIMEOUT_MS
|
|
32284
|
+
);
|
|
32285
|
+
timer.unref?.();
|
|
32286
|
+
this.turnSettlementWaiters.add(waiter);
|
|
32287
|
+
});
|
|
32288
|
+
}
|
|
32289
|
+
resolveTurnSettlement(settled) {
|
|
32290
|
+
if (this.turnSettlementWaiters.size === 0) {
|
|
32291
|
+
return;
|
|
32292
|
+
}
|
|
32293
|
+
const waiters = [...this.turnSettlementWaiters];
|
|
32294
|
+
this.turnSettlementWaiters.clear();
|
|
32295
|
+
for (const waiter of waiters) {
|
|
32296
|
+
waiter(settled);
|
|
32297
|
+
}
|
|
32298
|
+
}
|
|
32212
32299
|
flushDeferredMessages() {
|
|
32213
32300
|
if (this.deferredMessages.length === 0) {
|
|
32214
32301
|
return;
|
|
@@ -32233,9 +32320,11 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32233
32320
|
return;
|
|
32234
32321
|
}
|
|
32235
32322
|
const query = this.state.query;
|
|
32323
|
+
const hadInFlightToolUse = this.hasInFlightToolUse();
|
|
32324
|
+
const settlementBaseline = this.turnResultCount;
|
|
32236
32325
|
const startedAt = Date.now();
|
|
32237
32326
|
this.input.writeOutput?.(
|
|
32238
|
-
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()}`
|
|
32327
|
+
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()} in_flight_tool_use=${hadInFlightToolUse}`
|
|
32239
32328
|
);
|
|
32240
32329
|
const interruptPromise = (async () => {
|
|
32241
32330
|
try {
|
|
@@ -32248,6 +32337,9 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
32248
32337
|
`agent_bridge_claude_mid_turn_interrupt_failed duration_ms=${Date.now() - startedAt} error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
32249
32338
|
);
|
|
32250
32339
|
}
|
|
32340
|
+
if (hadInFlightToolUse) {
|
|
32341
|
+
await this.awaitTurnSettlement(settlementBaseline, startedAt);
|
|
32342
|
+
}
|
|
32251
32343
|
})();
|
|
32252
32344
|
this.interruptInFlight = interruptPromise;
|
|
32253
32345
|
try {
|
|
@@ -32405,6 +32497,38 @@ function claudeAgentUserMessage(message) {
|
|
|
32405
32497
|
function isClaudeAgentTurnResult(message) {
|
|
32406
32498
|
return message.type === "result";
|
|
32407
32499
|
}
|
|
32500
|
+
function toolUseIds(message) {
|
|
32501
|
+
if (message.type === "assistant") {
|
|
32502
|
+
return contentBlocks(message.message.content).flatMap(
|
|
32503
|
+
(block2) => block2.type === "tool_use" && typeof block2.id === "string" ? [block2.id] : []
|
|
32504
|
+
);
|
|
32505
|
+
}
|
|
32506
|
+
if (message.type !== "stream_event") {
|
|
32507
|
+
return [];
|
|
32508
|
+
}
|
|
32509
|
+
const event = message.event;
|
|
32510
|
+
if (event.type !== "content_block_start") {
|
|
32511
|
+
return [];
|
|
32512
|
+
}
|
|
32513
|
+
const block = event.content_block;
|
|
32514
|
+
return block.type === "tool_use" && typeof block.id === "string" ? [block.id] : [];
|
|
32515
|
+
}
|
|
32516
|
+
function toolResultIds(message) {
|
|
32517
|
+
if (message.type !== "user") {
|
|
32518
|
+
return [];
|
|
32519
|
+
}
|
|
32520
|
+
return contentBlocks(message.message.content).flatMap(
|
|
32521
|
+
(block) => block.type === "tool_result" && typeof block.tool_use_id === "string" ? [block.tool_use_id] : []
|
|
32522
|
+
);
|
|
32523
|
+
}
|
|
32524
|
+
function contentBlocks(content) {
|
|
32525
|
+
if (!Array.isArray(content)) {
|
|
32526
|
+
return [];
|
|
32527
|
+
}
|
|
32528
|
+
return content.filter(
|
|
32529
|
+
(block) => typeof block === "object" && block !== null
|
|
32530
|
+
);
|
|
32531
|
+
}
|
|
32408
32532
|
|
|
32409
32533
|
// src/commands/agent-bridge/harness/claude-code/index.ts
|
|
32410
32534
|
async function runAgentBridgeClaudeCode(options) {
|