skydive-cli 0.1.0-beta.288 → 0.1.0-beta.297
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/js/bin.mjs
CHANGED
|
@@ -16,7 +16,7 @@ import zlib from "node:zlib";
|
|
|
16
16
|
import os from "node:os";
|
|
17
17
|
|
|
18
18
|
//#region package.json
|
|
19
|
-
var version$1 = "0.1.0-beta.
|
|
19
|
+
var version$1 = "0.1.0-beta.297";
|
|
20
20
|
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/types.ts
|
|
@@ -960,7 +960,7 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
960
960
|
const { agent } = await post(`/api/v1/agents/${encodeURIComponent(agentId)}`, { model }, updateAgentResponseSchema, "PATCH");
|
|
961
961
|
return { model: agent.model ?? null };
|
|
962
962
|
},
|
|
963
|
-
listConversations: async ({ agentId, limit }) => {
|
|
963
|
+
listConversations: async ({ agentId, limit, onPage }) => {
|
|
964
964
|
const all = [];
|
|
965
965
|
const maxConversations = limit ?? 5e3;
|
|
966
966
|
let cursor;
|
|
@@ -975,6 +975,7 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
975
975
|
const page = await get(`/api/v1/conversations?${params.toString()}`, listConversationsResponseSchema);
|
|
976
976
|
all.push(...page.conversations);
|
|
977
977
|
cursor = page.nextCursor ?? void 0;
|
|
978
|
+
onPage?.(limit ? all.slice(0, limit) : [...all]);
|
|
978
979
|
} while (cursor && all.length < maxConversations);
|
|
979
980
|
return limit ? all.slice(0, limit) : all;
|
|
980
981
|
},
|
|
@@ -1022,7 +1023,12 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
1022
1023
|
}, sendResultSchema),
|
|
1023
1024
|
activeRun: async ({ conversationId }) => {
|
|
1024
1025
|
const { run } = await get(`/api/v1/chat/active-run?${new URLSearchParams({ conversationId }).toString()}`, activeRunResponseSchema);
|
|
1025
|
-
return
|
|
1026
|
+
if (!run) return null;
|
|
1027
|
+
return {
|
|
1028
|
+
runId: run.runId,
|
|
1029
|
+
agentId: run.agentId ?? "",
|
|
1030
|
+
agentName: run.agentName ?? ""
|
|
1031
|
+
};
|
|
1026
1032
|
},
|
|
1027
1033
|
cancelRun: async ({ runId }) => {
|
|
1028
1034
|
await post(`/api/v1/chat/runs/${encodeURIComponent(runId)}/cancel`, {}, z.object({ ok: z.boolean() }));
|
|
@@ -1186,7 +1192,11 @@ const uiMessagePartSchema = z.union([
|
|
|
1186
1192
|
const uiMessageSchema = z.object({
|
|
1187
1193
|
id: z.string(),
|
|
1188
1194
|
role: z.string(),
|
|
1189
|
-
parts: z.array(uiMessagePartSchema)
|
|
1195
|
+
parts: z.array(uiMessagePartSchema),
|
|
1196
|
+
metadata: z.object({ custom: z.object({
|
|
1197
|
+
agentId: z.string().nullish(),
|
|
1198
|
+
agentName: z.string().nullish()
|
|
1199
|
+
}).passthrough().optional() }).passthrough().optional()
|
|
1190
1200
|
});
|
|
1191
1201
|
const recapResponseSchema = z.object({ recap: z.object({ text: z.string() }).nullable() });
|
|
1192
1202
|
const listMessagesResponseSchema = z.object({ messages: z.array(uiMessageSchema) });
|
|
@@ -1195,6 +1205,8 @@ const sendResultSchema = z.object({
|
|
|
1195
1205
|
messageId: z.string().uuid().nullish(),
|
|
1196
1206
|
conversationId: z.string().uuid(),
|
|
1197
1207
|
isNewConversation: z.boolean(),
|
|
1208
|
+
agentId: z.string().nullish(),
|
|
1209
|
+
agentName: z.string().nullish(),
|
|
1198
1210
|
steered: z.boolean().optional(),
|
|
1199
1211
|
directive: z.object({ id: z.string() }).passthrough().optional()
|
|
1200
1212
|
});
|
|
@@ -1209,7 +1221,11 @@ const finalizeResponseSchema = z.object({
|
|
|
1209
1221
|
mediaType: z.string(),
|
|
1210
1222
|
sizeBytes: z.number().nullable().optional()
|
|
1211
1223
|
});
|
|
1212
|
-
const activeRunResponseSchema = z.object({ run: z.object({
|
|
1224
|
+
const activeRunResponseSchema = z.object({ run: z.object({
|
|
1225
|
+
runId: z.string(),
|
|
1226
|
+
agentId: z.string().nullish(),
|
|
1227
|
+
agentName: z.string().nullish()
|
|
1228
|
+
}).nullable() });
|
|
1213
1229
|
const oauthConnectResponseSchema = z.object({ connectLink: z.string() }).passthrough();
|
|
1214
1230
|
const externalOauthConnectResponseSchema = z.object({ authorizationUrl: z.string().optional() }).passthrough();
|
|
1215
1231
|
const runStreamEventSchema = z.union([z.object({
|
|
@@ -2591,7 +2607,7 @@ const chatCommand = {
|
|
|
2591
2607
|
printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
|
|
2592
2608
|
process.exit(1);
|
|
2593
2609
|
}
|
|
2594
|
-
const { runChat } = await import("./boot-
|
|
2610
|
+
const { runChat } = await import("./boot-DYzw1U0y.mjs");
|
|
2595
2611
|
await runChat({
|
|
2596
2612
|
appUrl,
|
|
2597
2613
|
sessionToken: session.value.sessionToken,
|
|
@@ -3236,7 +3252,8 @@ const listCommand$1 = {
|
|
|
3236
3252
|
}), argv.agent ?? null);
|
|
3237
3253
|
const conversations = await client.listConversations({
|
|
3238
3254
|
agentId: agent.id,
|
|
3239
|
-
limit: argv.limit
|
|
3255
|
+
limit: argv.limit,
|
|
3256
|
+
onPage: null
|
|
3240
3257
|
});
|
|
3241
3258
|
if (argv.json) {
|
|
3242
3259
|
output(argv, conversations);
|
|
@@ -3373,7 +3390,7 @@ const switchCommand = {
|
|
|
3373
3390
|
printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
|
|
3374
3391
|
process.exit(1);
|
|
3375
3392
|
}
|
|
3376
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
3393
|
+
const { runWorkspacePicker } = await import("./boot-DYzw1U0y.mjs");
|
|
3377
3394
|
await runWorkspacePicker(session);
|
|
3378
3395
|
return;
|
|
3379
3396
|
}
|
|
@@ -1341,12 +1341,19 @@ function ConversationPickerScreen({ agent }) {
|
|
|
1341
1341
|
try {
|
|
1342
1342
|
const conversations = await rest.listConversations({
|
|
1343
1343
|
agentId: agent.id,
|
|
1344
|
-
|
|
1344
|
+
onPage: (partial) => {
|
|
1345
|
+
if (!cancelled) setState({
|
|
1346
|
+
kind: "ready",
|
|
1347
|
+
conversations: partial,
|
|
1348
|
+
complete: false
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1345
1351
|
});
|
|
1346
1352
|
if (cancelled) return;
|
|
1347
1353
|
setState({
|
|
1348
1354
|
kind: "ready",
|
|
1349
|
-
conversations
|
|
1355
|
+
conversations,
|
|
1356
|
+
complete: true
|
|
1350
1357
|
});
|
|
1351
1358
|
} catch (err) {
|
|
1352
1359
|
if (cancelled) return;
|
|
@@ -1371,17 +1378,19 @@ function ConversationPickerScreen({ agent }) {
|
|
|
1371
1378
|
return /* @__PURE__ */ jsx(ConversationList, {
|
|
1372
1379
|
agent,
|
|
1373
1380
|
conversations: state.conversations,
|
|
1381
|
+
complete: state.complete,
|
|
1374
1382
|
onPick: goTo
|
|
1375
1383
|
});
|
|
1376
1384
|
}
|
|
1377
|
-
function ConversationList({ agent, conversations, onPick }) {
|
|
1385
|
+
function ConversationList({ agent, conversations, complete, onPick }) {
|
|
1378
1386
|
const { width, height } = useTerminalDimensions();
|
|
1379
1387
|
const rest = useStore((s) => s.rest);
|
|
1380
1388
|
const [query, setQuery] = useState("");
|
|
1381
1389
|
const [highlight, setHighlight] = useState(0);
|
|
1382
|
-
const [
|
|
1390
|
+
const [removedIds, setRemovedIds] = useState(/* @__PURE__ */ new Set());
|
|
1383
1391
|
const [confirmId, setConfirmId] = useState(null);
|
|
1384
1392
|
const [error, setError] = useState(null);
|
|
1393
|
+
const list = conversations.filter((c) => !removedIds.has(c.id));
|
|
1385
1394
|
const hits = fuzzyFilter(query, list, conversationKeys);
|
|
1386
1395
|
const rows = [{ kind: "new" }, ...hits.map((hit) => ({
|
|
1387
1396
|
kind: "conv",
|
|
@@ -1408,12 +1417,15 @@ function ConversationList({ agent, conversations, onPick }) {
|
|
|
1408
1417
|
};
|
|
1409
1418
|
const deleteConversation = (id) => {
|
|
1410
1419
|
if (!rest) return;
|
|
1411
|
-
|
|
1412
|
-
if (!removed) return;
|
|
1420
|
+
if (!list.some((c) => c.id === id)) return;
|
|
1413
1421
|
setConfirmId(null);
|
|
1414
|
-
|
|
1422
|
+
setRemovedIds((prev) => new Set([...prev, id]));
|
|
1415
1423
|
rest.deleteConversation({ conversationId: id }).catch((err) => {
|
|
1416
|
-
|
|
1424
|
+
setRemovedIds((prev) => {
|
|
1425
|
+
const next = new Set(prev);
|
|
1426
|
+
next.delete(id);
|
|
1427
|
+
return next;
|
|
1428
|
+
});
|
|
1417
1429
|
setError(err instanceof Error ? err.message : String(err));
|
|
1418
1430
|
});
|
|
1419
1431
|
};
|
|
@@ -1478,6 +1490,7 @@ function ConversationList({ agent, conversations, onPick }) {
|
|
|
1478
1490
|
hits.length,
|
|
1479
1491
|
"/",
|
|
1480
1492
|
list.length,
|
|
1493
|
+
complete ? "" : " (loading…)",
|
|
1481
1494
|
" · ↑/↓ move · ↵ open · ctrl+d delete · esc back"
|
|
1482
1495
|
]
|
|
1483
1496
|
}),
|
|
@@ -3014,16 +3027,23 @@ function str(chunk, key) {
|
|
|
3014
3027
|
const value = chunk[key];
|
|
3015
3028
|
return typeof value === "string" ? value : null;
|
|
3016
3029
|
}
|
|
3017
|
-
|
|
3030
|
+
/**
|
|
3031
|
+
* `agentName` is the display name of the agent producing this run's stream.
|
|
3032
|
+
* It's stamped onto each assistant-origin item so a multi-agent conversation
|
|
3033
|
+
* can attribute live turns; pass null in a solo thread to leave items
|
|
3034
|
+
* un-attributed (the chat screen only renders the name when the thread has
|
|
3035
|
+
* more than one agent).
|
|
3036
|
+
*/
|
|
3037
|
+
function applyChunk(items, chunk, agentName = null) {
|
|
3018
3038
|
const type = str(chunk, "type");
|
|
3019
3039
|
if (!type) return [...items];
|
|
3020
3040
|
switch (type) {
|
|
3021
|
-
case "text-start": return appendAssistantTextStart(items, str(chunk, "id") ?? cryptoId());
|
|
3041
|
+
case "text-start": return appendAssistantTextStart(items, str(chunk, "id") ?? cryptoId(), agentName);
|
|
3022
3042
|
case "text-delta": {
|
|
3023
3043
|
const id = str(chunk, "id");
|
|
3024
3044
|
const delta = str(chunk, "delta") ?? str(chunk, "text") ?? "";
|
|
3025
3045
|
if (!id || !delta) return [...items];
|
|
3026
|
-
return appendAssistantTextDelta(items, id, delta);
|
|
3046
|
+
return appendAssistantTextDelta(items, id, delta, agentName);
|
|
3027
3047
|
}
|
|
3028
3048
|
case "text-end": {
|
|
3029
3049
|
const id = str(chunk, "id");
|
|
@@ -3036,14 +3056,15 @@ function applyChunk(items, chunk) {
|
|
|
3036
3056
|
kind: "reasoning",
|
|
3037
3057
|
id: bubbleId,
|
|
3038
3058
|
text: "",
|
|
3039
|
-
done: false
|
|
3059
|
+
done: false,
|
|
3060
|
+
agentName
|
|
3040
3061
|
}];
|
|
3041
3062
|
}
|
|
3042
3063
|
case "reasoning-delta": {
|
|
3043
3064
|
const id = str(chunk, "id");
|
|
3044
3065
|
const delta = str(chunk, "delta") ?? str(chunk, "text") ?? "";
|
|
3045
3066
|
if (!id || !delta) return [...items];
|
|
3046
|
-
return appendReasoningDelta(items, id, delta);
|
|
3067
|
+
return appendReasoningDelta(items, id, delta, agentName);
|
|
3047
3068
|
}
|
|
3048
3069
|
case "reasoning-end": {
|
|
3049
3070
|
const id = str(chunk, "id");
|
|
@@ -3066,7 +3087,8 @@ function applyChunk(items, chunk) {
|
|
|
3066
3087
|
inputText: "",
|
|
3067
3088
|
input: null,
|
|
3068
3089
|
output: null,
|
|
3069
|
-
state: "streaming"
|
|
3090
|
+
state: "streaming",
|
|
3091
|
+
agentName
|
|
3070
3092
|
}];
|
|
3071
3093
|
}
|
|
3072
3094
|
case "tool-input-delta": {
|
|
@@ -3095,7 +3117,8 @@ function applyChunk(items, chunk) {
|
|
|
3095
3117
|
inputText: "",
|
|
3096
3118
|
input,
|
|
3097
3119
|
output: null,
|
|
3098
|
-
state: "input-ready"
|
|
3120
|
+
state: "input-ready",
|
|
3121
|
+
agentName
|
|
3099
3122
|
}];
|
|
3100
3123
|
}
|
|
3101
3124
|
case "tool-output-available": {
|
|
@@ -3152,7 +3175,8 @@ function applyChunk(items, chunk) {
|
|
|
3152
3175
|
id,
|
|
3153
3176
|
card,
|
|
3154
3177
|
status: "idle",
|
|
3155
|
-
detail: null
|
|
3178
|
+
detail: null,
|
|
3179
|
+
agentName
|
|
3156
3180
|
};
|
|
3157
3181
|
if (items.some((m) => m.kind === "card" && m.id === id)) return items.map((m) => m.kind === "card" && m.id === id ? next : m);
|
|
3158
3182
|
return [...items, next];
|
|
@@ -3193,16 +3217,17 @@ function openTextIndex(items, id, kind) {
|
|
|
3193
3217
|
}
|
|
3194
3218
|
return -1;
|
|
3195
3219
|
}
|
|
3196
|
-
function appendAssistantTextStart(items, id) {
|
|
3220
|
+
function appendAssistantTextStart(items, id, agentName) {
|
|
3197
3221
|
const bubbleId = freshTextId(items, id, "assistant-text");
|
|
3198
3222
|
return [...items, {
|
|
3199
3223
|
kind: "assistant-text",
|
|
3200
3224
|
id: bubbleId,
|
|
3201
3225
|
text: "",
|
|
3202
|
-
done: false
|
|
3226
|
+
done: false,
|
|
3227
|
+
agentName
|
|
3203
3228
|
}];
|
|
3204
3229
|
}
|
|
3205
|
-
function appendAssistantTextDelta(items, id, delta) {
|
|
3230
|
+
function appendAssistantTextDelta(items, id, delta, agentName) {
|
|
3206
3231
|
const idx = openTextIndex(items, id, "assistant-text");
|
|
3207
3232
|
if (idx === -1) {
|
|
3208
3233
|
const bubbleId = freshTextId(items, id, "assistant-text");
|
|
@@ -3210,7 +3235,8 @@ function appendAssistantTextDelta(items, id, delta) {
|
|
|
3210
3235
|
kind: "assistant-text",
|
|
3211
3236
|
id: bubbleId,
|
|
3212
3237
|
text: delta,
|
|
3213
|
-
done: false
|
|
3238
|
+
done: false,
|
|
3239
|
+
agentName
|
|
3214
3240
|
}];
|
|
3215
3241
|
}
|
|
3216
3242
|
return items.map((m, i) => i === idx && m.kind === "assistant-text" ? {
|
|
@@ -3218,7 +3244,7 @@ function appendAssistantTextDelta(items, id, delta) {
|
|
|
3218
3244
|
text: m.text + delta
|
|
3219
3245
|
} : m);
|
|
3220
3246
|
}
|
|
3221
|
-
function appendReasoningDelta(items, id, delta) {
|
|
3247
|
+
function appendReasoningDelta(items, id, delta, agentName) {
|
|
3222
3248
|
const idx = openTextIndex(items, id, "reasoning");
|
|
3223
3249
|
if (idx === -1) {
|
|
3224
3250
|
const bubbleId = freshTextId(items, id, "reasoning");
|
|
@@ -3226,7 +3252,8 @@ function appendReasoningDelta(items, id, delta) {
|
|
|
3226
3252
|
kind: "reasoning",
|
|
3227
3253
|
id: bubbleId,
|
|
3228
3254
|
text: delta,
|
|
3229
|
-
done: false
|
|
3255
|
+
done: false,
|
|
3256
|
+
agentName
|
|
3230
3257
|
}];
|
|
3231
3258
|
}
|
|
3232
3259
|
return items.map((m, i) => i === idx && m.kind === "reasoning" ? {
|
|
@@ -3256,6 +3283,59 @@ function cryptoId() {
|
|
|
3256
3283
|
return crypto.randomUUID();
|
|
3257
3284
|
}
|
|
3258
3285
|
|
|
3286
|
+
//#endregion
|
|
3287
|
+
//#region src/chat/tui/chat/attribution.ts
|
|
3288
|
+
/**
|
|
3289
|
+
* The agent that authored an item, or null for items with no agent (the user's
|
|
3290
|
+
* own turns, errors, the recap).
|
|
3291
|
+
*/
|
|
3292
|
+
function itemAgentName(m) {
|
|
3293
|
+
return "agentName" in m ? m.agentName ?? null : null;
|
|
3294
|
+
}
|
|
3295
|
+
/**
|
|
3296
|
+
* Items that end an agent's turn: the human speaking or acting. The next
|
|
3297
|
+
* assistant item after one of these starts a new turn and is re-headed with its
|
|
3298
|
+
* author, even when the same agent replies again — in a multi-agent thread the
|
|
3299
|
+
* reader can't be asked to scan back past their own message to work out who is
|
|
3300
|
+
* answering.
|
|
3301
|
+
*/
|
|
3302
|
+
function isTurnSeparator(m) {
|
|
3303
|
+
return m.kind === "user" || m.kind === "pending-steer" || m.kind === "shell";
|
|
3304
|
+
}
|
|
3305
|
+
/**
|
|
3306
|
+
* Every agent that has spoken in the transcript, plus the agent on screen.
|
|
3307
|
+
* Attribution renders only when this holds more than one name, mirroring web's
|
|
3308
|
+
* group-chat gate so a solo thread carries no attribution chrome at all.
|
|
3309
|
+
*/
|
|
3310
|
+
function conversationAgentNames(items, onScreenAgentName) {
|
|
3311
|
+
const names = new Set([onScreenAgentName]);
|
|
3312
|
+
for (const item of items) {
|
|
3313
|
+
const name = itemAgentName(item);
|
|
3314
|
+
if (name) names.add(name);
|
|
3315
|
+
}
|
|
3316
|
+
return names;
|
|
3317
|
+
}
|
|
3318
|
+
/**
|
|
3319
|
+
* The agent-name label to render above `items[i]`, or null for no label. Every
|
|
3320
|
+
* assistant turn is headed with its author's name. Within one turn the items
|
|
3321
|
+
* (text, reasoning, tool calls) share the single header, so a turn isn't
|
|
3322
|
+
* re-labeled on each tool row; `error` and `recap` items are transparent and
|
|
3323
|
+
* don't break that grouping.
|
|
3324
|
+
*/
|
|
3325
|
+
function agentLabelFor(items, i) {
|
|
3326
|
+
const current = items[i];
|
|
3327
|
+
const name = current ? itemAgentName(current) : null;
|
|
3328
|
+
if (!name) return null;
|
|
3329
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
3330
|
+
const prevItem = items[j];
|
|
3331
|
+
if (!prevItem) continue;
|
|
3332
|
+
if (isTurnSeparator(prevItem)) return name;
|
|
3333
|
+
const prev = itemAgentName(prevItem);
|
|
3334
|
+
if (prev !== null) return prev === name ? null : name;
|
|
3335
|
+
}
|
|
3336
|
+
return name;
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3259
3339
|
//#endregion
|
|
3260
3340
|
//#region src/chat/tui/chat/history.ts
|
|
3261
3341
|
function isDynamicTool(part) {
|
|
@@ -3284,6 +3364,7 @@ function uiMessagesToItems(messages) {
|
|
|
3284
3364
|
continue;
|
|
3285
3365
|
}
|
|
3286
3366
|
if (m.role === "assistant") {
|
|
3367
|
+
const agentName = m.metadata?.custom?.agentName ?? null;
|
|
3287
3368
|
let textBuf = "";
|
|
3288
3369
|
let textIdx = 0;
|
|
3289
3370
|
for (const part of m.parts) {
|
|
@@ -3296,7 +3377,8 @@ function uiMessagesToItems(messages) {
|
|
|
3296
3377
|
kind: "assistant-text",
|
|
3297
3378
|
id: `${m.id}#t${textIdx++}`,
|
|
3298
3379
|
text: textBuf,
|
|
3299
|
-
done: true
|
|
3380
|
+
done: true,
|
|
3381
|
+
agentName
|
|
3300
3382
|
});
|
|
3301
3383
|
textBuf = "";
|
|
3302
3384
|
}
|
|
@@ -3305,7 +3387,8 @@ function uiMessagesToItems(messages) {
|
|
|
3305
3387
|
kind: "reasoning",
|
|
3306
3388
|
id: `${m.id}#r${textIdx++}`,
|
|
3307
3389
|
text: "text" in part && typeof part.text === "string" ? part.text : "",
|
|
3308
|
-
done: true
|
|
3390
|
+
done: true,
|
|
3391
|
+
agentName
|
|
3309
3392
|
});
|
|
3310
3393
|
continue;
|
|
3311
3394
|
}
|
|
@@ -3319,7 +3402,8 @@ function uiMessagesToItems(messages) {
|
|
|
3319
3402
|
id: toolCallId ?? `${m.id}#c${textIdx++}`,
|
|
3320
3403
|
card,
|
|
3321
3404
|
status: "idle",
|
|
3322
|
-
detail: null
|
|
3405
|
+
detail: null,
|
|
3406
|
+
agentName
|
|
3323
3407
|
});
|
|
3324
3408
|
}
|
|
3325
3409
|
continue;
|
|
@@ -3339,7 +3423,8 @@ function uiMessagesToItems(messages) {
|
|
|
3339
3423
|
kind: "ok",
|
|
3340
3424
|
value: part.output
|
|
3341
3425
|
} : null,
|
|
3342
|
-
state
|
|
3426
|
+
state,
|
|
3427
|
+
agentName
|
|
3343
3428
|
});
|
|
3344
3429
|
}
|
|
3345
3430
|
}
|
|
@@ -3347,7 +3432,8 @@ function uiMessagesToItems(messages) {
|
|
|
3347
3432
|
kind: "assistant-text",
|
|
3348
3433
|
id: `${m.id}#t${textIdx++}`,
|
|
3349
3434
|
text: textBuf,
|
|
3350
|
-
done: true
|
|
3435
|
+
done: true,
|
|
3436
|
+
agentName
|
|
3351
3437
|
});
|
|
3352
3438
|
}
|
|
3353
3439
|
}
|
|
@@ -5155,10 +5241,11 @@ function ChatScreen({ agent, conversation }) {
|
|
|
5155
5241
|
cancelled = true;
|
|
5156
5242
|
};
|
|
5157
5243
|
}, [rest, initialConversationId]);
|
|
5158
|
-
const attachToRun = useCallback((runId) => {
|
|
5244
|
+
const attachToRun = useCallback((runId, runAgentName) => {
|
|
5159
5245
|
if (!rest) return;
|
|
5160
5246
|
const abort = new AbortController();
|
|
5161
5247
|
const responsePreview = createResponsePreview();
|
|
5248
|
+
const streamAgentName = runAgentName ?? agent.name;
|
|
5162
5249
|
setRun({
|
|
5163
5250
|
kind: "streaming",
|
|
5164
5251
|
runId,
|
|
@@ -5170,7 +5257,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
5170
5257
|
onEvent: (event) => {
|
|
5171
5258
|
if (event.kind === "chunk") {
|
|
5172
5259
|
responsePreview.addChunk(event.chunk);
|
|
5173
|
-
setItems((prev) => applyChunk(prev, event.chunk));
|
|
5260
|
+
setItems((prev) => applyChunk(prev, event.chunk, streamAgentName));
|
|
5174
5261
|
return;
|
|
5175
5262
|
}
|
|
5176
5263
|
const errorText = event.error;
|
|
@@ -5208,6 +5295,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
5208
5295
|
agent.name,
|
|
5209
5296
|
agentHost
|
|
5210
5297
|
]);
|
|
5298
|
+
const multiAgent = useMemo(() => conversationAgentNames(items, agent.name), [items, agent.name]).size > 1;
|
|
5211
5299
|
useEffect(() => {
|
|
5212
5300
|
if (!rest || !conversationId) return;
|
|
5213
5301
|
const abort = new AbortController();
|
|
@@ -5231,7 +5319,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
5231
5319
|
try {
|
|
5232
5320
|
const active = await rest.activeRun({ conversationId });
|
|
5233
5321
|
if (cancelled || !active) return;
|
|
5234
|
-
attachToRun(active.runId);
|
|
5322
|
+
attachToRun(active.runId, active.agentName || null);
|
|
5235
5323
|
} catch (_error) {}
|
|
5236
5324
|
})();
|
|
5237
5325
|
return () => {
|
|
@@ -5298,10 +5386,10 @@ function ChatScreen({ agent, conversation }) {
|
|
|
5298
5386
|
text: trimmed
|
|
5299
5387
|
} : m));
|
|
5300
5388
|
const current = runRef.current;
|
|
5301
|
-
if (!(current.kind === "streaming" && current.runId === result.runId)) attachToRun(result.runId);
|
|
5389
|
+
if (!(current.kind === "streaming" && current.runId === result.runId)) attachToRun(result.runId, result.agentName ?? null);
|
|
5302
5390
|
return;
|
|
5303
5391
|
}
|
|
5304
|
-
attachToRun(result.runId);
|
|
5392
|
+
attachToRun(result.runId, result.agentName ?? null);
|
|
5305
5393
|
} catch (err) {
|
|
5306
5394
|
setItems((prev) => [...prev.filter((m) => m.id !== optimisticId), {
|
|
5307
5395
|
kind: "error",
|
|
@@ -6032,7 +6120,22 @@ function ChatScreen({ agent, conversation }) {
|
|
|
6032
6120
|
agent.name,
|
|
6033
6121
|
" below."
|
|
6034
6122
|
]
|
|
6035
|
-
}) : /* @__PURE__ */ jsx(Fragment, { children: items.map((item
|
|
6123
|
+
}) : /* @__PURE__ */ jsx(Fragment, { children: items.map((item, i) => {
|
|
6124
|
+
const label = multiAgent ? agentLabelFor(items, i) : null;
|
|
6125
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
6126
|
+
style: { flexDirection: "column" },
|
|
6127
|
+
children: [label ? /* @__PURE__ */ jsx("box", {
|
|
6128
|
+
style: {
|
|
6129
|
+
paddingLeft: 3,
|
|
6130
|
+
paddingRight: 1
|
|
6131
|
+
},
|
|
6132
|
+
children: /* @__PURE__ */ jsx("text", {
|
|
6133
|
+
fg: theme.muted,
|
|
6134
|
+
children: /* @__PURE__ */ jsx("b", { children: label })
|
|
6135
|
+
})
|
|
6136
|
+
}) : null, /* @__PURE__ */ jsx(RenderItem, { item })]
|
|
6137
|
+
}, item.id);
|
|
6138
|
+
}) }), run.kind !== "idle" ? /* @__PURE__ */ jsx(ActivityRow, { label: run.kind === "sending" ? "sending" : "working" }) : null]
|
|
6036
6139
|
})
|
|
6037
6140
|
}),
|
|
6038
6141
|
pendingVisible ? /* @__PURE__ */ jsxs("box", {
|