@autohq/cli 0.1.449 → 0.1.451
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 +382 -163
- package/dist/index.js +383 -163
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -30825,7 +30825,7 @@ Object.assign(lookup, {
|
|
|
30825
30825
|
// package.json
|
|
30826
30826
|
var package_default = {
|
|
30827
30827
|
name: "@autohq/cli",
|
|
30828
|
-
version: "0.1.
|
|
30828
|
+
version: "0.1.451",
|
|
30829
30829
|
license: "SEE LICENSE IN README.md",
|
|
30830
30830
|
publishConfig: {
|
|
30831
30831
|
access: "public"
|
|
@@ -70697,8 +70697,7 @@ var AgentBridgeOutputBuffer = class {
|
|
|
70697
70697
|
await this.emitUiMessagePartSnapshots(context, projection.chunk, {
|
|
70698
70698
|
coveredSeq: this.outputSeq
|
|
70699
70699
|
});
|
|
70700
|
-
const toolEntry
|
|
70701
|
-
if (toolEntry) {
|
|
70700
|
+
for (const toolEntry of legacyToolEntries(projection.chunk)) {
|
|
70702
70701
|
await this.enqueueProjectionAndDrain(context, {
|
|
70703
70702
|
type: "entry",
|
|
70704
70703
|
entry: toolEntry
|
|
@@ -71177,73 +71176,112 @@ var UiMessageAssembler = class {
|
|
|
71177
71176
|
function isTerminalUiMessageChunk(chunk) {
|
|
71178
71177
|
return chunk.type === "finish" || chunk.type === "error" || chunk.type === "abort";
|
|
71179
71178
|
}
|
|
71180
|
-
function
|
|
71179
|
+
function legacyToolEntries(chunk) {
|
|
71181
71180
|
switch (chunk.type) {
|
|
71182
71181
|
case "tool-input-available":
|
|
71183
71182
|
if (chunk.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
71184
|
-
return
|
|
71183
|
+
return [];
|
|
71185
71184
|
}
|
|
71186
|
-
return
|
|
71187
|
-
|
|
71188
|
-
|
|
71189
|
-
|
|
71190
|
-
|
|
71191
|
-
|
|
71192
|
-
|
|
71193
|
-
|
|
71194
|
-
|
|
71195
|
-
|
|
71196
|
-
|
|
71197
|
-
|
|
71185
|
+
return [
|
|
71186
|
+
{
|
|
71187
|
+
role: "assistant",
|
|
71188
|
+
kind: "tool_call",
|
|
71189
|
+
content: {
|
|
71190
|
+
parts: [
|
|
71191
|
+
{
|
|
71192
|
+
type: "tool_call",
|
|
71193
|
+
toolCallId: legacyToolCallId(chunk.toolCallId),
|
|
71194
|
+
name: chunk.toolName,
|
|
71195
|
+
input: toJsonValue(chunk.input)
|
|
71196
|
+
}
|
|
71197
|
+
]
|
|
71198
|
+
}
|
|
71198
71199
|
}
|
|
71199
|
-
|
|
71200
|
+
];
|
|
71201
|
+
case "tool-input-error":
|
|
71202
|
+
return [
|
|
71203
|
+
{
|
|
71204
|
+
role: "assistant",
|
|
71205
|
+
kind: "tool_call",
|
|
71206
|
+
content: {
|
|
71207
|
+
parts: [
|
|
71208
|
+
{
|
|
71209
|
+
type: "tool_call",
|
|
71210
|
+
toolCallId: legacyToolCallId(chunk.toolCallId),
|
|
71211
|
+
name: chunk.toolName,
|
|
71212
|
+
input: toJsonValue(chunk.input)
|
|
71213
|
+
}
|
|
71214
|
+
]
|
|
71215
|
+
}
|
|
71216
|
+
},
|
|
71217
|
+
{
|
|
71218
|
+
role: "tool",
|
|
71219
|
+
kind: "tool_result",
|
|
71220
|
+
content: {
|
|
71221
|
+
parts: [
|
|
71222
|
+
{
|
|
71223
|
+
type: "tool_result",
|
|
71224
|
+
toolUseId: legacyToolCallId(chunk.toolCallId),
|
|
71225
|
+
output: chunk.errorText,
|
|
71226
|
+
isError: true
|
|
71227
|
+
}
|
|
71228
|
+
]
|
|
71229
|
+
}
|
|
71230
|
+
}
|
|
71231
|
+
];
|
|
71200
71232
|
case "tool-output-available":
|
|
71201
|
-
return
|
|
71202
|
-
|
|
71203
|
-
|
|
71204
|
-
|
|
71205
|
-
|
|
71206
|
-
|
|
71207
|
-
|
|
71208
|
-
|
|
71209
|
-
|
|
71210
|
-
|
|
71211
|
-
|
|
71212
|
-
|
|
71233
|
+
return [
|
|
71234
|
+
{
|
|
71235
|
+
role: "tool",
|
|
71236
|
+
kind: "tool_result",
|
|
71237
|
+
content: {
|
|
71238
|
+
parts: [
|
|
71239
|
+
{
|
|
71240
|
+
type: "tool_result",
|
|
71241
|
+
toolUseId: legacyToolCallId(chunk.toolCallId),
|
|
71242
|
+
output: toJsonValue(chunk.output),
|
|
71243
|
+
isError: false
|
|
71244
|
+
}
|
|
71245
|
+
]
|
|
71246
|
+
}
|
|
71213
71247
|
}
|
|
71214
|
-
|
|
71248
|
+
];
|
|
71215
71249
|
case "tool-output-error":
|
|
71216
|
-
return
|
|
71217
|
-
|
|
71218
|
-
|
|
71219
|
-
|
|
71220
|
-
|
|
71221
|
-
|
|
71222
|
-
|
|
71223
|
-
|
|
71224
|
-
|
|
71225
|
-
|
|
71226
|
-
|
|
71227
|
-
|
|
71250
|
+
return [
|
|
71251
|
+
{
|
|
71252
|
+
role: "tool",
|
|
71253
|
+
kind: "tool_result",
|
|
71254
|
+
content: {
|
|
71255
|
+
parts: [
|
|
71256
|
+
{
|
|
71257
|
+
type: "tool_result",
|
|
71258
|
+
toolUseId: legacyToolCallId(chunk.toolCallId),
|
|
71259
|
+
output: errorOutput(chunk.errorText),
|
|
71260
|
+
isError: true
|
|
71261
|
+
}
|
|
71262
|
+
]
|
|
71263
|
+
}
|
|
71228
71264
|
}
|
|
71229
|
-
|
|
71265
|
+
];
|
|
71230
71266
|
case "tool-output-denied":
|
|
71231
|
-
return
|
|
71232
|
-
|
|
71233
|
-
|
|
71234
|
-
|
|
71235
|
-
|
|
71236
|
-
|
|
71237
|
-
|
|
71238
|
-
|
|
71239
|
-
|
|
71240
|
-
|
|
71241
|
-
|
|
71242
|
-
|
|
71267
|
+
return [
|
|
71268
|
+
{
|
|
71269
|
+
role: "tool",
|
|
71270
|
+
kind: "tool_result",
|
|
71271
|
+
content: {
|
|
71272
|
+
parts: [
|
|
71273
|
+
{
|
|
71274
|
+
type: "tool_result",
|
|
71275
|
+
toolUseId: legacyToolCallId(chunk.toolCallId),
|
|
71276
|
+
output: { denied: true },
|
|
71277
|
+
isError: true
|
|
71278
|
+
}
|
|
71279
|
+
]
|
|
71280
|
+
}
|
|
71243
71281
|
}
|
|
71244
|
-
|
|
71282
|
+
];
|
|
71245
71283
|
default:
|
|
71246
|
-
return
|
|
71284
|
+
return [];
|
|
71247
71285
|
}
|
|
71248
71286
|
}
|
|
71249
71287
|
function legacyToolCallId(toolCallId) {
|
|
@@ -71451,6 +71489,10 @@ function jsonRecordString2(value2, key) {
|
|
|
71451
71489
|
|
|
71452
71490
|
// src/commands/agent-bridge/harness/claude-code/projector.ts
|
|
71453
71491
|
var ClaudeCodeProjector = class {
|
|
71492
|
+
constructor(input = {}) {
|
|
71493
|
+
this.input = input;
|
|
71494
|
+
}
|
|
71495
|
+
input;
|
|
71454
71496
|
currentMessageId = null;
|
|
71455
71497
|
// The turn's UI message id. Claude emits a `message_start` per assistant
|
|
71456
71498
|
// message, but a tool-using turn spans several (message A with the tool call,
|
|
@@ -71469,13 +71511,17 @@ var ClaudeCodeProjector = class {
|
|
|
71469
71511
|
// real turn failure (FRA-3548). Cleared on every result and on the next
|
|
71470
71512
|
// message_start so a stale marker can never reclassify a later failure.
|
|
71471
71513
|
interruptMarkerSeen = false;
|
|
71472
|
-
project(message) {
|
|
71514
|
+
project(message, context = {}) {
|
|
71473
71515
|
if (isClaudeCodeInterruptMarker(message)) {
|
|
71474
71516
|
this.interruptMarkerSeen = true;
|
|
71475
71517
|
}
|
|
71476
71518
|
if (message.type === "stream_event") {
|
|
71477
71519
|
return this.projectStreamEvent(message);
|
|
71478
71520
|
}
|
|
71521
|
+
const interruptContext = {
|
|
71522
|
+
marker: this.interruptMarkerSeen,
|
|
71523
|
+
bridge: context.bridgeInterruptSettling === true
|
|
71524
|
+
};
|
|
71479
71525
|
const parsed = parseClaudeCodeStreamRecord(message);
|
|
71480
71526
|
const snapshotMessageId = assistantSnapshotMessageId(message);
|
|
71481
71527
|
const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
|
|
@@ -71487,18 +71533,28 @@ var ClaudeCodeProjector = class {
|
|
|
71487
71533
|
return [];
|
|
71488
71534
|
}
|
|
71489
71535
|
return conversationProjectionToUiChunks(entry, {
|
|
71490
|
-
|
|
71536
|
+
interruptContext,
|
|
71537
|
+
emitDiagnostic: this.input.writeOutput
|
|
71491
71538
|
});
|
|
71492
71539
|
});
|
|
71493
71540
|
if (parsed.result) {
|
|
71494
|
-
|
|
71495
|
-
|
|
71496
|
-
|
|
71541
|
+
const interrupted = this.isInterruptCancellation(
|
|
71542
|
+
parsed.result,
|
|
71543
|
+
interruptContext
|
|
71544
|
+
);
|
|
71545
|
+
const failActiveInputs = parsed.result.isError && !interrupted;
|
|
71497
71546
|
outputs.push(
|
|
71498
|
-
|
|
71499
|
-
|
|
71500
|
-
})
|
|
71547
|
+
...this.endActiveParts(),
|
|
71548
|
+
...failActiveInputs ? this.failActiveToolInputs() : this.finishActiveToolInputs()
|
|
71501
71549
|
);
|
|
71550
|
+
this.currentMessageId = null;
|
|
71551
|
+
this.activeResponseMessageId = null;
|
|
71552
|
+
if (interrupted) {
|
|
71553
|
+
this.input.writeOutput?.(
|
|
71554
|
+
`agent_bridge_claude_result_interrupt_cancellation gate=${interruptGate(interruptContext)}`
|
|
71555
|
+
);
|
|
71556
|
+
}
|
|
71557
|
+
outputs.push(projectClaudeCodeResult(parsed.result, { interrupted }));
|
|
71502
71558
|
this.interruptMarkerSeen = false;
|
|
71503
71559
|
}
|
|
71504
71560
|
return outputs;
|
|
@@ -71508,13 +71564,16 @@ var ClaudeCodeProjector = class {
|
|
|
71508
71564
|
// surfaces as a diagnostic-only `error_during_execution`. Treating that as a
|
|
71509
71565
|
// turn failure fed the FRA-3548 redelivery loop (the bridge redelivered a
|
|
71510
71566
|
// message the SDK was actively answering), so a failed result bracketed by
|
|
71511
|
-
// the SDK's own
|
|
71512
|
-
|
|
71513
|
-
|
|
71567
|
+
// interrupt context — the SDK's own marker, or the session's knowledge that
|
|
71568
|
+
// a bridge interrupt is settling (which covers a missing or late marker) —
|
|
71569
|
+
// is classified as a cancellation instead.
|
|
71570
|
+
isInterruptCancellation(result, context) {
|
|
71571
|
+
return result.isError && (context.marker || context.bridge) && isClaudeCodeEdeDiagnosticOnlyError(result.errorMessage);
|
|
71514
71572
|
}
|
|
71515
71573
|
flushPendingAssistantMessages() {
|
|
71516
71574
|
const outputs = [
|
|
71517
71575
|
...this.endActiveParts(),
|
|
71576
|
+
...this.failActiveToolInputs(),
|
|
71518
71577
|
uiChunk({ type: "finish", finishReason: "stop" })
|
|
71519
71578
|
];
|
|
71520
71579
|
this.currentMessageId = null;
|
|
@@ -71618,6 +71677,23 @@ var ClaudeCodeProjector = class {
|
|
|
71618
71677
|
(index) => this.finishActiveToolInput(index)
|
|
71619
71678
|
);
|
|
71620
71679
|
}
|
|
71680
|
+
// Settle every still-active tool input as an error part that preserves the
|
|
71681
|
+
// partial input text. Used when the turn ends in an error before the tool
|
|
71682
|
+
// block completed: the tool was never dispatched, and persisting whatever
|
|
71683
|
+
// input streamed keeps the transcript diagnosable.
|
|
71684
|
+
failActiveToolInputs() {
|
|
71685
|
+
const outputs = [...this.activeToolInputs.values()].map(
|
|
71686
|
+
(active) => uiChunk({
|
|
71687
|
+
type: "tool-input-error",
|
|
71688
|
+
toolCallId: active.toolCallId,
|
|
71689
|
+
toolName: active.toolName,
|
|
71690
|
+
input: partialToolInput(active),
|
|
71691
|
+
errorText: truncatedToolInputErrorText(active)
|
|
71692
|
+
})
|
|
71693
|
+
);
|
|
71694
|
+
this.activeToolInputs.clear();
|
|
71695
|
+
return outputs;
|
|
71696
|
+
}
|
|
71621
71697
|
// A never-streamed assistant snapshot (an SDK-internal stream retry can
|
|
71622
71698
|
// reissue the in-flight message under a fresh id, so suppression misses it;
|
|
71623
71699
|
// pure snapshot delivery has no stream at all). Its content must respect the
|
|
@@ -71631,7 +71707,8 @@ var ClaudeCodeProjector = class {
|
|
|
71631
71707
|
const messageChunks = this.assistantSnapshotMessageChunks(projections);
|
|
71632
71708
|
const rest = projections.filter((projection) => !isAssistantMessageOrToolCall(projection)).flatMap(
|
|
71633
71709
|
(projection) => conversationProjectionToUiChunks(projection, {
|
|
71634
|
-
|
|
71710
|
+
interruptContext: { marker: this.interruptMarkerSeen, bridge: false },
|
|
71711
|
+
emitDiagnostic: this.input.writeOutput
|
|
71635
71712
|
})
|
|
71636
71713
|
);
|
|
71637
71714
|
const last = messageChunks.at(-1);
|
|
@@ -71793,6 +71870,21 @@ function completeToolInput(input) {
|
|
|
71793
71870
|
}
|
|
71794
71871
|
return input.initialInput ?? {};
|
|
71795
71872
|
}
|
|
71873
|
+
function partialToolInput(input) {
|
|
71874
|
+
const inputText = input.inputText.trim();
|
|
71875
|
+
if (inputText.length === 0) {
|
|
71876
|
+
return input.initialInput ?? {};
|
|
71877
|
+
}
|
|
71878
|
+
try {
|
|
71879
|
+
return JSON.parse(inputText);
|
|
71880
|
+
} catch {
|
|
71881
|
+
return input.inputText;
|
|
71882
|
+
}
|
|
71883
|
+
}
|
|
71884
|
+
function truncatedToolInputErrorText(input) {
|
|
71885
|
+
const bytes = Buffer.byteLength(input.inputText, "utf8");
|
|
71886
|
+
return `Tool input streaming was interrupted before the call completed; the tool was never dispatched (${bytes.toString()} bytes of partial input preserved).`;
|
|
71887
|
+
}
|
|
71796
71888
|
function sourceChunkFromDelta(delta, index) {
|
|
71797
71889
|
if (delta.type !== "citations_delta") {
|
|
71798
71890
|
return null;
|
|
@@ -71855,7 +71947,7 @@ function textContentFromDelta(delta) {
|
|
|
71855
71947
|
return null;
|
|
71856
71948
|
}
|
|
71857
71949
|
}
|
|
71858
|
-
function conversationProjectionToUiChunks(projection, options
|
|
71950
|
+
function conversationProjectionToUiChunks(projection, options) {
|
|
71859
71951
|
if (projection.role === "assistant" && projection.kind === "message") {
|
|
71860
71952
|
return messageContentChunks(projection);
|
|
71861
71953
|
}
|
|
@@ -71876,15 +71968,12 @@ function conversationProjectionToUiChunks(projection, options = { interrupted: f
|
|
|
71876
71968
|
})
|
|
71877
71969
|
];
|
|
71878
71970
|
}
|
|
71879
|
-
const remapped = typeof part.output === "string" ? remapClaudeCodeInterruptToolResultErrorText(part.output, {
|
|
71880
|
-
interrupted: options.interrupted
|
|
71881
|
-
}) : null;
|
|
71882
71971
|
return [
|
|
71883
|
-
|
|
71884
|
-
|
|
71885
|
-
|
|
71886
|
-
|
|
71887
|
-
|
|
71972
|
+
toolResultErrorChunk(
|
|
71973
|
+
part.toolUseId ?? UNKNOWN_MESSAGE_ID,
|
|
71974
|
+
part.output,
|
|
71975
|
+
options
|
|
71976
|
+
)
|
|
71888
71977
|
];
|
|
71889
71978
|
});
|
|
71890
71979
|
}
|
|
@@ -71928,6 +72017,32 @@ function conversationProjectionToUiChunks(projection, options = { interrupted: f
|
|
|
71928
72017
|
}
|
|
71929
72018
|
];
|
|
71930
72019
|
}
|
|
72020
|
+
function toolResultErrorChunk(toolCallId, output, options) {
|
|
72021
|
+
const context = options.interruptContext;
|
|
72022
|
+
const remapped = typeof output === "string" ? remapClaudeCodeInterruptToolResultErrorText(output, {
|
|
72023
|
+
interrupted: context.marker || context.bridge
|
|
72024
|
+
}) : null;
|
|
72025
|
+
if (remapped !== null) {
|
|
72026
|
+
options.emitDiagnostic?.(
|
|
72027
|
+
`agent_bridge_claude_tool_cancellation_remapped tool_use_id=${toolCallId} gate=${interruptGate(context)}`
|
|
72028
|
+
);
|
|
72029
|
+
} else if (typeof output === "string" && isClaudeCodePermissionDenialText(output)) {
|
|
72030
|
+
options.emitDiagnostic?.(
|
|
72031
|
+
`agent_bridge_claude_permission_denial_passthrough tool_use_id=${toolCallId}`
|
|
72032
|
+
);
|
|
72033
|
+
}
|
|
72034
|
+
return uiChunk({
|
|
72035
|
+
type: "tool-output-error",
|
|
72036
|
+
toolCallId,
|
|
72037
|
+
errorText: remapped ?? JSON.stringify(output)
|
|
72038
|
+
});
|
|
72039
|
+
}
|
|
72040
|
+
function interruptGate(context) {
|
|
72041
|
+
if (context.marker && context.bridge) {
|
|
72042
|
+
return "marker+bridge";
|
|
72043
|
+
}
|
|
72044
|
+
return context.marker ? "marker" : "bridge";
|
|
72045
|
+
}
|
|
71931
72046
|
function isAssistantMessageOrToolCall(projection) {
|
|
71932
72047
|
return projection.role === "assistant" && (projection.kind === "message" || projection.kind === "tool_call");
|
|
71933
72048
|
}
|
|
@@ -91972,7 +92087,7 @@ function withClaudeStderrDiagnosticsPointer(error51, capturedStderr) {
|
|
|
91972
92087
|
|
|
91973
92088
|
// src/commands/agent-bridge/harness/claude-code/session.ts
|
|
91974
92089
|
var CLAUDE_AGENT_STARTUP_TIMEOUT_MS = 3e4;
|
|
91975
|
-
var
|
|
92090
|
+
var CLAUDE_TOOL_BOUNDARY_WAIT_TIMEOUT_MS = 12e4;
|
|
91976
92091
|
var CLAUDE_INTERRUPT_ACK_TIMEOUT_MS = 1e4;
|
|
91977
92092
|
var CLAUDE_MCP_REGISTRATION_TIMEOUT_MS = 3e4;
|
|
91978
92093
|
var CLAUDE_MCP_REGISTRATION_POLL_INTERVAL_MS = 100;
|
|
@@ -92048,16 +92163,33 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92048
92163
|
// flushed command id.
|
|
92049
92164
|
openTurnCommandIds = [];
|
|
92050
92165
|
// tool_use ids the assistant has emitted whose tool_result has not yet been
|
|
92051
|
-
// observed
|
|
92052
|
-
//
|
|
92166
|
+
// observed, with the name/detail needed to describe them in a cancellation
|
|
92167
|
+
// notice. A non-empty map means a tool call is in flight: interrupting now
|
|
92168
|
+
// would destroy its work and record a denial-worded cancellation, and
|
|
92169
|
+
// injecting now would append the new user message after an unresolved
|
|
92053
92170
|
// stop_reason=tool_use — the invalid transcript that trips Claude Code's
|
|
92054
92171
|
// ede_diagnostic and auto-restarts the session (FRA-3049).
|
|
92055
|
-
|
|
92056
|
-
// Incremented on every turn-terminal `result
|
|
92057
|
-
//
|
|
92058
|
-
// message lands only once the interrupted turn has settled its tool_use.
|
|
92172
|
+
pendingToolUses = /* @__PURE__ */ new Map();
|
|
92173
|
+
// Incremented on every turn-terminal `result`; the interrupt-timeout latch
|
|
92174
|
+
// compares against it to tell whether the same wedged turn is still running.
|
|
92059
92175
|
turnResultCount = 0;
|
|
92060
|
-
|
|
92176
|
+
// A steering message is waiting for the in-flight tool call to settle so the
|
|
92177
|
+
// turn can be interrupted at the tool boundary instead of mid-tool. Armed by
|
|
92178
|
+
// sendMessage, fired by the output pump when the pending tool_use set
|
|
92179
|
+
// drains, bounded by the budget timer below.
|
|
92180
|
+
toolBoundaryWait = null;
|
|
92181
|
+
// True from the moment a bridge-initiated interrupt control request fires
|
|
92182
|
+
// until the targeted turn emits its terminal result (or the stream ends).
|
|
92183
|
+
// Reported to the projector on every message so the SDK's denial-worded
|
|
92184
|
+
// cancellation records are classified as platform cancellations even though
|
|
92185
|
+
// the SDK's own interrupt marker arrives after them (probe-verified wire
|
|
92186
|
+
// order, 2026-07-13: tool_result → marker → error_during_execution result).
|
|
92187
|
+
interruptSettling = false;
|
|
92188
|
+
// Tool calls the SDK cancelled while a bridge-initiated interrupt was
|
|
92189
|
+
// settling. Consumed by the deferred flush: the injected message gets a
|
|
92190
|
+
// platform-cancellation notice naming this work so the model re-runs it
|
|
92191
|
+
// instead of treating the denial-worded tool_result as a human rejection.
|
|
92192
|
+
cancelledToolRuns = [];
|
|
92061
92193
|
// Memoized MCP-registration gate, keyed by the attached query. A runtime
|
|
92062
92194
|
// restart warms a brand-new session + query, so keying off the query object
|
|
92063
92195
|
// (rather than a session-lifetime flag) re-arms the gate on every restart:
|
|
@@ -92116,18 +92248,34 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92116
92248
|
delivery_mode: mode,
|
|
92117
92249
|
state: this.state.kind,
|
|
92118
92250
|
active_turn_count: this.activeTurnCount,
|
|
92119
|
-
pending_tool_use_count: this.
|
|
92251
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92120
92252
|
deferred_count: this.deferredMessages.length
|
|
92121
92253
|
});
|
|
92122
92254
|
if (mode === "deferred" && this.hasInterruptibleTurn()) {
|
|
92123
92255
|
this.deferredMessages.push({ text: message, commandIds });
|
|
92124
92256
|
this.input.runtimeLogger?.info("agent_bridge_claude_message_deferred", {
|
|
92125
92257
|
active_turn_count: this.activeTurnCount,
|
|
92126
|
-
pending_tool_use_count: this.
|
|
92258
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92127
92259
|
deferred_count: this.deferredMessages.length
|
|
92128
92260
|
});
|
|
92129
92261
|
return;
|
|
92130
92262
|
}
|
|
92263
|
+
if (this.hasInterruptibleTurn() && this.hasInFlightToolUse()) {
|
|
92264
|
+
this.deferredMessages.push({ text: message, commandIds });
|
|
92265
|
+
this.armToolBoundaryWait();
|
|
92266
|
+
this.input.runtimeLogger?.info(
|
|
92267
|
+
"agent_bridge_claude_message_deferred_tool_boundary",
|
|
92268
|
+
{
|
|
92269
|
+
active_turn_count: this.activeTurnCount,
|
|
92270
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92271
|
+
pending_tools: [...this.pendingToolUses.values()].map(
|
|
92272
|
+
(tool) => tool.name
|
|
92273
|
+
),
|
|
92274
|
+
deferred_count: this.deferredMessages.length
|
|
92275
|
+
}
|
|
92276
|
+
);
|
|
92277
|
+
return;
|
|
92278
|
+
}
|
|
92131
92279
|
const interruption = await this.interruptActiveTurnBeforeMessage();
|
|
92132
92280
|
if (interruption === "defer" && this.hasInterruptibleTurn()) {
|
|
92133
92281
|
this.deferredMessages.push({ text: message, commandIds });
|
|
@@ -92135,7 +92283,7 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92135
92283
|
"agent_bridge_claude_message_deferred_after_interrupt_timeout",
|
|
92136
92284
|
{
|
|
92137
92285
|
active_turn_count: this.activeTurnCount,
|
|
92138
|
-
pending_tool_use_count: this.
|
|
92286
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92139
92287
|
deferred_count: this.deferredMessages.length
|
|
92140
92288
|
}
|
|
92141
92289
|
);
|
|
@@ -92148,7 +92296,7 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92148
92296
|
duration_ms: Date.now() - startedAt,
|
|
92149
92297
|
state: this.state.kind,
|
|
92150
92298
|
active_turn_count: this.activeTurnCount,
|
|
92151
|
-
pending_tool_use_count: this.
|
|
92299
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92152
92300
|
deferred_count: this.deferredMessages.length
|
|
92153
92301
|
});
|
|
92154
92302
|
}
|
|
@@ -92232,8 +92380,10 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92232
92380
|
}
|
|
92233
92381
|
this.state = { kind: "closed" };
|
|
92234
92382
|
this.activeTurnCount = 0;
|
|
92235
|
-
this.
|
|
92236
|
-
this.
|
|
92383
|
+
this.pendingToolUses.clear();
|
|
92384
|
+
this.cancelledToolRuns = [];
|
|
92385
|
+
this.interruptSettling = false;
|
|
92386
|
+
this.disarmToolBoundaryWait();
|
|
92237
92387
|
if (this.deferredMessages.length > 0) {
|
|
92238
92388
|
this.input.writeOutput?.(
|
|
92239
92389
|
`agent_bridge_claude_deferred_dropped count=${this.deferredMessages.length} reason=session_closed`
|
|
@@ -92324,19 +92474,21 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92324
92474
|
void (async () => {
|
|
92325
92475
|
try {
|
|
92326
92476
|
for await (const message of query) {
|
|
92477
|
+
const interruptSettling = this.interruptSettling;
|
|
92327
92478
|
this.trackToolUseLifecycle(message);
|
|
92328
|
-
let meta3;
|
|
92479
|
+
let meta3 = { interruptSettling };
|
|
92329
92480
|
if (isClaudeAgentTurnResult(message)) {
|
|
92330
92481
|
this.activeTurnCount = Math.max(0, this.activeTurnCount - 1);
|
|
92331
92482
|
meta3 = {
|
|
92483
|
+
interruptSettling,
|
|
92332
92484
|
consumedCommandIds: this.openTurnCommandIds.shift() ?? []
|
|
92333
92485
|
};
|
|
92334
|
-
this.
|
|
92486
|
+
this.pendingToolUses.clear();
|
|
92487
|
+
this.interruptSettling = false;
|
|
92335
92488
|
this.turnResultCount += 1;
|
|
92336
|
-
this.resolveTurnSettlement(true);
|
|
92337
92489
|
this.input.runtimeLogger?.info("agent_bridge_claude_turn_result", {
|
|
92338
92490
|
active_turn_count: this.activeTurnCount,
|
|
92339
|
-
pending_tool_use_count: this.
|
|
92491
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92340
92492
|
turn_result_count: this.turnResultCount,
|
|
92341
92493
|
deferred_count: this.deferredMessages.length,
|
|
92342
92494
|
consumed_command_ids: meta3.consumedCommandIds
|
|
@@ -92344,6 +92496,9 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92344
92496
|
if (this.activeTurnCount === 0) {
|
|
92345
92497
|
this.flushDeferredMessages();
|
|
92346
92498
|
}
|
|
92499
|
+
if (this.deferredMessages.length === 0) {
|
|
92500
|
+
this.cancelledToolRuns = [];
|
|
92501
|
+
}
|
|
92347
92502
|
}
|
|
92348
92503
|
const failure = probeClaudeAgentMessage(
|
|
92349
92504
|
message,
|
|
@@ -92368,8 +92523,9 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92368
92523
|
} finally {
|
|
92369
92524
|
this.activeTurnCount = 0;
|
|
92370
92525
|
this.openTurnCommandIds.length = 0;
|
|
92371
|
-
this.
|
|
92372
|
-
this.
|
|
92526
|
+
this.pendingToolUses.clear();
|
|
92527
|
+
this.interruptSettling = false;
|
|
92528
|
+
this.disarmToolBoundaryWait();
|
|
92373
92529
|
this.state = { kind: "closed" };
|
|
92374
92530
|
this.reportExit();
|
|
92375
92531
|
}
|
|
@@ -92386,7 +92542,7 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92386
92542
|
this.input.runtimeLogger?.info("agent_bridge_claude_message_enqueued", {
|
|
92387
92543
|
state: this.state.kind,
|
|
92388
92544
|
active_turn_count: this.activeTurnCount,
|
|
92389
|
-
pending_tool_use_count: this.
|
|
92545
|
+
pending_tool_use_count: this.pendingToolUses.size,
|
|
92390
92546
|
deferred_count: this.deferredMessages.length
|
|
92391
92547
|
});
|
|
92392
92548
|
void this.ensureRunningQuery().catch((error51) => {
|
|
@@ -92399,75 +92555,105 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92399
92555
|
return this.activeTurnCount > 0 && this.state.kind === "running";
|
|
92400
92556
|
}
|
|
92401
92557
|
// True while the assistant has an emitted tool_use with no matching
|
|
92402
|
-
// tool_result yet — the window where an immediate interrupt would
|
|
92558
|
+
// tool_result yet — the window where an immediate interrupt would cancel
|
|
92559
|
+
// real tool work, and where an immediate injection would strand an
|
|
92403
92560
|
// unresolved stop_reason=tool_use ahead of the injected user message.
|
|
92404
92561
|
hasInFlightToolUse() {
|
|
92405
|
-
return this.
|
|
92562
|
+
return this.pendingToolUses.size > 0;
|
|
92406
92563
|
}
|
|
92407
92564
|
// Track tool_use/tool_result pairs as they stream so hasInFlightToolUse()
|
|
92408
92565
|
// reflects the live transcript. A tool_use may appear first as a streaming
|
|
92409
92566
|
// content block before the full assistant message is available; the matching
|
|
92410
92567
|
// tool_result closes it; the turn's terminal result clears any remainder.
|
|
92568
|
+
// Two side jobs ride on the same observation point:
|
|
92569
|
+
// - a denial-worded error tool_result arriving while a bridge interrupt is
|
|
92570
|
+
// settling is that interrupt's cancellation of the tool — record it so the
|
|
92571
|
+
// flushed message can tell the model to re-run the cancelled work;
|
|
92572
|
+
// - a tool_result that drains the pending set is the tool boundary an armed
|
|
92573
|
+
// steering message has been waiting for — interrupt the turn now, while no
|
|
92574
|
+
// tool work is at risk.
|
|
92411
92575
|
trackToolUseLifecycle(message) {
|
|
92412
|
-
for (const
|
|
92413
|
-
this.
|
|
92576
|
+
for (const entry of toolUseEntries(message)) {
|
|
92577
|
+
this.pendingToolUses.set(entry.id, {
|
|
92578
|
+
name: entry.name,
|
|
92579
|
+
detail: entry.detail
|
|
92580
|
+
});
|
|
92581
|
+
}
|
|
92582
|
+
const hadInFlightToolUse = this.hasInFlightToolUse();
|
|
92583
|
+
for (const result of toolResultEntries(message)) {
|
|
92584
|
+
const pending = this.pendingToolUses.get(result.id);
|
|
92585
|
+
this.pendingToolUses.delete(result.id);
|
|
92586
|
+
if (pending && this.interruptSettling && result.isError && result.text !== null && isClaudeCodePermissionDenialText(result.text)) {
|
|
92587
|
+
this.cancelledToolRuns.push(pending);
|
|
92588
|
+
this.input.writeOutput?.(
|
|
92589
|
+
`agent_bridge_claude_tool_cancellation_observed tool=${pending.name}`
|
|
92590
|
+
);
|
|
92591
|
+
}
|
|
92414
92592
|
}
|
|
92415
|
-
|
|
92416
|
-
this.
|
|
92593
|
+
if (hadInFlightToolUse && !this.hasInFlightToolUse()) {
|
|
92594
|
+
this.fireToolBoundaryInterrupt();
|
|
92417
92595
|
}
|
|
92418
92596
|
}
|
|
92419
|
-
//
|
|
92420
|
-
//
|
|
92421
|
-
//
|
|
92422
|
-
//
|
|
92423
|
-
//
|
|
92424
|
-
|
|
92425
|
-
if (this.
|
|
92426
|
-
return
|
|
92597
|
+
// The pending tool_use set just drained mid-turn. If a steering message is
|
|
92598
|
+
// waiting on that boundary, interrupt the turn now: nothing is executing, so
|
|
92599
|
+
// the cancellation costs only the model's remaining reasoning, and the
|
|
92600
|
+
// turn's terminal result flushes the message. Fire-and-forget — the flush at
|
|
92601
|
+
// the turn result owns delivery whether or not this interrupt lands.
|
|
92602
|
+
fireToolBoundaryInterrupt() {
|
|
92603
|
+
if (!this.toolBoundaryWait || this.deferredMessages.length === 0 || !this.hasInterruptibleTurn()) {
|
|
92604
|
+
return;
|
|
92427
92605
|
}
|
|
92428
|
-
|
|
92429
|
-
|
|
92430
|
-
|
|
92431
|
-
|
|
92432
|
-
|
|
92433
|
-
|
|
92434
|
-
|
|
92435
|
-
|
|
92436
|
-
|
|
92437
|
-
|
|
92438
|
-
|
|
92439
|
-
|
|
92440
|
-
|
|
92441
|
-
|
|
92442
|
-
|
|
92443
|
-
|
|
92444
|
-
|
|
92445
|
-
|
|
92606
|
+
this.disarmToolBoundaryWait();
|
|
92607
|
+
this.input.writeOutput?.(
|
|
92608
|
+
`agent_bridge_claude_tool_boundary_interrupt deferred_count=${this.deferredMessages.length}`
|
|
92609
|
+
);
|
|
92610
|
+
void this.interruptActiveTurn();
|
|
92611
|
+
}
|
|
92612
|
+
// Bound the tool-boundary wait: past the budget the steering message is
|
|
92613
|
+
// judged more urgent than the in-flight tool, which is cancelled mid-run.
|
|
92614
|
+
// The cancellation is observed by trackToolUseLifecycle and reported to the
|
|
92615
|
+
// model in the flushed message's platform notice.
|
|
92616
|
+
armToolBoundaryWait() {
|
|
92617
|
+
if (this.toolBoundaryWait) {
|
|
92618
|
+
return;
|
|
92619
|
+
}
|
|
92620
|
+
const timer = setTimeout(() => {
|
|
92621
|
+
this.toolBoundaryWait = null;
|
|
92622
|
+
if (!this.hasInterruptibleTurn() || this.deferredMessages.length === 0) {
|
|
92623
|
+
return;
|
|
92624
|
+
}
|
|
92625
|
+
this.input.writeOutput?.(
|
|
92626
|
+
`agent_bridge_claude_tool_boundary_wait_timeout pending_tools=${[
|
|
92627
|
+
...this.pendingToolUses.values()
|
|
92628
|
+
].map((tool) => tool.name).join(",")} deferred_count=${this.deferredMessages.length}`
|
|
92446
92629
|
);
|
|
92447
|
-
|
|
92448
|
-
|
|
92449
|
-
|
|
92630
|
+
void this.interruptActiveTurn();
|
|
92631
|
+
}, CLAUDE_TOOL_BOUNDARY_WAIT_TIMEOUT_MS);
|
|
92632
|
+
timer.unref?.();
|
|
92633
|
+
this.toolBoundaryWait = { timer };
|
|
92450
92634
|
}
|
|
92451
|
-
|
|
92452
|
-
if (this.
|
|
92635
|
+
disarmToolBoundaryWait() {
|
|
92636
|
+
if (!this.toolBoundaryWait) {
|
|
92453
92637
|
return;
|
|
92454
92638
|
}
|
|
92455
|
-
|
|
92456
|
-
this.
|
|
92457
|
-
for (const waiter of waiters) {
|
|
92458
|
-
waiter(settled);
|
|
92459
|
-
}
|
|
92639
|
+
clearTimeout(this.toolBoundaryWait.timer);
|
|
92640
|
+
this.toolBoundaryWait = null;
|
|
92460
92641
|
}
|
|
92461
92642
|
flushDeferredMessages() {
|
|
92462
92643
|
if (this.deferredMessages.length === 0) {
|
|
92463
92644
|
return;
|
|
92464
92645
|
}
|
|
92465
92646
|
const pending = this.deferredMessages.splice(0);
|
|
92647
|
+
const cancelledToolRuns = this.cancelledToolRuns.splice(0);
|
|
92648
|
+
this.disarmToolBoundaryWait();
|
|
92466
92649
|
this.input.writeOutput?.(
|
|
92467
|
-
`agent_bridge_claude_deferred_flush count=${pending.length}`
|
|
92650
|
+
`agent_bridge_claude_deferred_flush count=${pending.length} cancelled_tool_count=${cancelledToolRuns.length}`
|
|
92468
92651
|
);
|
|
92652
|
+
const text2 = pending.map((entry) => entry.text).join("\n\n");
|
|
92469
92653
|
this.enqueueUserMessage(
|
|
92470
|
-
|
|
92654
|
+
cancelledToolRuns.length > 0 ? `${text2}
|
|
92655
|
+
|
|
92656
|
+
${cancelledToolPlatformNotice(cancelledToolRuns)}` : text2,
|
|
92471
92657
|
pending.flatMap((entry) => entry.commandIds)
|
|
92472
92658
|
);
|
|
92473
92659
|
}
|
|
@@ -92488,11 +92674,10 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92488
92674
|
return "proceed";
|
|
92489
92675
|
}
|
|
92490
92676
|
const query = this.state.query;
|
|
92491
|
-
const hadInFlightToolUse = this.hasInFlightToolUse();
|
|
92492
92677
|
const settlementBaseline = this.turnResultCount;
|
|
92493
92678
|
const startedAt = Date.now();
|
|
92494
92679
|
this.input.writeOutput?.(
|
|
92495
|
-
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()} in_flight_tool_use=${
|
|
92680
|
+
`agent_bridge_claude_mid_turn_interrupt_started at=${new Date(startedAt).toISOString()} in_flight_tool_use=${this.hasInFlightToolUse()}`
|
|
92496
92681
|
);
|
|
92497
92682
|
const interruptPromise = (async () => {
|
|
92498
92683
|
const ack = await this.requestInterruptAck(query, startedAt);
|
|
@@ -92500,16 +92685,6 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92500
92685
|
this.interruptTimeoutTurn = settlementBaseline;
|
|
92501
92686
|
return "defer";
|
|
92502
92687
|
}
|
|
92503
|
-
if (hadInFlightToolUse) {
|
|
92504
|
-
const settle = await this.awaitTurnSettlement(
|
|
92505
|
-
settlementBaseline,
|
|
92506
|
-
startedAt
|
|
92507
|
-
);
|
|
92508
|
-
if (settle === "timeout") {
|
|
92509
|
-
this.interruptTimeoutTurn = settlementBaseline;
|
|
92510
|
-
return "defer";
|
|
92511
|
-
}
|
|
92512
|
-
}
|
|
92513
92688
|
return "proceed";
|
|
92514
92689
|
})();
|
|
92515
92690
|
this.interruptInFlight = interruptPromise;
|
|
@@ -92546,6 +92721,7 @@ var ClaudeAgentBridgeSessionImpl = class {
|
|
|
92546
92721
|
);
|
|
92547
92722
|
}, CLAUDE_INTERRUPT_ACK_TIMEOUT_MS);
|
|
92548
92723
|
timer.unref?.();
|
|
92724
|
+
this.interruptSettling = true;
|
|
92549
92725
|
query.interrupt().then(
|
|
92550
92726
|
() => {
|
|
92551
92727
|
if (done) {
|
|
@@ -92902,10 +93078,10 @@ function claudeAgentUserMessage(message) {
|
|
|
92902
93078
|
function isClaudeAgentTurnResult(message) {
|
|
92903
93079
|
return message.type === "result";
|
|
92904
93080
|
}
|
|
92905
|
-
function
|
|
93081
|
+
function toolUseEntries(message) {
|
|
92906
93082
|
if (message.type === "assistant") {
|
|
92907
93083
|
return contentBlocks2(message.message.content).flatMap(
|
|
92908
|
-
(block2) => block2.type === "tool_use" && typeof block2.id === "string" ? [block2
|
|
93084
|
+
(block2) => block2.type === "tool_use" && typeof block2.id === "string" ? [toolUseEntryFromBlock(block2)] : []
|
|
92909
93085
|
);
|
|
92910
93086
|
}
|
|
92911
93087
|
if (message.type !== "stream_event") {
|
|
@@ -92916,16 +93092,54 @@ function toolUseIds(message) {
|
|
|
92916
93092
|
return [];
|
|
92917
93093
|
}
|
|
92918
93094
|
const block = event.content_block;
|
|
92919
|
-
return block.type === "tool_use" && typeof block.id === "string" ? [block
|
|
93095
|
+
return block.type === "tool_use" && typeof block.id === "string" ? [toolUseEntryFromBlock(block)] : [];
|
|
93096
|
+
}
|
|
93097
|
+
function toolUseEntryFromBlock(block) {
|
|
93098
|
+
return {
|
|
93099
|
+
id: String(block.id),
|
|
93100
|
+
name: typeof block.name === "string" ? block.name : "unknown_tool",
|
|
93101
|
+
detail: toolUseDetail(block.input)
|
|
93102
|
+
};
|
|
93103
|
+
}
|
|
93104
|
+
function toolUseDetail(input) {
|
|
93105
|
+
if (input === void 0 || input === null) {
|
|
93106
|
+
return "";
|
|
93107
|
+
}
|
|
93108
|
+
let text2;
|
|
93109
|
+
try {
|
|
93110
|
+
text2 = JSON.stringify(input);
|
|
93111
|
+
} catch {
|
|
93112
|
+
return "";
|
|
93113
|
+
}
|
|
93114
|
+
if (!text2 || text2 === "{}") {
|
|
93115
|
+
return "";
|
|
93116
|
+
}
|
|
93117
|
+
return text2.length > 160 ? `${text2.slice(0, 160)}\u2026` : text2;
|
|
92920
93118
|
}
|
|
92921
|
-
function
|
|
93119
|
+
function toolResultEntries(message) {
|
|
92922
93120
|
if (message.type !== "user") {
|
|
92923
93121
|
return [];
|
|
92924
93122
|
}
|
|
92925
93123
|
return contentBlocks2(message.message.content).flatMap(
|
|
92926
|
-
(block) => block.type === "tool_result" && typeof block.tool_use_id === "string" ? [
|
|
93124
|
+
(block) => block.type === "tool_result" && typeof block.tool_use_id === "string" ? [
|
|
93125
|
+
{
|
|
93126
|
+
id: block.tool_use_id,
|
|
93127
|
+
isError: block.is_error === true,
|
|
93128
|
+
text: typeof block.content === "string" ? block.content : null
|
|
93129
|
+
}
|
|
93130
|
+
] : []
|
|
92927
93131
|
);
|
|
92928
93132
|
}
|
|
93133
|
+
function cancelledToolPlatformNotice(cancelled) {
|
|
93134
|
+
const lines = cancelled.map(
|
|
93135
|
+
(tool) => `- ${tool.name}${tool.detail ? ` ${tool.detail}` : ""}`
|
|
93136
|
+
);
|
|
93137
|
+
return [
|
|
93138
|
+
"[Auto platform notice] To deliver the message above, the platform cancelled the following in-flight tool call(s) mid-execution:",
|
|
93139
|
+
...lines,
|
|
93140
|
+
"This was a platform-initiated cancellation for message delivery, NOT a rejection or permission denial by the user \u2014 ignore any tool result saying the user doesn't want to proceed. Re-run or resume that tool work if it is still needed once you have applied the message."
|
|
93141
|
+
].join("\n");
|
|
93142
|
+
}
|
|
92929
93143
|
function contentBlocks2(content) {
|
|
92930
93144
|
if (!Array.isArray(content)) {
|
|
92931
93145
|
return [];
|
|
@@ -92944,6 +93158,9 @@ var ClaudeCodeCommandHandler = class {
|
|
|
92944
93158
|
this.input = input;
|
|
92945
93159
|
this.claudeConfig = input.claude;
|
|
92946
93160
|
this.outputBuffer = new AgentBridgeOutputBuffer(input);
|
|
93161
|
+
this.projector = new ClaudeCodeProjector({
|
|
93162
|
+
writeOutput: input.writeOutput
|
|
93163
|
+
});
|
|
92947
93164
|
this.readState = input.readState ? new ClaudeReadStateTracker(input.readState) : null;
|
|
92948
93165
|
}
|
|
92949
93166
|
input;
|
|
@@ -92965,7 +93182,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
92965
93182
|
inFlightMessageCommands = /* @__PURE__ */ new Map();
|
|
92966
93183
|
pendingQuestions = /* @__PURE__ */ new Map();
|
|
92967
93184
|
outputBuffer;
|
|
92968
|
-
projector
|
|
93185
|
+
projector;
|
|
92969
93186
|
readState;
|
|
92970
93187
|
livenessTicker = null;
|
|
92971
93188
|
// -----------------------------------------------------------------------------
|
|
@@ -93346,7 +93563,9 @@ var ClaudeCodeCommandHandler = class {
|
|
|
93346
93563
|
this.trackReadState(activeContext, message);
|
|
93347
93564
|
let projections;
|
|
93348
93565
|
try {
|
|
93349
|
-
projections = this.projector.project(message
|
|
93566
|
+
projections = this.projector.project(message, {
|
|
93567
|
+
bridgeInterruptSettling: meta3?.interruptSettling === true
|
|
93568
|
+
});
|
|
93350
93569
|
} catch (error51) {
|
|
93351
93570
|
this.input.writeOutput?.(
|
|
93352
93571
|
`agent_bridge_claude_parse_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|