@invergent/agent-chat-react 2.15.9 → 2.16.1
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/index.cjs +184 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +184 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -61,6 +61,10 @@ interface AgentChatMessage {
|
|
|
61
61
|
status: AgentChatMessageStatus;
|
|
62
62
|
toolCalls?: AgentChatToolCallInfo[];
|
|
63
63
|
reasoning?: string;
|
|
64
|
+
/** Provider-reported reasoning usage for this iteration, when available. */
|
|
65
|
+
reasoningTokens?: number;
|
|
66
|
+
/** Incoming reasoning chunks counted live, before provider usage arrives. */
|
|
67
|
+
reasoningDeltaCount?: number;
|
|
64
68
|
systemKind?: AgentChatSystemKind;
|
|
65
69
|
systemMeta?: Record<string, unknown>;
|
|
66
70
|
errorInfo?: AgentChatErrorInfo;
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,10 @@ interface AgentChatMessage {
|
|
|
61
61
|
status: AgentChatMessageStatus;
|
|
62
62
|
toolCalls?: AgentChatToolCallInfo[];
|
|
63
63
|
reasoning?: string;
|
|
64
|
+
/** Provider-reported reasoning usage for this iteration, when available. */
|
|
65
|
+
reasoningTokens?: number;
|
|
66
|
+
/** Incoming reasoning chunks counted live, before provider usage arrives. */
|
|
67
|
+
reasoningDeltaCount?: number;
|
|
64
68
|
systemKind?: AgentChatSystemKind;
|
|
65
69
|
systemMeta?: Record<string, unknown>;
|
|
66
70
|
errorInfo?: AgentChatErrorInfo;
|
package/dist/index.js
CHANGED
|
@@ -5255,7 +5255,11 @@ function cancelledToolLabel(toolName) {
|
|
|
5255
5255
|
// Arbor research-mission tools (the /auto-research coordinator loop).
|
|
5256
5256
|
idea_tree: "Idea tree",
|
|
5257
5257
|
dispatch_experiments: "Dispatch experiments",
|
|
5258
|
-
merge_experiment: "Merge experiment"
|
|
5258
|
+
merge_experiment: "Merge experiment",
|
|
5259
|
+
kb_search_pages: "Knowledge base search",
|
|
5260
|
+
kb_list_pages: "Knowledge base index",
|
|
5261
|
+
kb_read_page: "Knowledge base page",
|
|
5262
|
+
vision_analyze: "Image analysis"
|
|
5259
5263
|
};
|
|
5260
5264
|
if (map[toolName]) return map[toolName];
|
|
5261
5265
|
if (toolName.startsWith("mcp__")) return formatMcpToolLabel(toolName);
|
|
@@ -5318,16 +5322,27 @@ function extractToolDetail(tc) {
|
|
|
5318
5322
|
return code3 ? truncate3(code3.split("\n")[0] ?? "", 40) : null;
|
|
5319
5323
|
}
|
|
5320
5324
|
case "web_search":
|
|
5321
|
-
case "
|
|
5325
|
+
case "session_search":
|
|
5322
5326
|
return stringArg("query");
|
|
5327
|
+
// web_crawl takes a start ``url``, not a query.
|
|
5328
|
+
case "web_crawl":
|
|
5323
5329
|
case "web_extract": {
|
|
5324
5330
|
const url = stringArg("url");
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
+
return url ? hostOf2(url) : null;
|
|
5332
|
+
}
|
|
5333
|
+
case "kb_search_pages": {
|
|
5334
|
+
const query = stringArg("query");
|
|
5335
|
+
return query ? truncate3(query, 60) : null;
|
|
5336
|
+
}
|
|
5337
|
+
case "kb_read_page": {
|
|
5338
|
+
const path = stringArg("path");
|
|
5339
|
+
if (!path) return null;
|
|
5340
|
+
const pages = stringArg("pages");
|
|
5341
|
+
return pages ? `${kbPageName(path)} \xB7 pages ${pages}` : kbPageName(path);
|
|
5342
|
+
}
|
|
5343
|
+
case "vision_analyze": {
|
|
5344
|
+
const image = stringArg("image");
|
|
5345
|
+
return image && !image.startsWith("data:") ? lastPathSegment(image) : null;
|
|
5331
5346
|
}
|
|
5332
5347
|
case "skill_view":
|
|
5333
5348
|
case "skill_manage":
|
|
@@ -5360,14 +5375,7 @@ function extractToolDetail(tc) {
|
|
|
5360
5375
|
const title = stringArg("title");
|
|
5361
5376
|
if (title) return truncate3(title, 60);
|
|
5362
5377
|
const url = stringArg("url");
|
|
5363
|
-
|
|
5364
|
-
try {
|
|
5365
|
-
return new URL(url).hostname.replace(/^www\./, "");
|
|
5366
|
-
} catch {
|
|
5367
|
-
return truncate3(url, 40);
|
|
5368
|
-
}
|
|
5369
|
-
}
|
|
5370
|
-
return null;
|
|
5378
|
+
return url ? hostOf2(url) : null;
|
|
5371
5379
|
}
|
|
5372
5380
|
if (action === "retrieve") {
|
|
5373
5381
|
return stringArg("query");
|
|
@@ -5400,6 +5408,34 @@ function lastPathSegment(path) {
|
|
|
5400
5408
|
function truncate3(s, max) {
|
|
5401
5409
|
return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
5402
5410
|
}
|
|
5411
|
+
function hostOf2(url) {
|
|
5412
|
+
try {
|
|
5413
|
+
return new URL(url).hostname.replace(/^www\./, "") || truncate3(url, 40);
|
|
5414
|
+
} catch {
|
|
5415
|
+
return truncate3(url, 40);
|
|
5416
|
+
}
|
|
5417
|
+
}
|
|
5418
|
+
function kbPageName(path) {
|
|
5419
|
+
return lastPathSegment(path).replace(/\.(md|json)$/, "");
|
|
5420
|
+
}
|
|
5421
|
+
var _PLURAL_LABEL = {
|
|
5422
|
+
read_file: (n) => `Read ${n} files`,
|
|
5423
|
+
write_file: (n) => `Wrote ${n} files`,
|
|
5424
|
+
patch: (n) => `Edited ${n} files`,
|
|
5425
|
+
search_files: (n) => `Ran ${n} file searches`,
|
|
5426
|
+
terminal: (n) => `Ran ${n} commands`,
|
|
5427
|
+
web_search: (n) => `Ran ${n} web searches`,
|
|
5428
|
+
web_extract: (n) => `Fetched ${n} pages`,
|
|
5429
|
+
session_search: (n) => `Ran ${n} session searches`,
|
|
5430
|
+
kb_search_pages: (n) => `Ran ${n} knowledge base searches`,
|
|
5431
|
+
kb_read_page: (n) => `Read ${n} knowledge base pages`,
|
|
5432
|
+
vision_analyze: (n) => `Looked at ${n} images`,
|
|
5433
|
+
consult_expert: (n) => `Consulted ${n} experts`,
|
|
5434
|
+
delegate_task: (n) => `Delegated ${n} tasks`
|
|
5435
|
+
};
|
|
5436
|
+
function sameToolGroupLabel(toolName, count) {
|
|
5437
|
+
return _PLURAL_LABEL[toolName]?.(count) ?? `${cancelledToolLabel(toolName)} \xD7 ${count}`;
|
|
5438
|
+
}
|
|
5403
5439
|
function toolRowLabel(tc) {
|
|
5404
5440
|
const detail = extractToolDetail(tc);
|
|
5405
5441
|
switch (tc.toolName) {
|
|
@@ -5423,7 +5459,22 @@ function toolRowLabel(tc) {
|
|
|
5423
5459
|
case "web_search":
|
|
5424
5460
|
return detail ? `Searched the web for "${detail}"` : "Searched the web";
|
|
5425
5461
|
case "web_crawl":
|
|
5426
|
-
return detail ? `Crawled
|
|
5462
|
+
return detail ? `Crawled ${detail}` : "Crawled a site";
|
|
5463
|
+
case "kb_search_pages": {
|
|
5464
|
+
if (!detail) return "Searched the knowledge base";
|
|
5465
|
+
return stringField(parseArgs(tc.args), "mode") === "documents" ? `Looked up document "${detail}"` : `Searched the knowledge base for "${detail}"`;
|
|
5466
|
+
}
|
|
5467
|
+
case "kb_list_pages":
|
|
5468
|
+
return "Browsed the knowledge base index";
|
|
5469
|
+
case "kb_read_page": {
|
|
5470
|
+
const args = parseArgs(tc.args);
|
|
5471
|
+
const path = stringField(args, "path");
|
|
5472
|
+
if (!path) return "Read a knowledge base page";
|
|
5473
|
+
const pages = stringField(args, "pages");
|
|
5474
|
+
return pages ? `Read ${kbPageName(path)}, pages ${pages}` : `Read ${kbPageName(path)}`;
|
|
5475
|
+
}
|
|
5476
|
+
case "vision_analyze":
|
|
5477
|
+
return detail ? `Looked at ${detail}` : "Looked at an image";
|
|
5427
5478
|
case "web_extract":
|
|
5428
5479
|
return detail ? `Fetched ${detail}` : "Fetched a page";
|
|
5429
5480
|
case "session_search":
|
|
@@ -10578,6 +10629,17 @@ function useSmoothStream(target, isStreaming) {
|
|
|
10578
10629
|
return displayedLen >= target.length ? target : target.slice(0, displayedLen);
|
|
10579
10630
|
}
|
|
10580
10631
|
|
|
10632
|
+
// src/runtime/reasoning-tokens.ts
|
|
10633
|
+
function formatReasoningTokens(tokens) {
|
|
10634
|
+
if (tokens < 1e3) return String(tokens);
|
|
10635
|
+
return `${(tokens / 1e3).toFixed(1).replace(/\.0$/, "")}k`;
|
|
10636
|
+
}
|
|
10637
|
+
function reasoningTokenLabel(message, live) {
|
|
10638
|
+
const tokens = message.reasoningTokens ?? message.reasoningDeltaCount;
|
|
10639
|
+
if (tokens === void 0) return live ? "Thinking..." : "Thought";
|
|
10640
|
+
return `${live ? "Thinking..." : "Thought \xB7"} ${formatReasoningTokens(tokens)} tokens`;
|
|
10641
|
+
}
|
|
10642
|
+
|
|
10581
10643
|
// src/lib/next-action.ts
|
|
10582
10644
|
var _NEXT_ACTION_RE = /<next_action([^>]*)>([\s\S]*?)<\/next_action>\s*/gi;
|
|
10583
10645
|
var _PARTIAL_NEXT_ACTION_FOOTER_RE = /(?:^|\n)\s*<(?:n(?:e(?:x(?:t(?:_(?:a(?:c(?:t(?:i(?:o(?:n[\s\S]*)?)?)?)?)?)?)?)?)?)?)?$/i;
|
|
@@ -12133,7 +12195,7 @@ function SimpleFinalAnswer({
|
|
|
12133
12195
|
function deriveIterationLabel(message) {
|
|
12134
12196
|
const calls = visibleToolCalls(message);
|
|
12135
12197
|
if (calls.length === 0) {
|
|
12136
|
-
return message.reasoning
|
|
12198
|
+
return message.reasoning || message.reasoningTokens ? reasoningTokenLabel(message, false) : null;
|
|
12137
12199
|
}
|
|
12138
12200
|
if (calls.every((tc) => tc.toolName === "skill_view")) {
|
|
12139
12201
|
return skillViewLabel(calls);
|
|
@@ -12145,8 +12207,7 @@ function deriveIterationLabel(message) {
|
|
|
12145
12207
|
const firstName = calls[0].toolName;
|
|
12146
12208
|
const allSame = calls.every((tc) => tc.toolName === firstName);
|
|
12147
12209
|
if (allSame) {
|
|
12148
|
-
|
|
12149
|
-
return `${human} \xD7 ${calls.length}`;
|
|
12210
|
+
return sameToolGroupLabel(firstName, calls.length);
|
|
12150
12211
|
}
|
|
12151
12212
|
return `Used ${calls.length} tools`;
|
|
12152
12213
|
}
|
|
@@ -12165,11 +12226,28 @@ function isIterationLive(message) {
|
|
|
12165
12226
|
}
|
|
12166
12227
|
return message.status === "streaming";
|
|
12167
12228
|
}
|
|
12229
|
+
function hasInlineRunningIndicator(messages, viewMode) {
|
|
12230
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
12231
|
+
const message = messages[i];
|
|
12232
|
+
if (message.role === "user") return false;
|
|
12233
|
+
if (message.role !== "assistant") continue;
|
|
12234
|
+
if (viewMode === "simple") {
|
|
12235
|
+
if (message.toolCalls?.some((tc) => tc.toolName === "ask_user_question")) {
|
|
12236
|
+
return false;
|
|
12237
|
+
}
|
|
12238
|
+
return isIterationLive(message) && (!!message.toolCalls?.length || !message.content || message.content === message.reasoning);
|
|
12239
|
+
}
|
|
12240
|
+
return messageToEntries(message, i === messages.length - 1, {}).some(
|
|
12241
|
+
(entry) => entry.kind === "reasoning" && entry.isStreaming
|
|
12242
|
+
);
|
|
12243
|
+
}
|
|
12244
|
+
return false;
|
|
12245
|
+
}
|
|
12168
12246
|
function liveIterationLabel(message) {
|
|
12169
12247
|
const running = (message.toolCalls ?? []).filter(
|
|
12170
12248
|
(tc) => tc.status === "running" && !isHiddenSimpleTool(tc)
|
|
12171
12249
|
);
|
|
12172
|
-
if (running.length === 0) return
|
|
12250
|
+
if (running.length === 0) return reasoningTokenLabel(message, true);
|
|
12173
12251
|
if (running.every((tc) => tc.toolName === "skill_view")) {
|
|
12174
12252
|
return `${skillViewLabel(running)}\u2026`;
|
|
12175
12253
|
}
|
|
@@ -12209,7 +12287,11 @@ var _TOOL_ROW_ICON = {
|
|
|
12209
12287
|
research_memory: BookOpenIcon,
|
|
12210
12288
|
research_outline: ListIcon,
|
|
12211
12289
|
run_coding_agent: BotIcon,
|
|
12212
|
-
code_run: BotIcon
|
|
12290
|
+
code_run: BotIcon,
|
|
12291
|
+
kb_search_pages: LibraryIcon,
|
|
12292
|
+
kb_list_pages: LibraryIcon,
|
|
12293
|
+
kb_read_page: LibraryIcon,
|
|
12294
|
+
vision_analyze: EyeIcon
|
|
12213
12295
|
};
|
|
12214
12296
|
function _toolRowIcon(toolName) {
|
|
12215
12297
|
return _TOOL_ROW_ICON[toolName] ?? WrenchIcon;
|
|
@@ -12226,44 +12308,16 @@ function SimpleDetailRow({ icon: Icon, children }) {
|
|
|
12226
12308
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 leading-relaxed text-foreground/60", children })
|
|
12227
12309
|
] });
|
|
12228
12310
|
}
|
|
12229
|
-
function ClampedReasoning({
|
|
12230
|
-
text,
|
|
12231
|
-
previewParagraphs = 2
|
|
12232
|
-
}) {
|
|
12233
|
-
const paragraphs = splitReasoningParagraphs(text);
|
|
12234
|
-
const [expanded, setExpanded] = useState(false);
|
|
12235
|
-
const hasMore = paragraphs.length > previewParagraphs;
|
|
12236
|
-
const visible = expanded || !hasMore ? paragraphs : paragraphs.slice(0, previewParagraphs);
|
|
12237
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
12238
|
-
visible.map((paragraph, i) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap", children: paragraph }, i)),
|
|
12239
|
-
hasMore && /* @__PURE__ */ jsx(
|
|
12240
|
-
"button",
|
|
12241
|
-
{
|
|
12242
|
-
type: "button",
|
|
12243
|
-
onClick: () => setExpanded((prev) => !prev),
|
|
12244
|
-
className: "text-xs font-medium text-foreground hover:text-foreground/70 cursor-pointer",
|
|
12245
|
-
children: expanded ? "Show less" : "Show more..."
|
|
12246
|
-
}
|
|
12247
|
-
)
|
|
12248
|
-
] });
|
|
12249
|
-
}
|
|
12250
|
-
function splitReasoningParagraphs(text) {
|
|
12251
|
-
const trimmed = text.trim();
|
|
12252
|
-
if (!trimmed) return [];
|
|
12253
|
-
const blankSplit = trimmed.split(/\n\s*\n+/).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
12254
|
-
if (blankSplit.length > 1) return blankSplit;
|
|
12255
|
-
return trimmed.split(/\n+/).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
12256
|
-
}
|
|
12257
12311
|
function IterationExpanded({
|
|
12258
12312
|
message
|
|
12259
12313
|
}) {
|
|
12260
12314
|
const calls = visibleToolCalls(message);
|
|
12261
|
-
const
|
|
12315
|
+
const hasReasoning = !!message.reasoning || !!message.reasoningTokens;
|
|
12262
12316
|
const anyVisibleRunning = calls.some((tc) => tc.status === "running");
|
|
12263
|
-
const showDone = !anyVisibleRunning && (calls.length > 0 ||
|
|
12264
|
-
if (!
|
|
12317
|
+
const showDone = !anyVisibleRunning && (calls.length > 0 || hasReasoning);
|
|
12318
|
+
if (!hasReasoning && calls.length === 0) return null;
|
|
12265
12319
|
return /* @__PURE__ */ jsxs("div", { className: "ml-2 space-y-3 border-l border-border/40 pl-4 py-1", children: [
|
|
12266
|
-
|
|
12320
|
+
hasReasoning && /* @__PURE__ */ jsx(SimpleDetailRow, { icon: ClockIcon, children: /* @__PURE__ */ jsx("span", { children: reasoningTokenLabel(message, false) }) }),
|
|
12267
12321
|
calls.map((tc) => {
|
|
12268
12322
|
if (tc.toolName === "todo") {
|
|
12269
12323
|
return /* @__PURE__ */ jsx("div", { className: "pr-1", children: /* @__PURE__ */ jsx(TodoToolBlock, { tc }) }, tc.id);
|
|
@@ -12278,6 +12332,7 @@ function IterationExpanded({
|
|
|
12278
12332
|
}
|
|
12279
12333
|
function IterationGroup({
|
|
12280
12334
|
message,
|
|
12335
|
+
isActive = true,
|
|
12281
12336
|
sessionId,
|
|
12282
12337
|
artifactFallbacks,
|
|
12283
12338
|
onFileSelect
|
|
@@ -12297,7 +12352,7 @@ function IterationGroup({
|
|
|
12297
12352
|
}
|
|
12298
12353
|
) });
|
|
12299
12354
|
}
|
|
12300
|
-
if (isIterationLive(message)) {
|
|
12355
|
+
if (isActive && isIterationLive(message)) {
|
|
12301
12356
|
return /* @__PURE__ */ jsx(
|
|
12302
12357
|
OrbShimmerLabel,
|
|
12303
12358
|
{
|
|
@@ -12311,6 +12366,9 @@ function IterationGroup({
|
|
|
12311
12366
|
if (!label) {
|
|
12312
12367
|
return null;
|
|
12313
12368
|
}
|
|
12369
|
+
if (!summary && visibleToolCalls(message).length === 0) {
|
|
12370
|
+
return /* @__PURE__ */ jsx("p", { className: "py-0.5 text-sm text-muted-foreground", children: label });
|
|
12371
|
+
}
|
|
12314
12372
|
const labelTone = summary ? "text-muted-foreground italic" : "text-muted-foreground";
|
|
12315
12373
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
12316
12374
|
/* @__PURE__ */ jsxs(
|
|
@@ -12404,6 +12462,7 @@ function LoopResultAffordance({ message }) {
|
|
|
12404
12462
|
}
|
|
12405
12463
|
function SimpleAssistantGroup({
|
|
12406
12464
|
messages,
|
|
12465
|
+
activeAssistantId,
|
|
12407
12466
|
isRunning,
|
|
12408
12467
|
sessionId,
|
|
12409
12468
|
artifactFallbacks,
|
|
@@ -12415,7 +12474,7 @@ function SimpleAssistantGroup({
|
|
|
12415
12474
|
const tail = assistantMessages[assistantMessages.length - 1];
|
|
12416
12475
|
const tailHasTools = !!(tail?.toolCalls && tail.toolCalls.length > 0);
|
|
12417
12476
|
const tailIsTextOnly = !!tail && !tailHasTools;
|
|
12418
|
-
const finalText = tailIsTextOnly && tail.content ? tail.content : "";
|
|
12477
|
+
const finalText = tailIsTextOnly && tail.content !== tail.reasoning ? tail.content : "";
|
|
12419
12478
|
const showErrorInfo = !!tail && tail.status === "error" && !!tail.errorInfo;
|
|
12420
12479
|
const turnComplete = !isRunning && tail?.status === "complete";
|
|
12421
12480
|
const summaryPref = finalText !== null ? stripAndParseNextAction(finalText).action?.summary ?? "hide" : "hide";
|
|
@@ -12452,7 +12511,7 @@ function SimpleAssistantGroup({
|
|
|
12452
12511
|
);
|
|
12453
12512
|
}
|
|
12454
12513
|
if (message === tail && tailIsTextOnly && finalText) return null;
|
|
12455
|
-
const rawContent = (message.content ?? "").trim();
|
|
12514
|
+
const rawContent = message.content === message.reasoning ? "" : (message.content ?? "").trim();
|
|
12456
12515
|
const { action, inferredNarration, cleaned } = stripAndParseNextAction(rawContent);
|
|
12457
12516
|
const narrationLine = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
12458
12517
|
const askBody = hasUserFacingAskContent(message) ? cleaned : null;
|
|
@@ -12462,6 +12521,7 @@ function SimpleAssistantGroup({
|
|
|
12462
12521
|
IterationGroup,
|
|
12463
12522
|
{
|
|
12464
12523
|
message,
|
|
12524
|
+
isActive: message.id === activeAssistantId,
|
|
12465
12525
|
sessionId,
|
|
12466
12526
|
artifactFallbacks,
|
|
12467
12527
|
onFileSelect
|
|
@@ -12494,6 +12554,7 @@ function SimpleAssistantGroup({
|
|
|
12494
12554
|
}
|
|
12495
12555
|
function AssistantGroup({
|
|
12496
12556
|
messages,
|
|
12557
|
+
activeAssistantId,
|
|
12497
12558
|
lastGlobalIndex,
|
|
12498
12559
|
totalMessages,
|
|
12499
12560
|
isRunning,
|
|
@@ -12509,6 +12570,7 @@ function AssistantGroup({
|
|
|
12509
12570
|
SimpleAssistantGroup,
|
|
12510
12571
|
{
|
|
12511
12572
|
messages,
|
|
12573
|
+
activeAssistantId,
|
|
12512
12574
|
isRunning,
|
|
12513
12575
|
sessionId,
|
|
12514
12576
|
artifactFallbacks,
|
|
@@ -12640,6 +12702,15 @@ function ChatThread({
|
|
|
12640
12702
|
onOpenIntegrations
|
|
12641
12703
|
}) {
|
|
12642
12704
|
const groups = useMemo(() => groupMessages(messages), [messages]);
|
|
12705
|
+
const activeAssistantId = useMemo(() => {
|
|
12706
|
+
if (!isRunning) return void 0;
|
|
12707
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
12708
|
+
const message = messages[i];
|
|
12709
|
+
if (message.role === "user") return void 0;
|
|
12710
|
+
if (message.role === "assistant") return message.id;
|
|
12711
|
+
}
|
|
12712
|
+
return void 0;
|
|
12713
|
+
}, [messages, isRunning]);
|
|
12643
12714
|
const pendingAsk = useMemo(() => pendingAskCall(messages), [messages]);
|
|
12644
12715
|
const askPolicy = useMemo(
|
|
12645
12716
|
() => askComposerPolicy(pendingAsk),
|
|
@@ -12647,13 +12718,26 @@ function ChatThread({
|
|
|
12647
12718
|
);
|
|
12648
12719
|
const awaitingInput = askPolicy !== null;
|
|
12649
12720
|
const orbActivity = useMemo(
|
|
12650
|
-
() =>
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12721
|
+
() => {
|
|
12722
|
+
const activity = deriveOrbActivity(
|
|
12723
|
+
messages,
|
|
12724
|
+
viewMode === "simple" ? SIMPLE_MODE_ORB_OPTIONS : void 0
|
|
12725
|
+
);
|
|
12726
|
+
if (viewMode === "simple" && activity.state === "solving") {
|
|
12727
|
+
const latest = [...messages].reverse().find((message) => message.role === "assistant");
|
|
12728
|
+
if (latest && !latest.toolCalls?.some((tc) => tc.status === "running")) {
|
|
12729
|
+
return { ...activity, label: reasoningTokenLabel(latest, true) };
|
|
12730
|
+
}
|
|
12731
|
+
}
|
|
12732
|
+
return activity;
|
|
12733
|
+
},
|
|
12654
12734
|
[messages, viewMode]
|
|
12655
12735
|
);
|
|
12656
|
-
const
|
|
12736
|
+
const inlineRunningIndicator = useMemo(
|
|
12737
|
+
() => hasInlineRunningIndicator(messages, viewMode),
|
|
12738
|
+
[messages, viewMode]
|
|
12739
|
+
);
|
|
12740
|
+
const showWorkingOnIt = useDelayedRunningIndicator(isRunning) && !awaitingInput && !inlineRunningIndicator;
|
|
12657
12741
|
const composerLocked = askPolicy?.locked ?? false;
|
|
12658
12742
|
const composerDisabled = disabled || composerLocked;
|
|
12659
12743
|
const composerDisabledReason = composerLocked ? askPolicy?.reason : disabledReason;
|
|
@@ -12839,6 +12923,7 @@ function ChatThread({
|
|
|
12839
12923
|
AssistantGroup,
|
|
12840
12924
|
{
|
|
12841
12925
|
messages: group.messages,
|
|
12926
|
+
activeAssistantId,
|
|
12842
12927
|
lastGlobalIndex: group.lastGlobalIndex,
|
|
12843
12928
|
totalMessages: messages.length,
|
|
12844
12929
|
isRunning,
|
|
@@ -13081,8 +13166,17 @@ function applyAgentChatEvent(state, event) {
|
|
|
13081
13166
|
return collectResearchSource(withResult, toolName, event.data);
|
|
13082
13167
|
}
|
|
13083
13168
|
case "harness.wake":
|
|
13084
|
-
case "llm.request":
|
|
13085
13169
|
return { ...nextState, terminal: false, isRunning: true };
|
|
13170
|
+
case "llm.request":
|
|
13171
|
+
return {
|
|
13172
|
+
...nextState,
|
|
13173
|
+
terminal: false,
|
|
13174
|
+
isRunning: true,
|
|
13175
|
+
hadDeltas: false,
|
|
13176
|
+
messages: nextState.messages.map(
|
|
13177
|
+
(message) => message.role === "assistant" && message.status === "streaming" && !message.toolCalls?.some((tc) => tc.status === "running") ? { ...message, status: "complete" } : message
|
|
13178
|
+
)
|
|
13179
|
+
};
|
|
13086
13180
|
case "harness.crash":
|
|
13087
13181
|
case "stream.timeout":
|
|
13088
13182
|
return nextState;
|
|
@@ -13299,22 +13393,31 @@ function browserMarker(event) {
|
|
|
13299
13393
|
function applyLlmDelta(state, event) {
|
|
13300
13394
|
const deltaContent = stringValue2(event.data.content);
|
|
13301
13395
|
const deltaReasoning = stringValue2(event.data.reasoning);
|
|
13396
|
+
const reasoningTokens = typeof event.data.reasoning_tokens === "number" && Number.isInteger(event.data.reasoning_tokens) && event.data.reasoning_tokens >= 0 ? event.data.reasoning_tokens : void 0;
|
|
13302
13397
|
const { turnId, iterationIndex } = readTurnMeta(event.data);
|
|
13303
13398
|
const messages = [...state.messages];
|
|
13304
13399
|
const lastIdx = findLastAssistantIndex(messages);
|
|
13305
13400
|
const lastMsg = lastIdx >= 0 ? messages[lastIdx] : null;
|
|
13306
13401
|
const hasUserAfter = lastIdx >= 0 && hasUserAfterIndex(messages, lastIdx);
|
|
13402
|
+
const matchesIteration = (turnId === void 0 || lastMsg?.turnId === turnId) && (iterationIndex === void 0 || lastMsg?.iterationIndex === iterationIndex);
|
|
13403
|
+
const sameIteration = turnId !== void 0 && iterationIndex !== void 0 && matchesIteration;
|
|
13404
|
+
if (reasoningTokens !== void 0 && !deltaContent && !deltaReasoning && lastMsg && !hasUserAfter && matchesIteration) {
|
|
13405
|
+
messages[lastIdx] = { ...lastMsg, reasoningTokens };
|
|
13406
|
+
return { ...state, messages };
|
|
13407
|
+
}
|
|
13307
13408
|
const allToolsDone = Boolean(
|
|
13308
13409
|
lastMsg?.toolCalls?.length && lastMsg.toolCalls.every((tc) => tc.status !== "running")
|
|
13309
13410
|
);
|
|
13310
13411
|
const canAppend = Boolean(
|
|
13311
|
-
lastMsg && lastMsg.status === "streaming" && !allToolsDone && !hasUserAfter
|
|
13412
|
+
lastMsg && lastMsg.status === "streaming" && (!allToolsDone || sameIteration) && !hasUserAfter && matchesIteration
|
|
13312
13413
|
);
|
|
13313
13414
|
if (canAppend && lastMsg) {
|
|
13314
13415
|
messages[lastIdx] = {
|
|
13315
13416
|
...lastMsg,
|
|
13316
13417
|
content: deltaContent ? lastMsg.content + deltaContent : lastMsg.content,
|
|
13317
13418
|
reasoning: deltaReasoning ? (lastMsg.reasoning ?? "") + deltaReasoning : lastMsg.reasoning,
|
|
13419
|
+
reasoningTokens: reasoningTokens ?? lastMsg.reasoningTokens,
|
|
13420
|
+
reasoningDeltaCount: deltaReasoning ? (lastMsg.reasoningDeltaCount ?? 0) + 1 : lastMsg.reasoningDeltaCount,
|
|
13318
13421
|
turnId: turnId ?? lastMsg.turnId,
|
|
13319
13422
|
iterationIndex: iterationIndex ?? lastMsg.iterationIndex
|
|
13320
13423
|
};
|
|
@@ -13324,6 +13427,8 @@ function applyLlmDelta(state, event) {
|
|
|
13324
13427
|
role: "assistant",
|
|
13325
13428
|
content: deltaContent,
|
|
13326
13429
|
reasoning: deltaReasoning || void 0,
|
|
13430
|
+
reasoningTokens,
|
|
13431
|
+
reasoningDeltaCount: deltaReasoning ? 1 : void 0,
|
|
13327
13432
|
createdAt: /* @__PURE__ */ new Date(),
|
|
13328
13433
|
status: "streaming",
|
|
13329
13434
|
turnId,
|
|
@@ -13399,6 +13504,11 @@ function applyLlmResponse(state, event) {
|
|
|
13399
13504
|
}
|
|
13400
13505
|
const inputTokens = numberValue(event.data.input_tokens);
|
|
13401
13506
|
const outputTokens = numberValue(event.data.output_tokens);
|
|
13507
|
+
const reasoningTokens = numberValue(event.data.reasoning_tokens);
|
|
13508
|
+
if (reasoningTokens > 0) {
|
|
13509
|
+
const responseIdx = findLastAssistantIndex(messages);
|
|
13510
|
+
messages[responseIdx] = { ...messages[responseIdx], reasoningTokens };
|
|
13511
|
+
}
|
|
13402
13512
|
return {
|
|
13403
13513
|
...state,
|
|
13404
13514
|
messages,
|
|
@@ -13407,7 +13517,7 @@ function applyLlmResponse(state, event) {
|
|
|
13407
13517
|
tokenUsage: {
|
|
13408
13518
|
inputTokens,
|
|
13409
13519
|
outputTokens,
|
|
13410
|
-
reasoningTokens
|
|
13520
|
+
reasoningTokens,
|
|
13411
13521
|
cachedInputTokens: numberValue(event.data.cache_read_tokens),
|
|
13412
13522
|
totalTokens: inputTokens + outputTokens,
|
|
13413
13523
|
contextWindow: numberValue(event.data.context_window),
|
|
@@ -13426,6 +13536,8 @@ ${addition}`;
|
|
|
13426
13536
|
}
|
|
13427
13537
|
function applyLlmThinking(state, event) {
|
|
13428
13538
|
const reasoningText = stringValue2(event.data.reasoning) || stringValue2(event.data.content);
|
|
13539
|
+
const reasoningTokens = optionalNumberValue(event.data.reasoning_tokens);
|
|
13540
|
+
const reasoningDeltaCount = optionalNumberValue(event.data.reasoning_delta_count);
|
|
13429
13541
|
const { turnId, iterationIndex } = readTurnMeta(event.data);
|
|
13430
13542
|
const messages = [...state.messages];
|
|
13431
13543
|
const idx = findLastAssistantIndex(messages);
|
|
@@ -13434,12 +13546,16 @@ function applyLlmThinking(state, event) {
|
|
|
13434
13546
|
prev?.toolCalls?.length && prev.toolCalls.every((tc) => tc.status !== "running")
|
|
13435
13547
|
);
|
|
13436
13548
|
const hasUserAfter = idx >= 0 && hasUserAfterIndex(messages, idx);
|
|
13437
|
-
|
|
13549
|
+
const sameIteration = turnId !== void 0 && iterationIndex !== void 0 && (prev?.turnId === turnId && prev.iterationIndex === iterationIndex || prev?.turnId === void 0 && prev?.iterationIndex === void 0 && prev?.llmResponseEventId === void 0);
|
|
13550
|
+
const differentIteration = !!prev && (turnId !== void 0 && prev.turnId !== void 0 && turnId !== prev.turnId || iterationIndex !== void 0 && prev.iterationIndex !== void 0 && iterationIndex !== prev.iterationIndex);
|
|
13551
|
+
if (!prev || allToolsDone && !sameIteration || hasUserAfter || differentIteration) {
|
|
13438
13552
|
messages.push({
|
|
13439
13553
|
id: `evt-${event.eventId}`,
|
|
13440
13554
|
role: "assistant",
|
|
13441
13555
|
content: "",
|
|
13442
13556
|
reasoning: reasoningText,
|
|
13557
|
+
reasoningTokens: reasoningTokens ?? void 0,
|
|
13558
|
+
reasoningDeltaCount: reasoningDeltaCount ?? void 0,
|
|
13443
13559
|
createdAt: /* @__PURE__ */ new Date(),
|
|
13444
13560
|
status: "streaming",
|
|
13445
13561
|
turnId,
|
|
@@ -13449,6 +13565,8 @@ function applyLlmThinking(state, event) {
|
|
|
13449
13565
|
messages[idx] = {
|
|
13450
13566
|
...prev,
|
|
13451
13567
|
reasoning: appendText(prev.reasoning, reasoningText),
|
|
13568
|
+
reasoningTokens: reasoningTokens ?? prev.reasoningTokens,
|
|
13569
|
+
reasoningDeltaCount: reasoningDeltaCount ?? prev.reasoningDeltaCount,
|
|
13452
13570
|
turnId: turnId ?? prev.turnId,
|
|
13453
13571
|
iterationIndex: iterationIndex ?? prev.iterationIndex
|
|
13454
13572
|
};
|