@autohq/cli 0.1.282 → 0.1.283
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 +9657 -757
- package/dist/index.js +962 -240
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -15840,7 +15840,7 @@ var init_chat = __esm({
|
|
|
15840
15840
|
});
|
|
15841
15841
|
|
|
15842
15842
|
// ../../packages/schemas/src/conversation.ts
|
|
15843
|
-
var CONVERSATION_ROLES, CONVERSATION_ENTRY_KINDS, CONVERSATION_ENTRY_STATUSES, UNKNOWN_MESSAGE_ID, ConversationRoleSchema, ConversationEntryKindSchema, ConversationEntryStatusSchema, ConversationTextContentPartSchema, ConversationReasoningContentPartSchema, ConversationToolCallContentPartSchema, ConversationToolResultContentPartSchema, ConversationQuestionOptionSchema, ConversationQuestionSchema, ConversationQuestionContentPartSchema, ConversationContentPartSchema, ConversationEntryContentSchema, ConversationEntryEventSchema, ConversationTextDeltaSchema, ConversationReasoningDeltaSchema, ConversationDeltaSchema, ConversationDeltaEventSchema, ConversationRealtimeEventSchema;
|
|
15843
|
+
var CONVERSATION_ROLES, CONVERSATION_ENTRY_KINDS, CONVERSATION_ENTRY_STATUSES, UNKNOWN_MESSAGE_ID, ConversationRoleSchema, ConversationEntryKindSchema, ConversationEntryStatusSchema, ConversationTextContentPartSchema, ConversationReasoningContentPartSchema, ConversationToolCallContentPartSchema, ConversationToolResultContentPartSchema, ConversationQuestionOptionSchema, ConversationQuestionSchema, ConversationQuestionContentPartSchema, ConversationUiMessageContentPartSchema, ConversationContentPartSchema, ConversationEntryContentSchema, ConversationEntryEventSchema, ConversationTextDeltaSchema, ConversationReasoningDeltaSchema, ConversationDeltaSchema, ConversationDeltaEventSchema, ConversationUiMessageChunkEventSchema, ConversationRealtimeEventSchema;
|
|
15844
15844
|
var init_conversation = __esm({
|
|
15845
15845
|
"../../packages/schemas/src/conversation.ts"() {
|
|
15846
15846
|
"use strict";
|
|
@@ -15906,12 +15906,17 @@ var init_conversation = __esm({
|
|
|
15906
15906
|
toolCallId: external_exports.string().min(1).nullable(),
|
|
15907
15907
|
questions: external_exports.array(ConversationQuestionSchema)
|
|
15908
15908
|
});
|
|
15909
|
+
ConversationUiMessageContentPartSchema = external_exports.object({
|
|
15910
|
+
type: external_exports.literal("ui_message"),
|
|
15911
|
+
message: JsonValueSchema
|
|
15912
|
+
});
|
|
15909
15913
|
ConversationContentPartSchema = external_exports.discriminatedUnion("type", [
|
|
15910
15914
|
ConversationTextContentPartSchema,
|
|
15911
15915
|
ConversationReasoningContentPartSchema,
|
|
15912
15916
|
ConversationToolCallContentPartSchema,
|
|
15913
15917
|
ConversationToolResultContentPartSchema,
|
|
15914
|
-
ConversationQuestionContentPartSchema
|
|
15918
|
+
ConversationQuestionContentPartSchema,
|
|
15919
|
+
ConversationUiMessageContentPartSchema
|
|
15915
15920
|
]);
|
|
15916
15921
|
ConversationEntryContentSchema = external_exports.object({
|
|
15917
15922
|
parts: external_exports.array(ConversationContentPartSchema)
|
|
@@ -15953,9 +15958,18 @@ var init_conversation = __esm({
|
|
|
15953
15958
|
delta: ConversationDeltaSchema,
|
|
15954
15959
|
createdAt: external_exports.string().datetime()
|
|
15955
15960
|
});
|
|
15961
|
+
ConversationUiMessageChunkEventSchema = external_exports.object({
|
|
15962
|
+
type: external_exports.literal("ui.message.chunk"),
|
|
15963
|
+
id: external_exports.string().min(1),
|
|
15964
|
+
sessionId: SessionIdSchema,
|
|
15965
|
+
sequence: external_exports.number().int().nonnegative(),
|
|
15966
|
+
chunk: JsonValueSchema,
|
|
15967
|
+
createdAt: external_exports.string().datetime()
|
|
15968
|
+
});
|
|
15956
15969
|
ConversationRealtimeEventSchema = external_exports.discriminatedUnion("type", [
|
|
15957
15970
|
ConversationEntryEventSchema,
|
|
15958
|
-
ConversationDeltaEventSchema
|
|
15971
|
+
ConversationDeltaEventSchema,
|
|
15972
|
+
ConversationUiMessageChunkEventSchema
|
|
15959
15973
|
]);
|
|
15960
15974
|
}
|
|
15961
15975
|
});
|
|
@@ -16064,6 +16078,7 @@ function assistantContentProjections(message, messageId) {
|
|
|
16064
16078
|
projections.push({
|
|
16065
16079
|
role: "assistant",
|
|
16066
16080
|
kind: "tool_call",
|
|
16081
|
+
...messageId ? { messageId } : {},
|
|
16067
16082
|
content: {
|
|
16068
16083
|
parts: [
|
|
16069
16084
|
{
|
|
@@ -16305,87 +16320,6 @@ function parseCodexServerFrame(raw) {
|
|
|
16305
16320
|
const notification = parseNotification(frame.method, frame.params);
|
|
16306
16321
|
return notification ? { kind: "notification", notification } : { kind: "ignored" };
|
|
16307
16322
|
}
|
|
16308
|
-
function projectCodexItem(input) {
|
|
16309
|
-
const { item, phase } = input;
|
|
16310
|
-
switch (item.type) {
|
|
16311
|
-
case "agentMessage":
|
|
16312
|
-
return phase === "completed" && item.text.length > 0 ? [
|
|
16313
|
-
{
|
|
16314
|
-
role: "assistant",
|
|
16315
|
-
kind: "message",
|
|
16316
|
-
messageId: item.id,
|
|
16317
|
-
content: textContent2(item.text)
|
|
16318
|
-
}
|
|
16319
|
-
] : [];
|
|
16320
|
-
case "reasoning": {
|
|
16321
|
-
if (phase !== "completed") {
|
|
16322
|
-
return [];
|
|
16323
|
-
}
|
|
16324
|
-
const text = item.summary.map((line) => line.trim()).filter(Boolean).join("\n\n");
|
|
16325
|
-
return text.length > 0 ? [
|
|
16326
|
-
{
|
|
16327
|
-
role: "assistant",
|
|
16328
|
-
kind: "message",
|
|
16329
|
-
messageId: item.id,
|
|
16330
|
-
content: reasoningContent(text)
|
|
16331
|
-
}
|
|
16332
|
-
] : [];
|
|
16333
|
-
}
|
|
16334
|
-
case "commandExecution":
|
|
16335
|
-
return toolProjection({
|
|
16336
|
-
phase,
|
|
16337
|
-
itemId: item.id,
|
|
16338
|
-
name: "shell",
|
|
16339
|
-
input: {
|
|
16340
|
-
command: item.command,
|
|
16341
|
-
...item.cwd ? { cwd: item.cwd } : {}
|
|
16342
|
-
},
|
|
16343
|
-
output: item.aggregatedOutput ?? "",
|
|
16344
|
-
isError: isFailedStatus(item.status) || (item.exitCode ?? 0) !== 0
|
|
16345
|
-
});
|
|
16346
|
-
case "fileChange":
|
|
16347
|
-
return toolProjection({
|
|
16348
|
-
phase,
|
|
16349
|
-
itemId: item.id,
|
|
16350
|
-
name: "apply_patch",
|
|
16351
|
-
input: { changes: toJsonValue(item.changes) },
|
|
16352
|
-
output: { status: item.status ?? "unknown" },
|
|
16353
|
-
isError: isFailedStatus(item.status)
|
|
16354
|
-
});
|
|
16355
|
-
case "mcpToolCall":
|
|
16356
|
-
return toolProjection({
|
|
16357
|
-
phase,
|
|
16358
|
-
itemId: item.id,
|
|
16359
|
-
name: `${item.server}.${item.tool}`,
|
|
16360
|
-
input: toJsonValue(item.arguments),
|
|
16361
|
-
output: item.error ? { error: item.error.message } : toJsonValue(item.result),
|
|
16362
|
-
isError: isFailedStatus(item.status) || item.error != null
|
|
16363
|
-
});
|
|
16364
|
-
default:
|
|
16365
|
-
return [];
|
|
16366
|
-
}
|
|
16367
|
-
}
|
|
16368
|
-
function projectCodexApproval(request) {
|
|
16369
|
-
const subject = request.type === "commandExecution" ? `run the command: ${request.command ?? "(unknown command)"}` : "apply file changes";
|
|
16370
|
-
const question = {
|
|
16371
|
-
question: request.reason ? `Codex requests approval to ${subject}. ${request.reason}` : `Codex requests approval to ${subject}.`,
|
|
16372
|
-
header: "Approval",
|
|
16373
|
-
options: [
|
|
16374
|
-
{ label: APPROVE_OPTION_LABEL, description: "Allow this action." },
|
|
16375
|
-
{ label: DECLINE_OPTION_LABEL, description: "Reject this action." }
|
|
16376
|
-
],
|
|
16377
|
-
multiSelect: false
|
|
16378
|
-
};
|
|
16379
|
-
return {
|
|
16380
|
-
role: "assistant",
|
|
16381
|
-
kind: "question",
|
|
16382
|
-
content: {
|
|
16383
|
-
parts: [
|
|
16384
|
-
{ type: "question", toolCallId: request.itemId, questions: [question] }
|
|
16385
|
-
]
|
|
16386
|
-
}
|
|
16387
|
-
};
|
|
16388
|
-
}
|
|
16389
16323
|
function codexApprovalDecision(input) {
|
|
16390
16324
|
const values = [...Object.values(input.answers), input.response ?? ""];
|
|
16391
16325
|
const approved = values.some(
|
|
@@ -16510,51 +16444,6 @@ function parseApprovalRequest(method, requestId, params) {
|
|
|
16510
16444
|
return null;
|
|
16511
16445
|
}
|
|
16512
16446
|
}
|
|
16513
|
-
function toolProjection(input) {
|
|
16514
|
-
if (input.phase === "started") {
|
|
16515
|
-
return [
|
|
16516
|
-
{
|
|
16517
|
-
role: "assistant",
|
|
16518
|
-
kind: "tool_call",
|
|
16519
|
-
content: {
|
|
16520
|
-
parts: [
|
|
16521
|
-
{
|
|
16522
|
-
type: "tool_call",
|
|
16523
|
-
toolCallId: input.itemId,
|
|
16524
|
-
name: input.name,
|
|
16525
|
-
input: input.input
|
|
16526
|
-
}
|
|
16527
|
-
]
|
|
16528
|
-
}
|
|
16529
|
-
}
|
|
16530
|
-
];
|
|
16531
|
-
}
|
|
16532
|
-
return [
|
|
16533
|
-
{
|
|
16534
|
-
role: "tool",
|
|
16535
|
-
kind: "tool_result",
|
|
16536
|
-
content: {
|
|
16537
|
-
parts: [
|
|
16538
|
-
{
|
|
16539
|
-
type: "tool_result",
|
|
16540
|
-
toolUseId: input.itemId,
|
|
16541
|
-
output: input.output,
|
|
16542
|
-
isError: input.isError
|
|
16543
|
-
}
|
|
16544
|
-
]
|
|
16545
|
-
}
|
|
16546
|
-
}
|
|
16547
|
-
];
|
|
16548
|
-
}
|
|
16549
|
-
function textContent2(text) {
|
|
16550
|
-
return { parts: [{ type: "text", text }] };
|
|
16551
|
-
}
|
|
16552
|
-
function reasoningContent(text) {
|
|
16553
|
-
return { parts: [{ type: "reasoning", text }] };
|
|
16554
|
-
}
|
|
16555
|
-
function isFailedStatus(status) {
|
|
16556
|
-
return status === "failed" || status === "declined";
|
|
16557
|
-
}
|
|
16558
16447
|
var CodexRequestIdSchema, CodexTurnStatusSchema, CodexUserMessageItemSchema, CodexAgentMessageItemSchema, CodexReasoningItemSchema, CodexCommandExecutionItemSchema, CodexFileChangeItemSchema, CodexMcpToolCallItemSchema, CodexItemSchema, OptionalCodexItemSchema, CodexItemEnvelopeSchema, CodexTurnEnvelopeSchema, CodexTokenUsageSchema, CodexTokenUsageEnvelopeSchema, CodexFrameSchema, APPROVE_OPTION_LABEL, DECLINE_OPTION_LABEL;
|
|
16559
16448
|
var init_codex = __esm({
|
|
16560
16449
|
"../../packages/schemas/src/codex.ts"() {
|
|
@@ -16658,6 +16547,9 @@ var init_codex = __esm({
|
|
|
16658
16547
|
|
|
16659
16548
|
// ../../packages/schemas/src/conversation-reducer.ts
|
|
16660
16549
|
function reduceConversationRealtimeEvent(entries, event) {
|
|
16550
|
+
if (event.type === "ui.message.chunk") {
|
|
16551
|
+
return [...entries];
|
|
16552
|
+
}
|
|
16661
16553
|
if (event.type === "conversation.delta") {
|
|
16662
16554
|
const existingIndex = entries.findIndex(
|
|
16663
16555
|
(entry) => entry.messageId === event.messageId
|
|
@@ -18988,7 +18880,7 @@ function isSessionTerminalStatus(status) {
|
|
|
18988
18880
|
(terminalStatus) => terminalStatus === status
|
|
18989
18881
|
);
|
|
18990
18882
|
}
|
|
18991
|
-
var SESSION_STATUSES, SESSION_RUNTIME_PHASES, SESSION_TERMINAL_STATUSES, SESSION_DISPLAY_TITLE_MAX_LENGTH, SessionStatusSchema, SessionRuntimePhaseSchema, RunDisplayTitleSchema, AmbientStatusSchema, SESSION_CHECK_STATUSES, SESSION_CHECK_CONCLUSIONS, SESSION_CHECK_TIMEOUT_PHASES, SessionCheckStatusSchema, SessionCheckConclusionSchema, SessionCheckTimeoutPhaseSchema, ManualSessionRequestSchema, SessionArchiveRequestSchema, SessionsArchiveRequestSchema, SessionRecordSchema, SessionListItemAgentSchema, SessionListItemSchema, SessionListResponseSchema, SessionsArchiveResponseSchema;
|
|
18883
|
+
var SESSION_STATUSES, SESSION_RUNTIME_PHASES, SESSION_TERMINAL_STATUSES, SESSION_DISPLAY_TITLE_MAX_LENGTH, SESSION_MESSAGE_ROLES, SESSION_MESSAGE_STATUSES, SessionStatusSchema, SessionRuntimePhaseSchema, SessionMessageRoleSchema, SessionMessageStatusSchema, RunDisplayTitleSchema, AmbientStatusSchema, SESSION_CHECK_STATUSES, SESSION_CHECK_CONCLUSIONS, SESSION_CHECK_TIMEOUT_PHASES, SessionCheckStatusSchema, SessionCheckConclusionSchema, SessionCheckTimeoutPhaseSchema, ManualSessionRequestSchema, SessionArchiveRequestSchema, SessionsArchiveRequestSchema, SessionRecordSchema, SessionUiMessageRecordSchema, SessionListItemAgentSchema, SessionListItemSchema, SessionListResponseSchema, SessionsArchiveResponseSchema;
|
|
18992
18884
|
var init_sessions = __esm({
|
|
18993
18885
|
"../../packages/schemas/src/sessions.ts"() {
|
|
18994
18886
|
"use strict";
|
|
@@ -19015,8 +18907,16 @@ var init_sessions = __esm({
|
|
|
19015
18907
|
];
|
|
19016
18908
|
SESSION_TERMINAL_STATUSES = ["failed", "stopped"];
|
|
19017
18909
|
SESSION_DISPLAY_TITLE_MAX_LENGTH = 64;
|
|
18910
|
+
SESSION_MESSAGE_ROLES = ["system", "user", "assistant"];
|
|
18911
|
+
SESSION_MESSAGE_STATUSES = [
|
|
18912
|
+
"in_progress",
|
|
18913
|
+
"completed",
|
|
18914
|
+
"failed"
|
|
18915
|
+
];
|
|
19018
18916
|
SessionStatusSchema = external_exports.enum(SESSION_STATUSES);
|
|
19019
18917
|
SessionRuntimePhaseSchema = external_exports.enum(SESSION_RUNTIME_PHASES);
|
|
18918
|
+
SessionMessageRoleSchema = external_exports.enum(SESSION_MESSAGE_ROLES);
|
|
18919
|
+
SessionMessageStatusSchema = external_exports.enum(SESSION_MESSAGE_STATUSES);
|
|
19020
18920
|
RunDisplayTitleSchema = external_exports.string().trim().max(SESSION_DISPLAY_TITLE_MAX_LENGTH);
|
|
19021
18921
|
AmbientStatusSchema = external_exports.string().trim().min(1);
|
|
19022
18922
|
SESSION_CHECK_STATUSES = [
|
|
@@ -19054,6 +18954,12 @@ var init_sessions = __esm({
|
|
|
19054
18954
|
correlationKey: external_exports.string().nullable(),
|
|
19055
18955
|
workflowId: external_exports.string().min(1),
|
|
19056
18956
|
displayTitle: RunDisplayTitleSchema,
|
|
18957
|
+
// Default to null so session.upsert entity records emitted before/without the
|
|
18958
|
+
// active-stream metadata validate (undefined -> null) instead of throwing;
|
|
18959
|
+
// the output type stays `string | null`, so consumers are unaffected.
|
|
18960
|
+
activeUiMessageStreamId: external_exports.string().trim().min(1).nullable().default(null),
|
|
18961
|
+
activeUiMessageStreamCommandId: external_exports.string().trim().min(1).nullable().default(null),
|
|
18962
|
+
activeUiMessageStreamStartedAt: external_exports.string().datetime().nullable().default(null),
|
|
19057
18963
|
ambientStatus: AmbientStatusSchema.nullable(),
|
|
19058
18964
|
ambientStatusUpdatedAt: external_exports.string().datetime().nullable(),
|
|
19059
18965
|
starterActor: AuthActorSchema.nullable(),
|
|
@@ -19075,6 +18981,20 @@ var init_sessions = __esm({
|
|
|
19075
18981
|
archivedAt: external_exports.string().datetime().nullable(),
|
|
19076
18982
|
error: JsonValueSchema.nullable()
|
|
19077
18983
|
});
|
|
18984
|
+
SessionUiMessageRecordSchema = external_exports.object({
|
|
18985
|
+
id: external_exports.string().trim().min(1),
|
|
18986
|
+
sessionId: SessionIdSchema,
|
|
18987
|
+
sequence: external_exports.number().int().nonnegative(),
|
|
18988
|
+
messageId: external_exports.string().trim().min(1),
|
|
18989
|
+
commandId: external_exports.string().trim().min(1).nullable(),
|
|
18990
|
+
turnId: external_exports.string().trim().min(1).nullable(),
|
|
18991
|
+
role: SessionMessageRoleSchema,
|
|
18992
|
+
status: SessionMessageStatusSchema,
|
|
18993
|
+
message: JsonValueSchema,
|
|
18994
|
+
createdAt: external_exports.string().datetime(),
|
|
18995
|
+
updatedAt: external_exports.string().datetime(),
|
|
18996
|
+
completedAt: external_exports.string().datetime().nullable()
|
|
18997
|
+
});
|
|
19078
18998
|
SessionListItemAgentSchema = external_exports.object({
|
|
19079
18999
|
name: external_exports.string(),
|
|
19080
19000
|
displayName: external_exports.string().nullable(),
|
|
@@ -23220,7 +23140,7 @@ var init_package = __esm({
|
|
|
23220
23140
|
"package.json"() {
|
|
23221
23141
|
package_default = {
|
|
23222
23142
|
name: "@autohq/cli",
|
|
23223
|
-
version: "0.1.
|
|
23143
|
+
version: "0.1.283",
|
|
23224
23144
|
license: "SEE LICENSE IN README.md",
|
|
23225
23145
|
publishConfig: {
|
|
23226
23146
|
access: "public"
|
|
@@ -23252,6 +23172,7 @@ var init_package = __esm({
|
|
|
23252
23172
|
"@anthropic-ai/claude-agent-sdk": "^0.3.153",
|
|
23253
23173
|
"@inkjs/ui": "^2.0.0",
|
|
23254
23174
|
"@tanstack/react-query": "^5.100.14",
|
|
23175
|
+
ai: "^6.0.217",
|
|
23255
23176
|
chalk: "^5.3.0",
|
|
23256
23177
|
commander: "^14.0.2",
|
|
23257
23178
|
ink: "^7",
|
|
@@ -23860,6 +23781,9 @@ function createConversationStreamWriter(input) {
|
|
|
23860
23781
|
input.writeLine(formatConversationRealtimeEvent(event));
|
|
23861
23782
|
return;
|
|
23862
23783
|
}
|
|
23784
|
+
if (event.type === "ui.message.chunk") {
|
|
23785
|
+
return;
|
|
23786
|
+
}
|
|
23863
23787
|
if (event.messageId && streamedMessageIds.has(event.messageId)) {
|
|
23864
23788
|
streamedMessageIds.delete(event.messageId);
|
|
23865
23789
|
input.writeChunk?.("\n");
|
|
@@ -23872,6 +23796,10 @@ function createConversationStreamWriter(input) {
|
|
|
23872
23796
|
};
|
|
23873
23797
|
}
|
|
23874
23798
|
function formatConversationRealtimeEvent(event) {
|
|
23799
|
+
if (event.type === "ui.message.chunk") {
|
|
23800
|
+
const chunkType = typeof event.chunk === "object" && event.chunk !== null && !Array.isArray(event.chunk) && typeof event.chunk.type === "string" ? event.chunk.type : "unknown";
|
|
23801
|
+
return `[${event.sequence}] ui message chunk: ${chunkType}`;
|
|
23802
|
+
}
|
|
23875
23803
|
if (event.type === "conversation.delta") {
|
|
23876
23804
|
return `[${event.sequence}] assistant/message ${event.delta.type} delta: ${event.delta.text}`;
|
|
23877
23805
|
}
|
|
@@ -23893,6 +23821,9 @@ function formatConversationEntry(entry) {
|
|
|
23893
23821
|
(question) => `${question.question} [${question.options.map((option) => option.label).join(" | ")}]`
|
|
23894
23822
|
).join("; ");
|
|
23895
23823
|
}
|
|
23824
|
+
if (part.type === "ui_message") {
|
|
23825
|
+
return JSON.stringify(part.message);
|
|
23826
|
+
}
|
|
23896
23827
|
return `${part.isError ? "tool error" : "tool result"} ${part.toolUseId ?? ""}: ${JSON.stringify(part.output)}`;
|
|
23897
23828
|
}).join("");
|
|
23898
23829
|
return `[${entry.sequence}] ${entry.role}/${entry.kind}: ${content}`;
|
|
@@ -27643,6 +27574,10 @@ function ConversationView({
|
|
|
27643
27574
|
sawLiveTurnActivity.current = true;
|
|
27644
27575
|
return;
|
|
27645
27576
|
}
|
|
27577
|
+
if (event.type === "ui.message.chunk") {
|
|
27578
|
+
sawLiveTurnActivity.current = true;
|
|
27579
|
+
return;
|
|
27580
|
+
}
|
|
27646
27581
|
if (event.kind === "question") {
|
|
27647
27582
|
pendingLocalCommand.current = null;
|
|
27648
27583
|
updateAwaitingReply(false);
|
|
@@ -28159,6 +28094,9 @@ function streamedCharCount(event) {
|
|
|
28159
28094
|
if (event.type === "conversation.delta") {
|
|
28160
28095
|
return event.delta.text.length;
|
|
28161
28096
|
}
|
|
28097
|
+
if (event.type !== "conversation.entry") {
|
|
28098
|
+
return 0;
|
|
28099
|
+
}
|
|
28162
28100
|
if (event.kind === "tool_call" && event.status !== "in_progress") {
|
|
28163
28101
|
return event.content.parts.filter((part) => part.type === "tool_call").reduce((total, part) => total + JSON.stringify(part.input).length, 0);
|
|
28164
28102
|
}
|
|
@@ -32996,12 +32934,17 @@ var ConversationQuestionContentPartSchema2 = external_exports.object({
|
|
|
32996
32934
|
toolCallId: external_exports.string().min(1).nullable(),
|
|
32997
32935
|
questions: external_exports.array(ConversationQuestionSchema2)
|
|
32998
32936
|
});
|
|
32937
|
+
var ConversationUiMessageContentPartSchema2 = external_exports.object({
|
|
32938
|
+
type: external_exports.literal("ui_message"),
|
|
32939
|
+
message: JsonValueSchema2
|
|
32940
|
+
});
|
|
32999
32941
|
var ConversationContentPartSchema2 = external_exports.discriminatedUnion("type", [
|
|
33000
32942
|
ConversationTextContentPartSchema2,
|
|
33001
32943
|
ConversationReasoningContentPartSchema2,
|
|
33002
32944
|
ConversationToolCallContentPartSchema2,
|
|
33003
32945
|
ConversationToolResultContentPartSchema2,
|
|
33004
|
-
ConversationQuestionContentPartSchema2
|
|
32946
|
+
ConversationQuestionContentPartSchema2,
|
|
32947
|
+
ConversationUiMessageContentPartSchema2
|
|
33005
32948
|
]);
|
|
33006
32949
|
var ConversationEntryContentSchema2 = external_exports.object({
|
|
33007
32950
|
parts: external_exports.array(ConversationContentPartSchema2)
|
|
@@ -33183,9 +33126,35 @@ var RuntimeBridgeOutputDeltaEnvelopeSchema = external_exports.object({
|
|
|
33183
33126
|
delta: ConversationDeltaSchema2,
|
|
33184
33127
|
createdAt: external_exports.string().datetime()
|
|
33185
33128
|
}).strict();
|
|
33129
|
+
var RuntimeBridgeOutputUiMessageChunkEnvelopeSchema = external_exports.object({
|
|
33130
|
+
type: external_exports.literal("ui.message.chunk"),
|
|
33131
|
+
sessionId: SessionIdSchema2,
|
|
33132
|
+
runtimeId: RuntimeIdSchema2,
|
|
33133
|
+
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
33134
|
+
outputSeq: external_exports.number().int().positive(),
|
|
33135
|
+
chunk: JsonValueSchema2,
|
|
33136
|
+
createdAt: external_exports.string().datetime()
|
|
33137
|
+
}).strict();
|
|
33138
|
+
var RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema = external_exports.object({
|
|
33139
|
+
type: external_exports.literal("ui.message.completed"),
|
|
33140
|
+
sessionId: SessionIdSchema2,
|
|
33141
|
+
runtimeId: RuntimeIdSchema2,
|
|
33142
|
+
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
33143
|
+
outputSeq: external_exports.number().int().positive(),
|
|
33144
|
+
messageId: external_exports.string().trim().min(1),
|
|
33145
|
+
role: external_exports.enum(["system", "user", "assistant"]),
|
|
33146
|
+
status: ConversationEntryStatusSchema2,
|
|
33147
|
+
message: JsonValueSchema2,
|
|
33148
|
+
turnStatus: external_exports.enum(["waiting_for_input", "completed", "failed"]).optional(),
|
|
33149
|
+
usage: RuntimeBridgeTurnUsageSchema.optional(),
|
|
33150
|
+
createdAt: external_exports.string().datetime(),
|
|
33151
|
+
completedAt: external_exports.string().datetime().nullable()
|
|
33152
|
+
}).strict();
|
|
33186
33153
|
var RuntimeBridgeOutputEnvelopeSchema = external_exports.union([
|
|
33187
33154
|
RuntimeBridgeOutputEntryEnvelopeSchema,
|
|
33188
|
-
RuntimeBridgeOutputDeltaEnvelopeSchema
|
|
33155
|
+
RuntimeBridgeOutputDeltaEnvelopeSchema,
|
|
33156
|
+
RuntimeBridgeOutputUiMessageChunkEnvelopeSchema,
|
|
33157
|
+
RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema
|
|
33189
33158
|
]);
|
|
33190
33159
|
function legacyRuntimeTurnStatus(entry, sessionStatusAfter) {
|
|
33191
33160
|
if (sessionStatusAfter === "failed" || entry.status === "failed") {
|
|
@@ -33665,17 +33634,27 @@ function outputLogContext(output, socketId) {
|
|
|
33665
33634
|
kind: "kind" in output ? output.kind : void 0,
|
|
33666
33635
|
output_status: "status" in output ? output.status : void 0,
|
|
33667
33636
|
delta_type: output.type === "conversation.delta" ? output.delta.type : void 0,
|
|
33637
|
+
ui_chunk_type: output.type === "ui.message.chunk" ? jsonRecordString(output.chunk, "type") : void 0,
|
|
33668
33638
|
message_id: "messageId" in output ? output.messageId : void 0
|
|
33669
33639
|
};
|
|
33670
33640
|
}
|
|
33671
33641
|
function errorMessage(error51) {
|
|
33672
33642
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
33673
33643
|
}
|
|
33644
|
+
function jsonRecordString(value, key) {
|
|
33645
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
33646
|
+
return void 0;
|
|
33647
|
+
}
|
|
33648
|
+
const field = value[key];
|
|
33649
|
+
return typeof field === "string" ? field : void 0;
|
|
33650
|
+
}
|
|
33674
33651
|
|
|
33675
33652
|
// src/commands/agent-bridge/harness/claude-code/index.ts
|
|
33676
33653
|
init_src();
|
|
33677
33654
|
|
|
33678
33655
|
// src/commands/agent-bridge/harness/output-buffer.ts
|
|
33656
|
+
init_src();
|
|
33657
|
+
import { readUIMessageStream } from "ai";
|
|
33679
33658
|
var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
|
|
33680
33659
|
var AgentBridgeOutputBuffer = class {
|
|
33681
33660
|
constructor(input) {
|
|
@@ -33687,12 +33666,17 @@ var AgentBridgeOutputBuffer = class {
|
|
|
33687
33666
|
pendingOutputs = /* @__PURE__ */ new Map();
|
|
33688
33667
|
pendingDelta = null;
|
|
33689
33668
|
deltaFlushTimer = null;
|
|
33669
|
+
activeUiMessageAssembler = null;
|
|
33690
33670
|
drainBlocked = false;
|
|
33691
33671
|
drainPromise = null;
|
|
33692
33672
|
// ---------------------------------------------------------------------------
|
|
33693
33673
|
// Public API
|
|
33694
33674
|
// ---------------------------------------------------------------------------
|
|
33695
33675
|
async emitProjection(context, projection) {
|
|
33676
|
+
if (projection.type === "ui_message_chunk") {
|
|
33677
|
+
await this.emitUiMessageChunk(context, projection);
|
|
33678
|
+
return;
|
|
33679
|
+
}
|
|
33696
33680
|
if (projection.type === "delta") {
|
|
33697
33681
|
await this.bufferDelta(context, projection.delta);
|
|
33698
33682
|
return;
|
|
@@ -33704,6 +33688,75 @@ var AgentBridgeOutputBuffer = class {
|
|
|
33704
33688
|
await this.flushPendingDelta({ force: true });
|
|
33705
33689
|
await this.drainPendingOutputs({ force: true });
|
|
33706
33690
|
}
|
|
33691
|
+
async emitUiMessageChunk(context, projection) {
|
|
33692
|
+
if (projection.chunk.type === "data-auto-question") {
|
|
33693
|
+
await this.flushPendingDelta();
|
|
33694
|
+
await this.emitLiveUiMessageChunk(context, projection.chunk);
|
|
33695
|
+
await this.enqueueProjectionAndDrain(context, {
|
|
33696
|
+
type: "entry",
|
|
33697
|
+
entry: {
|
|
33698
|
+
role: "assistant",
|
|
33699
|
+
kind: "question",
|
|
33700
|
+
...projection.turnStatus ? { turnStatus: projection.turnStatus } : {},
|
|
33701
|
+
content: {
|
|
33702
|
+
parts: [questionPart(projection.chunk.data)]
|
|
33703
|
+
}
|
|
33704
|
+
}
|
|
33705
|
+
});
|
|
33706
|
+
return;
|
|
33707
|
+
}
|
|
33708
|
+
await this.flushPendingDelta();
|
|
33709
|
+
await this.emitLiveUiMessageChunk(context, projection.chunk);
|
|
33710
|
+
const completedMessage = await this.appendUiChunkToAssembler(
|
|
33711
|
+
projection.chunk
|
|
33712
|
+
);
|
|
33713
|
+
if (!completedMessage || !completedMessage.id.trim()) {
|
|
33714
|
+
if (isTerminalUiMessageChunk(projection.chunk)) {
|
|
33715
|
+
const statusText = terminalStatusText(projection);
|
|
33716
|
+
if (statusText) {
|
|
33717
|
+
await this.enqueueProjectionAndDrain(context, {
|
|
33718
|
+
type: "entry",
|
|
33719
|
+
entry: {
|
|
33720
|
+
role: "system",
|
|
33721
|
+
kind: "status",
|
|
33722
|
+
status: terminalEntryStatus(projection),
|
|
33723
|
+
...projection.turnStatus ? { turnStatus: projection.turnStatus } : {},
|
|
33724
|
+
...projection.usage ? { usage: projection.usage } : {},
|
|
33725
|
+
content: {
|
|
33726
|
+
parts: [{ type: "text", text: statusText }]
|
|
33727
|
+
}
|
|
33728
|
+
}
|
|
33729
|
+
});
|
|
33730
|
+
}
|
|
33731
|
+
}
|
|
33732
|
+
return;
|
|
33733
|
+
}
|
|
33734
|
+
this.outputSeq += 1;
|
|
33735
|
+
const completedAt = now2();
|
|
33736
|
+
const completedOutput = buildUiMessageCompletedOutputEnvelope({
|
|
33737
|
+
context,
|
|
33738
|
+
outputSeq: this.outputSeq,
|
|
33739
|
+
message: completedMessage,
|
|
33740
|
+
status: terminalEntryStatus(projection),
|
|
33741
|
+
turnStatus: projection.turnStatus,
|
|
33742
|
+
usage: projection.usage,
|
|
33743
|
+
createdAt: completedAt,
|
|
33744
|
+
completedAt
|
|
33745
|
+
});
|
|
33746
|
+
this.enqueueOutput(completedOutput);
|
|
33747
|
+
await this.drainPendingOutputs();
|
|
33748
|
+
}
|
|
33749
|
+
async emitLiveUiMessageChunk(context, chunk) {
|
|
33750
|
+
this.outputSeq += 1;
|
|
33751
|
+
const output = buildUiMessageChunkOutputEnvelope({
|
|
33752
|
+
context,
|
|
33753
|
+
outputSeq: this.outputSeq,
|
|
33754
|
+
chunk,
|
|
33755
|
+
createdAt: now2()
|
|
33756
|
+
});
|
|
33757
|
+
this.enqueueOutput(output);
|
|
33758
|
+
await this.drainPendingOutputs();
|
|
33759
|
+
}
|
|
33707
33760
|
// ---------------------------------------------------------------------------
|
|
33708
33761
|
// Transport emit
|
|
33709
33762
|
// ---------------------------------------------------------------------------
|
|
@@ -33860,11 +33913,91 @@ var AgentBridgeOutputBuffer = class {
|
|
|
33860
33913
|
kind: output && "kind" in output ? output.kind : void 0,
|
|
33861
33914
|
output_status: output && "status" in output ? output.status : void 0,
|
|
33862
33915
|
delta_type: output?.type === "conversation.delta" ? output.delta.type : void 0,
|
|
33916
|
+
ui_chunk_type: output?.type === "ui.message.chunk" ? jsonRecordString2(output.chunk, "type") : void 0,
|
|
33863
33917
|
message_id: output && "messageId" in output ? output.messageId : void 0,
|
|
33864
33918
|
...fields
|
|
33865
33919
|
};
|
|
33866
33920
|
}
|
|
33921
|
+
async appendUiChunkToAssembler(chunk) {
|
|
33922
|
+
if (chunk.type === "start" || !this.activeUiMessageAssembler || this.activeUiMessageAssembler.done) {
|
|
33923
|
+
this.activeUiMessageAssembler = new UiMessageAssembler();
|
|
33924
|
+
}
|
|
33925
|
+
const completedMessage = await this.activeUiMessageAssembler.appendChunk(chunk);
|
|
33926
|
+
if (completedMessage) {
|
|
33927
|
+
this.activeUiMessageAssembler = null;
|
|
33928
|
+
}
|
|
33929
|
+
return completedMessage;
|
|
33930
|
+
}
|
|
33867
33931
|
};
|
|
33932
|
+
var UiMessageAssembler = class {
|
|
33933
|
+
controller = null;
|
|
33934
|
+
latestMessage = null;
|
|
33935
|
+
closed = false;
|
|
33936
|
+
drained;
|
|
33937
|
+
constructor() {
|
|
33938
|
+
const stream = new ReadableStream({
|
|
33939
|
+
start: (controller) => {
|
|
33940
|
+
this.controller = controller;
|
|
33941
|
+
}
|
|
33942
|
+
});
|
|
33943
|
+
this.drained = (async () => {
|
|
33944
|
+
try {
|
|
33945
|
+
for await (const message of readUIMessageStream({
|
|
33946
|
+
stream,
|
|
33947
|
+
terminateOnError: false
|
|
33948
|
+
})) {
|
|
33949
|
+
this.latestMessage = message;
|
|
33950
|
+
}
|
|
33951
|
+
} finally {
|
|
33952
|
+
this.closed = true;
|
|
33953
|
+
}
|
|
33954
|
+
})();
|
|
33955
|
+
}
|
|
33956
|
+
get done() {
|
|
33957
|
+
return this.closed;
|
|
33958
|
+
}
|
|
33959
|
+
async appendChunk(chunk) {
|
|
33960
|
+
try {
|
|
33961
|
+
this.controller?.enqueue(chunk);
|
|
33962
|
+
} catch {
|
|
33963
|
+
this.closed = true;
|
|
33964
|
+
return null;
|
|
33965
|
+
}
|
|
33966
|
+
if (!isTerminalUiMessageChunk(chunk)) {
|
|
33967
|
+
return null;
|
|
33968
|
+
}
|
|
33969
|
+
this.closed = true;
|
|
33970
|
+
this.controller?.close();
|
|
33971
|
+
await this.drained;
|
|
33972
|
+
return this.latestMessage;
|
|
33973
|
+
}
|
|
33974
|
+
};
|
|
33975
|
+
function isTerminalUiMessageChunk(chunk) {
|
|
33976
|
+
return chunk.type === "finish" || chunk.type === "error" || chunk.type === "abort";
|
|
33977
|
+
}
|
|
33978
|
+
function questionPart(data) {
|
|
33979
|
+
const parsed = data;
|
|
33980
|
+
return {
|
|
33981
|
+
type: "question",
|
|
33982
|
+
toolCallId: parsed.toolCallId ?? null,
|
|
33983
|
+
questions: parsed.questions
|
|
33984
|
+
};
|
|
33985
|
+
}
|
|
33986
|
+
function terminalStatusText(projection) {
|
|
33987
|
+
if (projection.statusText) {
|
|
33988
|
+
return projection.statusText;
|
|
33989
|
+
}
|
|
33990
|
+
if (projection.chunk.type === "error") {
|
|
33991
|
+
return projection.chunk.errorText;
|
|
33992
|
+
}
|
|
33993
|
+
return null;
|
|
33994
|
+
}
|
|
33995
|
+
function terminalEntryStatus(projection) {
|
|
33996
|
+
if (projection.turnStatus === "failed" || projection.chunk.type === "error" || projection.chunk.type === "abort") {
|
|
33997
|
+
return "failed";
|
|
33998
|
+
}
|
|
33999
|
+
return "completed";
|
|
34000
|
+
}
|
|
33868
34001
|
function canCoalesceDelta(pending, context, delta) {
|
|
33869
34002
|
return pending.context.sessionId === context.sessionId && pending.context.runtimeId === context.runtimeId && pending.context.bridgeLeaseId === context.bridgeLeaseId && pending.delta.messageId === delta.messageId && pending.delta.partId === delta.partId && pending.delta.role === delta.role && pending.delta.kind === delta.kind && pending.delta.delta.type === delta.delta.type;
|
|
33870
34003
|
}
|
|
@@ -33924,67 +34057,209 @@ function buildDeltaOutputEnvelope(input) {
|
|
|
33924
34057
|
createdAt: input.createdAt
|
|
33925
34058
|
});
|
|
33926
34059
|
}
|
|
34060
|
+
function buildUiMessageChunkOutputEnvelope(input) {
|
|
34061
|
+
const { context } = input;
|
|
34062
|
+
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
34063
|
+
type: "ui.message.chunk",
|
|
34064
|
+
sessionId: context.sessionId,
|
|
34065
|
+
runtimeId: context.runtimeId,
|
|
34066
|
+
bridgeLeaseId: context.bridgeLeaseId,
|
|
34067
|
+
outputSeq: input.outputSeq,
|
|
34068
|
+
chunk: toJsonValue(input.chunk),
|
|
34069
|
+
createdAt: input.createdAt
|
|
34070
|
+
});
|
|
34071
|
+
}
|
|
34072
|
+
function buildUiMessageCompletedOutputEnvelope(input) {
|
|
34073
|
+
const { context } = input;
|
|
34074
|
+
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
34075
|
+
type: "ui.message.completed",
|
|
34076
|
+
sessionId: context.sessionId,
|
|
34077
|
+
runtimeId: context.runtimeId,
|
|
34078
|
+
bridgeLeaseId: context.bridgeLeaseId,
|
|
34079
|
+
outputSeq: input.outputSeq,
|
|
34080
|
+
messageId: input.message.id,
|
|
34081
|
+
role: input.message.role,
|
|
34082
|
+
status: input.status,
|
|
34083
|
+
message: toJsonValue(input.message),
|
|
34084
|
+
...input.turnStatus ? { turnStatus: input.turnStatus } : {},
|
|
34085
|
+
...input.usage ? { usage: input.usage } : {},
|
|
34086
|
+
createdAt: input.createdAt,
|
|
34087
|
+
completedAt: input.completedAt
|
|
34088
|
+
});
|
|
34089
|
+
}
|
|
33927
34090
|
function isSuccessfulOutputAck(ack) {
|
|
33928
34091
|
return ack.status === "persisted" || ack.status === "duplicate" || ack.status === "published";
|
|
33929
34092
|
}
|
|
33930
34093
|
function now2() {
|
|
33931
34094
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
33932
34095
|
}
|
|
34096
|
+
function jsonRecordString2(value, key) {
|
|
34097
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
34098
|
+
return void 0;
|
|
34099
|
+
}
|
|
34100
|
+
const field = value[key];
|
|
34101
|
+
return typeof field === "string" ? field : void 0;
|
|
34102
|
+
}
|
|
33933
34103
|
|
|
33934
34104
|
// src/commands/agent-bridge/harness/claude-code/projector.ts
|
|
33935
34105
|
init_src();
|
|
33936
34106
|
var ClaudeCodeProjector = class {
|
|
33937
34107
|
currentMessageId = null;
|
|
34108
|
+
// The turn's UI message id. Claude emits a `message_start` per assistant
|
|
34109
|
+
// message, but a tool-using turn spans several (message A with the tool call,
|
|
34110
|
+
// the tool result, then message B). We open the UI message once per turn and
|
|
34111
|
+
// bracket each message as a step (finish-step at message_stop), closing it
|
|
34112
|
+
// with the single terminal `finish` at the turn result — so the whole turn,
|
|
34113
|
+
// including paired tool input/output, assembles into one UIMessage. Mirrors
|
|
34114
|
+
// the Codex projector's `ensureResponseStarted`.
|
|
34115
|
+
activeResponseMessageId = null;
|
|
34116
|
+
activeParts = /* @__PURE__ */ new Map();
|
|
34117
|
+
activeToolInputs = /* @__PURE__ */ new Map();
|
|
34118
|
+
streamedMessageIds = /* @__PURE__ */ new Set();
|
|
33938
34119
|
project(message) {
|
|
33939
34120
|
if (message.type === "stream_event") {
|
|
33940
|
-
|
|
33941
|
-
this.currentMessageId = anthropicMessageIdFromStreamStart(message) ?? UNKNOWN_MESSAGE_ID;
|
|
33942
|
-
return [];
|
|
33943
|
-
}
|
|
33944
|
-
if (message.event.type === "message_stop") {
|
|
33945
|
-
this.currentMessageId = null;
|
|
33946
|
-
return [];
|
|
33947
|
-
}
|
|
33948
|
-
const delta = partialAssistantDeltaPayload(
|
|
33949
|
-
message,
|
|
33950
|
-
this.currentMessageId ?? UNKNOWN_MESSAGE_ID
|
|
33951
|
-
);
|
|
33952
|
-
return delta ? [{ type: "delta", delta }] : [];
|
|
34121
|
+
return this.projectStreamEvent(message);
|
|
33953
34122
|
}
|
|
33954
34123
|
const parsed = parseClaudeCodeStreamRecord(message);
|
|
33955
|
-
const
|
|
33956
|
-
|
|
33957
|
-
|
|
33958
|
-
|
|
33959
|
-
|
|
33960
|
-
|
|
33961
|
-
|
|
33962
|
-
);
|
|
34124
|
+
const snapshotMessageId = assistantSnapshotMessageId(message);
|
|
34125
|
+
const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
|
|
34126
|
+
const outputs = !suppressStreamed && message.type === "assistant" ? projectAssistantSnapshot(parsed.projections) : parsed.projections.flatMap((entry) => {
|
|
34127
|
+
if (suppressStreamed && (entry.kind === "message" || entry.kind === "tool_call")) {
|
|
34128
|
+
return [];
|
|
34129
|
+
}
|
|
34130
|
+
return conversationProjectionToUiChunks(entry);
|
|
34131
|
+
});
|
|
33963
34132
|
if (parsed.result) {
|
|
34133
|
+
outputs.push(...this.endActiveParts(), ...this.finishActiveToolInputs());
|
|
34134
|
+
this.currentMessageId = null;
|
|
34135
|
+
this.activeResponseMessageId = null;
|
|
33964
34136
|
outputs.push(projectClaudeCodeResult(parsed.result));
|
|
33965
34137
|
}
|
|
33966
34138
|
return outputs;
|
|
33967
34139
|
}
|
|
34140
|
+
flushPendingAssistantMessages() {
|
|
34141
|
+
const outputs = [
|
|
34142
|
+
...this.endActiveParts(),
|
|
34143
|
+
uiChunk({ type: "finish", finishReason: "stop" })
|
|
34144
|
+
];
|
|
34145
|
+
this.currentMessageId = null;
|
|
34146
|
+
this.activeResponseMessageId = null;
|
|
34147
|
+
return outputs;
|
|
34148
|
+
}
|
|
34149
|
+
projectStreamEvent(message) {
|
|
34150
|
+
if (message.event.type === "message_start") {
|
|
34151
|
+
this.currentMessageId = anthropicMessageIdFromStreamStart(message) ?? UNKNOWN_MESSAGE_ID;
|
|
34152
|
+
this.streamedMessageIds.add(this.currentMessageId);
|
|
34153
|
+
this.activeParts.clear();
|
|
34154
|
+
this.activeToolInputs.clear();
|
|
34155
|
+
return this.ensureResponseStarted(this.currentMessageId);
|
|
34156
|
+
}
|
|
34157
|
+
if (message.event.type === "message_stop") {
|
|
34158
|
+
const outputs = [
|
|
34159
|
+
...this.endActiveParts(),
|
|
34160
|
+
...this.finishActiveToolInputs(),
|
|
34161
|
+
uiChunk({ type: "finish-step" })
|
|
34162
|
+
];
|
|
34163
|
+
this.currentMessageId = null;
|
|
34164
|
+
return outputs;
|
|
34165
|
+
}
|
|
34166
|
+
if (message.event.type === "content_block_start") {
|
|
34167
|
+
return this.startToolInput(message);
|
|
34168
|
+
}
|
|
34169
|
+
if (message.event.type === "content_block_stop") {
|
|
34170
|
+
return [
|
|
34171
|
+
...this.endActivePart(blockIndexId(message.event.index)),
|
|
34172
|
+
...this.finishActiveToolInput(blockIndexId(message.event.index))
|
|
34173
|
+
];
|
|
34174
|
+
}
|
|
34175
|
+
return partialAssistantDeltaProjections(
|
|
34176
|
+
message,
|
|
34177
|
+
this.activeParts,
|
|
34178
|
+
this.activeToolInputs
|
|
34179
|
+
);
|
|
34180
|
+
}
|
|
34181
|
+
// Open the turn's UI message exactly once. Subsequent messages in the same
|
|
34182
|
+
// turn reuse it (their content becomes additional steps), so the turn
|
|
34183
|
+
// assembles into a single UIMessage instead of the assembler resetting on
|
|
34184
|
+
// each `start` and dropping every message but the last.
|
|
34185
|
+
ensureResponseStarted(messageId) {
|
|
34186
|
+
if (this.activeResponseMessageId !== null) {
|
|
34187
|
+
return [];
|
|
34188
|
+
}
|
|
34189
|
+
this.activeResponseMessageId = messageId;
|
|
34190
|
+
return [uiChunk({ type: "start", messageId })];
|
|
34191
|
+
}
|
|
34192
|
+
endActiveParts() {
|
|
34193
|
+
const outputs = [...this.activeParts].map(([id]) => this.endActivePart(id));
|
|
34194
|
+
this.activeParts.clear();
|
|
34195
|
+
return outputs.flat();
|
|
34196
|
+
}
|
|
34197
|
+
endActivePart(id) {
|
|
34198
|
+
const type = this.activeParts.get(id);
|
|
34199
|
+
if (!type) {
|
|
34200
|
+
return [];
|
|
34201
|
+
}
|
|
34202
|
+
this.activeParts.delete(id);
|
|
34203
|
+
return [uiChunk({ type: `${type}-end`, id })];
|
|
34204
|
+
}
|
|
34205
|
+
startToolInput(message) {
|
|
34206
|
+
const started = toolInputStartFromEvent(message);
|
|
34207
|
+
if (!started) {
|
|
34208
|
+
return [];
|
|
34209
|
+
}
|
|
34210
|
+
this.activeToolInputs.set(started.index, {
|
|
34211
|
+
toolCallId: started.toolCallId,
|
|
34212
|
+
toolName: started.toolName,
|
|
34213
|
+
initialInput: started.input,
|
|
34214
|
+
inputText: ""
|
|
34215
|
+
});
|
|
34216
|
+
return [
|
|
34217
|
+
uiChunk({
|
|
34218
|
+
type: "tool-input-start",
|
|
34219
|
+
toolCallId: started.toolCallId,
|
|
34220
|
+
toolName: started.toolName
|
|
34221
|
+
})
|
|
34222
|
+
];
|
|
34223
|
+
}
|
|
34224
|
+
finishActiveToolInput(index) {
|
|
34225
|
+
const active = this.activeToolInputs.get(index);
|
|
34226
|
+
if (!active) {
|
|
34227
|
+
return [];
|
|
34228
|
+
}
|
|
34229
|
+
this.activeToolInputs.delete(index);
|
|
34230
|
+
return [
|
|
34231
|
+
uiChunk({
|
|
34232
|
+
type: "tool-input-available",
|
|
34233
|
+
toolCallId: active.toolCallId,
|
|
34234
|
+
toolName: active.toolName,
|
|
34235
|
+
input: completeToolInput(active)
|
|
34236
|
+
})
|
|
34237
|
+
];
|
|
34238
|
+
}
|
|
34239
|
+
finishActiveToolInputs() {
|
|
34240
|
+
return [...this.activeToolInputs.keys()].flatMap(
|
|
34241
|
+
(index) => this.finishActiveToolInput(index)
|
|
34242
|
+
);
|
|
34243
|
+
}
|
|
33968
34244
|
};
|
|
33969
34245
|
function projectClaudeCodeResult(result) {
|
|
33970
34246
|
return {
|
|
33971
|
-
type: "
|
|
33972
|
-
|
|
33973
|
-
|
|
33974
|
-
|
|
33975
|
-
|
|
33976
|
-
|
|
33977
|
-
|
|
33978
|
-
parts: [
|
|
33979
|
-
{
|
|
33980
|
-
type: "text",
|
|
33981
|
-
text: result.isError ? `claude-code failed: ${result.errorMessage ?? "unknown error"}` : "claude-code completed"
|
|
33982
|
-
}
|
|
33983
|
-
]
|
|
33984
|
-
}
|
|
33985
|
-
}
|
|
34247
|
+
type: "ui_message_chunk",
|
|
34248
|
+
chunk: {
|
|
34249
|
+
type: "finish",
|
|
34250
|
+
finishReason: result.isError ? "error" : "stop"
|
|
34251
|
+
},
|
|
34252
|
+
statusText: result.isError ? `claude-code failed: ${result.errorMessage ?? "unknown error"}` : "claude-code completed",
|
|
34253
|
+
turnStatus: result.isError ? "failed" : "completed"
|
|
33986
34254
|
};
|
|
33987
34255
|
}
|
|
34256
|
+
function assistantSnapshotMessageId(message) {
|
|
34257
|
+
if (message.type !== "assistant") {
|
|
34258
|
+
return null;
|
|
34259
|
+
}
|
|
34260
|
+
const id = message.message.id;
|
|
34261
|
+
return typeof id === "string" && id.trim() ? id : UNKNOWN_MESSAGE_ID;
|
|
34262
|
+
}
|
|
33988
34263
|
function anthropicMessageIdFromStreamStart(message) {
|
|
33989
34264
|
const event = message.event;
|
|
33990
34265
|
if (event.type !== "message_start") {
|
|
@@ -33993,27 +34268,284 @@ function anthropicMessageIdFromStreamStart(message) {
|
|
|
33993
34268
|
const id = event.message.id;
|
|
33994
34269
|
return typeof id === "string" && id.trim() ? id : null;
|
|
33995
34270
|
}
|
|
33996
|
-
function
|
|
34271
|
+
function partialAssistantDeltaProjections(message, activeParts, activeToolInputs) {
|
|
33997
34272
|
const event = message.event;
|
|
33998
34273
|
if (event.type !== "content_block_delta") {
|
|
33999
|
-
return
|
|
34274
|
+
return [];
|
|
34275
|
+
}
|
|
34276
|
+
const toolInputDelta = toolInputDeltaFromDelta(event.delta);
|
|
34277
|
+
if (toolInputDelta) {
|
|
34278
|
+
const active = activeToolInputs.get(blockIndexId(event.index));
|
|
34279
|
+
if (!active) {
|
|
34280
|
+
return [];
|
|
34281
|
+
}
|
|
34282
|
+
active.inputText += toolInputDelta;
|
|
34283
|
+
return [
|
|
34284
|
+
uiChunk({
|
|
34285
|
+
type: "tool-input-delta",
|
|
34286
|
+
toolCallId: active.toolCallId,
|
|
34287
|
+
inputTextDelta: toolInputDelta
|
|
34288
|
+
})
|
|
34289
|
+
];
|
|
34290
|
+
}
|
|
34291
|
+
const sourceChunk = sourceChunkFromDelta(event.delta, event.index);
|
|
34292
|
+
if (sourceChunk) {
|
|
34293
|
+
return [uiChunk(sourceChunk)];
|
|
34000
34294
|
}
|
|
34001
34295
|
const delta = event.delta;
|
|
34002
|
-
const
|
|
34003
|
-
if (text.length === 0) {
|
|
34296
|
+
const content = textContentFromDelta(delta);
|
|
34297
|
+
if (!content || content.text.length === 0) {
|
|
34298
|
+
return [];
|
|
34299
|
+
}
|
|
34300
|
+
const id = typeof event.index === "number" ? String(event.index) : "0";
|
|
34301
|
+
const outputs = [];
|
|
34302
|
+
if (!activeParts.has(id)) {
|
|
34303
|
+
activeParts.set(id, content.type);
|
|
34304
|
+
outputs.push(
|
|
34305
|
+
uiChunk({ type: `${content.type}-start`, id })
|
|
34306
|
+
);
|
|
34307
|
+
}
|
|
34308
|
+
outputs.push(
|
|
34309
|
+
uiChunk({
|
|
34310
|
+
type: `${content.type}-delta`,
|
|
34311
|
+
id,
|
|
34312
|
+
delta: content.text
|
|
34313
|
+
})
|
|
34314
|
+
);
|
|
34315
|
+
return outputs;
|
|
34316
|
+
}
|
|
34317
|
+
function toolInputStartFromEvent(message) {
|
|
34318
|
+
const event = message.event;
|
|
34319
|
+
if (event.type !== "content_block_start") {
|
|
34320
|
+
return null;
|
|
34321
|
+
}
|
|
34322
|
+
const contentBlock = event.content_block;
|
|
34323
|
+
if (contentBlock.type !== "tool_use" && contentBlock.type !== "mcp_tool_use" && contentBlock.type !== "server_tool_use") {
|
|
34324
|
+
return null;
|
|
34325
|
+
}
|
|
34326
|
+
const id = contentBlock.id;
|
|
34327
|
+
const name = contentBlock.name;
|
|
34328
|
+
if (typeof id !== "string" || typeof name !== "string") {
|
|
34329
|
+
return null;
|
|
34330
|
+
}
|
|
34331
|
+
if (name === ASK_USER_QUESTION_TOOL_NAME) {
|
|
34004
34332
|
return null;
|
|
34005
34333
|
}
|
|
34006
|
-
const index = event.index;
|
|
34007
|
-
const type = delta.type === "thinking_delta" ? "reasoning" : "text";
|
|
34008
34334
|
return {
|
|
34009
|
-
|
|
34010
|
-
|
|
34011
|
-
|
|
34012
|
-
|
|
34013
|
-
|
|
34014
|
-
|
|
34015
|
-
|
|
34335
|
+
index: blockIndexId(event.index),
|
|
34336
|
+
toolCallId: id,
|
|
34337
|
+
toolName: toolNameFromContentBlock(contentBlock, name),
|
|
34338
|
+
input: contentBlock.input
|
|
34339
|
+
};
|
|
34340
|
+
}
|
|
34341
|
+
function toolInputDeltaFromDelta(delta) {
|
|
34342
|
+
if (delta.type !== "input_json_delta") {
|
|
34343
|
+
return null;
|
|
34344
|
+
}
|
|
34345
|
+
return delta.partial_json;
|
|
34346
|
+
}
|
|
34347
|
+
function completeToolInput(input) {
|
|
34348
|
+
const inputText = input.inputText.trim();
|
|
34349
|
+
if (inputText.length > 0) {
|
|
34350
|
+
try {
|
|
34351
|
+
return JSON.parse(inputText);
|
|
34352
|
+
} catch {
|
|
34353
|
+
return input.inputText;
|
|
34354
|
+
}
|
|
34355
|
+
}
|
|
34356
|
+
return input.initialInput ?? {};
|
|
34357
|
+
}
|
|
34358
|
+
function sourceChunkFromDelta(delta, index) {
|
|
34359
|
+
if (delta.type !== "citations_delta") {
|
|
34360
|
+
return null;
|
|
34361
|
+
}
|
|
34362
|
+
const citation = delta.citation;
|
|
34363
|
+
if (citation.type === "web_search_result_location" && typeof citation.url === "string") {
|
|
34364
|
+
return {
|
|
34365
|
+
type: "source-url",
|
|
34366
|
+
sourceId: citationSourceId(citation, index),
|
|
34367
|
+
url: citation.url,
|
|
34368
|
+
...typeof citation.title === "string" ? { title: citation.title } : {},
|
|
34369
|
+
providerMetadata: anthropicCitationMetadata(citation)
|
|
34370
|
+
};
|
|
34371
|
+
}
|
|
34372
|
+
return {
|
|
34373
|
+
type: "source-document",
|
|
34374
|
+
sourceId: citationSourceId(citation, index),
|
|
34375
|
+
mediaType: "text/plain",
|
|
34376
|
+
title: citationTitle(citation, index),
|
|
34377
|
+
providerMetadata: anthropicCitationMetadata(citation)
|
|
34378
|
+
};
|
|
34379
|
+
}
|
|
34380
|
+
function toolNameFromContentBlock(contentBlock, name) {
|
|
34381
|
+
return contentBlock.type === "mcp_tool_use" && typeof contentBlock.server_name === "string" ? `${contentBlock.server_name}.${name}` : name;
|
|
34382
|
+
}
|
|
34383
|
+
function citationSourceId(citation, index) {
|
|
34384
|
+
for (const key of ["encrypted_index", "file_id", "source"]) {
|
|
34385
|
+
const value = citation[key];
|
|
34386
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
34387
|
+
return value;
|
|
34388
|
+
}
|
|
34389
|
+
}
|
|
34390
|
+
if (typeof citation.document_index === "number") {
|
|
34391
|
+
return `document:${citation.document_index.toString()}`;
|
|
34392
|
+
}
|
|
34393
|
+
return `citation:${index.toString()}`;
|
|
34394
|
+
}
|
|
34395
|
+
function citationTitle(citation, index) {
|
|
34396
|
+
for (const key of ["title", "document_title", "source", "file_id"]) {
|
|
34397
|
+
const value = citation[key];
|
|
34398
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
34399
|
+
return value;
|
|
34400
|
+
}
|
|
34401
|
+
}
|
|
34402
|
+
return `Claude citation ${index.toString()}`;
|
|
34403
|
+
}
|
|
34404
|
+
function anthropicCitationMetadata(citation) {
|
|
34405
|
+
return { anthropic: { citation: toJsonValue(citation) } };
|
|
34406
|
+
}
|
|
34407
|
+
function blockIndexId(index) {
|
|
34408
|
+
return index.toString();
|
|
34409
|
+
}
|
|
34410
|
+
function textContentFromDelta(delta) {
|
|
34411
|
+
switch (delta.type) {
|
|
34412
|
+
case "text_delta":
|
|
34413
|
+
return { type: "text", text: delta.text };
|
|
34414
|
+
case "thinking_delta":
|
|
34415
|
+
return { type: "reasoning", text: delta.thinking };
|
|
34416
|
+
default:
|
|
34417
|
+
return null;
|
|
34418
|
+
}
|
|
34419
|
+
}
|
|
34420
|
+
function conversationProjectionToUiChunks(projection) {
|
|
34421
|
+
if (projection.role === "assistant" && projection.kind === "message") {
|
|
34422
|
+
return messageContentChunks(projection);
|
|
34423
|
+
}
|
|
34424
|
+
if (projection.kind === "tool_call") {
|
|
34425
|
+
return toolCallChunks(projection);
|
|
34426
|
+
}
|
|
34427
|
+
if (projection.kind === "tool_result") {
|
|
34428
|
+
return projection.content.parts.flatMap((part) => {
|
|
34429
|
+
if (part.type !== "tool_result") {
|
|
34430
|
+
return [];
|
|
34431
|
+
}
|
|
34432
|
+
return [
|
|
34433
|
+
uiChunk(
|
|
34434
|
+
part.isError ? {
|
|
34435
|
+
type: "tool-output-error",
|
|
34436
|
+
toolCallId: part.toolUseId ?? UNKNOWN_MESSAGE_ID,
|
|
34437
|
+
errorText: JSON.stringify(part.output)
|
|
34438
|
+
} : {
|
|
34439
|
+
type: "tool-output-available",
|
|
34440
|
+
toolCallId: part.toolUseId ?? UNKNOWN_MESSAGE_ID,
|
|
34441
|
+
output: part.output
|
|
34442
|
+
}
|
|
34443
|
+
)
|
|
34444
|
+
];
|
|
34445
|
+
});
|
|
34446
|
+
}
|
|
34447
|
+
if (projection.kind === "question") {
|
|
34448
|
+
return projection.content.parts.flatMap(
|
|
34449
|
+
(part) => part.type === "question" ? [
|
|
34450
|
+
{
|
|
34451
|
+
type: "ui_message_chunk",
|
|
34452
|
+
chunk: {
|
|
34453
|
+
type: "data-auto-question",
|
|
34454
|
+
data: {
|
|
34455
|
+
toolCallId: part.toolCallId,
|
|
34456
|
+
questions: part.questions
|
|
34457
|
+
}
|
|
34458
|
+
},
|
|
34459
|
+
turnStatus: "waiting_for_input"
|
|
34460
|
+
}
|
|
34461
|
+
] : []
|
|
34462
|
+
);
|
|
34463
|
+
}
|
|
34464
|
+
return [
|
|
34465
|
+
{
|
|
34466
|
+
type: "entry",
|
|
34467
|
+
entry: projection
|
|
34468
|
+
}
|
|
34469
|
+
];
|
|
34470
|
+
}
|
|
34471
|
+
function projectAssistantSnapshot(projections) {
|
|
34472
|
+
return [
|
|
34473
|
+
...assistantSnapshotMessageChunks(projections),
|
|
34474
|
+
...projections.filter((projection) => !isAssistantMessageOrToolCall(projection)).flatMap((projection) => conversationProjectionToUiChunks(projection))
|
|
34475
|
+
];
|
|
34476
|
+
}
|
|
34477
|
+
function assistantSnapshotMessageChunks(projections) {
|
|
34478
|
+
const messageProjection = projections.find(
|
|
34479
|
+
(projection) => projection.role === "assistant" && projection.kind === "message"
|
|
34480
|
+
);
|
|
34481
|
+
const toolCallProjections = projections.filter(
|
|
34482
|
+
(projection) => projection.role === "assistant" && projection.kind === "tool_call"
|
|
34483
|
+
);
|
|
34484
|
+
if (!messageProjection && toolCallProjections.length === 0) {
|
|
34485
|
+
return [];
|
|
34486
|
+
}
|
|
34487
|
+
const messageId = messageProjection?.messageId ?? toolCallProjections.find((projection) => projection.messageId)?.messageId ?? UNKNOWN_MESSAGE_ID;
|
|
34488
|
+
const outputs = [
|
|
34489
|
+
uiChunk({ type: "start", messageId })
|
|
34490
|
+
];
|
|
34491
|
+
if (messageProjection) {
|
|
34492
|
+
outputs.push(...messagePartChunks(messageProjection));
|
|
34493
|
+
}
|
|
34494
|
+
outputs.push(
|
|
34495
|
+
...toolCallProjections.flatMap((projection) => toolCallChunks(projection))
|
|
34496
|
+
);
|
|
34497
|
+
if (toolCallProjections.length === 0) {
|
|
34498
|
+
outputs.push(uiChunk({ type: "finish", finishReason: "stop" }));
|
|
34499
|
+
}
|
|
34500
|
+
return outputs;
|
|
34501
|
+
}
|
|
34502
|
+
function isAssistantMessageOrToolCall(projection) {
|
|
34503
|
+
return projection.role === "assistant" && (projection.kind === "message" || projection.kind === "tool_call");
|
|
34504
|
+
}
|
|
34505
|
+
function messageContentChunks(projection) {
|
|
34506
|
+
const messageId = projection.messageId ?? UNKNOWN_MESSAGE_ID;
|
|
34507
|
+
const outputs = [
|
|
34508
|
+
uiChunk({ type: "start", messageId })
|
|
34509
|
+
];
|
|
34510
|
+
outputs.push(...messagePartChunks(projection));
|
|
34511
|
+
outputs.push(uiChunk({ type: "finish", finishReason: "stop" }));
|
|
34512
|
+
return outputs;
|
|
34513
|
+
}
|
|
34514
|
+
function messagePartChunks(projection) {
|
|
34515
|
+
const outputs = [];
|
|
34516
|
+
for (const [index, part] of projection.content.parts.entries()) {
|
|
34517
|
+
if (part.type !== "text" && part.type !== "reasoning") {
|
|
34518
|
+
continue;
|
|
34016
34519
|
}
|
|
34520
|
+
const id = `${part.type}-${index.toString()}`;
|
|
34521
|
+
outputs.push(
|
|
34522
|
+
uiChunk({ type: `${part.type}-start`, id }),
|
|
34523
|
+
uiChunk({
|
|
34524
|
+
type: `${part.type}-delta`,
|
|
34525
|
+
id,
|
|
34526
|
+
delta: part.text
|
|
34527
|
+
}),
|
|
34528
|
+
uiChunk({ type: `${part.type}-end`, id })
|
|
34529
|
+
);
|
|
34530
|
+
}
|
|
34531
|
+
return outputs;
|
|
34532
|
+
}
|
|
34533
|
+
function toolCallChunks(projection) {
|
|
34534
|
+
return projection.content.parts.flatMap(
|
|
34535
|
+
(part) => part.type === "tool_call" ? [
|
|
34536
|
+
uiChunk({
|
|
34537
|
+
type: "tool-input-available",
|
|
34538
|
+
toolCallId: part.toolCallId ?? UNKNOWN_MESSAGE_ID,
|
|
34539
|
+
toolName: part.name,
|
|
34540
|
+
input: part.input
|
|
34541
|
+
})
|
|
34542
|
+
] : []
|
|
34543
|
+
);
|
|
34544
|
+
}
|
|
34545
|
+
function uiChunk(chunk) {
|
|
34546
|
+
return {
|
|
34547
|
+
type: "ui_message_chunk",
|
|
34548
|
+
chunk
|
|
34017
34549
|
};
|
|
34018
34550
|
}
|
|
34019
34551
|
|
|
@@ -35264,6 +35796,9 @@ var ClaudeCodeCommandHandler = class {
|
|
|
35264
35796
|
if (!activeContext) {
|
|
35265
35797
|
return;
|
|
35266
35798
|
}
|
|
35799
|
+
for (const projection of this.projector.flushPendingAssistantMessages()) {
|
|
35800
|
+
await this.emitBridgeOutput(activeContext, projection);
|
|
35801
|
+
}
|
|
35267
35802
|
await this.emitBridgeOutput(
|
|
35268
35803
|
activeContext,
|
|
35269
35804
|
projectClaudeCodeResult({
|
|
@@ -35377,30 +35912,27 @@ init_src();
|
|
|
35377
35912
|
// src/commands/agent-bridge/harness/codex/projector.ts
|
|
35378
35913
|
init_src();
|
|
35379
35914
|
var CodexProjector = class {
|
|
35915
|
+
activeAgentMessages = /* @__PURE__ */ new Set();
|
|
35916
|
+
activeToolCalls = /* @__PURE__ */ new Set();
|
|
35917
|
+
activeResponseMessageId = null;
|
|
35380
35918
|
project(notification) {
|
|
35381
35919
|
switch (notification.type) {
|
|
35382
35920
|
case "agentMessageDelta":
|
|
35383
35921
|
return [
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
|
|
35389
|
-
role: "assistant",
|
|
35390
|
-
kind: "message",
|
|
35391
|
-
delta: { type: "text", text: notification.delta }
|
|
35392
|
-
}
|
|
35393
|
-
}
|
|
35922
|
+
...this.ensureResponseStarted(notification.itemId),
|
|
35923
|
+
...this.projectAgentMessageDelta(
|
|
35924
|
+
notification.itemId,
|
|
35925
|
+
notification.delta
|
|
35926
|
+
)
|
|
35394
35927
|
];
|
|
35395
35928
|
case "itemStarted":
|
|
35396
|
-
return
|
|
35397
|
-
projectCodexItem({ item: notification.item, phase: "started" })
|
|
35398
|
-
);
|
|
35929
|
+
return this.projectItem(notification.item, "started");
|
|
35399
35930
|
case "itemCompleted":
|
|
35400
|
-
return
|
|
35401
|
-
projectCodexItem({ item: notification.item, phase: "completed" })
|
|
35402
|
-
);
|
|
35931
|
+
return this.projectItem(notification.item, "completed");
|
|
35403
35932
|
case "turnCompleted":
|
|
35933
|
+
this.activeResponseMessageId = null;
|
|
35934
|
+
this.activeAgentMessages.clear();
|
|
35935
|
+
this.activeToolCalls.clear();
|
|
35404
35936
|
return [turnCompletionEntry(notification)];
|
|
35405
35937
|
case "error":
|
|
35406
35938
|
return [errorEntry(notification)];
|
|
@@ -35408,81 +35940,267 @@ var CodexProjector = class {
|
|
|
35408
35940
|
return [];
|
|
35409
35941
|
}
|
|
35410
35942
|
}
|
|
35411
|
-
// An approval parks the turn on operator input, so the question
|
|
35943
|
+
// An approval parks the turn on operator input, so the question chunk also
|
|
35412
35944
|
// marks the delivered turn as waiting for input.
|
|
35413
35945
|
projectApproval(request) {
|
|
35414
|
-
return
|
|
35415
|
-
|
|
35416
|
-
|
|
35417
|
-
|
|
35946
|
+
return [
|
|
35947
|
+
uiChunk2({
|
|
35948
|
+
type: "tool-approval-request",
|
|
35949
|
+
approvalId: String(request.requestId),
|
|
35950
|
+
toolCallId: request.itemId
|
|
35951
|
+
}),
|
|
35952
|
+
{
|
|
35953
|
+
type: "ui_message_chunk",
|
|
35954
|
+
chunk: {
|
|
35955
|
+
type: "data-auto-question",
|
|
35956
|
+
data: {
|
|
35957
|
+
toolCallId: request.itemId,
|
|
35958
|
+
questions: [approvalQuestion(request)]
|
|
35959
|
+
}
|
|
35960
|
+
},
|
|
35418
35961
|
turnStatus: "waiting_for_input"
|
|
35419
35962
|
}
|
|
35420
|
-
|
|
35963
|
+
];
|
|
35421
35964
|
}
|
|
35422
35965
|
// Surfaces a session-level failure (e.g. the app-server process dying) as a
|
|
35423
35966
|
// durable failed status entry rather than only a diagnostic log line.
|
|
35424
35967
|
projectSessionFailure(message) {
|
|
35425
35968
|
return {
|
|
35426
|
-
type: "
|
|
35427
|
-
|
|
35428
|
-
role: "system",
|
|
35429
|
-
kind: "status",
|
|
35430
|
-
status: "failed",
|
|
35431
|
-
turnStatus: "failed",
|
|
35432
|
-
content: {
|
|
35433
|
-
parts: [{ type: "text", text: `codex failed: ${message}` }]
|
|
35434
|
-
}
|
|
35435
|
-
}
|
|
35969
|
+
type: "ui_message_chunk",
|
|
35970
|
+
chunk: { type: "error", errorText: `codex failed: ${message}` }
|
|
35436
35971
|
};
|
|
35437
35972
|
}
|
|
35973
|
+
projectAgentMessageDelta(itemId, delta) {
|
|
35974
|
+
const outputs = [];
|
|
35975
|
+
if (!this.activeAgentMessages.has(itemId)) {
|
|
35976
|
+
this.activeAgentMessages.add(itemId);
|
|
35977
|
+
outputs.push(uiChunk2({ type: "text-start", id: textPartId(itemId) }));
|
|
35978
|
+
}
|
|
35979
|
+
outputs.push(
|
|
35980
|
+
uiChunk2({ type: "text-delta", id: textPartId(itemId), delta })
|
|
35981
|
+
);
|
|
35982
|
+
return outputs;
|
|
35983
|
+
}
|
|
35984
|
+
projectItem(item, phase) {
|
|
35985
|
+
switch (item.type) {
|
|
35986
|
+
case "agentMessage":
|
|
35987
|
+
return [
|
|
35988
|
+
...this.ensureResponseStarted(item.id),
|
|
35989
|
+
...this.projectAgentMessageItem(item, phase)
|
|
35990
|
+
];
|
|
35991
|
+
case "reasoning":
|
|
35992
|
+
return phase === "completed" ? [
|
|
35993
|
+
...this.ensureResponseStarted(item.id),
|
|
35994
|
+
...reasoningItemChunks(item)
|
|
35995
|
+
] : [];
|
|
35996
|
+
case "commandExecution":
|
|
35997
|
+
return this.projectToolItem({
|
|
35998
|
+
phase,
|
|
35999
|
+
itemId: item.id,
|
|
36000
|
+
name: "shell",
|
|
36001
|
+
input: {
|
|
36002
|
+
command: item.command,
|
|
36003
|
+
...item.cwd ? { cwd: item.cwd } : {}
|
|
36004
|
+
},
|
|
36005
|
+
output: item.aggregatedOutput ?? "",
|
|
36006
|
+
isError: isFailedStatus(item.status) || (item.exitCode ?? 0) !== 0,
|
|
36007
|
+
title: item.command,
|
|
36008
|
+
toolMetadata: statusMetadata(item.status, {
|
|
36009
|
+
...item.exitCode !== void 0 ? { exitCode: item.exitCode } : {}
|
|
36010
|
+
})
|
|
36011
|
+
});
|
|
36012
|
+
case "fileChange":
|
|
36013
|
+
return this.projectToolItem({
|
|
36014
|
+
phase,
|
|
36015
|
+
itemId: item.id,
|
|
36016
|
+
name: "apply_patch",
|
|
36017
|
+
input: { changes: toJsonValue(item.changes) },
|
|
36018
|
+
output: { status: item.status ?? "unknown" },
|
|
36019
|
+
isError: isFailedStatus(item.status),
|
|
36020
|
+
title: "apply_patch",
|
|
36021
|
+
toolMetadata: statusMetadata(item.status)
|
|
36022
|
+
});
|
|
36023
|
+
case "mcpToolCall":
|
|
36024
|
+
return this.projectToolItem({
|
|
36025
|
+
phase,
|
|
36026
|
+
itemId: item.id,
|
|
36027
|
+
name: `${item.server}.${item.tool}`,
|
|
36028
|
+
input: toJsonValue(item.arguments),
|
|
36029
|
+
output: item.error ? { error: item.error.message } : toJsonValue(item.result),
|
|
36030
|
+
isError: isFailedStatus(item.status) || item.error != null,
|
|
36031
|
+
title: `${item.server}.${item.tool}`,
|
|
36032
|
+
toolMetadata: statusMetadata(item.status, {
|
|
36033
|
+
server: item.server,
|
|
36034
|
+
tool: item.tool
|
|
36035
|
+
})
|
|
36036
|
+
});
|
|
36037
|
+
default:
|
|
36038
|
+
return [];
|
|
36039
|
+
}
|
|
36040
|
+
}
|
|
36041
|
+
projectToolItem(input) {
|
|
36042
|
+
const outputs = [];
|
|
36043
|
+
outputs.push(...this.ensureResponseStarted(input.itemId));
|
|
36044
|
+
if (input.phase === "started" || !this.activeToolCalls.has(input.itemId)) {
|
|
36045
|
+
outputs.push(toolInputChunk(input));
|
|
36046
|
+
this.activeToolCalls.add(input.itemId);
|
|
36047
|
+
}
|
|
36048
|
+
if (input.phase === "started") {
|
|
36049
|
+
return outputs;
|
|
36050
|
+
}
|
|
36051
|
+
outputs.push(toolOutputChunk(input));
|
|
36052
|
+
outputs.push(uiChunk2({ type: "finish-step" }));
|
|
36053
|
+
this.activeToolCalls.delete(input.itemId);
|
|
36054
|
+
return outputs;
|
|
36055
|
+
}
|
|
36056
|
+
projectAgentMessageItem(item, phase) {
|
|
36057
|
+
if (phase === "started") {
|
|
36058
|
+
if (this.activeAgentMessages.has(item.id)) {
|
|
36059
|
+
return [];
|
|
36060
|
+
}
|
|
36061
|
+
this.activeAgentMessages.add(item.id);
|
|
36062
|
+
return [uiChunk2({ type: "text-start", id: textPartId(item.id) })];
|
|
36063
|
+
}
|
|
36064
|
+
const outputs = [];
|
|
36065
|
+
if (!this.activeAgentMessages.has(item.id)) {
|
|
36066
|
+
outputs.push(uiChunk2({ type: "text-start", id: textPartId(item.id) }));
|
|
36067
|
+
if (item.text.length > 0) {
|
|
36068
|
+
outputs.push(
|
|
36069
|
+
uiChunk2({
|
|
36070
|
+
type: "text-delta",
|
|
36071
|
+
id: textPartId(item.id),
|
|
36072
|
+
delta: item.text
|
|
36073
|
+
})
|
|
36074
|
+
);
|
|
36075
|
+
}
|
|
36076
|
+
}
|
|
36077
|
+
outputs.push(
|
|
36078
|
+
uiChunk2({ type: "text-end", id: textPartId(item.id) }),
|
|
36079
|
+
uiChunk2({ type: "finish-step" })
|
|
36080
|
+
);
|
|
36081
|
+
this.activeAgentMessages.delete(item.id);
|
|
36082
|
+
return outputs;
|
|
36083
|
+
}
|
|
36084
|
+
ensureResponseStarted(messageId) {
|
|
36085
|
+
if (this.activeResponseMessageId !== null) {
|
|
36086
|
+
return [];
|
|
36087
|
+
}
|
|
36088
|
+
this.activeResponseMessageId = messageId;
|
|
36089
|
+
return [uiChunk2({ type: "start", messageId })];
|
|
36090
|
+
}
|
|
35438
36091
|
};
|
|
35439
|
-
function
|
|
35440
|
-
|
|
35441
|
-
|
|
35442
|
-
|
|
35443
|
-
}
|
|
36092
|
+
function reasoningItemChunks(item) {
|
|
36093
|
+
const text = item.summary.map((line) => line.trim()).filter(Boolean).join("\n\n");
|
|
36094
|
+
if (text.length === 0) {
|
|
36095
|
+
return [];
|
|
36096
|
+
}
|
|
36097
|
+
const id = reasoningPartId(item.id);
|
|
36098
|
+
return [
|
|
36099
|
+
uiChunk2({ type: "reasoning-start", id }),
|
|
36100
|
+
uiChunk2({ type: "reasoning-delta", id, delta: text }),
|
|
36101
|
+
uiChunk2({ type: "reasoning-end", id }),
|
|
36102
|
+
uiChunk2({ type: "finish-step" })
|
|
36103
|
+
];
|
|
36104
|
+
}
|
|
36105
|
+
function toolInputChunk(input) {
|
|
36106
|
+
return uiChunk2({
|
|
36107
|
+
type: "tool-input-available",
|
|
36108
|
+
toolCallId: input.itemId,
|
|
36109
|
+
toolName: input.name,
|
|
36110
|
+
input: input.input,
|
|
36111
|
+
...input.title ? { title: input.title } : {},
|
|
36112
|
+
...input.toolMetadata ? { toolMetadata: input.toolMetadata } : {}
|
|
36113
|
+
});
|
|
36114
|
+
}
|
|
36115
|
+
function toolOutputChunk(input) {
|
|
36116
|
+
return uiChunk2(
|
|
36117
|
+
input.isError ? {
|
|
36118
|
+
type: "tool-output-error",
|
|
36119
|
+
toolCallId: input.itemId,
|
|
36120
|
+
errorText: JSON.stringify(input.output),
|
|
36121
|
+
...input.toolMetadata ? { toolMetadata: input.toolMetadata } : {}
|
|
36122
|
+
} : {
|
|
36123
|
+
type: "tool-output-available",
|
|
36124
|
+
toolCallId: input.itemId,
|
|
36125
|
+
output: input.output,
|
|
36126
|
+
...input.toolMetadata ? { toolMetadata: input.toolMetadata } : {}
|
|
36127
|
+
}
|
|
36128
|
+
);
|
|
35444
36129
|
}
|
|
35445
36130
|
function turnCompletionEntry(notification) {
|
|
35446
36131
|
if (notification.status === "failed") {
|
|
35447
36132
|
const detail = notification.errorMessage ?? "unknown error";
|
|
35448
|
-
return
|
|
36133
|
+
return statusFinish({
|
|
35449
36134
|
text: `codex turn failed: ${detail}`,
|
|
35450
|
-
status: "failed",
|
|
35451
36135
|
turnStatus: "failed"
|
|
35452
36136
|
});
|
|
35453
36137
|
}
|
|
35454
|
-
|
|
35455
|
-
|
|
35456
|
-
text,
|
|
35457
|
-
status: "completed",
|
|
36138
|
+
return statusFinish({
|
|
36139
|
+
text: notification.status === "interrupted" ? "codex turn interrupted" : "codex turn completed",
|
|
35458
36140
|
turnStatus: "completed"
|
|
35459
36141
|
});
|
|
35460
36142
|
}
|
|
35461
36143
|
function errorEntry(notification) {
|
|
35462
36144
|
if (notification.willRetry) {
|
|
35463
|
-
return
|
|
35464
|
-
text: `codex retrying after error: ${notification.message}
|
|
35465
|
-
status: "completed"
|
|
36145
|
+
return statusFinish({
|
|
36146
|
+
text: `codex retrying after error: ${notification.message}`
|
|
35466
36147
|
});
|
|
35467
36148
|
}
|
|
35468
|
-
return
|
|
36149
|
+
return statusFinish({
|
|
35469
36150
|
text: `codex error: ${notification.message}`,
|
|
35470
|
-
status: "failed",
|
|
35471
36151
|
turnStatus: "failed"
|
|
35472
36152
|
});
|
|
35473
36153
|
}
|
|
35474
|
-
function
|
|
36154
|
+
function statusFinish(input) {
|
|
35475
36155
|
return {
|
|
35476
|
-
type: "
|
|
35477
|
-
|
|
35478
|
-
|
|
35479
|
-
|
|
35480
|
-
|
|
35481
|
-
|
|
35482
|
-
|
|
35483
|
-
}
|
|
36156
|
+
type: "ui_message_chunk",
|
|
36157
|
+
chunk: {
|
|
36158
|
+
type: "finish",
|
|
36159
|
+
finishReason: input.turnStatus === "failed" ? "error" : "stop"
|
|
36160
|
+
},
|
|
36161
|
+
statusText: input.text,
|
|
36162
|
+
...input.turnStatus ? { turnStatus: input.turnStatus } : {}
|
|
35484
36163
|
};
|
|
35485
36164
|
}
|
|
36165
|
+
function approvalQuestion(request) {
|
|
36166
|
+
const subject = request.type === "commandExecution" ? `run the command: ${request.command ?? "(unknown command)"}` : "apply file changes";
|
|
36167
|
+
return {
|
|
36168
|
+
question: request.reason ? `Codex requests approval to ${subject}. ${request.reason}` : `Codex requests approval to ${subject}.`,
|
|
36169
|
+
header: "Approval",
|
|
36170
|
+
options: [
|
|
36171
|
+
{ label: APPROVE_OPTION_LABEL, description: "Allow this action." },
|
|
36172
|
+
{ label: DECLINE_OPTION_LABEL, description: "Reject this action." }
|
|
36173
|
+
],
|
|
36174
|
+
multiSelect: false
|
|
36175
|
+
};
|
|
36176
|
+
}
|
|
36177
|
+
function textPartId(itemId) {
|
|
36178
|
+
return `${itemId}:text`;
|
|
36179
|
+
}
|
|
36180
|
+
function reasoningPartId(itemId) {
|
|
36181
|
+
return `${itemId}:reasoning`;
|
|
36182
|
+
}
|
|
36183
|
+
function isFailedStatus(status) {
|
|
36184
|
+
return status === "failed" || status === "declined";
|
|
36185
|
+
}
|
|
36186
|
+
function statusMetadata(status, fields = {}) {
|
|
36187
|
+
return {
|
|
36188
|
+
status: status ?? "unknown",
|
|
36189
|
+
...fields
|
|
36190
|
+
};
|
|
36191
|
+
}
|
|
36192
|
+
function uiChunk2(chunk) {
|
|
36193
|
+
return {
|
|
36194
|
+
type: "ui_message_chunk",
|
|
36195
|
+
chunk: normalizeChunk(chunk)
|
|
36196
|
+
};
|
|
36197
|
+
}
|
|
36198
|
+
function normalizeChunk(chunk) {
|
|
36199
|
+
if ("toolCallId" in chunk && (!chunk.toolCallId || chunk.toolCallId.trim().length === 0)) {
|
|
36200
|
+
return { ...chunk, toolCallId: UNKNOWN_MESSAGE_ID };
|
|
36201
|
+
}
|
|
36202
|
+
return chunk;
|
|
36203
|
+
}
|
|
35486
36204
|
|
|
35487
36205
|
// src/commands/agent-bridge/harness/codex/resume-store.ts
|
|
35488
36206
|
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -36253,7 +36971,9 @@ var CodexCommandHandler = class {
|
|
|
36253
36971
|
this.input.writeOutput?.(
|
|
36254
36972
|
`agent_bridge_codex_question_pending tool_use_id=${request.itemId}`
|
|
36255
36973
|
);
|
|
36256
|
-
|
|
36974
|
+
for (const projection of this.projector.projectApproval(request)) {
|
|
36975
|
+
await this.emit(activeContext, projection);
|
|
36976
|
+
}
|
|
36257
36977
|
}
|
|
36258
36978
|
async handleSessionError(error51) {
|
|
36259
36979
|
this.input.writeOutput?.(
|
|
@@ -40261,6 +40981,8 @@ function entryPreview(event, full) {
|
|
|
40261
40981
|
return stringify5(part.output);
|
|
40262
40982
|
case "question":
|
|
40263
40983
|
return part.questions.map((question) => question.question).join(" ");
|
|
40984
|
+
case "ui_message":
|
|
40985
|
+
return stringify5(part.message);
|
|
40264
40986
|
default:
|
|
40265
40987
|
return "";
|
|
40266
40988
|
}
|