claude-code-rust 0.14.3 → 0.14.5
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/README.md +3 -4
- package/agent-sdk/dist/bridge/account_metadata.js +6 -2
- package/agent-sdk/dist/bridge/agents.js +9 -3
- package/agent-sdk/dist/bridge/available_commands.js +13 -3
- package/agent-sdk/dist/bridge/command_lifecycle.js +79 -4
- package/agent-sdk/dist/bridge/command_scheduler.js +7 -2
- package/agent-sdk/dist/bridge/command_session_control.js +5 -1
- package/agent-sdk/dist/bridge/command_session_data.js +225 -10
- package/agent-sdk/dist/bridge/commands.js +48 -11
- package/agent-sdk/dist/bridge/error_classification.js +6 -1
- package/agent-sdk/dist/bridge/events.js +45 -7
- package/agent-sdk/dist/bridge/history.js +34 -10
- package/agent-sdk/dist/bridge/logger.js +19 -3
- package/agent-sdk/dist/bridge/mcp.js +7 -2
- package/agent-sdk/dist/bridge/mcp_auth_adapter.js +4 -2
- package/agent-sdk/dist/bridge/mcp_metadata.js +113 -39
- package/agent-sdk/dist/bridge/mcp_monitor.js +6 -1
- package/agent-sdk/dist/bridge/message_handlers.js +324 -66
- package/agent-sdk/dist/bridge/model_metadata.js +19 -6
- package/agent-sdk/dist/bridge/permissions.js +32 -8
- package/agent-sdk/dist/bridge/session_lifecycle.js +234 -52
- package/agent-sdk/dist/bridge/state_parsing.js +23 -8
- package/agent-sdk/dist/bridge/tasks.js +63 -22
- package/agent-sdk/dist/bridge/tool_calls.js +82 -25
- package/agent-sdk/dist/bridge/tooling.js +311 -88
- package/agent-sdk/dist/bridge/user_interaction.js +45 -13
- package/agent-sdk/dist/bridge.js +200 -104
- package/package.json +8 -8
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { asRecordOrNull } from "./shared.js";
|
|
2
|
-
import { toPermissionMode, buildModeState, refreshSupportedModesForSession } from "./commands.js";
|
|
2
|
+
import { toPermissionMode, buildModeState, refreshSupportedModesForSession, } from "./commands.js";
|
|
3
3
|
import { writeEvent, emitSessionUpdate, emitConnectEvent, emitSessionReplacedEvent, } from "./events.js";
|
|
4
4
|
import { TOOL_RESULT_TYPES, isToolSearchToolName, isToolSearchToolResultType, unwrapToolUseResult, parseToolNonExecutionMetadata, } from "./tooling.js";
|
|
5
5
|
import { emitToolCall, emitToolCallUpdate, emitToolResultUpdate, finalizeOpenToolCalls, emitToolProgressUpdate, emitToolSummaryUpdate, ensureToolCallVisible, resolveTaskToolUseId, defersTaskNotificationCompletion, toolAcceptsTaskLifecycle, taskProgressText, taskUpdatedFields, } from "./tool_calls.js";
|
|
6
|
-
import { applyBackgroundTasksChanged, applyTaskLifecycleState } from "./tasks.js";
|
|
6
|
+
import { applyBackgroundTasksChanged, applyTaskLifecycleState, } from "./tasks.js";
|
|
7
7
|
import { linkTaskToolUse, unlinkTaskToolUse } from "./task_links.js";
|
|
8
8
|
import { emitAuthRequired, classifyTurnErrorKind, emitFastModeUpdate, emitFastModeUpdateIfChanged, setFastModeSnapshotIfChanged, } from "./error_classification.js";
|
|
9
|
-
import { mapAvailableAgentsFromNames, emitAvailableAgentsIfChanged, refreshAvailableAgents } from "./agents.js";
|
|
9
|
+
import { mapAvailableAgentsFromNames, emitAvailableAgentsIfChanged, refreshAvailableAgents, } from "./agents.js";
|
|
10
10
|
import { mapInitSlashCommands, mapSdkSlashCommands, updateAvailableCommands, } from "./available_commands.js";
|
|
11
11
|
import { buildApiRetryUpdate, buildRateLimitUpdate, buildSubagentRetryUpdate, normalizeSettingsParseErrors, nonNegativeIntegerField, numberField, parseApiRetryError, parseRuntimeSessionState, } from "./state_parsing.js";
|
|
12
12
|
import { looksLikeAuthRequired } from "./auth.js";
|
|
13
|
-
import { emitCurrentModelUpdate, refreshCurrentModel, updateSessionId } from "./session_lifecycle.js";
|
|
13
|
+
import { emitCurrentModelUpdate, refreshCurrentModel, updateSessionId, } from "./session_lifecycle.js";
|
|
14
14
|
import { bridgeLogger, LOG_TARGETS } from "./logger.js";
|
|
15
15
|
import { emitMcpSnapshotFromStatuses } from "./mcp.js";
|
|
16
16
|
export function textFromPrompt(command) {
|
|
@@ -38,23 +38,46 @@ function sdkCorrelationMetadata(msg) {
|
|
|
38
38
|
return {
|
|
39
39
|
requestId: typeof msg.request_id === "string" ? msg.request_id : undefined,
|
|
40
40
|
subagentType: typeof msg.subagent_type === "string" ? msg.subagent_type : undefined,
|
|
41
|
-
taskDescription: typeof msg.task_description === "string"
|
|
41
|
+
taskDescription: typeof msg.task_description === "string"
|
|
42
|
+
? msg.task_description
|
|
43
|
+
: undefined,
|
|
42
44
|
parentAgentId: typeof msg.parent_agent_id === "string" ? msg.parent_agent_id : undefined,
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
function sdkTaskMetadata(msg) {
|
|
46
48
|
const metadata = sdkCorrelationMetadata(msg);
|
|
47
|
-
const taskType = typeof msg.task_type === "string" && msg.task_type.length > 0
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const taskType = typeof msg.task_type === "string" && msg.task_type.length > 0
|
|
50
|
+
? msg.task_type
|
|
51
|
+
: undefined;
|
|
52
|
+
const workflowName = typeof msg.workflow_name === "string" && msg.workflow_name.length > 0
|
|
53
|
+
? msg.workflow_name
|
|
54
|
+
: undefined;
|
|
55
|
+
const prompt = typeof msg.prompt === "string" && msg.prompt.length > 0
|
|
56
|
+
? msg.prompt
|
|
57
|
+
: undefined;
|
|
58
|
+
const outputFile = typeof msg.output_file === "string" && msg.output_file.length > 0
|
|
59
|
+
? msg.output_file
|
|
60
|
+
: undefined;
|
|
61
|
+
const status = typeof msg.status === "string" && msg.status.length > 0
|
|
62
|
+
? msg.status
|
|
63
|
+
: undefined;
|
|
64
|
+
const summary = status && typeof msg.summary === "string" && msg.summary.length > 0
|
|
65
|
+
? msg.summary
|
|
66
|
+
: undefined;
|
|
67
|
+
const spawnDepth = typeof msg.spawn_depth === "number" &&
|
|
68
|
+
Number.isSafeInteger(msg.spawn_depth) &&
|
|
69
|
+
msg.spawn_depth > 0
|
|
70
|
+
? msg.spawn_depth
|
|
71
|
+
: undefined;
|
|
53
72
|
const taskMetadata = {
|
|
54
73
|
...(metadata.requestId ? { request_id: metadata.requestId } : {}),
|
|
55
74
|
...(metadata.subagentType ? { subagent_type: metadata.subagentType } : {}),
|
|
56
|
-
...(metadata.taskDescription
|
|
57
|
-
|
|
75
|
+
...(metadata.taskDescription
|
|
76
|
+
? { task_description: metadata.taskDescription }
|
|
77
|
+
: {}),
|
|
78
|
+
...(metadata.parentAgentId
|
|
79
|
+
? { parent_agent_id: metadata.parentAgentId }
|
|
80
|
+
: {}),
|
|
58
81
|
...(taskType ? { task_type: taskType } : {}),
|
|
59
82
|
...(workflowName ? { workflow_name: workflowName } : {}),
|
|
60
83
|
...(prompt ? { prompt } : {}),
|
|
@@ -62,14 +85,78 @@ function sdkTaskMetadata(msg) {
|
|
|
62
85
|
...(summary ? { summary } : {}),
|
|
63
86
|
...(status ? { terminal_status: status } : {}),
|
|
64
87
|
...(typeof msg.blocked === "boolean" ? { blocked: msg.blocked } : {}),
|
|
88
|
+
...(typeof msg.is_backgrounded === "boolean"
|
|
89
|
+
? { is_backgrounded: msg.is_backgrounded }
|
|
90
|
+
: {}),
|
|
91
|
+
...(spawnDepth !== undefined ? { spawn_depth: spawnDepth } : {}),
|
|
65
92
|
};
|
|
66
93
|
return Object.keys(taskMetadata).length > 0 ? taskMetadata : undefined;
|
|
67
94
|
}
|
|
68
95
|
function sdkMessageOriginKind(msg) {
|
|
69
|
-
const origin = msg.origin && typeof msg.origin === "object"
|
|
96
|
+
const origin = msg.origin && typeof msg.origin === "object"
|
|
97
|
+
? msg.origin
|
|
98
|
+
: null;
|
|
70
99
|
return typeof origin?.kind === "string" ? origin.kind : undefined;
|
|
71
100
|
}
|
|
101
|
+
function externalMessageUpdateFromSdkUser(msg) {
|
|
102
|
+
const origin = asRecordOrNull(msg.origin);
|
|
103
|
+
if (!origin) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const kind = typeof origin?.kind === "string" ? origin.kind : undefined;
|
|
107
|
+
if (kind !== "peer" && kind !== "task-notification") {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const payload = asRecordOrNull(msg.message);
|
|
111
|
+
const content = payload?.content;
|
|
112
|
+
const contentText = typeof content === "string"
|
|
113
|
+
? content
|
|
114
|
+
: Array.isArray(content)
|
|
115
|
+
? content
|
|
116
|
+
.flatMap((block) => {
|
|
117
|
+
const record = asRecordOrNull(block);
|
|
118
|
+
return record?.type === "text" && typeof record.text === "string"
|
|
119
|
+
? [record.text]
|
|
120
|
+
: [];
|
|
121
|
+
})
|
|
122
|
+
.join("\n")
|
|
123
|
+
: "";
|
|
124
|
+
const text = typeof origin.body === "string" ? origin.body : contentText;
|
|
125
|
+
if (!text.trim()) {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
type: "external_message_update",
|
|
130
|
+
content: text,
|
|
131
|
+
...(sourceMessageUuid(msg)
|
|
132
|
+
? { source_message_uuid: sourceMessageUuid(msg) }
|
|
133
|
+
: {}),
|
|
134
|
+
origin: {
|
|
135
|
+
kind,
|
|
136
|
+
...(typeof origin.subkind === "string"
|
|
137
|
+
? { subkind: origin.subkind }
|
|
138
|
+
: {}),
|
|
139
|
+
...(typeof origin.from === "string" ? { from: origin.from } : {}),
|
|
140
|
+
...(typeof origin.name === "string" ? { name: origin.name } : {}),
|
|
141
|
+
...(typeof origin.fromSession === "string"
|
|
142
|
+
? { from_session: origin.fromSession }
|
|
143
|
+
: {}),
|
|
144
|
+
...(typeof origin.senderTaskId === "string"
|
|
145
|
+
? { sender_task_id: origin.senderTaskId }
|
|
146
|
+
: {}),
|
|
147
|
+
...(typeof origin.verifiedPeerPid === "number" &&
|
|
148
|
+
Number.isSafeInteger(origin.verifiedPeerPid) &&
|
|
149
|
+
origin.verifiedPeerPid >= 0
|
|
150
|
+
? { verified_peer_pid: origin.verifiedPeerPid }
|
|
151
|
+
: {}),
|
|
152
|
+
...(origin.fromMode === "bypass" || origin.fromMode === "prompting"
|
|
153
|
+
? { from_mode: origin.fromMode }
|
|
154
|
+
: {}),
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
72
158
|
function logSdkMessageOrigin(session, msg) {
|
|
159
|
+
const origin = asRecordOrNull(msg.origin);
|
|
73
160
|
const originKind = sdkMessageOriginKind(msg);
|
|
74
161
|
if (!originKind) {
|
|
75
162
|
return;
|
|
@@ -83,6 +170,19 @@ function logSdkMessageOrigin(session, msg) {
|
|
|
83
170
|
fields: {
|
|
84
171
|
message_type: typeof msg.type === "string" ? msg.type : undefined,
|
|
85
172
|
origin_kind: originKind,
|
|
173
|
+
origin_subkind: typeof origin?.subkind === "string" ? origin.subkind : undefined,
|
|
174
|
+
origin_from_session: typeof origin?.fromSession === "string"
|
|
175
|
+
? origin.fromSession
|
|
176
|
+
: undefined,
|
|
177
|
+
origin_sender_task_id: typeof origin?.senderTaskId === "string"
|
|
178
|
+
? origin.senderTaskId
|
|
179
|
+
: undefined,
|
|
180
|
+
origin_verified_peer_pid: typeof origin?.verifiedPeerPid === "number"
|
|
181
|
+
? origin.verifiedPeerPid
|
|
182
|
+
: undefined,
|
|
183
|
+
origin_from_mode: origin?.fromMode === "bypass" || origin?.fromMode === "prompting"
|
|
184
|
+
? origin.fromMode
|
|
185
|
+
: undefined,
|
|
86
186
|
},
|
|
87
187
|
});
|
|
88
188
|
}
|
|
@@ -91,7 +191,11 @@ function emitSystemNoticeUpdate(session, severity, message) {
|
|
|
91
191
|
if (!trimmed) {
|
|
92
192
|
return;
|
|
93
193
|
}
|
|
94
|
-
emitSessionUpdate(session.sessionId, {
|
|
194
|
+
emitSessionUpdate(session.sessionId, {
|
|
195
|
+
type: "system_notice_update",
|
|
196
|
+
severity,
|
|
197
|
+
message: trimmed,
|
|
198
|
+
});
|
|
95
199
|
}
|
|
96
200
|
const MAX_INFORMATIONAL_DEDUP_KEYS = 256;
|
|
97
201
|
function shouldEmitInformationalMessage(session, level, content, toolUseId) {
|
|
@@ -203,7 +307,9 @@ function handleModelRefusalNoFallbackMessage(session, msg) {
|
|
|
203
307
|
}
|
|
204
308
|
function workerShutdownMessage(reason) {
|
|
205
309
|
const trimmed = reason.trim();
|
|
206
|
-
return trimmed
|
|
310
|
+
return trimmed
|
|
311
|
+
? `Claude worker is shutting down: ${trimmed}`
|
|
312
|
+
: "Claude worker is shutting down.";
|
|
207
313
|
}
|
|
208
314
|
function handleWorkerShuttingDownSystemMessage(session, msg) {
|
|
209
315
|
const reason = typeof msg.reason === "string" ? msg.reason.trim() : "";
|
|
@@ -280,7 +386,9 @@ export function contentFromPrompt(command) {
|
|
|
280
386
|
}
|
|
281
387
|
}
|
|
282
388
|
else if (chunk.kind === "image") {
|
|
283
|
-
const val = chunk.value && typeof chunk.value === "object"
|
|
389
|
+
const val = chunk.value && typeof chunk.value === "object"
|
|
390
|
+
? chunk.value
|
|
391
|
+
: null;
|
|
284
392
|
if (!val)
|
|
285
393
|
continue;
|
|
286
394
|
const data = typeof val.data === "string" ? val.data : "";
|
|
@@ -400,7 +508,9 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
400
508
|
const fields = {
|
|
401
509
|
status: "in_progress",
|
|
402
510
|
raw_output: description,
|
|
403
|
-
content: [
|
|
511
|
+
content: [
|
|
512
|
+
{ type: "content", content: { type: "text", text: description } },
|
|
513
|
+
],
|
|
404
514
|
...(messageTaskMetadata ? { task_metadata: messageTaskMetadata } : {}),
|
|
405
515
|
};
|
|
406
516
|
emitToolCallUpdate(session, toolUseId, fields, "task_started");
|
|
@@ -423,7 +533,10 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
423
533
|
if (subtype === "task_updated") {
|
|
424
534
|
const fields = taskUpdatedFields(msg);
|
|
425
535
|
if (messageTaskMetadata) {
|
|
426
|
-
fields.task_metadata = {
|
|
536
|
+
fields.task_metadata = {
|
|
537
|
+
...(fields.task_metadata ?? {}),
|
|
538
|
+
...messageTaskMetadata,
|
|
539
|
+
};
|
|
427
540
|
}
|
|
428
541
|
if (Object.keys(fields).length === 0) {
|
|
429
542
|
return true;
|
|
@@ -451,15 +564,23 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
451
564
|
}
|
|
452
565
|
const status = typeof msg.status === "string" ? msg.status : "";
|
|
453
566
|
const summary = typeof msg.summary === "string" ? msg.summary : "";
|
|
454
|
-
const finalStatus = status === "completed"
|
|
567
|
+
const finalStatus = status === "completed"
|
|
568
|
+
? "completed"
|
|
569
|
+
: status === "stopped"
|
|
570
|
+
? "killed"
|
|
571
|
+
: "failed";
|
|
455
572
|
const deferCompletion = finalStatus === "completed" && defersTaskNotificationCompletion(toolCall);
|
|
456
|
-
const fields = deferCompletion
|
|
573
|
+
const fields = deferCompletion
|
|
574
|
+
? {}
|
|
575
|
+
: { status: finalStatus };
|
|
457
576
|
if (messageTaskMetadata) {
|
|
458
577
|
fields.task_metadata = messageTaskMetadata;
|
|
459
578
|
}
|
|
460
579
|
if (summary) {
|
|
461
580
|
fields.raw_output = summary;
|
|
462
|
-
fields.content = [
|
|
581
|
+
fields.content = [
|
|
582
|
+
{ type: "content", content: { type: "text", text: summary } },
|
|
583
|
+
];
|
|
463
584
|
}
|
|
464
585
|
if (Object.keys(fields).length > 0) {
|
|
465
586
|
emitToolCallUpdate(session, toolUseId, fields, "task_notification");
|
|
@@ -510,10 +631,19 @@ function emitTranscriptRetraction(session, messageUuids, reason, metadata = {})
|
|
|
510
631
|
...(metadata.requestId ? { request_id: metadata.requestId } : {}),
|
|
511
632
|
...(metadata.trigger ? { trigger: metadata.trigger } : {}),
|
|
512
633
|
...(metadata.direction ? { direction: metadata.direction } : {}),
|
|
513
|
-
...(metadata.originalModel
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
...(metadata.
|
|
634
|
+
...(metadata.originalModel
|
|
635
|
+
? { original_model: metadata.originalModel }
|
|
636
|
+
: {}),
|
|
637
|
+
...(metadata.fallbackModel
|
|
638
|
+
? { fallback_model: metadata.fallbackModel }
|
|
639
|
+
: {}),
|
|
640
|
+
...(metadata.scope ? { scope: metadata.scope } : {}),
|
|
641
|
+
...(metadata.apiRefusalCategory
|
|
642
|
+
? { api_refusal_category: metadata.apiRefusalCategory }
|
|
643
|
+
: {}),
|
|
644
|
+
...(metadata.apiRefusalExplanation
|
|
645
|
+
? { api_refusal_explanation: metadata.apiRefusalExplanation }
|
|
646
|
+
: {}),
|
|
517
647
|
...(metadata.content ? { content: metadata.content } : {}),
|
|
518
648
|
});
|
|
519
649
|
return true;
|
|
@@ -530,6 +660,7 @@ function handleFallbackRetractionMessage(session, subtype, msg) {
|
|
|
530
660
|
direction: stringField(msg, "direction"),
|
|
531
661
|
originalModel: stringField(msg, "original_model"),
|
|
532
662
|
fallbackModel: stringField(msg, "fallback_model"),
|
|
663
|
+
scope: stringField(msg, "scope") ?? "session",
|
|
533
664
|
apiRefusalCategory: nullableStringField(msg, "api_refusal_category"),
|
|
534
665
|
apiRefusalExplanation: nullableStringField(msg, "api_refusal_explanation"),
|
|
535
666
|
content: stringField(msg, "content"),
|
|
@@ -549,6 +680,7 @@ function handleFallbackRetractionMessage(session, subtype, msg) {
|
|
|
549
680
|
direction: metadata.direction,
|
|
550
681
|
original_model: metadata.originalModel,
|
|
551
682
|
fallback_model: metadata.fallbackModel,
|
|
683
|
+
scope: metadata.scope,
|
|
552
684
|
api_refusal_category: metadata.apiRefusalCategory,
|
|
553
685
|
has_api_refusal_explanation: metadata.apiRefusalExplanation !== undefined,
|
|
554
686
|
has_content: metadata.content !== undefined,
|
|
@@ -621,7 +753,9 @@ export function handleContentBlock(session, block, linkage) {
|
|
|
621
753
|
emitSessionUpdate(session.sessionId, {
|
|
622
754
|
type: "agent_message_chunk",
|
|
623
755
|
content: { type: "text", text },
|
|
624
|
-
...(linkage?.sourceMessageUuid
|
|
756
|
+
...(linkage?.sourceMessageUuid
|
|
757
|
+
? { source_message_uuid: linkage.sourceMessageUuid }
|
|
758
|
+
: {}),
|
|
625
759
|
});
|
|
626
760
|
}
|
|
627
761
|
return;
|
|
@@ -632,15 +766,21 @@ export function handleContentBlock(session, block, linkage) {
|
|
|
632
766
|
emitSessionUpdate(session.sessionId, {
|
|
633
767
|
type: "agent_thought_chunk",
|
|
634
768
|
content: { type: "text", text },
|
|
635
|
-
...(linkage?.sourceMessageUuid
|
|
769
|
+
...(linkage?.sourceMessageUuid
|
|
770
|
+
? { source_message_uuid: linkage.sourceMessageUuid }
|
|
771
|
+
: {}),
|
|
636
772
|
});
|
|
637
773
|
}
|
|
638
774
|
return;
|
|
639
775
|
}
|
|
640
|
-
if (blockType === "tool_use" ||
|
|
776
|
+
if (blockType === "tool_use" ||
|
|
777
|
+
blockType === "server_tool_use" ||
|
|
778
|
+
blockType === "mcp_tool_use") {
|
|
641
779
|
const toolUseId = typeof block.id === "string" ? block.id : "";
|
|
642
780
|
const name = typeof block.name === "string" ? block.name : "Tool";
|
|
643
|
-
const input = block.input && typeof block.input === "object"
|
|
781
|
+
const input = block.input && typeof block.input === "object"
|
|
782
|
+
? block.input
|
|
783
|
+
: {};
|
|
644
784
|
if (!toolUseId) {
|
|
645
785
|
return;
|
|
646
786
|
}
|
|
@@ -688,7 +828,9 @@ export function handleStreamEvent(session, event, parentToolUseId, sourceMessage
|
|
|
688
828
|
emitSessionUpdate(session.sessionId, {
|
|
689
829
|
type: "agent_message_chunk",
|
|
690
830
|
content: { type: "text", text },
|
|
691
|
-
...(sourceMessageUuid
|
|
831
|
+
...(sourceMessageUuid
|
|
832
|
+
? { source_message_uuid: sourceMessageUuid }
|
|
833
|
+
: {}),
|
|
692
834
|
});
|
|
693
835
|
}
|
|
694
836
|
}
|
|
@@ -698,7 +840,9 @@ export function handleStreamEvent(session, event, parentToolUseId, sourceMessage
|
|
|
698
840
|
emitSessionUpdate(session.sessionId, {
|
|
699
841
|
type: "agent_thought_chunk",
|
|
700
842
|
content: { type: "text", text },
|
|
701
|
-
...(sourceMessageUuid
|
|
843
|
+
...(sourceMessageUuid
|
|
844
|
+
? { source_message_uuid: sourceMessageUuid }
|
|
845
|
+
: {}),
|
|
702
846
|
});
|
|
703
847
|
}
|
|
704
848
|
}
|
|
@@ -718,7 +862,30 @@ export function handleAssistantMessage(session, message) {
|
|
|
718
862
|
if (!messageObject) {
|
|
719
863
|
return;
|
|
720
864
|
}
|
|
721
|
-
const content = Array.isArray(messageObject.content)
|
|
865
|
+
const content = Array.isArray(messageObject.content)
|
|
866
|
+
? messageObject.content
|
|
867
|
+
: [];
|
|
868
|
+
if (asRecordOrNull(message.context_usage)) {
|
|
869
|
+
const markdown = content
|
|
870
|
+
.flatMap((block) => {
|
|
871
|
+
const record = asRecordOrNull(block);
|
|
872
|
+
return record?.type === "text" &&
|
|
873
|
+
typeof record.text === "string" &&
|
|
874
|
+
record.text.trim().length > 0
|
|
875
|
+
? [record.text]
|
|
876
|
+
: [];
|
|
877
|
+
})
|
|
878
|
+
.join("\n\n");
|
|
879
|
+
if (markdown.length > 0) {
|
|
880
|
+
emitSessionUpdate(session.sessionId, {
|
|
881
|
+
type: "agent_message_chunk",
|
|
882
|
+
content: { type: "text", text: markdown },
|
|
883
|
+
...(assistantMessageUuid
|
|
884
|
+
? { source_message_uuid: assistantMessageUuid }
|
|
885
|
+
: {}),
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
722
889
|
for (const block of content) {
|
|
723
890
|
if (!block || typeof block !== "object") {
|
|
724
891
|
continue;
|
|
@@ -729,7 +896,9 @@ export function handleAssistantMessage(session, message) {
|
|
|
729
896
|
blockType === "server_tool_use" ||
|
|
730
897
|
blockType === "mcp_tool_use" ||
|
|
731
898
|
TOOL_RESULT_TYPES.has(blockType)) {
|
|
732
|
-
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
899
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
900
|
+
? message.parent_tool_use_id
|
|
901
|
+
: undefined;
|
|
733
902
|
handleContentBlock(session, blockRecord, {
|
|
734
903
|
source: "assistant",
|
|
735
904
|
parentToolUseId,
|
|
@@ -755,7 +924,9 @@ export function handleUserToolResultBlocks(session, message) {
|
|
|
755
924
|
if (!messageObject) {
|
|
756
925
|
return false;
|
|
757
926
|
}
|
|
758
|
-
const content = Array.isArray(messageObject.content)
|
|
927
|
+
const content = Array.isArray(messageObject.content)
|
|
928
|
+
? messageObject.content
|
|
929
|
+
: [];
|
|
759
930
|
const nonExecutionByToolUseId = parseToolNonExecutionMetadata(message.tool_result_meta);
|
|
760
931
|
let handled = false;
|
|
761
932
|
for (const block of content) {
|
|
@@ -765,8 +936,12 @@ export function handleUserToolResultBlocks(session, message) {
|
|
|
765
936
|
const blockRecord = block;
|
|
766
937
|
const blockType = typeof blockRecord.type === "string" ? blockRecord.type : "";
|
|
767
938
|
if (TOOL_RESULT_TYPES.has(blockType)) {
|
|
768
|
-
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
769
|
-
|
|
939
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
940
|
+
? message.parent_tool_use_id
|
|
941
|
+
: undefined;
|
|
942
|
+
const toolUseId = typeof blockRecord.tool_use_id === "string"
|
|
943
|
+
? blockRecord.tool_use_id
|
|
944
|
+
: "";
|
|
770
945
|
if (!toolUseId) {
|
|
771
946
|
continue;
|
|
772
947
|
}
|
|
@@ -798,9 +973,30 @@ export function handleResultMessage(session, message) {
|
|
|
798
973
|
});
|
|
799
974
|
return;
|
|
800
975
|
}
|
|
801
|
-
const errors = Array.isArray(message.errors) &&
|
|
976
|
+
const errors = Array.isArray(message.errors) &&
|
|
977
|
+
message.errors.every((entry) => typeof entry === "string")
|
|
802
978
|
? message.errors
|
|
803
979
|
: [];
|
|
980
|
+
const resumeDropsTurnRefusal = errors.find((entry) => entry.startsWith("Resume rejected by --resume-drops-turn:"));
|
|
981
|
+
if (session.deferConnect &&
|
|
982
|
+
session.resumeDropsTurn &&
|
|
983
|
+
resumeDropsTurnRefusal) {
|
|
984
|
+
session.initializationReady = false;
|
|
985
|
+
session.initializationError = resumeDropsTurnRefusal;
|
|
986
|
+
bridgeLogger.warn({
|
|
987
|
+
target: LOG_TARGETS.APP_SESSION,
|
|
988
|
+
eventName: "session_resume_drops_turn_rejected",
|
|
989
|
+
message: "guarded resume candidate rejected because the source session changed",
|
|
990
|
+
outcome: "failure",
|
|
991
|
+
sessionId: session.sessionId,
|
|
992
|
+
fields: {
|
|
993
|
+
drop_turn_id: session.resumeDropsTurn,
|
|
994
|
+
validation_fence_complete: session.resumeGuardFenceComplete === true,
|
|
995
|
+
error_message: resumeDropsTurnRefusal,
|
|
996
|
+
},
|
|
997
|
+
});
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
804
1000
|
const assistantError = session.lastAssistantError;
|
|
805
1001
|
const authHint = errors.find((entry) => looksLikeAuthRequired(entry));
|
|
806
1002
|
if (authHint) {
|
|
@@ -820,7 +1016,9 @@ export function handleResultMessage(session, message) {
|
|
|
820
1016
|
error_kind: errorKind,
|
|
821
1017
|
...(subtype ? { sdk_result_subtype: subtype } : {}),
|
|
822
1018
|
...(assistantError ? { assistant_error: assistantError } : {}),
|
|
823
|
-
...(apiErrorStatus !== undefined
|
|
1019
|
+
...(apiErrorStatus !== undefined
|
|
1020
|
+
? { api_error_status: apiErrorStatus }
|
|
1021
|
+
: {}),
|
|
824
1022
|
...(terminalReason ? { terminal_reason: terminalReason } : {}),
|
|
825
1023
|
});
|
|
826
1024
|
session.lastAssistantError = undefined;
|
|
@@ -940,8 +1138,12 @@ export function handleSdkMessage(session, message) {
|
|
|
940
1138
|
fields: {
|
|
941
1139
|
tool_name: typeof msg.tool_name === "string" ? msg.tool_name : undefined,
|
|
942
1140
|
agent_id: typeof msg.agent_id === "string" ? msg.agent_id : undefined,
|
|
943
|
-
decision_reason_type: typeof msg.decision_reason_type === "string"
|
|
944
|
-
|
|
1141
|
+
decision_reason_type: typeof msg.decision_reason_type === "string"
|
|
1142
|
+
? msg.decision_reason_type
|
|
1143
|
+
: undefined,
|
|
1144
|
+
decision_reason: typeof msg.decision_reason === "string"
|
|
1145
|
+
? msg.decision_reason
|
|
1146
|
+
: undefined,
|
|
945
1147
|
denial_message: typeof msg.message === "string" ? msg.message : undefined,
|
|
946
1148
|
},
|
|
947
1149
|
});
|
|
@@ -956,9 +1158,15 @@ export function handleSdkMessage(session, message) {
|
|
|
956
1158
|
sessionId: session.sessionId,
|
|
957
1159
|
fields: {
|
|
958
1160
|
sdk_subtype: subtype,
|
|
959
|
-
memory_count: Array.isArray(msg.memories)
|
|
960
|
-
|
|
961
|
-
|
|
1161
|
+
memory_count: Array.isArray(msg.memories)
|
|
1162
|
+
? msg.memories.length
|
|
1163
|
+
: undefined,
|
|
1164
|
+
estimated_tokens: typeof msg.estimated_tokens === "number"
|
|
1165
|
+
? msg.estimated_tokens
|
|
1166
|
+
: undefined,
|
|
1167
|
+
estimated_tokens_delta: typeof msg.estimated_tokens_delta === "number"
|
|
1168
|
+
? msg.estimated_tokens_delta
|
|
1169
|
+
: undefined,
|
|
962
1170
|
},
|
|
963
1171
|
});
|
|
964
1172
|
return;
|
|
@@ -987,7 +1195,9 @@ export function handleSdkMessage(session, message) {
|
|
|
987
1195
|
const modelName = typeof msg.model === "string" ? msg.model : session.model;
|
|
988
1196
|
session.model = modelName;
|
|
989
1197
|
const currentModelChanged = refreshCurrentModel(session, false);
|
|
990
|
-
const incomingMode = typeof msg.permissionMode === "string"
|
|
1198
|
+
const incomingMode = typeof msg.permissionMode === "string"
|
|
1199
|
+
? toPermissionMode(msg.permissionMode)
|
|
1200
|
+
: null;
|
|
991
1201
|
if (incomingMode) {
|
|
992
1202
|
session.mode = incomingMode;
|
|
993
1203
|
}
|
|
@@ -1019,7 +1229,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1019
1229
|
if (Array.isArray(msg.mcp_servers)) {
|
|
1020
1230
|
emitMcpSnapshotFromStatuses(session, msg.mcp_servers, "init");
|
|
1021
1231
|
}
|
|
1022
|
-
if (session.lastAvailableAgentsSignature === undefined &&
|
|
1232
|
+
if (session.lastAvailableAgentsSignature === undefined &&
|
|
1233
|
+
Array.isArray(msg.agents)) {
|
|
1023
1234
|
emitAvailableAgentsIfChanged(session, mapAvailableAgentsFromNames(msg.agents));
|
|
1024
1235
|
}
|
|
1025
1236
|
void session.query
|
|
@@ -1041,17 +1252,28 @@ export function handleSdkMessage(session, message) {
|
|
|
1041
1252
|
return;
|
|
1042
1253
|
}
|
|
1043
1254
|
if (subtype === "status") {
|
|
1044
|
-
const mode = typeof msg.permissionMode === "string"
|
|
1255
|
+
const mode = typeof msg.permissionMode === "string"
|
|
1256
|
+
? toPermissionMode(msg.permissionMode)
|
|
1257
|
+
: null;
|
|
1045
1258
|
if (mode) {
|
|
1046
1259
|
session.mode = mode;
|
|
1047
1260
|
refreshSupportedModesForSession(session);
|
|
1048
|
-
emitSessionUpdate(session.sessionId, {
|
|
1261
|
+
emitSessionUpdate(session.sessionId, {
|
|
1262
|
+
type: "current_mode_update",
|
|
1263
|
+
current_mode_id: mode,
|
|
1264
|
+
});
|
|
1049
1265
|
}
|
|
1050
1266
|
if (msg.status === "compacting") {
|
|
1051
|
-
emitSessionUpdate(session.sessionId, {
|
|
1267
|
+
emitSessionUpdate(session.sessionId, {
|
|
1268
|
+
type: "compaction_update",
|
|
1269
|
+
phase: "started",
|
|
1270
|
+
});
|
|
1052
1271
|
}
|
|
1053
1272
|
else if (msg.status === "requesting") {
|
|
1054
|
-
emitSessionUpdate(session.sessionId, {
|
|
1273
|
+
emitSessionUpdate(session.sessionId, {
|
|
1274
|
+
type: "session_status_update",
|
|
1275
|
+
status: "requesting",
|
|
1276
|
+
});
|
|
1055
1277
|
}
|
|
1056
1278
|
else if (msg.status === null) {
|
|
1057
1279
|
if (msg.compact_result === "success") {
|
|
@@ -1062,7 +1284,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1062
1284
|
});
|
|
1063
1285
|
}
|
|
1064
1286
|
else if (msg.compact_result === "failed") {
|
|
1065
|
-
const compactError = typeof msg.compact_error === "string" &&
|
|
1287
|
+
const compactError = typeof msg.compact_error === "string" &&
|
|
1288
|
+
msg.compact_error.trim().length > 0
|
|
1066
1289
|
? msg.compact_error.trim()
|
|
1067
1290
|
: undefined;
|
|
1068
1291
|
emitSessionUpdate(session.sessionId, {
|
|
@@ -1073,7 +1296,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1073
1296
|
...(compactError ? { error: compactError } : {}),
|
|
1074
1297
|
});
|
|
1075
1298
|
}
|
|
1076
|
-
emitSessionUpdate(session.sessionId, {
|
|
1299
|
+
emitSessionUpdate(session.sessionId, {
|
|
1300
|
+
type: "session_status_update",
|
|
1301
|
+
status: "idle",
|
|
1302
|
+
});
|
|
1077
1303
|
}
|
|
1078
1304
|
emitFastModeUpdateIfChanged(session, msg.fast_mode_state, msg.fast_mode_disabled_reason);
|
|
1079
1305
|
return;
|
|
@@ -1087,7 +1313,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1087
1313
|
const preTokens = nonNegativeIntegerField(compactMetadata, "pre_tokens", "preTokens");
|
|
1088
1314
|
const postTokens = nonNegativeIntegerField(compactMetadata, "post_tokens", "postTokens");
|
|
1089
1315
|
const durationMs = nonNegativeIntegerField(compactMetadata, "duration_ms", "durationMs");
|
|
1090
|
-
if ((trigger === "manual" || trigger === "auto") &&
|
|
1316
|
+
if ((trigger === "manual" || trigger === "auto") &&
|
|
1317
|
+
preTokens !== undefined) {
|
|
1091
1318
|
emitSessionUpdate(session.sessionId, {
|
|
1092
1319
|
type: "compaction_update",
|
|
1093
1320
|
phase: "boundary",
|
|
@@ -1105,7 +1332,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1105
1332
|
emitSessionUpdate(session.sessionId, {
|
|
1106
1333
|
type: "agent_message_chunk",
|
|
1107
1334
|
content: { type: "text", text: content },
|
|
1108
|
-
...(sourceMessageUuid(msg)
|
|
1335
|
+
...(sourceMessageUuid(msg)
|
|
1336
|
+
? { source_message_uuid: sourceMessageUuid(msg) }
|
|
1337
|
+
: {}),
|
|
1109
1338
|
});
|
|
1110
1339
|
}
|
|
1111
1340
|
return;
|
|
@@ -1120,7 +1349,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1120
1349
|
session_id: session.sessionId,
|
|
1121
1350
|
completion: {
|
|
1122
1351
|
elicitation_id: elicitationId,
|
|
1123
|
-
...(typeof msg.mcp_server_name === "string"
|
|
1352
|
+
...(typeof msg.mcp_server_name === "string"
|
|
1353
|
+
? { server_name: msg.mcp_server_name }
|
|
1354
|
+
: {}),
|
|
1124
1355
|
},
|
|
1125
1356
|
});
|
|
1126
1357
|
return;
|
|
@@ -1143,7 +1374,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1143
1374
|
if (type === "prompt_suggestion") {
|
|
1144
1375
|
const suggestion = typeof msg.suggestion === "string" ? msg.suggestion.trim() : "";
|
|
1145
1376
|
if (suggestion) {
|
|
1146
|
-
emitSessionUpdate(session.sessionId, {
|
|
1377
|
+
emitSessionUpdate(session.sessionId, {
|
|
1378
|
+
type: "prompt_suggestion_update",
|
|
1379
|
+
suggestion,
|
|
1380
|
+
});
|
|
1147
1381
|
}
|
|
1148
1382
|
return;
|
|
1149
1383
|
}
|
|
@@ -1158,10 +1392,14 @@ export function handleSdkMessage(session, message) {
|
|
|
1158
1392
|
}
|
|
1159
1393
|
if (type === "auth_status") {
|
|
1160
1394
|
const output = Array.isArray(msg.output)
|
|
1161
|
-
? msg.output
|
|
1395
|
+
? msg.output
|
|
1396
|
+
.filter((entry) => typeof entry === "string")
|
|
1397
|
+
.join("\n")
|
|
1162
1398
|
: "";
|
|
1163
1399
|
const errorText = typeof msg.error === "string" ? msg.error : "";
|
|
1164
|
-
const combined = [errorText, output]
|
|
1400
|
+
const combined = [errorText, output]
|
|
1401
|
+
.filter((entry) => entry.length > 0)
|
|
1402
|
+
.join("\n");
|
|
1165
1403
|
if (combined && looksLikeAuthRequired(combined)) {
|
|
1166
1404
|
emitAuthRequired(session, combined);
|
|
1167
1405
|
}
|
|
@@ -1169,7 +1407,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1169
1407
|
}
|
|
1170
1408
|
if (type === "stream_event") {
|
|
1171
1409
|
if (msg.event && typeof msg.event === "object") {
|
|
1172
|
-
const parentToolUseId = typeof msg.parent_tool_use_id === "string"
|
|
1410
|
+
const parentToolUseId = typeof msg.parent_tool_use_id === "string"
|
|
1411
|
+
? msg.parent_tool_use_id
|
|
1412
|
+
: undefined;
|
|
1173
1413
|
handleStreamEvent(session, msg.event, parentToolUseId, sourceMessageUuid(msg));
|
|
1174
1414
|
}
|
|
1175
1415
|
return;
|
|
@@ -1179,7 +1419,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1179
1419
|
const toolName = typeof msg.tool_name === "string" ? msg.tool_name : "Tool";
|
|
1180
1420
|
const parentToolUseId = typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : "";
|
|
1181
1421
|
const taskId = typeof msg.task_id === "string" ? msg.task_id : "";
|
|
1182
|
-
const taskToolUseId = taskId
|
|
1422
|
+
const taskToolUseId = taskId
|
|
1423
|
+
? (session.taskToolUseIds.get(taskId) ?? "")
|
|
1424
|
+
: "";
|
|
1183
1425
|
if (isHiddenToolUse(session, toolUseId, toolName)) {
|
|
1184
1426
|
return;
|
|
1185
1427
|
}
|
|
@@ -1204,7 +1446,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1204
1446
|
});
|
|
1205
1447
|
if (resolvedToolUseId) {
|
|
1206
1448
|
const hasSubagentRetry = Object.hasOwn(msg, "subagent_retry");
|
|
1207
|
-
const subagentRetry = hasSubagentRetry
|
|
1449
|
+
const subagentRetry = hasSubagentRetry
|
|
1450
|
+
? buildSubagentRetryUpdate(msg)
|
|
1451
|
+
: null;
|
|
1208
1452
|
if (hasSubagentRetry && !subagentRetry) {
|
|
1209
1453
|
bridgeLogger.warn({
|
|
1210
1454
|
target: LOG_TARGETS.APP_TOOL,
|
|
@@ -1247,8 +1491,12 @@ export function handleSdkMessage(session, message) {
|
|
|
1247
1491
|
if (type === "rate_limit_event") {
|
|
1248
1492
|
const rateLimitInfo = asRecordOrNull(msg.rate_limit_info);
|
|
1249
1493
|
const update = buildRateLimitUpdate(msg.rate_limit_info);
|
|
1250
|
-
const rawIsUsingOverage = typeof rateLimitInfo?.isUsingOverage === "boolean"
|
|
1251
|
-
|
|
1494
|
+
const rawIsUsingOverage = typeof rateLimitInfo?.isUsingOverage === "boolean"
|
|
1495
|
+
? rateLimitInfo.isUsingOverage
|
|
1496
|
+
: undefined;
|
|
1497
|
+
const rawOverageInUse = typeof rateLimitInfo?.overageInUse === "boolean"
|
|
1498
|
+
? rateLimitInfo.overageInUse
|
|
1499
|
+
: undefined;
|
|
1252
1500
|
if (rawIsUsingOverage !== undefined &&
|
|
1253
1501
|
rawOverageInUse !== undefined &&
|
|
1254
1502
|
rawIsUsingOverage !== rawOverageInUse) {
|
|
@@ -1271,11 +1519,17 @@ export function handleSdkMessage(session, message) {
|
|
|
1271
1519
|
outcome: update ? "success" : "dropped",
|
|
1272
1520
|
sessionId: session.sessionId,
|
|
1273
1521
|
fields: {
|
|
1274
|
-
raw_status: typeof rateLimitInfo?.status === "string"
|
|
1275
|
-
|
|
1522
|
+
raw_status: typeof rateLimitInfo?.status === "string"
|
|
1523
|
+
? rateLimitInfo.status
|
|
1524
|
+
: undefined,
|
|
1525
|
+
raw_rate_limit_type: typeof rateLimitInfo?.rateLimitType === "string"
|
|
1526
|
+
? rateLimitInfo.rateLimitType
|
|
1527
|
+
: undefined,
|
|
1276
1528
|
raw_utilization: numberField(rateLimitInfo ?? {}, "utilization"),
|
|
1277
1529
|
raw_resets_at: numberField(rateLimitInfo ?? {}, "resetsAt"),
|
|
1278
|
-
raw_overage_status: typeof rateLimitInfo?.overageStatus === "string"
|
|
1530
|
+
raw_overage_status: typeof rateLimitInfo?.overageStatus === "string"
|
|
1531
|
+
? rateLimitInfo.overageStatus
|
|
1532
|
+
: undefined,
|
|
1279
1533
|
raw_overage_resets_at: numberField(rateLimitInfo ?? {}, "overageResetsAt"),
|
|
1280
1534
|
raw_is_using_overage: rawIsUsingOverage,
|
|
1281
1535
|
raw_overage_in_use: rawOverageInUse,
|
|
@@ -1306,6 +1560,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1306
1560
|
return;
|
|
1307
1561
|
}
|
|
1308
1562
|
if (type === "user") {
|
|
1563
|
+
const externalMessageUpdate = externalMessageUpdateFromSdkUser(msg);
|
|
1564
|
+
if (externalMessageUpdate) {
|
|
1565
|
+
emitSessionUpdate(session.sessionId, externalMessageUpdate);
|
|
1566
|
+
}
|
|
1309
1567
|
const handledBlocks = handleUserToolResultBlocks(session, msg);
|
|
1310
1568
|
const toolUseId = typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : "";
|
|
1311
1569
|
const rawToolUseResult = messageToolUseResult(msg);
|