replicas-engine 0.1.462 → 0.1.464
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/src/index.js +1197 -16
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -51,6 +51,9 @@ function isValidAgentProvider(value) {
|
|
|
51
51
|
return VALID_AGENT_PROVIDERS.some((p) => p === value);
|
|
52
52
|
}
|
|
53
53
|
var VALID_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
54
|
+
function isValidThinkingLevel(value) {
|
|
55
|
+
return VALID_THINKING_LEVELS.some((l) => l === value);
|
|
56
|
+
}
|
|
54
57
|
var CODEX_REASONING_EFFORT_BY_THINKING_LEVEL = {
|
|
55
58
|
low: "low",
|
|
56
59
|
medium: "medium",
|
|
@@ -64,6 +67,21 @@ function codexReasoningEffortForThinkingLevel(thinkingLevel) {
|
|
|
64
67
|
|
|
65
68
|
// ../shared/src/event.ts
|
|
66
69
|
var CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE = "claude-partial-message";
|
|
70
|
+
function coerceClaudePartialMessagePayload(payload) {
|
|
71
|
+
const streamId = payload.streamId;
|
|
72
|
+
if (typeof streamId !== "string" || !streamId) return null;
|
|
73
|
+
const parentToolUseId = payload.parent_tool_use_id;
|
|
74
|
+
const text = typeof payload.text === "string" && payload.text ? payload.text : void 0;
|
|
75
|
+
const thinking = typeof payload.thinking === "string" && payload.thinking ? payload.thinking : void 0;
|
|
76
|
+
if (!text && !thinking) return null;
|
|
77
|
+
return {
|
|
78
|
+
streamId,
|
|
79
|
+
parent_tool_use_id: typeof parentToolUseId === "string" ? parentToolUseId : null,
|
|
80
|
+
...text ? { text } : {},
|
|
81
|
+
...thinking ? { thinking } : {},
|
|
82
|
+
status: payload.status === "completed" ? "completed" : "in_progress"
|
|
83
|
+
};
|
|
84
|
+
}
|
|
67
85
|
var ACCEPTED_USER_MESSAGE_SOURCE = "replicas-chat-turn-accepted";
|
|
68
86
|
var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
69
87
|
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
@@ -543,7 +561,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
543
561
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
544
562
|
|
|
545
563
|
// ../shared/src/e2b.ts
|
|
546
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-19-
|
|
564
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-19-v16";
|
|
547
565
|
|
|
548
566
|
// ../shared/src/runtime-env.ts
|
|
549
567
|
function shellQuotePosix(value) {
|
|
@@ -3087,6 +3105,10 @@ var AUDIT_LOG_ACTIONS = Object.values(AUDIT_LOG_ACTION);
|
|
|
3087
3105
|
// ../shared/src/automations/types.ts
|
|
3088
3106
|
var AUTOMATION_DEBOUNCE_MAX_SECONDS = 24 * 60 * 60;
|
|
3089
3107
|
|
|
3108
|
+
// ../shared/src/routes/admin.ts
|
|
3109
|
+
var WEBHOOK_PROVIDERS = ["linear", "github", "gitlab", "slack", "e2b", "stripe", "sentry"];
|
|
3110
|
+
var WEBHOOK_PROVIDER_SET = new Set(WEBHOOK_PROVIDERS);
|
|
3111
|
+
|
|
3090
3112
|
// ../shared/src/display-message/types.ts
|
|
3091
3113
|
var BACKGROUND_TASK_SUBTYPES = /* @__PURE__ */ new Set([
|
|
3092
3114
|
"task_started",
|
|
@@ -3154,6 +3176,654 @@ function isTerminalBackgroundTaskStatus(status) {
|
|
|
3154
3176
|
// ../shared/src/display-message/constants.ts
|
|
3155
3177
|
var USER_MESSAGE_MATCH_GRACE_PERIOD_MS = 3e4;
|
|
3156
3178
|
|
|
3179
|
+
// ../shared/src/json.ts
|
|
3180
|
+
function safeJsonParse(str, fallback) {
|
|
3181
|
+
try {
|
|
3182
|
+
return JSON.parse(str);
|
|
3183
|
+
} catch {
|
|
3184
|
+
return fallback;
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
3189
|
+
function getStatusFromExitCode(exitCode) {
|
|
3190
|
+
return exitCode === 0 ? "completed" : "failed";
|
|
3191
|
+
}
|
|
3192
|
+
function getPayloadString(event, key) {
|
|
3193
|
+
const value = event.payload?.[key];
|
|
3194
|
+
return typeof value === "string" ? value : null;
|
|
3195
|
+
}
|
|
3196
|
+
function displayId(event, eventIndex, prefix) {
|
|
3197
|
+
const stableId = getPayloadString(event, USER_MESSAGE_ID_PAYLOAD_KEY) ?? getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY);
|
|
3198
|
+
return stableId ? `${prefix}-${stableId}` : `${prefix}-${event.timestamp}-${eventIndex}`;
|
|
3199
|
+
}
|
|
3200
|
+
function userMessageImages(value) {
|
|
3201
|
+
if (!Array.isArray(value)) return void 0;
|
|
3202
|
+
const images = value.filter((item) => {
|
|
3203
|
+
if (!isRecord(item)) return false;
|
|
3204
|
+
return item.type === "image" && typeof item.mediaType === "string" && typeof item.data === "string";
|
|
3205
|
+
});
|
|
3206
|
+
return images.length > 0 ? images : void 0;
|
|
3207
|
+
}
|
|
3208
|
+
function parseShellOutput(raw) {
|
|
3209
|
+
const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
|
|
3210
|
+
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
3211
|
+
const outputIndex = raw.indexOf("Output:\n");
|
|
3212
|
+
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
3213
|
+
return { exitCode, output };
|
|
3214
|
+
}
|
|
3215
|
+
function parsePatch(input) {
|
|
3216
|
+
const operations = [];
|
|
3217
|
+
const lines = input.split("\n");
|
|
3218
|
+
let currentOp = null;
|
|
3219
|
+
let diffLines = [];
|
|
3220
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3221
|
+
const line = lines[i];
|
|
3222
|
+
if (line.startsWith("*** Add File:")) {
|
|
3223
|
+
if (currentOp) {
|
|
3224
|
+
if (diffLines.length > 0) currentOp.diff = diffLines.join("\n");
|
|
3225
|
+
operations.push(currentOp);
|
|
3226
|
+
diffLines = [];
|
|
3227
|
+
}
|
|
3228
|
+
currentOp = {
|
|
3229
|
+
action: "add",
|
|
3230
|
+
path: line.replace("*** Add File:", "").trim()
|
|
3231
|
+
};
|
|
3232
|
+
} else if (line.startsWith("*** Update File:")) {
|
|
3233
|
+
if (currentOp) {
|
|
3234
|
+
if (diffLines.length > 0) currentOp.diff = diffLines.join("\n");
|
|
3235
|
+
operations.push(currentOp);
|
|
3236
|
+
diffLines = [];
|
|
3237
|
+
}
|
|
3238
|
+
currentOp = {
|
|
3239
|
+
action: "update",
|
|
3240
|
+
path: line.replace("*** Update File:", "").trim()
|
|
3241
|
+
};
|
|
3242
|
+
} else if (line.startsWith("*** Delete File:")) {
|
|
3243
|
+
if (currentOp) {
|
|
3244
|
+
if (diffLines.length > 0) currentOp.diff = diffLines.join("\n");
|
|
3245
|
+
operations.push(currentOp);
|
|
3246
|
+
diffLines = [];
|
|
3247
|
+
}
|
|
3248
|
+
currentOp = {
|
|
3249
|
+
action: "delete",
|
|
3250
|
+
path: line.replace("*** Delete File:", "").trim()
|
|
3251
|
+
};
|
|
3252
|
+
} else if (line.startsWith("*** Move to:")) {
|
|
3253
|
+
if (currentOp) {
|
|
3254
|
+
currentOp.moveTo = line.replace("*** Move to:", "").trim();
|
|
3255
|
+
}
|
|
3256
|
+
} else if (line.startsWith("*** Begin Patch") || line.startsWith("*** End Patch")) {
|
|
3257
|
+
continue;
|
|
3258
|
+
} else if (currentOp && (line.startsWith("+") || line.startsWith("-") || line.startsWith(" ") || line.startsWith("@@") || line.trim() === "")) {
|
|
3259
|
+
diffLines.push(line);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
if (currentOp) {
|
|
3263
|
+
if (diffLines.length > 0) currentOp.diff = diffLines.join("\n");
|
|
3264
|
+
operations.push(currentOp);
|
|
3265
|
+
}
|
|
3266
|
+
return operations;
|
|
3267
|
+
}
|
|
3268
|
+
function parseCodexEvents(events) {
|
|
3269
|
+
const messages = [];
|
|
3270
|
+
const pendingCommands = /* @__PURE__ */ new Map();
|
|
3271
|
+
const pendingToolCalls = /* @__PURE__ */ new Map();
|
|
3272
|
+
const pendingPatches = /* @__PURE__ */ new Map();
|
|
3273
|
+
events.forEach((event, eventIndex) => {
|
|
3274
|
+
if (event.type === CODEX_QUOTA_STATUS_EVENT_TYPE) {
|
|
3275
|
+
const state = event.payload?.state;
|
|
3276
|
+
if (state) {
|
|
3277
|
+
messages.push({
|
|
3278
|
+
id: `codex-quota-${event.timestamp}-${eventIndex}`,
|
|
3279
|
+
type: "quota_status",
|
|
3280
|
+
provider: "codex",
|
|
3281
|
+
state,
|
|
3282
|
+
balance: event.payload?.balance ?? null,
|
|
3283
|
+
rateLimitResetType: event.payload?.rateLimitResetType ?? null,
|
|
3284
|
+
planType: event.payload?.planType ?? null,
|
|
3285
|
+
timestamp: event.timestamp
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
return;
|
|
3289
|
+
}
|
|
3290
|
+
if (event.type === "event_msg" && event.payload?.type === "user_message") {
|
|
3291
|
+
const message = getPayloadString(event, "message");
|
|
3292
|
+
messages.push({
|
|
3293
|
+
id: displayId(event, eventIndex, "user"),
|
|
3294
|
+
type: "user",
|
|
3295
|
+
content: message ?? "",
|
|
3296
|
+
images: userMessageImages(event.payload.images),
|
|
3297
|
+
timestamp: event.timestamp
|
|
3298
|
+
});
|
|
3299
|
+
}
|
|
3300
|
+
if (event.type === "event_msg" && event.payload?.type === "agent_reasoning") {
|
|
3301
|
+
messages.push({
|
|
3302
|
+
id: displayId(event, eventIndex, "reasoning"),
|
|
3303
|
+
type: "reasoning",
|
|
3304
|
+
content: event.payload.text || "",
|
|
3305
|
+
status: "completed",
|
|
3306
|
+
timestamp: event.timestamp
|
|
3307
|
+
});
|
|
3308
|
+
}
|
|
3309
|
+
if (event.type === "response_item") {
|
|
3310
|
+
const payloadType = event.payload?.type;
|
|
3311
|
+
if (payloadType === "message" && event.payload?.role === "assistant") {
|
|
3312
|
+
const content = event.payload.content || [];
|
|
3313
|
+
const textContent = content.filter((c) => c.type === "output_text").map((c) => c.text || "").join("\n");
|
|
3314
|
+
if (textContent) {
|
|
3315
|
+
messages.push({
|
|
3316
|
+
id: displayId(event, eventIndex, "agent"),
|
|
3317
|
+
type: "agent",
|
|
3318
|
+
content: textContent,
|
|
3319
|
+
timestamp: event.timestamp
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command" || event.payload?.name === "exec_command")) {
|
|
3324
|
+
const callId = event.payload.call_id;
|
|
3325
|
+
const args = safeJsonParse(event.payload.arguments || "{}", {});
|
|
3326
|
+
const command = args.cmd || (Array.isArray(args.command) ? args.command.join(" ") : args.command) || "";
|
|
3327
|
+
const msg = {
|
|
3328
|
+
id: `command-${callId || "no-call-id"}-${eventIndex}`,
|
|
3329
|
+
type: "command",
|
|
3330
|
+
command,
|
|
3331
|
+
output: "",
|
|
3332
|
+
status: "in_progress",
|
|
3333
|
+
timestamp: event.timestamp
|
|
3334
|
+
};
|
|
3335
|
+
messages.push(msg);
|
|
3336
|
+
if (callId) {
|
|
3337
|
+
pendingCommands.set(callId, msg);
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
if (payloadType === "function_call_output") {
|
|
3341
|
+
const callId = event.payload.call_id;
|
|
3342
|
+
const rawOutput = event.payload.output || "";
|
|
3343
|
+
const commandMsg = callId ? pendingCommands.get(callId) : void 0;
|
|
3344
|
+
if (commandMsg) {
|
|
3345
|
+
const { exitCode, output } = parseShellOutput(rawOutput);
|
|
3346
|
+
commandMsg.output = output;
|
|
3347
|
+
commandMsg.exitCode = exitCode;
|
|
3348
|
+
commandMsg.status = getStatusFromExitCode(exitCode);
|
|
3349
|
+
pendingCommands.delete(callId);
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
if (payloadType === "custom_tool_call") {
|
|
3353
|
+
const callId = event.payload.call_id;
|
|
3354
|
+
const name = event.payload.name;
|
|
3355
|
+
const input = event.payload.input || "";
|
|
3356
|
+
const server = typeof event.payload.server === "string" ? event.payload.server : "custom";
|
|
3357
|
+
const status = event.payload.status || "in_progress";
|
|
3358
|
+
if (name === "apply_patch") {
|
|
3359
|
+
const operations = parsePatch(input);
|
|
3360
|
+
pendingPatches.set(callId, { input, status, timestamp: event.timestamp, operations });
|
|
3361
|
+
} else {
|
|
3362
|
+
const msg = {
|
|
3363
|
+
id: `toolcall-${callId || getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY) || `${event.timestamp}-${eventIndex}`}`,
|
|
3364
|
+
type: "tool_call",
|
|
3365
|
+
server,
|
|
3366
|
+
tool: name,
|
|
3367
|
+
input,
|
|
3368
|
+
status,
|
|
3369
|
+
timestamp: event.timestamp
|
|
3370
|
+
};
|
|
3371
|
+
messages.push(msg);
|
|
3372
|
+
if (callId) {
|
|
3373
|
+
pendingToolCalls.set(callId, msg);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
if (payloadType === "custom_tool_call_output") {
|
|
3378
|
+
const callId = event.payload.call_id;
|
|
3379
|
+
const output = safeJsonParse(
|
|
3380
|
+
event.payload.output || "{}",
|
|
3381
|
+
{}
|
|
3382
|
+
);
|
|
3383
|
+
const pendingPatch = pendingPatches.get(callId);
|
|
3384
|
+
if (pendingPatch) {
|
|
3385
|
+
messages.push({
|
|
3386
|
+
id: `patch-${pendingPatch.timestamp}-${eventIndex}`,
|
|
3387
|
+
type: "patch",
|
|
3388
|
+
operations: pendingPatch.operations,
|
|
3389
|
+
output: output.output || "",
|
|
3390
|
+
exitCode: output.metadata?.exit_code,
|
|
3391
|
+
status: getStatusFromExitCode(output.metadata?.exit_code),
|
|
3392
|
+
timestamp: pendingPatch.timestamp
|
|
3393
|
+
});
|
|
3394
|
+
pendingPatches.delete(callId);
|
|
3395
|
+
} else {
|
|
3396
|
+
const fallbackToolCallMsg = messages.findLast((m) => m.type === "tool_call");
|
|
3397
|
+
const toolCallMsg = pendingToolCalls.get(callId) ?? fallbackToolCallMsg;
|
|
3398
|
+
if (toolCallMsg) {
|
|
3399
|
+
toolCallMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
3400
|
+
toolCallMsg.output = output.output ?? (typeof event.payload.output === "string" ? event.payload.output : "");
|
|
3401
|
+
if (callId) {
|
|
3402
|
+
pendingToolCalls.delete(callId);
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
}
|
|
3407
|
+
if (payloadType === "function_call" && event.payload?.name === "update_plan") {
|
|
3408
|
+
const args = safeJsonParse(
|
|
3409
|
+
event.payload.arguments || "{}",
|
|
3410
|
+
{}
|
|
3411
|
+
);
|
|
3412
|
+
if (args.plan && Array.isArray(args.plan)) {
|
|
3413
|
+
const todoItems = args.plan.map((item) => ({
|
|
3414
|
+
text: item.step,
|
|
3415
|
+
completed: item.status === "completed"
|
|
3416
|
+
}));
|
|
3417
|
+
messages.push({
|
|
3418
|
+
id: `todo-${event.timestamp}-${eventIndex}`,
|
|
3419
|
+
type: "todo_list",
|
|
3420
|
+
items: todoItems,
|
|
3421
|
+
status: "completed",
|
|
3422
|
+
timestamp: event.timestamp
|
|
3423
|
+
});
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
return messages;
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
// ../shared/src/display-message/parsers/utils.ts
|
|
3432
|
+
function stringifyDisplayValue(value) {
|
|
3433
|
+
if (value === void 0 || value === null) return void 0;
|
|
3434
|
+
if (typeof value === "string") return value;
|
|
3435
|
+
try {
|
|
3436
|
+
return JSON.stringify(value, null, 2);
|
|
3437
|
+
} catch {
|
|
3438
|
+
return String(value);
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
|
|
3442
|
+
// ../shared/src/display-message/parsers/cursor-parser.ts
|
|
3443
|
+
function getTextContent(value) {
|
|
3444
|
+
if (!Array.isArray(value)) return "";
|
|
3445
|
+
return value.map((block) => isRecord(block) && block.type === "text" && typeof block.text === "string" ? block.text : "").join("");
|
|
3446
|
+
}
|
|
3447
|
+
function cursorStatusToDisplayStatus(status) {
|
|
3448
|
+
return status === "completed" || status === "FINISHED" ? "completed" : status === "error" || status === "ERROR" || status === "CANCELLED" || status === "EXPIRED" ? "failed" : "in_progress";
|
|
3449
|
+
}
|
|
3450
|
+
function cursorRunId(event) {
|
|
3451
|
+
const runId = event.payload.run_id;
|
|
3452
|
+
return typeof runId === "string" ? runId : "unknown-run";
|
|
3453
|
+
}
|
|
3454
|
+
function getCursorAssistantText(event) {
|
|
3455
|
+
const message = isRecord(event.payload.message) ? event.payload.message : null;
|
|
3456
|
+
return getTextContent(message?.content);
|
|
3457
|
+
}
|
|
3458
|
+
function getCursorThinkingText(event) {
|
|
3459
|
+
const text = event.payload.text;
|
|
3460
|
+
if (typeof text === "string") return text;
|
|
3461
|
+
const message = isRecord(event.payload.message) ? event.payload.message : null;
|
|
3462
|
+
return typeof message?.text === "string" ? message.text : "";
|
|
3463
|
+
}
|
|
3464
|
+
function isTerminalStatus(status) {
|
|
3465
|
+
return status === "FINISHED" || status === "ERROR" || status === "CANCELLED" || status === "EXPIRED";
|
|
3466
|
+
}
|
|
3467
|
+
function finalizeOpenTools(messages, toolIndexes, status) {
|
|
3468
|
+
for (const index of toolIndexes.values()) {
|
|
3469
|
+
const message = messages[index];
|
|
3470
|
+
if (message?.type === "tool_call" && message.status === "in_progress") {
|
|
3471
|
+
messages[index] = {
|
|
3472
|
+
...message,
|
|
3473
|
+
status
|
|
3474
|
+
};
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
function parseCursorEvents(events) {
|
|
3479
|
+
const messages = [];
|
|
3480
|
+
const toolIndexes = /* @__PURE__ */ new Map();
|
|
3481
|
+
const runAssistantSegments = /* @__PURE__ */ new Map();
|
|
3482
|
+
const runThinkingSegments = /* @__PURE__ */ new Map();
|
|
3483
|
+
let activeAssistant = null;
|
|
3484
|
+
let activeThinking = null;
|
|
3485
|
+
const finalizeActiveThinking = (status) => {
|
|
3486
|
+
if (!activeThinking) return;
|
|
3487
|
+
const message = messages[activeThinking.index];
|
|
3488
|
+
if (message?.type === "reasoning") {
|
|
3489
|
+
messages[activeThinking.index] = {
|
|
3490
|
+
...message,
|
|
3491
|
+
status
|
|
3492
|
+
};
|
|
3493
|
+
}
|
|
3494
|
+
};
|
|
3495
|
+
for (const event of events) {
|
|
3496
|
+
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
3497
|
+
activeAssistant = null;
|
|
3498
|
+
activeThinking = null;
|
|
3499
|
+
const message = event.payload.message;
|
|
3500
|
+
if (typeof message === "string" && message.trim()) {
|
|
3501
|
+
messages.push({
|
|
3502
|
+
id: `cursor-user-${event.timestamp}-${messages.length}`,
|
|
3503
|
+
type: "user",
|
|
3504
|
+
content: message,
|
|
3505
|
+
timestamp: event.timestamp
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
continue;
|
|
3509
|
+
}
|
|
3510
|
+
if (event.type === "cursor-assistant") {
|
|
3511
|
+
const text = getCursorAssistantText(event);
|
|
3512
|
+
if (text) {
|
|
3513
|
+
const runId = cursorRunId(event);
|
|
3514
|
+
if (!activeAssistant || activeAssistant.runId !== runId) {
|
|
3515
|
+
const segment = runAssistantSegments.get(runId) ?? 0;
|
|
3516
|
+
runAssistantSegments.set(runId, segment + 1);
|
|
3517
|
+
activeAssistant = {
|
|
3518
|
+
runId,
|
|
3519
|
+
index: messages.push({
|
|
3520
|
+
id: `cursor-agent-${runId}-${segment}`,
|
|
3521
|
+
type: "agent",
|
|
3522
|
+
content: "",
|
|
3523
|
+
timestamp: event.timestamp
|
|
3524
|
+
}) - 1
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
const message = messages[activeAssistant.index];
|
|
3528
|
+
if (message?.type === "agent") {
|
|
3529
|
+
messages[activeAssistant.index] = {
|
|
3530
|
+
...message,
|
|
3531
|
+
content: `${message.content}${text}`
|
|
3532
|
+
};
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
continue;
|
|
3536
|
+
}
|
|
3537
|
+
if (event.type === "cursor-thinking") {
|
|
3538
|
+
const text = getCursorThinkingText(event);
|
|
3539
|
+
if (text.trim()) {
|
|
3540
|
+
const runId = cursorRunId(event);
|
|
3541
|
+
if (!activeThinking || activeThinking.runId !== runId) {
|
|
3542
|
+
const segment = runThinkingSegments.get(runId) ?? 0;
|
|
3543
|
+
runThinkingSegments.set(runId, segment + 1);
|
|
3544
|
+
activeThinking = {
|
|
3545
|
+
runId,
|
|
3546
|
+
index: messages.push({
|
|
3547
|
+
id: `cursor-reasoning-${runId}-${segment}`,
|
|
3548
|
+
type: "reasoning",
|
|
3549
|
+
content: "",
|
|
3550
|
+
status: "in_progress",
|
|
3551
|
+
timestamp: event.timestamp
|
|
3552
|
+
}) - 1
|
|
3553
|
+
};
|
|
3554
|
+
}
|
|
3555
|
+
const message = messages[activeThinking.index];
|
|
3556
|
+
if (message?.type === "reasoning") {
|
|
3557
|
+
messages[activeThinking.index] = {
|
|
3558
|
+
...message,
|
|
3559
|
+
content: `${message.content}${text}`,
|
|
3560
|
+
status: "in_progress"
|
|
3561
|
+
};
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
continue;
|
|
3565
|
+
}
|
|
3566
|
+
if (event.type === "cursor-tool_call") {
|
|
3567
|
+
activeAssistant = null;
|
|
3568
|
+
const callId = typeof event.payload.call_id === "string" ? event.payload.call_id : `cursor-tool-${event.timestamp}-${messages.length}`;
|
|
3569
|
+
const tool2 = typeof event.payload.name === "string" ? event.payload.name : "tool";
|
|
3570
|
+
const status = cursorStatusToDisplayStatus(event.payload.status);
|
|
3571
|
+
const input = isRecord(event.payload.args) ? event.payload.args : typeof event.payload.args === "string" ? event.payload.args : void 0;
|
|
3572
|
+
const existing = toolIndexes.get(callId);
|
|
3573
|
+
const next = {
|
|
3574
|
+
id: callId,
|
|
3575
|
+
type: "tool_call",
|
|
3576
|
+
server: "cursor",
|
|
3577
|
+
tool: tool2,
|
|
3578
|
+
...input !== void 0 ? { input } : {},
|
|
3579
|
+
output: stringifyDisplayValue(event.payload.result),
|
|
3580
|
+
status,
|
|
3581
|
+
timestamp: event.timestamp
|
|
3582
|
+
};
|
|
3583
|
+
if (existing === void 0) {
|
|
3584
|
+
toolIndexes.set(callId, messages.push(next) - 1);
|
|
3585
|
+
} else {
|
|
3586
|
+
messages[existing] = { ...messages[existing], ...next };
|
|
3587
|
+
}
|
|
3588
|
+
continue;
|
|
3589
|
+
}
|
|
3590
|
+
if (event.type === "cursor-task") {
|
|
3591
|
+
activeAssistant = null;
|
|
3592
|
+
const text = event.payload.text;
|
|
3593
|
+
if (typeof text === "string" && text.trim()) {
|
|
3594
|
+
messages.push({
|
|
3595
|
+
id: `cursor-task-${event.timestamp}-${messages.length}`,
|
|
3596
|
+
type: "agent",
|
|
3597
|
+
content: text,
|
|
3598
|
+
timestamp: event.timestamp
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
continue;
|
|
3602
|
+
}
|
|
3603
|
+
if (event.type === "cursor-status") {
|
|
3604
|
+
const status = event.payload.status;
|
|
3605
|
+
if (isTerminalStatus(status)) {
|
|
3606
|
+
const displayStatus = cursorStatusToDisplayStatus(status);
|
|
3607
|
+
finalizeActiveThinking(displayStatus);
|
|
3608
|
+
finalizeOpenTools(messages, toolIndexes, displayStatus);
|
|
3609
|
+
activeThinking = null;
|
|
3610
|
+
activeAssistant = null;
|
|
3611
|
+
}
|
|
3612
|
+
continue;
|
|
3613
|
+
}
|
|
3614
|
+
if (event.type === "cursor-error") {
|
|
3615
|
+
finalizeActiveThinking("failed");
|
|
3616
|
+
finalizeOpenTools(messages, toolIndexes, "failed");
|
|
3617
|
+
activeAssistant = null;
|
|
3618
|
+
activeThinking = null;
|
|
3619
|
+
const message = typeof event.payload.message === "string" ? event.payload.message : "Cursor run failed";
|
|
3620
|
+
messages.push({
|
|
3621
|
+
id: `cursor-error-${event.timestamp}-${messages.length}`,
|
|
3622
|
+
type: "error",
|
|
3623
|
+
message,
|
|
3624
|
+
timestamp: event.timestamp
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
return messages;
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3631
|
+
// ../shared/src/display-message/parsers/opencode-parser.ts
|
|
3632
|
+
function timestampFromMs(value, fallback) {
|
|
3633
|
+
return typeof value === "number" && Number.isFinite(value) ? new Date(value).toISOString() : fallback;
|
|
3634
|
+
}
|
|
3635
|
+
function partFromEvent(event) {
|
|
3636
|
+
return isRecord(event.payload.part) ? event.payload.part : null;
|
|
3637
|
+
}
|
|
3638
|
+
function toolStatus(status) {
|
|
3639
|
+
return status === "completed" ? "completed" : status === "error" ? "failed" : "in_progress";
|
|
3640
|
+
}
|
|
3641
|
+
function setById(messages, id, next) {
|
|
3642
|
+
const index = messages.findIndex((message) => message.id === id);
|
|
3643
|
+
if (index === -1) {
|
|
3644
|
+
messages.push(next);
|
|
3645
|
+
} else {
|
|
3646
|
+
messages[index] = next;
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
function assistantError(info) {
|
|
3650
|
+
if (!isRecord(info) || !isRecord(info.error)) return null;
|
|
3651
|
+
const data = isRecord(info.error.data) ? info.error.data : null;
|
|
3652
|
+
if (typeof data?.message === "string") return data.message;
|
|
3653
|
+
if (typeof info.error.message === "string") return info.error.message;
|
|
3654
|
+
return stringifyDisplayValue(info.error) ?? "Opencode run failed";
|
|
3655
|
+
}
|
|
3656
|
+
function parseOpencodeEvents(events) {
|
|
3657
|
+
const messages = [];
|
|
3658
|
+
for (const event of events) {
|
|
3659
|
+
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
3660
|
+
const message = event.payload.message;
|
|
3661
|
+
if (typeof message === "string" && message.trim()) {
|
|
3662
|
+
messages.push({
|
|
3663
|
+
id: `opencode-user-${event.timestamp}-${messages.length}`,
|
|
3664
|
+
type: "user",
|
|
3665
|
+
content: message,
|
|
3666
|
+
timestamp: event.timestamp
|
|
3667
|
+
});
|
|
3668
|
+
}
|
|
3669
|
+
continue;
|
|
3670
|
+
}
|
|
3671
|
+
if (event.type === "opencode-message.updated") {
|
|
3672
|
+
const error = assistantError(event.payload.info);
|
|
3673
|
+
if (error) {
|
|
3674
|
+
messages.push({
|
|
3675
|
+
id: `opencode-error-${event.timestamp}-${messages.length}`,
|
|
3676
|
+
type: "error",
|
|
3677
|
+
message: error,
|
|
3678
|
+
timestamp: event.timestamp
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3681
|
+
continue;
|
|
3682
|
+
}
|
|
3683
|
+
if (event.type === "opencode-error") {
|
|
3684
|
+
const message = typeof event.payload.message === "string" ? event.payload.message : "Opencode run failed";
|
|
3685
|
+
messages.push({
|
|
3686
|
+
id: `opencode-error-${event.timestamp}-${messages.length}`,
|
|
3687
|
+
type: "error",
|
|
3688
|
+
message,
|
|
3689
|
+
timestamp: event.timestamp
|
|
3690
|
+
});
|
|
3691
|
+
continue;
|
|
3692
|
+
}
|
|
3693
|
+
const part = partFromEvent(event);
|
|
3694
|
+
if (!part) continue;
|
|
3695
|
+
const id = typeof part.id === "string" ? `opencode-${part.id}` : `opencode-${event.timestamp}-${messages.length}`;
|
|
3696
|
+
const time = isRecord(part.time) ? part.time : null;
|
|
3697
|
+
const timestamp = timestampFromMs(time?.start, event.timestamp);
|
|
3698
|
+
if (part.type === "text") {
|
|
3699
|
+
const text = typeof part.text === "string" ? part.text : "";
|
|
3700
|
+
if (text.trim()) {
|
|
3701
|
+
setById(messages, id, {
|
|
3702
|
+
id,
|
|
3703
|
+
type: "agent",
|
|
3704
|
+
content: text,
|
|
3705
|
+
timestamp
|
|
3706
|
+
});
|
|
3707
|
+
}
|
|
3708
|
+
continue;
|
|
3709
|
+
}
|
|
3710
|
+
if (part.type === "reasoning") {
|
|
3711
|
+
const text = typeof part.text === "string" ? part.text : "";
|
|
3712
|
+
if (text.trim()) {
|
|
3713
|
+
setById(messages, id, {
|
|
3714
|
+
id,
|
|
3715
|
+
type: "reasoning",
|
|
3716
|
+
content: text,
|
|
3717
|
+
status: time?.end ? "completed" : "in_progress",
|
|
3718
|
+
timestamp
|
|
3719
|
+
});
|
|
3720
|
+
}
|
|
3721
|
+
continue;
|
|
3722
|
+
}
|
|
3723
|
+
if (part.type === "tool" && isRecord(part.state)) {
|
|
3724
|
+
const state = part.state;
|
|
3725
|
+
const status = toolStatus(state.status);
|
|
3726
|
+
const output = state.status === "completed" ? stringifyDisplayValue(state.output) : state.status === "error" ? stringifyDisplayValue(state.error) : void 0;
|
|
3727
|
+
setById(messages, id, {
|
|
3728
|
+
id,
|
|
3729
|
+
type: "tool_call",
|
|
3730
|
+
server: "opencode",
|
|
3731
|
+
tool: typeof part.tool === "string" ? part.tool : "tool",
|
|
3732
|
+
input: isRecord(state.input) ? state.input : stringifyDisplayValue(state.input),
|
|
3733
|
+
output,
|
|
3734
|
+
status,
|
|
3735
|
+
timestamp
|
|
3736
|
+
});
|
|
3737
|
+
continue;
|
|
3738
|
+
}
|
|
3739
|
+
if (part.type === "patch") {
|
|
3740
|
+
const files = Array.isArray(part.files) ? part.files.filter((file) => typeof file === "string") : [];
|
|
3741
|
+
if (files.length > 0) {
|
|
3742
|
+
setById(messages, id, {
|
|
3743
|
+
id,
|
|
3744
|
+
type: "file_change",
|
|
3745
|
+
changes: files.map((path6) => ({ path: path6, kind: "update" })),
|
|
3746
|
+
status: "completed",
|
|
3747
|
+
timestamp
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
return messages;
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
// ../shared/src/display-message/parsers/pi-parser.ts
|
|
3756
|
+
function nestedPayload(event) {
|
|
3757
|
+
return isRecord(event.payload.assistantMessageEvent) ? event.payload.assistantMessageEvent : event.payload;
|
|
3758
|
+
}
|
|
3759
|
+
function setById2(messages, id, message) {
|
|
3760
|
+
const index = messages.findIndex((candidate) => candidate.id === id);
|
|
3761
|
+
if (index === -1) messages.push(message);
|
|
3762
|
+
else messages[index] = message;
|
|
3763
|
+
}
|
|
3764
|
+
function toolStatus2(value) {
|
|
3765
|
+
return value === "completed" || value === "success" ? "completed" : value === "error" ? "failed" : "in_progress";
|
|
3766
|
+
}
|
|
3767
|
+
function assistantErrorMessage(value) {
|
|
3768
|
+
if (!isRecord(value) || value.role !== "assistant" || value.stopReason !== "error") return null;
|
|
3769
|
+
return typeof value.errorMessage === "string" && value.errorMessage ? value.errorMessage : "Pi run failed";
|
|
3770
|
+
}
|
|
3771
|
+
function parsePiEvents(events) {
|
|
3772
|
+
const messages = [];
|
|
3773
|
+
const text = /* @__PURE__ */ new Map();
|
|
3774
|
+
const thinking = /* @__PURE__ */ new Map();
|
|
3775
|
+
let activeMessageId = "assistant";
|
|
3776
|
+
for (const event of events) {
|
|
3777
|
+
if (event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string") {
|
|
3778
|
+
messages.push({ id: `pi-user-${event.timestamp}-${messages.length}`, type: "user", content: event.payload.message, timestamp: event.timestamp });
|
|
3779
|
+
continue;
|
|
3780
|
+
}
|
|
3781
|
+
if (event.type === "pi-error") {
|
|
3782
|
+
messages.push({ id: `pi-error-${event.timestamp}-${messages.length}`, type: "error", message: String(event.payload.message ?? "Pi run failed"), timestamp: event.timestamp });
|
|
3783
|
+
continue;
|
|
3784
|
+
}
|
|
3785
|
+
if (event.type === "pi-message_end") {
|
|
3786
|
+
const error = assistantErrorMessage(event.payload.message);
|
|
3787
|
+
if (error) {
|
|
3788
|
+
messages.push({ id: `pi-error-${event.timestamp}-${messages.length}`, type: "error", message: error, timestamp: event.timestamp });
|
|
3789
|
+
}
|
|
3790
|
+
continue;
|
|
3791
|
+
}
|
|
3792
|
+
if (event.type === "pi-message_update") {
|
|
3793
|
+
const payload = nestedPayload(event);
|
|
3794
|
+
const id = typeof payload.id === "string" ? payload.id : activeMessageId;
|
|
3795
|
+
if (payload.type === "text_delta" && typeof payload.delta === "string") text.set(id, `${text.get(id) ?? ""}${payload.delta}`);
|
|
3796
|
+
if (payload.type === "thinking_delta" && typeof payload.delta === "string") thinking.set(id, `${thinking.get(id) ?? ""}${payload.delta}`);
|
|
3797
|
+
const textContent = text.get(id);
|
|
3798
|
+
const thinkingContent = thinking.get(id);
|
|
3799
|
+
if (textContent !== void 0) setById2(messages, `pi-${id}`, { id: `pi-${id}`, type: "agent", content: textContent, timestamp: event.timestamp });
|
|
3800
|
+
if (thinkingContent !== void 0) setById2(messages, `pi-thinking-${id}`, { id: `pi-thinking-${id}`, type: "reasoning", content: thinkingContent, status: "in_progress", timestamp: event.timestamp });
|
|
3801
|
+
continue;
|
|
3802
|
+
}
|
|
3803
|
+
if (event.type === "pi-message_start") {
|
|
3804
|
+
const message = isRecord(event.payload.message) ? event.payload.message : null;
|
|
3805
|
+
activeMessageId = typeof message?.id === "string" ? message.id : `assistant-${event.timestamp}`;
|
|
3806
|
+
continue;
|
|
3807
|
+
}
|
|
3808
|
+
if (event.type === "pi-tool_execution_start" || event.type === "pi-tool_execution_update" || event.type === "pi-tool_execution_end") {
|
|
3809
|
+
const payload = event.payload;
|
|
3810
|
+
const input = payload.args ?? payload.input;
|
|
3811
|
+
const id = typeof payload.toolCallId === "string" ? payload.toolCallId : typeof payload.id === "string" ? payload.id : `tool-${event.timestamp}`;
|
|
3812
|
+
setById2(messages, `pi-tool-${id}`, {
|
|
3813
|
+
id: `pi-tool-${id}`,
|
|
3814
|
+
type: "tool_call",
|
|
3815
|
+
server: "pi",
|
|
3816
|
+
tool: typeof payload.toolName === "string" ? payload.toolName : "tool",
|
|
3817
|
+
input: isRecord(input) ? input : stringifyDisplayValue(input),
|
|
3818
|
+
output: event.type === "pi-tool_execution_end" ? stringifyDisplayValue(payload.result ?? payload.error) : void 0,
|
|
3819
|
+
status: event.type === "pi-tool_execution_end" ? toolStatus2(payload.isError ? "error" : "completed") : "in_progress",
|
|
3820
|
+
timestamp: event.timestamp
|
|
3821
|
+
});
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3824
|
+
return messages;
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3157
3827
|
// ../shared/src/display-message/task-accumulator.ts
|
|
3158
3828
|
function mapTaskStatus(status) {
|
|
3159
3829
|
if (status === "in_progress" || status === "completed") return status;
|
|
@@ -3281,6 +3951,19 @@ var TaskAccumulator = class {
|
|
|
3281
3951
|
}
|
|
3282
3952
|
};
|
|
3283
3953
|
|
|
3954
|
+
// ../shared/src/display-message/parsers/mcp.ts
|
|
3955
|
+
function parseMcpToolName(name) {
|
|
3956
|
+
const prefix = "mcp__";
|
|
3957
|
+
if (!name.startsWith(prefix)) return null;
|
|
3958
|
+
const rest = name.slice(prefix.length);
|
|
3959
|
+
const sep = rest.indexOf("__");
|
|
3960
|
+
if (sep <= 0) return null;
|
|
3961
|
+
const server = rest.slice(0, sep);
|
|
3962
|
+
const tool2 = rest.slice(sep + 2);
|
|
3963
|
+
if (!server || !tool2) return null;
|
|
3964
|
+
return { server, tool: tool2 };
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3284
3967
|
// ../shared/src/display-message/parsers/claude-parser.ts
|
|
3285
3968
|
function coerceClaudeResultPayload(payload) {
|
|
3286
3969
|
return {
|
|
@@ -3292,6 +3975,436 @@ function coerceClaudeResultPayload(payload) {
|
|
|
3292
3975
|
function isClaudeResultError(payload) {
|
|
3293
3976
|
return Boolean(payload.is_error) || payload.subtype !== "success";
|
|
3294
3977
|
}
|
|
3978
|
+
function upsertDisplayMessage(messages, message) {
|
|
3979
|
+
const index = messages.findIndex((existing) => existing.id === message.id);
|
|
3980
|
+
if (index === -1) {
|
|
3981
|
+
messages.push(message);
|
|
3982
|
+
} else {
|
|
3983
|
+
messages[index] = message;
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
var LOCAL_COMMAND_ECHO_REGEX = /^<(?:command-name|command-message|local-command-stdout|local-command-stderr)>/;
|
|
3987
|
+
function parseClaudeEvents(events, parentToolUseId) {
|
|
3988
|
+
const messages = [];
|
|
3989
|
+
const filterValue = parentToolUseId !== void 0 ? parentToolUseId : null;
|
|
3990
|
+
const filteredEvents = events.filter((e) => {
|
|
3991
|
+
const eventParentToolUseId = e.payload.parent_tool_use_id ?? null;
|
|
3992
|
+
return eventParentToolUseId === filterValue;
|
|
3993
|
+
});
|
|
3994
|
+
const toolCallMap = /* @__PURE__ */ new Map();
|
|
3995
|
+
const taskMessageMap = /* @__PURE__ */ new Map();
|
|
3996
|
+
const partialIndexes = /* @__PURE__ */ new Map();
|
|
3997
|
+
const completedStreamIds = /* @__PURE__ */ new Set();
|
|
3998
|
+
const supersededStreamIds = /* @__PURE__ */ new Set();
|
|
3999
|
+
let liveStreamId = null;
|
|
4000
|
+
const assistantThinking = /* @__PURE__ */ new Map();
|
|
4001
|
+
const assistantTextCounts = /* @__PURE__ */ new Map();
|
|
4002
|
+
const taskAccumulator = new TaskAccumulator();
|
|
4003
|
+
const taskSnapshot = () => taskAccumulator.getTasks().map((task) => ({
|
|
4004
|
+
text: task.subject,
|
|
4005
|
+
completed: task.status === "completed",
|
|
4006
|
+
itemStatus: task.status
|
|
4007
|
+
}));
|
|
4008
|
+
filteredEvents.forEach((event) => {
|
|
4009
|
+
if (event.type === CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE) {
|
|
4010
|
+
const payload = coerceClaudePartialMessagePayload(event.payload);
|
|
4011
|
+
if (!payload) return;
|
|
4012
|
+
if (liveStreamId !== null && liveStreamId !== payload.streamId) {
|
|
4013
|
+
supersededStreamIds.add(liveStreamId);
|
|
4014
|
+
}
|
|
4015
|
+
liveStreamId = payload.streamId;
|
|
4016
|
+
const existing = partialIndexes.get(payload.streamId) ?? {};
|
|
4017
|
+
if (payload.thinking) {
|
|
4018
|
+
const reasoningMessage = {
|
|
4019
|
+
id: `reasoning-${payload.streamId}-thinking`,
|
|
4020
|
+
type: "reasoning",
|
|
4021
|
+
content: payload.thinking,
|
|
4022
|
+
status: payload.status,
|
|
4023
|
+
timestamp: event.timestamp
|
|
4024
|
+
};
|
|
4025
|
+
if (existing.reasoning !== void 0) messages[existing.reasoning] = reasoningMessage;
|
|
4026
|
+
else existing.reasoning = messages.push(reasoningMessage) - 1;
|
|
4027
|
+
}
|
|
4028
|
+
if (payload.text) {
|
|
4029
|
+
const agentMessage = {
|
|
4030
|
+
id: `agent-${payload.streamId}-0`,
|
|
4031
|
+
type: "agent",
|
|
4032
|
+
content: payload.text,
|
|
4033
|
+
timestamp: event.timestamp
|
|
4034
|
+
};
|
|
4035
|
+
if (existing.agent !== void 0) messages[existing.agent] = agentMessage;
|
|
4036
|
+
else existing.agent = messages.push(agentMessage) - 1;
|
|
4037
|
+
}
|
|
4038
|
+
partialIndexes.set(payload.streamId, existing);
|
|
4039
|
+
return;
|
|
4040
|
+
}
|
|
4041
|
+
if (event.type === "claude-user") {
|
|
4042
|
+
const content = normalizeContentBlocks(event.payload.message?.content);
|
|
4043
|
+
const toolResult = content.find((c) => c.type === "tool_result");
|
|
4044
|
+
if (toolResult && toolResult.tool_use_id) {
|
|
4045
|
+
if (!toolResult.is_error) {
|
|
4046
|
+
taskAccumulator.processContentBlock(toolResult);
|
|
4047
|
+
}
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
if (event.payload.isSynthetic) {
|
|
4051
|
+
return;
|
|
4052
|
+
}
|
|
4053
|
+
const textContent = content.filter((c) => c.type === "text").map((c) => c.text || "").join("\n");
|
|
4054
|
+
if (LOCAL_COMMAND_ECHO_REGEX.test(textContent.trim())) {
|
|
4055
|
+
return;
|
|
4056
|
+
}
|
|
4057
|
+
const images = content.filter((c) => c.type === "image" && c.source).map((c) => {
|
|
4058
|
+
const source = c.source;
|
|
4059
|
+
return {
|
|
4060
|
+
type: "image",
|
|
4061
|
+
mediaType: source.media_type || "image/png",
|
|
4062
|
+
data: source.data || ""
|
|
4063
|
+
};
|
|
4064
|
+
}).filter((img) => img.data);
|
|
4065
|
+
if (textContent || images.length > 0) {
|
|
4066
|
+
messages.push({
|
|
4067
|
+
id: `user-${event.timestamp}`,
|
|
4068
|
+
type: "user",
|
|
4069
|
+
content: textContent || (images.length > 0 ? `[${images.length} image${images.length > 1 ? "s" : ""} attached]` : ""),
|
|
4070
|
+
images: images.length > 0 ? images : void 0,
|
|
4071
|
+
timestamp: event.timestamp
|
|
4072
|
+
});
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
if (event.type === "claude-assistant") {
|
|
4076
|
+
const messageId = event.payload.message?.id;
|
|
4077
|
+
const contentBlocks = normalizeContentBlocks(event.payload.message?.content);
|
|
4078
|
+
const messageKey = messageId || event.timestamp;
|
|
4079
|
+
const streamRefs = messageId ? partialIndexes.get(messageId) : void 0;
|
|
4080
|
+
if (messageId) {
|
|
4081
|
+
completedStreamIds.add(messageId);
|
|
4082
|
+
if (liveStreamId !== null && liveStreamId !== messageId) {
|
|
4083
|
+
supersededStreamIds.add(liveStreamId);
|
|
4084
|
+
}
|
|
4085
|
+
liveStreamId = null;
|
|
4086
|
+
}
|
|
4087
|
+
const thinkingBlocks = contentBlocks.flatMap(
|
|
4088
|
+
(block) => block.type === "thinking" && typeof block.thinking === "string" ? [block.thinking] : []
|
|
4089
|
+
);
|
|
4090
|
+
if (thinkingBlocks.length > 0) {
|
|
4091
|
+
const allThinking = [...assistantThinking.get(messageKey) ?? [], ...thinkingBlocks];
|
|
4092
|
+
assistantThinking.set(messageKey, allThinking);
|
|
4093
|
+
const reasoningMessage = {
|
|
4094
|
+
id: `reasoning-${messageKey}-thinking`,
|
|
4095
|
+
type: "reasoning",
|
|
4096
|
+
content: allThinking.join("\n\n"),
|
|
4097
|
+
status: "completed",
|
|
4098
|
+
timestamp: event.timestamp
|
|
4099
|
+
};
|
|
4100
|
+
if (streamRefs?.reasoning !== void 0) {
|
|
4101
|
+
messages[streamRefs.reasoning] = reasoningMessage;
|
|
4102
|
+
streamRefs.reasoning = void 0;
|
|
4103
|
+
} else {
|
|
4104
|
+
upsertDisplayMessage(messages, reasoningMessage);
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
contentBlocks.forEach((block) => {
|
|
4108
|
+
if (block.type === "text" && block.text) {
|
|
4109
|
+
const textIndex = assistantTextCounts.get(messageKey) ?? 0;
|
|
4110
|
+
assistantTextCounts.set(messageKey, textIndex + 1);
|
|
4111
|
+
const agentMessage = {
|
|
4112
|
+
id: `agent-${messageKey}-${textIndex}`,
|
|
4113
|
+
type: "agent",
|
|
4114
|
+
content: block.text,
|
|
4115
|
+
timestamp: event.timestamp
|
|
4116
|
+
};
|
|
4117
|
+
if (streamRefs?.agent !== void 0) {
|
|
4118
|
+
messages[streamRefs.agent] = agentMessage;
|
|
4119
|
+
streamRefs.agent = void 0;
|
|
4120
|
+
} else {
|
|
4121
|
+
upsertDisplayMessage(messages, agentMessage);
|
|
4122
|
+
}
|
|
4123
|
+
}
|
|
4124
|
+
if (block.type === "tool_use" && block.id) {
|
|
4125
|
+
const toolName = block.name || "unknown";
|
|
4126
|
+
const toolInput = block.input || {};
|
|
4127
|
+
const toolUseId = block.id;
|
|
4128
|
+
toolCallMap.set(toolUseId, {
|
|
4129
|
+
messageIndex: messages.length,
|
|
4130
|
+
toolName,
|
|
4131
|
+
input: toolInput
|
|
4132
|
+
});
|
|
4133
|
+
if (toolName === "Task" || toolName === "Agent") {
|
|
4134
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4135
|
+
const nestedEvents = events.filter((e) => e.payload.parent_tool_use_id === toolUseId).map((e) => ({
|
|
4136
|
+
timestamp: e.timestamp,
|
|
4137
|
+
type: e.type,
|
|
4138
|
+
payload: e.payload
|
|
4139
|
+
}));
|
|
4140
|
+
messages.push({
|
|
4141
|
+
id: `subagent-${event.timestamp}-${messages.length}`,
|
|
4142
|
+
type: "subagent",
|
|
4143
|
+
toolUseId,
|
|
4144
|
+
description: inputObj.description || "Subagent Task",
|
|
4145
|
+
prompt: inputObj.prompt || "",
|
|
4146
|
+
subagentType: inputObj.subagent_type || "general",
|
|
4147
|
+
model: inputObj.model,
|
|
4148
|
+
status: "in_progress",
|
|
4149
|
+
nestedEvents,
|
|
4150
|
+
timestamp: event.timestamp
|
|
4151
|
+
});
|
|
4152
|
+
} else if (toolName === "Bash" || toolName === "bash" || toolName === "shell") {
|
|
4153
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4154
|
+
const command = inputObj.command || "";
|
|
4155
|
+
messages.push({
|
|
4156
|
+
id: `command-${event.timestamp}-${messages.length}`,
|
|
4157
|
+
type: "command",
|
|
4158
|
+
command,
|
|
4159
|
+
output: "",
|
|
4160
|
+
status: "in_progress",
|
|
4161
|
+
timestamp: event.timestamp
|
|
4162
|
+
});
|
|
4163
|
+
} else if (toolName === "Write" || toolName === "Edit") {
|
|
4164
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4165
|
+
const filePath = inputObj.file_path || "";
|
|
4166
|
+
const action = toolName === "Write" ? "add" : "update";
|
|
4167
|
+
let diff;
|
|
4168
|
+
if (toolName === "Edit" && inputObj.old_string != null && inputObj.new_string != null) {
|
|
4169
|
+
const oldLines = inputObj.old_string.replace(/\n$/, "").split("\n");
|
|
4170
|
+
const newLines = inputObj.new_string.replace(/\n$/, "").split("\n");
|
|
4171
|
+
const hunk = `@@ -1,${oldLines.length} +1,${newLines.length} @@`;
|
|
4172
|
+
diff = [
|
|
4173
|
+
`--- a/${filePath}`,
|
|
4174
|
+
`+++ b/${filePath}`,
|
|
4175
|
+
hunk,
|
|
4176
|
+
...oldLines.map((l) => `-${l}`),
|
|
4177
|
+
...newLines.map((l) => `+${l}`)
|
|
4178
|
+
].join("\n");
|
|
4179
|
+
} else if (toolName === "Write" && inputObj.content != null) {
|
|
4180
|
+
const newLines = inputObj.content.replace(/\n$/, "").split("\n");
|
|
4181
|
+
const hunk = `@@ -0,0 +1,${newLines.length} @@`;
|
|
4182
|
+
diff = [
|
|
4183
|
+
`--- /dev/null`,
|
|
4184
|
+
`+++ b/${filePath}`,
|
|
4185
|
+
hunk,
|
|
4186
|
+
...newLines.map((l) => `+${l}`)
|
|
4187
|
+
].join("\n");
|
|
4188
|
+
}
|
|
4189
|
+
messages.push({
|
|
4190
|
+
id: `patch-${event.timestamp}-${messages.length}`,
|
|
4191
|
+
type: "patch",
|
|
4192
|
+
operations: [{
|
|
4193
|
+
action,
|
|
4194
|
+
path: filePath,
|
|
4195
|
+
diff
|
|
4196
|
+
}],
|
|
4197
|
+
status: "in_progress",
|
|
4198
|
+
timestamp: event.timestamp
|
|
4199
|
+
});
|
|
4200
|
+
} else if (toolName === "TaskCreate" || toolName === "TaskUpdate" || toolName === "TaskList") {
|
|
4201
|
+
taskAccumulator.processContentBlock(block);
|
|
4202
|
+
const snapshot = taskSnapshot();
|
|
4203
|
+
if (snapshot.length > 0) {
|
|
4204
|
+
messages.push({
|
|
4205
|
+
id: `todo-${event.timestamp}-${messages.length}`,
|
|
4206
|
+
type: "todo_list",
|
|
4207
|
+
items: snapshot,
|
|
4208
|
+
status: "completed",
|
|
4209
|
+
timestamp: event.timestamp
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
} else if (toolName === "WebSearch") {
|
|
4213
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4214
|
+
const query2 = inputObj.query || "";
|
|
4215
|
+
messages.push({
|
|
4216
|
+
id: `search-${event.timestamp}-${messages.length}`,
|
|
4217
|
+
type: "web_search",
|
|
4218
|
+
query: query2,
|
|
4219
|
+
status: "in_progress",
|
|
4220
|
+
timestamp: event.timestamp
|
|
4221
|
+
});
|
|
4222
|
+
} else if (toolName === "Skill") {
|
|
4223
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4224
|
+
messages.push({
|
|
4225
|
+
id: `skill-${event.timestamp}-${messages.length}`,
|
|
4226
|
+
type: "skill",
|
|
4227
|
+
skillName: inputObj.skill || "unknown",
|
|
4228
|
+
args: inputObj.args,
|
|
4229
|
+
status: "in_progress",
|
|
4230
|
+
timestamp: event.timestamp
|
|
4231
|
+
});
|
|
4232
|
+
} else if (toolName === "mcp__relay-subagent-tools__spawn_agent") {
|
|
4233
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4234
|
+
const provider = typeof inputObj.provider === "string" ? inputObj.provider : "unknown";
|
|
4235
|
+
const prompt = typeof inputObj.prompt === "string" ? inputObj.prompt : "";
|
|
4236
|
+
const model = typeof inputObj.model === "string" ? inputObj.model : void 0;
|
|
4237
|
+
const title = typeof inputObj.title === "string" ? inputObj.title : void 0;
|
|
4238
|
+
messages.push({
|
|
4239
|
+
id: `subagent-${event.timestamp}-${messages.length}`,
|
|
4240
|
+
type: "subagent",
|
|
4241
|
+
toolUseId,
|
|
4242
|
+
description: title || `Relay subagent (${provider})`,
|
|
4243
|
+
prompt,
|
|
4244
|
+
subagentType: provider,
|
|
4245
|
+
model,
|
|
4246
|
+
thinkingLevel: isValidThinkingLevel(inputObj.thinking_level) ? inputObj.thinking_level : void 0,
|
|
4247
|
+
status: "in_progress",
|
|
4248
|
+
nestedEvents: [],
|
|
4249
|
+
isChatBased: true,
|
|
4250
|
+
timestamp: event.timestamp
|
|
4251
|
+
});
|
|
4252
|
+
} else if (toolName === "mcp__relay-subagent-tools__delete_agent") {
|
|
4253
|
+
const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
|
|
4254
|
+
const mcp = parseMcpToolName(toolName);
|
|
4255
|
+
messages.push({
|
|
4256
|
+
id: `toolcall-${event.timestamp}-${messages.length}`,
|
|
4257
|
+
type: "tool_call",
|
|
4258
|
+
server: mcp?.server ?? "relay-subagent-tools",
|
|
4259
|
+
tool: mcp?.tool ?? "delete_agent",
|
|
4260
|
+
input: inputObj,
|
|
4261
|
+
status: "in_progress",
|
|
4262
|
+
timestamp: event.timestamp
|
|
4263
|
+
});
|
|
4264
|
+
} else {
|
|
4265
|
+
messages.push({
|
|
4266
|
+
id: `toolcall-${event.timestamp}-${messages.length}`,
|
|
4267
|
+
type: "tool_call",
|
|
4268
|
+
server: "claude",
|
|
4269
|
+
tool: toolName,
|
|
4270
|
+
input: toolInput,
|
|
4271
|
+
status: "in_progress",
|
|
4272
|
+
timestamp: event.timestamp
|
|
4273
|
+
});
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
});
|
|
4277
|
+
}
|
|
4278
|
+
if (event.type === "claude-result") {
|
|
4279
|
+
const payload = coerceClaudeResultPayload(event.payload);
|
|
4280
|
+
if (isClaudeResultError(payload)) {
|
|
4281
|
+
const errorList = payload.errors || [];
|
|
4282
|
+
const errorMessage = errorList.length > 0 ? errorList.join("\n") : "Claude session encountered an unexpected error.";
|
|
4283
|
+
messages.push({
|
|
4284
|
+
id: `error-${event.timestamp}`,
|
|
4285
|
+
type: "error",
|
|
4286
|
+
message: errorMessage,
|
|
4287
|
+
timestamp: event.timestamp
|
|
4288
|
+
});
|
|
4289
|
+
}
|
|
4290
|
+
}
|
|
4291
|
+
if (event.type === "claude-system") {
|
|
4292
|
+
const payload = coerceBackgroundTaskPayload(event.payload);
|
|
4293
|
+
if (payload) {
|
|
4294
|
+
const existing = taskMessageMap.get(payload.taskId);
|
|
4295
|
+
const nextStatus = payload.subtype === "task_notification" ? normalizeBackgroundTaskStatus(payload.status) : payload.subtype === "task_updated" ? normalizeBackgroundTaskStatus(payload.patch?.status) : existing?.status ?? "in_progress";
|
|
4296
|
+
const nextMessage = {
|
|
4297
|
+
id: existing?.id ?? `task-${event.timestamp}-${messages.length}`,
|
|
4298
|
+
type: "background_task",
|
|
4299
|
+
taskId: payload.taskId,
|
|
4300
|
+
status: nextStatus,
|
|
4301
|
+
description: payload.description ?? payload.patch?.description ?? existing?.description,
|
|
4302
|
+
summary: payload.summary ?? existing?.summary,
|
|
4303
|
+
outputFile: payload.outputFile ?? existing?.outputFile,
|
|
4304
|
+
taskType: payload.taskType ?? existing?.taskType,
|
|
4305
|
+
workflowName: payload.workflowName ?? existing?.workflowName,
|
|
4306
|
+
prompt: payload.prompt ?? existing?.prompt,
|
|
4307
|
+
lastToolName: payload.lastToolName ?? existing?.lastToolName,
|
|
4308
|
+
usage: payload.usage ?? existing?.usage,
|
|
4309
|
+
error: payload.patch?.error ?? existing?.error,
|
|
4310
|
+
isBackgrounded: payload.patch?.isBackgrounded ?? existing?.isBackgrounded,
|
|
4311
|
+
timestamp: existing?.timestamp ?? event.timestamp
|
|
4312
|
+
};
|
|
4313
|
+
if (existing) {
|
|
4314
|
+
Object.assign(existing, nextMessage);
|
|
4315
|
+
} else {
|
|
4316
|
+
taskMessageMap.set(payload.taskId, nextMessage);
|
|
4317
|
+
messages.push(nextMessage);
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
});
|
|
4322
|
+
filteredEvents.forEach((event) => {
|
|
4323
|
+
if (event.type === "replicas-tool-input-request") {
|
|
4324
|
+
const payload = event.payload;
|
|
4325
|
+
if (!payload.toolUseId || !payload.requestId) return;
|
|
4326
|
+
if (!Array.isArray(payload.options) && !Array.isArray(payload.questions)) return;
|
|
4327
|
+
const toolInfo = toolCallMap.get(payload.toolUseId);
|
|
4328
|
+
if (!toolInfo) return;
|
|
4329
|
+
const message = messages[toolInfo.messageIndex];
|
|
4330
|
+
if (!message || message.type !== "tool_call") return;
|
|
4331
|
+
message.inputRequest = {
|
|
4332
|
+
requestId: payload.requestId,
|
|
4333
|
+
status: "pending",
|
|
4334
|
+
options: payload.options,
|
|
4335
|
+
questions: payload.questions
|
|
4336
|
+
};
|
|
4337
|
+
}
|
|
4338
|
+
if (event.type === "replicas-tool-input-resolved") {
|
|
4339
|
+
const payload = event.payload;
|
|
4340
|
+
if (!payload.toolUseId || !payload.selectionId) return;
|
|
4341
|
+
const toolInfo = toolCallMap.get(payload.toolUseId);
|
|
4342
|
+
if (!toolInfo) return;
|
|
4343
|
+
const message = messages[toolInfo.messageIndex];
|
|
4344
|
+
if (!message || message.type !== "tool_call" || !message.inputRequest) return;
|
|
4345
|
+
message.inputRequest = {
|
|
4346
|
+
...message.inputRequest,
|
|
4347
|
+
status: payload.selectionId === "aborted" ? "aborted" : "resolved",
|
|
4348
|
+
selectionId: payload.selectionId,
|
|
4349
|
+
selectionSummary: payload.selectionSummary
|
|
4350
|
+
};
|
|
4351
|
+
}
|
|
4352
|
+
});
|
|
4353
|
+
filteredEvents.forEach((event) => {
|
|
4354
|
+
if (event.type === "claude-user") {
|
|
4355
|
+
const content = normalizeContentBlocks(event.payload.message?.content);
|
|
4356
|
+
const toolResult = content.find((c) => c.type === "tool_result");
|
|
4357
|
+
if (toolResult && toolResult.tool_use_id) {
|
|
4358
|
+
const toolInfo = toolCallMap.get(toolResult.tool_use_id);
|
|
4359
|
+
if (!toolInfo) return;
|
|
4360
|
+
const resultContent = extractToolResultText(toolResult.content);
|
|
4361
|
+
const isError = toolResult.is_error || false;
|
|
4362
|
+
const status = isError ? "failed" : "completed";
|
|
4363
|
+
if (toolInfo.toolName === "TaskCreate" && !isError) {
|
|
4364
|
+
taskAccumulator.processContentBlock(toolResult);
|
|
4365
|
+
}
|
|
4366
|
+
const message = messages[toolInfo.messageIndex];
|
|
4367
|
+
if (!message) return;
|
|
4368
|
+
if (message.type === "command") {
|
|
4369
|
+
message.output = resultContent;
|
|
4370
|
+
message.status = status;
|
|
4371
|
+
const exitCodeMatch = resultContent.match(/exit code:?\s*(\d+)/i);
|
|
4372
|
+
if (exitCodeMatch) {
|
|
4373
|
+
message.exitCode = parseInt(exitCodeMatch[1], 10);
|
|
4374
|
+
} else {
|
|
4375
|
+
message.exitCode = isError ? 1 : 0;
|
|
4376
|
+
}
|
|
4377
|
+
} else if (message.type === "patch") {
|
|
4378
|
+
message.status = status;
|
|
4379
|
+
} else if (message.type === "web_search") {
|
|
4380
|
+
message.status = status;
|
|
4381
|
+
} else if (message.type === "tool_call") {
|
|
4382
|
+
message.output = resultContent;
|
|
4383
|
+
message.status = status;
|
|
4384
|
+
} else if (message.type === "skill") {
|
|
4385
|
+
message.status = status;
|
|
4386
|
+
} else if (message.type === "subagent") {
|
|
4387
|
+
message.output = resultContent;
|
|
4388
|
+
message.status = status;
|
|
4389
|
+
if (!message.chatId && resultContent) {
|
|
4390
|
+
const parsed = safeJsonParse(resultContent, {});
|
|
4391
|
+
if (parsed.chatId) {
|
|
4392
|
+
message.chatId = parsed.chatId;
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
});
|
|
4399
|
+
const staleIndexes = /* @__PURE__ */ new Set();
|
|
4400
|
+
for (const streamId of [...completedStreamIds, ...supersededStreamIds]) {
|
|
4401
|
+
const refs = partialIndexes.get(streamId);
|
|
4402
|
+
if (refs?.reasoning !== void 0) staleIndexes.add(refs.reasoning);
|
|
4403
|
+
if (refs?.agent !== void 0) staleIndexes.add(refs.agent);
|
|
4404
|
+
}
|
|
4405
|
+
if (staleIndexes.size === 0) return messages;
|
|
4406
|
+
return messages.filter((_, index) => !staleIndexes.has(index));
|
|
4407
|
+
}
|
|
3295
4408
|
|
|
3296
4409
|
// ../shared/src/agent-event-utils.ts
|
|
3297
4410
|
function getUserMessage(event) {
|
|
@@ -3369,6 +4482,21 @@ function parseAgentEventJsonlWithCodexAspTranscript(content, options = {}) {
|
|
|
3369
4482
|
var DUPLICATE_WINDOW_MS = 5 * 60 * 1e3;
|
|
3370
4483
|
|
|
3371
4484
|
// ../shared/src/display-message/parsers/index.ts
|
|
4485
|
+
function parseAgentEvents(events, agentType) {
|
|
4486
|
+
if (agentType === "codex") {
|
|
4487
|
+
return parseCodexEvents(events);
|
|
4488
|
+
}
|
|
4489
|
+
if (agentType === "cursor") {
|
|
4490
|
+
return parseCursorEvents(events);
|
|
4491
|
+
}
|
|
4492
|
+
if (agentType === "opencode") {
|
|
4493
|
+
return parseOpencodeEvents(events);
|
|
4494
|
+
}
|
|
4495
|
+
if (agentType === "pi") {
|
|
4496
|
+
return parsePiEvents(events);
|
|
4497
|
+
}
|
|
4498
|
+
return parseClaudeEvents(events);
|
|
4499
|
+
}
|
|
3372
4500
|
function isAgentBackendEvent(value) {
|
|
3373
4501
|
if (!value || typeof value !== "object") return false;
|
|
3374
4502
|
const candidate = value;
|
|
@@ -8617,7 +9745,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
8617
9745
|
var MIN_CODEX_CLI_VERSION = "0.144.0";
|
|
8618
9746
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
8619
9747
|
var codexCliVersionEnsured = null;
|
|
8620
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
9748
|
+
var ENGINE_PACKAGE_VERSION = "0.1.464";
|
|
8621
9749
|
var INITIALIZE_METHOD = "initialize";
|
|
8622
9750
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
8623
9751
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9828,16 +10956,25 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
9828
10956
|
try {
|
|
9829
10957
|
await dispatch();
|
|
9830
10958
|
} catch (error) {
|
|
9831
|
-
|
|
9832
|
-
|
|
10959
|
+
let terminalError = error;
|
|
10960
|
+
if (isCodexAuthError(terminalError)) {
|
|
10961
|
+
const refreshed = await codexTokenManager.fetchFreshCredentials(terminalError instanceof Error ? terminalError.message : String(terminalError));
|
|
9833
10962
|
if (refreshed) {
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
10963
|
+
try {
|
|
10964
|
+
await restartCodexAspHost();
|
|
10965
|
+
this.threadAttached = false;
|
|
10966
|
+
await dispatch();
|
|
10967
|
+
return;
|
|
10968
|
+
} catch (retryError) {
|
|
10969
|
+
terminalError = retryError;
|
|
10970
|
+
}
|
|
9838
10971
|
}
|
|
9839
10972
|
}
|
|
9840
|
-
|
|
10973
|
+
const event = this.recordHistoryEvent("codex-asp-error", {
|
|
10974
|
+
message: terminalError instanceof Error ? terminalError.message : String(terminalError)
|
|
10975
|
+
});
|
|
10976
|
+
this.onEvent(event);
|
|
10977
|
+
throw terminalError;
|
|
9841
10978
|
} finally {
|
|
9842
10979
|
this.transcriptUpdateCoalescer.flushPending();
|
|
9843
10980
|
this.transcriptUpdateCoalescer.dispose();
|
|
@@ -12984,6 +14121,28 @@ function getCodexTranscriptFromEvent(event) {
|
|
|
12984
14121
|
}
|
|
12985
14122
|
return applyCodexAspTranscriptDelta(null, transcriptDelta);
|
|
12986
14123
|
}
|
|
14124
|
+
function terminalErrorsFromEvent(event, provider, codexTranscript) {
|
|
14125
|
+
if (event.type === "claude-result") {
|
|
14126
|
+
const payload = coerceClaudeResultPayload(event.payload);
|
|
14127
|
+
if (!isClaudeResultError(payload)) return null;
|
|
14128
|
+
return payload.errors?.length ? payload.errors : ["Claude run failed"];
|
|
14129
|
+
}
|
|
14130
|
+
if (event.type === CODEX_QUOTA_STATUS_EVENT_TYPE) {
|
|
14131
|
+
return event.payload.state === "out_of_credits" ? ["Codex is out of credits. Top up the connected OpenAI account to resume."] : null;
|
|
14132
|
+
}
|
|
14133
|
+
if (event.type === "codex-asp-error") {
|
|
14134
|
+
return [typeof event.payload.message === "string" ? event.payload.message : "Codex run failed"];
|
|
14135
|
+
}
|
|
14136
|
+
const failedCodexTurn = codexTranscript?.turns.at(-1);
|
|
14137
|
+
if (failedCodexTurn?.status === "failed") {
|
|
14138
|
+
const errors2 = failedCodexTurn.items.flatMap((item) => item.type === "error" ? [item.message] : []);
|
|
14139
|
+
return errors2.length > 0 ? errors2 : ["Codex run failed"];
|
|
14140
|
+
}
|
|
14141
|
+
const mayContainProviderError = provider === "cursor" && event.type === "cursor-error" || provider === "opencode" && (event.type === "opencode-error" || event.type === "opencode-message.updated") || provider === "pi" && (event.type === "pi-error" || event.type === "pi-message_end");
|
|
14142
|
+
if (!mayContainProviderError) return void 0;
|
|
14143
|
+
const errors = parseAgentEvents([event], provider).flatMap((message) => message.type === "error" ? [message.message] : []);
|
|
14144
|
+
return errors.length > 0 ? errors : void 0;
|
|
14145
|
+
}
|
|
12987
14146
|
function acceptedEventInCodexTranscript(acceptedEvent, transcript) {
|
|
12988
14147
|
const message = getUserMessage(acceptedEvent);
|
|
12989
14148
|
if (!message) return false;
|
|
@@ -13149,6 +14308,9 @@ var ChatService = class {
|
|
|
13149
14308
|
}
|
|
13150
14309
|
const acceptedEvent = createUserMessageEvent(request.message, result.messageId, request.images);
|
|
13151
14310
|
chat.pendingMessageIds.push(result.messageId);
|
|
14311
|
+
if (request.errorNotificationTarget) {
|
|
14312
|
+
chat.errorNotificationTargets.set(result.messageId, request.errorNotificationTarget);
|
|
14313
|
+
}
|
|
13152
14314
|
chat.acceptedUserEvents.set(result.messageId, acceptedEvent);
|
|
13153
14315
|
chat.persisted.lastMessageText = request.message.trim().slice(0, LAST_MESSAGE_PREVIEW_MAX) || null;
|
|
13154
14316
|
this.touch(chat);
|
|
@@ -13515,7 +14677,9 @@ var ChatService = class {
|
|
|
13515
14677
|
activeMessageId: null,
|
|
13516
14678
|
hasActiveTurn: false,
|
|
13517
14679
|
observedBranchesByRepo: /* @__PURE__ */ new Map(),
|
|
13518
|
-
lastTurnErrors: null
|
|
14680
|
+
lastTurnErrors: null,
|
|
14681
|
+
errorNotificationTargets: /* @__PURE__ */ new Map(),
|
|
14682
|
+
activeErrorNotificationTarget: null
|
|
13519
14683
|
};
|
|
13520
14684
|
}
|
|
13521
14685
|
touch(chat) {
|
|
@@ -13560,6 +14724,8 @@ var ChatService = class {
|
|
|
13560
14724
|
}
|
|
13561
14725
|
chat.hasActiveTurn = true;
|
|
13562
14726
|
chat.activeMessageId = messageId;
|
|
14727
|
+
chat.activeErrorNotificationTarget = chat.errorNotificationTargets.get(messageId) ?? null;
|
|
14728
|
+
chat.errorNotificationTargets.delete(messageId);
|
|
13563
14729
|
this.publish({
|
|
13564
14730
|
type: "chat.turn.started",
|
|
13565
14731
|
payload: {
|
|
@@ -13569,9 +14735,10 @@ var ChatService = class {
|
|
|
13569
14735
|
}).catch(() => {
|
|
13570
14736
|
});
|
|
13571
14737
|
}
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
14738
|
+
const codexTranscript = getCodexTranscriptFromEvent(event);
|
|
14739
|
+
const terminalErrors = terminalErrorsFromEvent(event, chat.persisted.provider, codexTranscript);
|
|
14740
|
+
if (terminalErrors !== void 0) {
|
|
14741
|
+
chat.lastTurnErrors = terminalErrors;
|
|
13575
14742
|
}
|
|
13576
14743
|
let eventToPublish = event;
|
|
13577
14744
|
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
@@ -13592,7 +14759,6 @@ var ChatService = class {
|
|
|
13592
14759
|
}
|
|
13593
14760
|
}
|
|
13594
14761
|
}
|
|
13595
|
-
const codexTranscript = getCodexTranscriptFromEvent(event);
|
|
13596
14762
|
if (codexTranscript) {
|
|
13597
14763
|
for (const [messageId, acceptedEvent] of chat.acceptedUserEvents) {
|
|
13598
14764
|
if (acceptedEventInCodexTranscript(acceptedEvent, codexTranscript)) {
|
|
@@ -13746,6 +14912,8 @@ var ChatService = class {
|
|
|
13746
14912
|
chat.observedBranchesByRepo = /* @__PURE__ */ new Map();
|
|
13747
14913
|
const errors = chat.persisted.parentChatId === null ? chat.lastTurnErrors : null;
|
|
13748
14914
|
chat.lastTurnErrors = null;
|
|
14915
|
+
const errorNotificationTarget = chat.activeErrorNotificationTarget;
|
|
14916
|
+
chat.activeErrorNotificationTarget = null;
|
|
13749
14917
|
let repoStatuses = [];
|
|
13750
14918
|
let repoStateComplete = false;
|
|
13751
14919
|
try {
|
|
@@ -13765,7 +14933,8 @@ var ChatService = class {
|
|
|
13765
14933
|
const payload = {
|
|
13766
14934
|
...linearSessionId ? { linearSessionId } : {},
|
|
13767
14935
|
repoStatuses,
|
|
13768
|
-
...errors?.length ? { errors } : {}
|
|
14936
|
+
...errors?.length ? { errors } : {},
|
|
14937
|
+
...errors?.length && errorNotificationTarget ? { errorNotificationTarget } : {}
|
|
13769
14938
|
};
|
|
13770
14939
|
await monolithService.sendEvent({ type: "agent_turn_complete", payload });
|
|
13771
14940
|
} catch (error) {
|
|
@@ -14603,7 +15772,19 @@ var sendMessageSchema = z4.object({
|
|
|
14603
15772
|
senderUserId: z4.string().optional(),
|
|
14604
15773
|
senderEmail: z4.string().optional(),
|
|
14605
15774
|
senderDisplayName: z4.string().optional(),
|
|
14606
|
-
senderAvatarUrl: z4.string().optional()
|
|
15775
|
+
senderAvatarUrl: z4.string().optional(),
|
|
15776
|
+
errorNotificationTarget: z4.discriminatedUnion("type", [
|
|
15777
|
+
z4.object({ type: z4.literal("slack") }),
|
|
15778
|
+
z4.object({ type: z4.literal("linear"), sessionId: z4.string().min(1) }),
|
|
15779
|
+
z4.object({
|
|
15780
|
+
type: z4.literal("code_host"),
|
|
15781
|
+
provider: z4.enum(["github", "gitlab"]),
|
|
15782
|
+
resource: z4.enum(["issue", "pull_request"]),
|
|
15783
|
+
repositoryId: z4.string().min(1),
|
|
15784
|
+
resourceNumber: z4.number().int().positive()
|
|
15785
|
+
}),
|
|
15786
|
+
z4.object({ type: z4.literal("automation"), executionId: z4.string().min(1) })
|
|
15787
|
+
]).optional()
|
|
14607
15788
|
});
|
|
14608
15789
|
var respondToolInputSchema = z4.object({
|
|
14609
15790
|
requestId: z4.string().min(1),
|