@invergent/agent-chat-react 2.5.0 → 2.5.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 +412 -244
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +407 -244
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2428,6 +2428,37 @@ function MCPToolBlock({ tc }) {
|
|
|
2428
2428
|
summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/60 truncate text-xs", children: summary })
|
|
2429
2429
|
] });
|
|
2430
2430
|
}
|
|
2431
|
+
function ResearchMemoryBlock({ tc }) {
|
|
2432
|
+
const args = parseArgs(tc.args) ?? {};
|
|
2433
|
+
const result = tc.result ? parseArgs(tc.result) ?? {} : {};
|
|
2434
|
+
let detail = "";
|
|
2435
|
+
if (args.action === "add") {
|
|
2436
|
+
const host = args.url ? hostname(args.url) : "";
|
|
2437
|
+
const sid = result.source_id ?? "";
|
|
2438
|
+
detail = sid ? `recorded ${sid}${host ? ` \xB7 ${host}` : ""}` : host ? `recorded \xB7 ${host}` : "recorded";
|
|
2439
|
+
} else if (args.action === "retrieve") {
|
|
2440
|
+
const n = result.sources?.length ?? 0;
|
|
2441
|
+
detail = args.query ? `${n} source${n === 1 ? "" : "s"} for "${truncate2(args.query, 40)}"` : `${n} source${n === 1 ? "" : "s"}`;
|
|
2442
|
+
} else if (args.action === "list") {
|
|
2443
|
+
const n = result.sources?.length ?? 0;
|
|
2444
|
+
detail = `${n} source${n === 1 ? "" : "s"}`;
|
|
2445
|
+
}
|
|
2446
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm py-0.5", children: [
|
|
2447
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookOpenIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2448
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Research" }),
|
|
2449
|
+
detail && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70 truncate text-xs", children: detail })
|
|
2450
|
+
] });
|
|
2451
|
+
}
|
|
2452
|
+
function hostname(url) {
|
|
2453
|
+
try {
|
|
2454
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
2455
|
+
} catch {
|
|
2456
|
+
return url;
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
function truncate2(s, n) {
|
|
2460
|
+
return s.length > n ? `${s.slice(0, n)}\u2026` : s;
|
|
2461
|
+
}
|
|
2431
2462
|
function VisionAnalyzeBlock({ tc }) {
|
|
2432
2463
|
let image = "";
|
|
2433
2464
|
try {
|
|
@@ -4143,21 +4174,15 @@ function ArtifactToolBlock({
|
|
|
4143
4174
|
name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: name })
|
|
4144
4175
|
] });
|
|
4145
4176
|
}
|
|
4146
|
-
|
|
4147
|
-
// src/components/chat/tools/delegate-tool.tsx
|
|
4148
4177
|
init_utils();
|
|
4149
4178
|
function firstLine(s) {
|
|
4150
4179
|
const idx = s.indexOf("\n");
|
|
4151
4180
|
return idx === -1 ? s : s.slice(0, idx);
|
|
4152
4181
|
}
|
|
4153
4182
|
function DelegateToolBlock({ tc }) {
|
|
4154
|
-
const [expanded, setExpanded] = react.useState(false);
|
|
4155
4183
|
const args = parseArgs(tc.args);
|
|
4156
|
-
const goal = args?.goal ?? "";
|
|
4157
|
-
const context = args?.context ?? "";
|
|
4184
|
+
const goal = firstLine(args?.goal ?? "").trim();
|
|
4158
4185
|
const agentType = args?.agent_type;
|
|
4159
|
-
const model = args?.model;
|
|
4160
|
-
const summary = firstLine(goal).trim();
|
|
4161
4186
|
let resultError = null;
|
|
4162
4187
|
if (tc.result) {
|
|
4163
4188
|
try {
|
|
@@ -4166,84 +4191,29 @@ function DelegateToolBlock({ tc }) {
|
|
|
4166
4191
|
} catch {
|
|
4167
4192
|
}
|
|
4168
4193
|
}
|
|
4169
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4170
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4171
|
-
|
|
4194
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm py-0.5", children: [
|
|
4195
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranchIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
4196
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Delegate" }),
|
|
4197
|
+
agentType && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 text-xs", children: [
|
|
4198
|
+
"\xB7 ",
|
|
4199
|
+
agentType
|
|
4200
|
+
] }),
|
|
4201
|
+
goal && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 truncate text-xs italic", children: [
|
|
4202
|
+
"\xB7 \u201C",
|
|
4203
|
+
goal,
|
|
4204
|
+
"\u201D"
|
|
4205
|
+
] }),
|
|
4206
|
+
resultError && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4207
|
+
"span",
|
|
4172
4208
|
{
|
|
4173
|
-
type: "button",
|
|
4174
|
-
onClick: () => setExpanded(!expanded),
|
|
4175
4209
|
className: cn(
|
|
4176
|
-
"
|
|
4177
|
-
"text-
|
|
4210
|
+
"shrink-0 text-xs",
|
|
4211
|
+
"text-destructive"
|
|
4178
4212
|
),
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
lucideReact.ChevronRightIcon,
|
|
4182
|
-
{
|
|
4183
|
-
className: cn(
|
|
4184
|
-
"size-3 shrink-0 transition-transform duration-150",
|
|
4185
|
-
expanded && "rotate-90"
|
|
4186
|
-
)
|
|
4187
|
-
}
|
|
4188
|
-
),
|
|
4189
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranchIcon, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
4190
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground/80", children: "delegate_task" }),
|
|
4191
|
-
agentType && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
4192
|
-
"\xB7 ",
|
|
4193
|
-
agentType
|
|
4194
|
-
] }),
|
|
4195
|
-
summary && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground truncate min-w-0", children: [
|
|
4196
|
-
"\xB7 ",
|
|
4197
|
-
summary
|
|
4198
|
-
] })
|
|
4199
|
-
]
|
|
4213
|
+
title: resultError,
|
|
4214
|
+
children: "\xB7 failed"
|
|
4200
4215
|
}
|
|
4201
|
-
)
|
|
4202
|
-
expanded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-6 mt-0.5 space-y-1.5 text-sm font-mono", children: [
|
|
4203
|
-
(agentType || model) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-x-3 gap-y-0.5 text-xs text-muted-foreground", children: [
|
|
4204
|
-
agentType && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4205
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70", children: "agent:" }),
|
|
4206
|
-
" ",
|
|
4207
|
-
agentType
|
|
4208
|
-
] }),
|
|
4209
|
-
model && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4210
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70", children: "model:" }),
|
|
4211
|
-
" ",
|
|
4212
|
-
model
|
|
4213
|
-
] })
|
|
4214
|
-
] }),
|
|
4215
|
-
goal && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded bg-muted/40 px-2 py-1", children: [
|
|
4216
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground/70", children: "Goal" }),
|
|
4217
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-0.5 whitespace-pre-wrap break-words text-foreground/90", children: goal })
|
|
4218
|
-
] }),
|
|
4219
|
-
context && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded bg-muted/40 px-2 py-1", children: [
|
|
4220
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground/70", children: "Context" }),
|
|
4221
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-0.5 whitespace-pre-wrap break-words text-muted-foreground", children: truncate(context, 2e3) })
|
|
4222
|
-
] }),
|
|
4223
|
-
tc.status === "running" && !tc.result && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground italic", children: "Sub-agent running\u2026" }),
|
|
4224
|
-
tc.result && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4225
|
-
"div",
|
|
4226
|
-
{
|
|
4227
|
-
className: cn(
|
|
4228
|
-
"rounded px-2 py-1 max-h-64 overflow-y-auto",
|
|
4229
|
-
resultError ? "bg-destructive/10" : "bg-muted/40"
|
|
4230
|
-
),
|
|
4231
|
-
children: [
|
|
4232
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4233
|
-
"div",
|
|
4234
|
-
{
|
|
4235
|
-
className: cn(
|
|
4236
|
-
"text-[10px] uppercase tracking-wide",
|
|
4237
|
-
resultError ? "text-destructive/80" : "text-emerald-600 dark:text-emerald-400"
|
|
4238
|
-
),
|
|
4239
|
-
children: resultError ? "Error" : "Sub-agent response"
|
|
4240
|
-
}
|
|
4241
|
-
),
|
|
4242
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-0.5 whitespace-pre-wrap break-words text-foreground/90", children: truncate(resultError ?? tc.result, 4e3) })
|
|
4243
|
-
]
|
|
4244
|
-
}
|
|
4245
|
-
)
|
|
4246
|
-
] })
|
|
4216
|
+
)
|
|
4247
4217
|
] });
|
|
4248
4218
|
}
|
|
4249
4219
|
init_utils();
|
|
@@ -4486,38 +4456,6 @@ function ResearchOutlineBlock({ tc }) {
|
|
|
4486
4456
|
outline ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap font-mono text-[11px] leading-snug", children: outline }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "updated" })
|
|
4487
4457
|
] });
|
|
4488
4458
|
}
|
|
4489
|
-
function ResearchMemoryBlock({ tc }) {
|
|
4490
|
-
const args = parseArgs(tc.args) ?? {};
|
|
4491
|
-
const result = tc.result ? parseArgs(tc.result) ?? {} : {};
|
|
4492
|
-
let label;
|
|
4493
|
-
if (args.action === "add") {
|
|
4494
|
-
const host = args.url ? hostname(args.url) : "";
|
|
4495
|
-
label = `Recorded source ${result.source_id ?? ""}${host ? ` \xB7 ${host}` : ""}`;
|
|
4496
|
-
} else if (args.action === "retrieve") {
|
|
4497
|
-
const n = result.sources?.length ?? 0;
|
|
4498
|
-
label = `Retrieved ${n} source${n === 1 ? "" : "s"}${args.query ? ` for "${truncate2(args.query)}"` : ""}`;
|
|
4499
|
-
} else if (args.action === "list") {
|
|
4500
|
-
const n = result.sources?.length ?? 0;
|
|
4501
|
-
label = `Listed ${n} source${n === 1 ? "" : "s"}`;
|
|
4502
|
-
} else {
|
|
4503
|
-
label = "research_memory";
|
|
4504
|
-
}
|
|
4505
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
4506
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "research" }),
|
|
4507
|
-
" ",
|
|
4508
|
-
label
|
|
4509
|
-
] });
|
|
4510
|
-
}
|
|
4511
|
-
function hostname(url) {
|
|
4512
|
-
try {
|
|
4513
|
-
return new URL(url).hostname.replace(/^www\./, "");
|
|
4514
|
-
} catch {
|
|
4515
|
-
return url;
|
|
4516
|
-
}
|
|
4517
|
-
}
|
|
4518
|
-
function truncate2(s, n = 40) {
|
|
4519
|
-
return s.length > n ? `${s.slice(0, n)}\u2026` : s;
|
|
4520
|
-
}
|
|
4521
4459
|
function ToolCallBlock({
|
|
4522
4460
|
tc,
|
|
4523
4461
|
resolvedArtifactName,
|
|
@@ -4627,12 +4565,14 @@ function WebSearchGroupBlock({ tcs }) {
|
|
|
4627
4565
|
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1 ml-5 space-y-0.5", children: tcs.map((tc) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(WebSearchRow, { tc }) }, tc.id)) })
|
|
4628
4566
|
] });
|
|
4629
4567
|
}
|
|
4568
|
+
init_utils();
|
|
4569
|
+
var COLLAPSED_MAX_HEIGHT_PX = 160;
|
|
4630
4570
|
var ChatMessage = react.memo(function ChatMessage2({
|
|
4631
4571
|
message,
|
|
4632
4572
|
onFileSelect
|
|
4633
4573
|
}) {
|
|
4634
4574
|
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "user", children: /* @__PURE__ */ jsxRuntime.jsxs(MessageContent, { children: [
|
|
4635
|
-
message.content,
|
|
4575
|
+
/* @__PURE__ */ jsxRuntime.jsx(CollapsibleMessageBody, { content: message.content }),
|
|
4636
4576
|
message.images && message.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 mt-2", children: message.images.map((img, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4637
4577
|
"img",
|
|
4638
4578
|
{
|
|
@@ -4652,6 +4592,48 @@ var ChatMessage = react.memo(function ChatMessage2({
|
|
|
4652
4592
|
)) })
|
|
4653
4593
|
] }) });
|
|
4654
4594
|
});
|
|
4595
|
+
function CollapsibleMessageBody({ content }) {
|
|
4596
|
+
const ref = react.useRef(null);
|
|
4597
|
+
const [overflowing, setOverflowing] = react.useState(false);
|
|
4598
|
+
const [expanded, setExpanded] = react.useState(false);
|
|
4599
|
+
react.useLayoutEffect(() => {
|
|
4600
|
+
const el = ref.current;
|
|
4601
|
+
if (!el) return;
|
|
4602
|
+
const measure = () => {
|
|
4603
|
+
setOverflowing(el.scrollHeight > el.clientHeight + 1);
|
|
4604
|
+
};
|
|
4605
|
+
measure();
|
|
4606
|
+
const observer = new ResizeObserver(measure);
|
|
4607
|
+
observer.observe(el);
|
|
4608
|
+
return () => observer.disconnect();
|
|
4609
|
+
}, [content]);
|
|
4610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4611
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4612
|
+
"div",
|
|
4613
|
+
{
|
|
4614
|
+
ref,
|
|
4615
|
+
className: cn(
|
|
4616
|
+
"whitespace-pre-wrap wrap-break-word",
|
|
4617
|
+
!expanded && "overflow-hidden"
|
|
4618
|
+
),
|
|
4619
|
+
style: !expanded ? { maxHeight: COLLAPSED_MAX_HEIGHT_PX } : void 0,
|
|
4620
|
+
children: content
|
|
4621
|
+
}
|
|
4622
|
+
),
|
|
4623
|
+
(overflowing || expanded) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4624
|
+
"button",
|
|
4625
|
+
{
|
|
4626
|
+
type: "button",
|
|
4627
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
4628
|
+
className: cn(
|
|
4629
|
+
"mt-2 text-xs font-bold text-primary",
|
|
4630
|
+
"hover:underline focus:outline-none focus-visible:underline"
|
|
4631
|
+
),
|
|
4632
|
+
children: expanded ? "Show less..." : "Show more..."
|
|
4633
|
+
}
|
|
4634
|
+
)
|
|
4635
|
+
] });
|
|
4636
|
+
}
|
|
4655
4637
|
function iconForMime(mime) {
|
|
4656
4638
|
if (!mime) return lucideReact.File;
|
|
4657
4639
|
if (mime.startsWith("image/")) return lucideReact.FileImage;
|
|
@@ -6141,10 +6123,10 @@ function ChatComposerInner({
|
|
|
6141
6123
|
}
|
|
6142
6124
|
}, [buttonMenuOpen, menuDismissed, textInput.value]);
|
|
6143
6125
|
react.useEffect(() => {
|
|
6144
|
-
if (textInput.value.startsWith("/")) {
|
|
6126
|
+
if (!buttonMenuOpen && textInput.value.startsWith("/")) {
|
|
6145
6127
|
setMenuMode("all");
|
|
6146
6128
|
}
|
|
6147
|
-
}, [textInput.value]);
|
|
6129
|
+
}, [buttonMenuOpen, textInput.value]);
|
|
6148
6130
|
react.useEffect(() => {
|
|
6149
6131
|
if (showSlashMenu && (menuMode === "skills" || menuMode === "all")) {
|
|
6150
6132
|
adapter.listSlashCommands?.().then(setAdapterCommands).catch(() => {
|
|
@@ -6316,7 +6298,7 @@ function ChatComposerInner({
|
|
|
6316
6298
|
},
|
|
6317
6299
|
children: [
|
|
6318
6300
|
/* @__PURE__ */ jsxRuntime.jsx(AttachmentPreviewStrip, {}),
|
|
6319
|
-
viewMode === "expert" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2 px-1 pb-2", children: [
|
|
6301
|
+
viewMode === "expert" && !disabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2 px-1 pb-2", children: [
|
|
6320
6302
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6321
6303
|
Button,
|
|
6322
6304
|
{
|
|
@@ -6391,7 +6373,7 @@ function ChatComposerInner({
|
|
|
6391
6373
|
) }),
|
|
6392
6374
|
/* @__PURE__ */ jsxRuntime.jsxs(PromptInputFooter, { children: [
|
|
6393
6375
|
/* @__PURE__ */ jsxRuntime.jsxs(PromptInputTools, { children: [
|
|
6394
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: addMenuOpen, onOpenChange: setAddMenuOpen, children: [
|
|
6376
|
+
!disabled && /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: addMenuOpen, onOpenChange: setAddMenuOpen, children: [
|
|
6395
6377
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputButton, { "aria-label": "Add", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-4" }) }) }),
|
|
6396
6378
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6397
6379
|
PopoverContent,
|
|
@@ -6463,7 +6445,7 @@ function ChatComposerInner({
|
|
|
6463
6445
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderIcon, { className: "size-4" })
|
|
6464
6446
|
}
|
|
6465
6447
|
),
|
|
6466
|
-
tokenUsage && tokenUsage.contextWindow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6448
|
+
!disabled && tokenUsage && tokenUsage.contextWindow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6467
6449
|
Context,
|
|
6468
6450
|
{
|
|
6469
6451
|
usedTokens: tokenUsage.totalTokens,
|
|
@@ -6551,7 +6533,7 @@ function ChatComposerInner({
|
|
|
6551
6533
|
]
|
|
6552
6534
|
}
|
|
6553
6535
|
),
|
|
6554
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6536
|
+
!disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6555
6537
|
PromptInputSubmit,
|
|
6556
6538
|
{
|
|
6557
6539
|
status,
|
|
@@ -6689,6 +6671,83 @@ function ChatComposerInner({
|
|
|
6689
6671
|
);
|
|
6690
6672
|
}
|
|
6691
6673
|
|
|
6674
|
+
// src/components/research/research-sources-panel.tsx
|
|
6675
|
+
init_utils();
|
|
6676
|
+
function ResearchSourcesPanel({
|
|
6677
|
+
sources
|
|
6678
|
+
}) {
|
|
6679
|
+
const [expanded, setExpanded] = react.useState(false);
|
|
6680
|
+
const rootRef = react.useRef(null);
|
|
6681
|
+
react.useEffect(() => {
|
|
6682
|
+
const root = rootRef.current;
|
|
6683
|
+
if (!root) return;
|
|
6684
|
+
const handler = (event) => {
|
|
6685
|
+
const target = event.target;
|
|
6686
|
+
if (target?.closest('[id^="source-"]')) {
|
|
6687
|
+
setExpanded(true);
|
|
6688
|
+
}
|
|
6689
|
+
};
|
|
6690
|
+
document.addEventListener("scroll-to-source", handler, true);
|
|
6691
|
+
return () => document.removeEventListener("scroll-to-source", handler, true);
|
|
6692
|
+
}, []);
|
|
6693
|
+
if (sources.length === 0) return null;
|
|
6694
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6695
|
+
"div",
|
|
6696
|
+
{
|
|
6697
|
+
ref: rootRef,
|
|
6698
|
+
className: "rounded-md border border-line bg-card",
|
|
6699
|
+
children: [
|
|
6700
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6701
|
+
"button",
|
|
6702
|
+
{
|
|
6703
|
+
type: "button",
|
|
6704
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
6705
|
+
"aria-expanded": expanded,
|
|
6706
|
+
className: "flex w-full items-center gap-1.5 px-2 py-1.5 text-left hover:bg-muted/40",
|
|
6707
|
+
children: [
|
|
6708
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6709
|
+
lucideReact.ChevronRightIcon,
|
|
6710
|
+
{
|
|
6711
|
+
className: cn(
|
|
6712
|
+
"size-3 shrink-0 text-muted-foreground transition-transform duration-150",
|
|
6713
|
+
expanded && "rotate-90"
|
|
6714
|
+
)
|
|
6715
|
+
}
|
|
6716
|
+
),
|
|
6717
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: [
|
|
6718
|
+
"Sources \xB7 ",
|
|
6719
|
+
sources.length
|
|
6720
|
+
] })
|
|
6721
|
+
]
|
|
6722
|
+
}
|
|
6723
|
+
),
|
|
6724
|
+
expanded && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "max-h-35 overflow-y-auto border-t border-line py-1", children: sources.map((s) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6725
|
+
"a",
|
|
6726
|
+
{
|
|
6727
|
+
id: `source-${s.sourceId}`,
|
|
6728
|
+
href: s.url,
|
|
6729
|
+
target: "_blank",
|
|
6730
|
+
rel: "noreferrer",
|
|
6731
|
+
className: "group flex items-baseline gap-2 px-2 py-1 hover:bg-muted/60",
|
|
6732
|
+
children: [
|
|
6733
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] font-semibold text-primary tabular-nums", children: s.sourceId }),
|
|
6734
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-foreground group-hover:underline", children: s.title || s.url }),
|
|
6735
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0 truncate text-[10px] text-muted-foreground max-w-[40%]", children: hostname2(s.url) })
|
|
6736
|
+
]
|
|
6737
|
+
}
|
|
6738
|
+
) }, s.sourceId)) })
|
|
6739
|
+
]
|
|
6740
|
+
}
|
|
6741
|
+
);
|
|
6742
|
+
}
|
|
6743
|
+
function hostname2(url) {
|
|
6744
|
+
try {
|
|
6745
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
6746
|
+
} catch {
|
|
6747
|
+
return url;
|
|
6748
|
+
}
|
|
6749
|
+
}
|
|
6750
|
+
|
|
6692
6751
|
// src/components/chat/turn-feedback.tsx
|
|
6693
6752
|
init_utils();
|
|
6694
6753
|
var MAX_REASON_LENGTH2 = 500;
|
|
@@ -7066,8 +7125,23 @@ var ArtifactContent = ({
|
|
|
7066
7125
|
className,
|
|
7067
7126
|
...props
|
|
7068
7127
|
}) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-1 overflow-auto p-4", className), ...props });
|
|
7069
|
-
|
|
7070
|
-
|
|
7128
|
+
|
|
7129
|
+
// src/components/chat/artifacts/artifact-markdown.tsx
|
|
7130
|
+
init_utils();
|
|
7131
|
+
function ArtifactMarkdown({
|
|
7132
|
+
spec,
|
|
7133
|
+
fill = false
|
|
7134
|
+
}) {
|
|
7135
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7136
|
+
"div",
|
|
7137
|
+
{
|
|
7138
|
+
className: cn(
|
|
7139
|
+
"px-4 py-3",
|
|
7140
|
+
!fill && "max-h-112 overflow-y-auto"
|
|
7141
|
+
),
|
|
7142
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children: spec.content ?? "" })
|
|
7143
|
+
}
|
|
7144
|
+
);
|
|
7071
7145
|
}
|
|
7072
7146
|
function formatCell(value) {
|
|
7073
7147
|
if (value == null) return "";
|
|
@@ -7440,7 +7514,7 @@ function ArtifactBody({
|
|
|
7440
7514
|
}
|
|
7441
7515
|
switch (payload.kind) {
|
|
7442
7516
|
case "markdown":
|
|
7443
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ArtifactMarkdown, { spec: payload.spec });
|
|
7517
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ArtifactMarkdown, { spec: payload.spec, fill });
|
|
7444
7518
|
case "table":
|
|
7445
7519
|
return /* @__PURE__ */ jsxRuntime.jsx(ArtifactTable, { spec: payload.spec });
|
|
7446
7520
|
case "chart":
|
|
@@ -8341,17 +8415,15 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
8341
8415
|
}];
|
|
8342
8416
|
}
|
|
8343
8417
|
if (msg.systemKind === "artifact") {
|
|
8344
|
-
const { artifactId, name, kind, version } = unpackArtifactMeta(
|
|
8345
|
-
msg.systemMeta,
|
|
8346
|
-
msg.content
|
|
8347
|
-
);
|
|
8418
|
+
const { artifactId, name, kind, version, originatingSessionId } = unpackArtifactMeta(msg.systemMeta, msg.content);
|
|
8348
8419
|
return [{
|
|
8349
8420
|
kind: "artifact",
|
|
8350
8421
|
key: msg.id,
|
|
8351
8422
|
artifactId,
|
|
8352
8423
|
name,
|
|
8353
8424
|
artifactKind: kind,
|
|
8354
|
-
version
|
|
8425
|
+
version,
|
|
8426
|
+
originatingSessionId
|
|
8355
8427
|
}];
|
|
8356
8428
|
}
|
|
8357
8429
|
if (msg.systemKind === "browser_marker" || msg.systemKind === "browser_marker_warning") {
|
|
@@ -8523,7 +8595,8 @@ function unpackArtifactMeta(systemMeta, fallbackName) {
|
|
|
8523
8595
|
artifactId: meta.artifact_id ?? "",
|
|
8524
8596
|
name: meta.name ?? fallbackName,
|
|
8525
8597
|
kind: meta.kind ?? "markdown",
|
|
8526
|
-
version: meta.version ?? 1
|
|
8598
|
+
version: meta.version ?? 1,
|
|
8599
|
+
originatingSessionId: meta.originating_session_id ?? null
|
|
8527
8600
|
};
|
|
8528
8601
|
}
|
|
8529
8602
|
function OrphanSystemMarker({
|
|
@@ -8549,7 +8622,7 @@ function OrphanSystemMarker({
|
|
|
8549
8622
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8550
8623
|
ArtifactBlock,
|
|
8551
8624
|
{
|
|
8552
|
-
sessionId,
|
|
8625
|
+
sessionId: unpacked.originatingSessionId ?? sessionId,
|
|
8553
8626
|
artifactId: unpacked.artifactId,
|
|
8554
8627
|
name: unpacked.name,
|
|
8555
8628
|
kind: unpacked.kind,
|
|
@@ -8582,25 +8655,32 @@ function OrphanSystemMarker({
|
|
|
8582
8655
|
function cancelledToolLabel(toolName) {
|
|
8583
8656
|
const map = {
|
|
8584
8657
|
terminal: "Command",
|
|
8585
|
-
execute_code: "Execute
|
|
8658
|
+
execute_code: "Execute code",
|
|
8586
8659
|
read_file: "Read",
|
|
8587
8660
|
write_file: "Write",
|
|
8588
8661
|
patch: "Patch",
|
|
8589
|
-
search_files: "Search
|
|
8590
|
-
list_files: "List
|
|
8591
|
-
web_search: "Web
|
|
8592
|
-
web_extract: "Web
|
|
8593
|
-
web_crawl: "Web
|
|
8594
|
-
session_search: "Session
|
|
8662
|
+
search_files: "Search files",
|
|
8663
|
+
list_files: "List files",
|
|
8664
|
+
web_search: "Web search",
|
|
8665
|
+
web_extract: "Web fetch",
|
|
8666
|
+
web_crawl: "Web crawl",
|
|
8667
|
+
session_search: "Session search",
|
|
8595
8668
|
memory: "Memory",
|
|
8596
8669
|
todo: "Todo",
|
|
8597
8670
|
skills_list: "Skills",
|
|
8598
8671
|
skill_view: "Skill",
|
|
8599
8672
|
consult_expert: "Expert",
|
|
8600
|
-
delegate_task: "Delegate",
|
|
8673
|
+
delegate_task: "Delegate task",
|
|
8601
8674
|
ask_user_question: "Ask User Question",
|
|
8602
8675
|
process: "Process",
|
|
8603
|
-
create_artifact: "
|
|
8676
|
+
create_artifact: "Create artifact",
|
|
8677
|
+
// ``Research memory`` reads as a noun ("memory of research") and
|
|
8678
|
+
// makes the shimmer awkward ("Running Research memory…"). The
|
|
8679
|
+
// one-liner renderer shows just ``Research`` as the label, so
|
|
8680
|
+
// mirror that here so the live shimmer matches the row that
|
|
8681
|
+
// replaces it on completion.
|
|
8682
|
+
research_memory: "Research",
|
|
8683
|
+
research_outline: "Research"
|
|
8604
8684
|
};
|
|
8605
8685
|
return map[toolName] ?? toolName;
|
|
8606
8686
|
}
|
|
@@ -8729,7 +8809,7 @@ function TimelineEntryItem({
|
|
|
8729
8809
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: sessionId ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
8730
8810
|
ArtifactBlock,
|
|
8731
8811
|
{
|
|
8732
|
-
sessionId,
|
|
8812
|
+
sessionId: entry.originatingSessionId ?? sessionId,
|
|
8733
8813
|
artifactId: entry.artifactId,
|
|
8734
8814
|
name: entry.name,
|
|
8735
8815
|
kind: entry.artifactKind,
|
|
@@ -8870,8 +8950,15 @@ function extractToolDetail(tc) {
|
|
|
8870
8950
|
case "web_search":
|
|
8871
8951
|
case "web_crawl":
|
|
8872
8952
|
return stringArg("query");
|
|
8873
|
-
case "web_extract":
|
|
8874
|
-
|
|
8953
|
+
case "web_extract": {
|
|
8954
|
+
const url = stringArg("url");
|
|
8955
|
+
if (!url) return null;
|
|
8956
|
+
try {
|
|
8957
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
8958
|
+
} catch {
|
|
8959
|
+
return truncate3(url, 40);
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8875
8962
|
case "skill_view":
|
|
8876
8963
|
case "skill_manage":
|
|
8877
8964
|
return stringArg("name") ?? stringArg("skill");
|
|
@@ -8881,6 +8968,40 @@ function extractToolDetail(tc) {
|
|
|
8881
8968
|
return stringArg("name") ?? stringArg("task") ?? stringArg("title");
|
|
8882
8969
|
case "memory":
|
|
8883
8970
|
return stringArg("action") ?? stringArg("key");
|
|
8971
|
+
case "research_memory": {
|
|
8972
|
+
const action = stringArg("action");
|
|
8973
|
+
if (action === "add") {
|
|
8974
|
+
const title = stringArg("title");
|
|
8975
|
+
if (title) return truncate3(title, 60);
|
|
8976
|
+
const url = stringArg("url");
|
|
8977
|
+
if (url) {
|
|
8978
|
+
try {
|
|
8979
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
8980
|
+
} catch {
|
|
8981
|
+
return truncate3(url, 40);
|
|
8982
|
+
}
|
|
8983
|
+
}
|
|
8984
|
+
return null;
|
|
8985
|
+
}
|
|
8986
|
+
if (action === "retrieve") {
|
|
8987
|
+
return stringArg("query");
|
|
8988
|
+
}
|
|
8989
|
+
return action;
|
|
8990
|
+
}
|
|
8991
|
+
case "research_outline": {
|
|
8992
|
+
const action = stringArg("action");
|
|
8993
|
+
if (action === "set") {
|
|
8994
|
+
const outline = stringArg("outline");
|
|
8995
|
+
if (outline) {
|
|
8996
|
+
const sections = outline.split(/\r?\n/).filter((line) => /^#{2,6}\s+\S/.test(line)).length;
|
|
8997
|
+
if (sections > 0) {
|
|
8998
|
+
return `${sections} ${sections === 1 ? "section" : "sections"}`;
|
|
8999
|
+
}
|
|
9000
|
+
}
|
|
9001
|
+
return "outline";
|
|
9002
|
+
}
|
|
9003
|
+
return action;
|
|
9004
|
+
}
|
|
8884
9005
|
default:
|
|
8885
9006
|
return null;
|
|
8886
9007
|
}
|
|
@@ -8966,7 +9087,9 @@ var _TOOL_ROW_ICON = {
|
|
|
8966
9087
|
delegate_task: lucideReact.ArrowRight,
|
|
8967
9088
|
create_artifact: lucideReact.FileTextIcon,
|
|
8968
9089
|
memory: lucideReact.PenLineIcon,
|
|
8969
|
-
todo: lucideReact.ListIcon
|
|
9090
|
+
todo: lucideReact.ListIcon,
|
|
9091
|
+
research_memory: lucideReact.BookOpenIcon,
|
|
9092
|
+
research_outline: lucideReact.ListIcon
|
|
8970
9093
|
};
|
|
8971
9094
|
function _toolRowIcon(toolName) {
|
|
8972
9095
|
return _TOOL_ROW_ICON[toolName] ?? lucideReact.WrenchIcon;
|
|
@@ -9012,6 +9135,31 @@ function _toolRowLabel(tc) {
|
|
|
9012
9135
|
return detail ? `Memory ${detail}` : "Updated memory";
|
|
9013
9136
|
case "todo":
|
|
9014
9137
|
return detail ? `Todo ${detail}` : "Updated todo list";
|
|
9138
|
+
case "research_memory": {
|
|
9139
|
+
const args = parseArgs(tc.args);
|
|
9140
|
+
const action = args?.action;
|
|
9141
|
+
if (action === "add") {
|
|
9142
|
+
return detail ? `Stored source "${detail}"` : "Stored a source";
|
|
9143
|
+
}
|
|
9144
|
+
if (action === "retrieve") {
|
|
9145
|
+
return detail ? `Retrieved sources for "${detail}"` : "Retrieved sources";
|
|
9146
|
+
}
|
|
9147
|
+
if (action === "list") {
|
|
9148
|
+
return "Listed sources";
|
|
9149
|
+
}
|
|
9150
|
+
return "Updated research memory";
|
|
9151
|
+
}
|
|
9152
|
+
case "research_outline": {
|
|
9153
|
+
const args = parseArgs(tc.args);
|
|
9154
|
+
const action = args?.action;
|
|
9155
|
+
if (action === "set") {
|
|
9156
|
+
return detail ? `Updated outline (${detail})` : "Updated outline";
|
|
9157
|
+
}
|
|
9158
|
+
if (action === "get") {
|
|
9159
|
+
return "Read outline";
|
|
9160
|
+
}
|
|
9161
|
+
return "Touched outline";
|
|
9162
|
+
}
|
|
9015
9163
|
default:
|
|
9016
9164
|
return cancelledToolLabel(tc.toolName);
|
|
9017
9165
|
}
|
|
@@ -9185,7 +9333,8 @@ function SimpleAssistantGroup({
|
|
|
9185
9333
|
sessionId,
|
|
9186
9334
|
artifactFallbacks,
|
|
9187
9335
|
onFileSelect,
|
|
9188
|
-
onRetry
|
|
9336
|
+
onRetry,
|
|
9337
|
+
hideTurnSummary = false
|
|
9189
9338
|
}) {
|
|
9190
9339
|
const assistantMessages = messages.filter((m) => m.role === "assistant");
|
|
9191
9340
|
const tail = assistantMessages[assistantMessages.length - 1];
|
|
@@ -9253,7 +9402,7 @@ function SimpleAssistantGroup({
|
|
|
9253
9402
|
tail
|
|
9254
9403
|
}
|
|
9255
9404
|
),
|
|
9256
|
-
effectiveTurnSummary && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9405
|
+
effectiveTurnSummary && !hideTurnSummary && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9257
9406
|
TurnSummaryCard,
|
|
9258
9407
|
{
|
|
9259
9408
|
summary: effectiveTurnSummary,
|
|
@@ -9274,7 +9423,8 @@ function AssistantGroup({
|
|
|
9274
9423
|
artifactFallbacks,
|
|
9275
9424
|
onFileSelect,
|
|
9276
9425
|
onRetry,
|
|
9277
|
-
viewMode = "simple"
|
|
9426
|
+
viewMode = "simple",
|
|
9427
|
+
hideTurnSummary = false
|
|
9278
9428
|
}) {
|
|
9279
9429
|
if (viewMode === "simple") {
|
|
9280
9430
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9285,7 +9435,8 @@ function AssistantGroup({
|
|
|
9285
9435
|
sessionId,
|
|
9286
9436
|
artifactFallbacks,
|
|
9287
9437
|
onFileSelect,
|
|
9288
|
-
onRetry
|
|
9438
|
+
onRetry,
|
|
9439
|
+
hideTurnSummary
|
|
9289
9440
|
}
|
|
9290
9441
|
);
|
|
9291
9442
|
}
|
|
@@ -9392,7 +9543,9 @@ function ChatThread({
|
|
|
9392
9543
|
canShowWorkspace = false,
|
|
9393
9544
|
viewMode = "simple",
|
|
9394
9545
|
onViewModeChange,
|
|
9395
|
-
deepResearchEnabled = false
|
|
9546
|
+
deepResearchEnabled = false,
|
|
9547
|
+
researchSources = [],
|
|
9548
|
+
hideTurnSummary = false
|
|
9396
9549
|
}) {
|
|
9397
9550
|
const groups = react.useMemo(() => groupMessages(messages), [messages]);
|
|
9398
9551
|
const awaitingInput = react.useMemo(() => isAwaitingUserInput(messages), [messages]);
|
|
@@ -9490,7 +9643,8 @@ function ChatThread({
|
|
|
9490
9643
|
artifactFallbacks,
|
|
9491
9644
|
onFileSelect,
|
|
9492
9645
|
onRetry: groupRetry,
|
|
9493
|
-
viewMode
|
|
9646
|
+
viewMode,
|
|
9647
|
+
hideTurnSummary
|
|
9494
9648
|
},
|
|
9495
9649
|
group.messages[0].id
|
|
9496
9650
|
);
|
|
@@ -9501,14 +9655,8 @@ function ChatThread({
|
|
|
9501
9655
|
] }),
|
|
9502
9656
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-4xl px-3 sm:px-6 pb-3 sm:pb-5 pt-3", children: [
|
|
9503
9657
|
retryIndicator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(RetryBanner, { indicator: retryIndicator }) }),
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
{
|
|
9507
|
-
className: "rounded border border-line bg-muted/40 px-3 py-2 text-sm text-foreground/60",
|
|
9508
|
-
role: "status",
|
|
9509
|
-
children: composerDisabledReason
|
|
9510
|
-
}
|
|
9511
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
9658
|
+
researchSources.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ResearchSourcesPanel, { sources: researchSources }) }),
|
|
9659
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9512
9660
|
ChatComposer,
|
|
9513
9661
|
{
|
|
9514
9662
|
onSend,
|
|
@@ -9532,44 +9680,6 @@ function ChatThread({
|
|
|
9532
9680
|
] })
|
|
9533
9681
|
] });
|
|
9534
9682
|
}
|
|
9535
|
-
function ResearchSourcesPanel({
|
|
9536
|
-
sources
|
|
9537
|
-
}) {
|
|
9538
|
-
if (sources.length === 0) {
|
|
9539
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 text-xs text-muted-foreground", children: "No research sources yet. Sources appear here as the deep-research agent curates evidence." });
|
|
9540
|
-
}
|
|
9541
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 p-2", children: [
|
|
9542
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: [
|
|
9543
|
-
"Sources \xB7 ",
|
|
9544
|
-
sources.length
|
|
9545
|
-
] }),
|
|
9546
|
-
sources.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9547
|
-
"a",
|
|
9548
|
-
{
|
|
9549
|
-
id: `source-${s.sourceId}`,
|
|
9550
|
-
href: s.url,
|
|
9551
|
-
target: "_blank",
|
|
9552
|
-
rel: "noreferrer",
|
|
9553
|
-
className: "group flex items-baseline gap-2 rounded-sm px-1 py-1 hover:bg-muted",
|
|
9554
|
-
children: [
|
|
9555
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] font-semibold text-primary", children: s.sourceId }),
|
|
9556
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col overflow-hidden", children: [
|
|
9557
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-foreground group-hover:underline", children: s.title || s.url }),
|
|
9558
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[10px] text-muted-foreground", children: hostname2(s.url) })
|
|
9559
|
-
] })
|
|
9560
|
-
]
|
|
9561
|
-
},
|
|
9562
|
-
s.sourceId
|
|
9563
|
-
))
|
|
9564
|
-
] });
|
|
9565
|
-
}
|
|
9566
|
-
function hostname2(url) {
|
|
9567
|
-
try {
|
|
9568
|
-
return new URL(url).hostname.replace(/^www\./, "");
|
|
9569
|
-
} catch {
|
|
9570
|
-
return url;
|
|
9571
|
-
}
|
|
9572
|
-
}
|
|
9573
9683
|
|
|
9574
9684
|
// src/components/ai-elements/file-tree.tsx
|
|
9575
9685
|
init_utils();
|
|
@@ -10247,6 +10357,29 @@ function isScheduledRunSession(session) {
|
|
|
10247
10357
|
session?.channel === "scheduled" || session?.config?.scheduled_session_id
|
|
10248
10358
|
);
|
|
10249
10359
|
}
|
|
10360
|
+
var _SUB_AGENT_CHANNELS = /* @__PURE__ */ new Set([
|
|
10361
|
+
"delegation",
|
|
10362
|
+
"worker",
|
|
10363
|
+
"task"
|
|
10364
|
+
]);
|
|
10365
|
+
function isSubAgentSession(session) {
|
|
10366
|
+
if (!session) return false;
|
|
10367
|
+
if (session.parentId) return true;
|
|
10368
|
+
if (session.channel && _SUB_AGENT_CHANNELS.has(session.channel)) return true;
|
|
10369
|
+
return false;
|
|
10370
|
+
}
|
|
10371
|
+
function readOnlyReasonForSession(session) {
|
|
10372
|
+
if (isScheduledRunSession(session)) {
|
|
10373
|
+
return { readOnly: true, reason: "Scheduled run is read-only" };
|
|
10374
|
+
}
|
|
10375
|
+
if (isSubAgentSession(session)) {
|
|
10376
|
+
return {
|
|
10377
|
+
readOnly: true,
|
|
10378
|
+
reason: "Sub-task started by parent session \u2014 read-only"
|
|
10379
|
+
};
|
|
10380
|
+
}
|
|
10381
|
+
return { readOnly: false };
|
|
10382
|
+
}
|
|
10250
10383
|
|
|
10251
10384
|
// src/runtime/events.ts
|
|
10252
10385
|
var WORKSPACE_MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -10369,7 +10502,13 @@ function applyAgentChatEvent(state, event) {
|
|
|
10369
10502
|
name: event.data.name,
|
|
10370
10503
|
kind: event.data.kind,
|
|
10371
10504
|
version: event.data.version,
|
|
10372
|
-
size: event.data.size
|
|
10505
|
+
size: event.data.size,
|
|
10506
|
+
// Propagated artifacts (a delegated child's report
|
|
10507
|
+
// surfacing on the parent's chat thread) carry this
|
|
10508
|
+
// field; without it the ArtifactBlock fetches via the
|
|
10509
|
+
// chat's own session id and 404s because the spec lives
|
|
10510
|
+
// under the writer's S3 prefix, not the parent's.
|
|
10511
|
+
originating_session_id: event.data.originating_session_id
|
|
10373
10512
|
}
|
|
10374
10513
|
}
|
|
10375
10514
|
]);
|
|
@@ -10756,7 +10895,7 @@ function applyLlmThinking(state, event) {
|
|
|
10756
10895
|
} else {
|
|
10757
10896
|
messages[idx] = {
|
|
10758
10897
|
...prev,
|
|
10759
|
-
reasoning: (prev.reasoning
|
|
10898
|
+
reasoning: appendText(prev.reasoning, reasoningText),
|
|
10760
10899
|
turnId: turnId ?? prev.turnId,
|
|
10761
10900
|
iterationIndex: iterationIndex ?? prev.iterationIndex
|
|
10762
10901
|
};
|
|
@@ -11691,16 +11830,24 @@ function AgentChat({
|
|
|
11691
11830
|
react.useEffect(() => {
|
|
11692
11831
|
setShowWorkspace(runtime.viewMode === "expert");
|
|
11693
11832
|
}, [runtime.viewMode]);
|
|
11694
|
-
const
|
|
11695
|
-
const effectiveDisabled = disabled ||
|
|
11696
|
-
const disabledReason =
|
|
11833
|
+
const readOnly = readOnlyReasonForSession(runtime.session);
|
|
11834
|
+
const effectiveDisabled = disabled || readOnly.readOnly;
|
|
11835
|
+
const disabledReason = readOnly.reason;
|
|
11836
|
+
const orchestratesDeepResearch = react.useMemo(
|
|
11837
|
+
() => runtime.messages.some(
|
|
11838
|
+
(m) => m.toolCalls?.some(
|
|
11839
|
+
(tc) => tc.toolName === "delegate_task" && delegateTaskTargets(tc.args).includes("deep-research")
|
|
11840
|
+
)
|
|
11841
|
+
),
|
|
11842
|
+
[runtime.messages]
|
|
11843
|
+
);
|
|
11844
|
+
const hideTurnSummary = isSubAgentSession(runtime.session) || orchestratesDeepResearch;
|
|
11697
11845
|
const browserState = runtime.state.browser;
|
|
11698
11846
|
const browserAvailable = browserState !== null && browserState.status !== "closed" && !!sessionId;
|
|
11699
11847
|
const browserVisible = browserAvailable && showBrowser;
|
|
11700
11848
|
const workspaceAvailable = !!sessionId;
|
|
11701
11849
|
const workspaceVisible = workspaceAvailable && showWorkspace;
|
|
11702
|
-
const
|
|
11703
|
-
const rightStackVisible = browserVisible || workspaceVisible || sourcesVisible;
|
|
11850
|
+
const rightStackVisible = browserVisible || workspaceVisible;
|
|
11704
11851
|
const bothPanesVisible = browserVisible && workspaceVisible;
|
|
11705
11852
|
react.useEffect(() => {
|
|
11706
11853
|
onMessagesChange?.(runtime.messages);
|
|
@@ -11816,7 +11963,9 @@ function AgentChat({
|
|
|
11816
11963
|
canShowWorkspace: workspaceAvailable,
|
|
11817
11964
|
viewMode: runtime.viewMode,
|
|
11818
11965
|
onViewModeChange: runtime.setViewMode,
|
|
11819
|
-
deepResearchEnabled
|
|
11966
|
+
deepResearchEnabled,
|
|
11967
|
+
researchSources: runtime.researchSources,
|
|
11968
|
+
hideTurnSummary
|
|
11820
11969
|
}
|
|
11821
11970
|
)
|
|
11822
11971
|
}
|
|
@@ -11876,20 +12025,6 @@ function AgentChat({
|
|
|
11876
12025
|
}
|
|
11877
12026
|
)
|
|
11878
12027
|
}
|
|
11879
|
-
),
|
|
11880
|
-
sourcesVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11881
|
-
"div",
|
|
11882
|
-
{
|
|
11883
|
-
"data-testid": "research-sources-panel-frame",
|
|
11884
|
-
className: cn(
|
|
11885
|
-
"min-h-0 w-full overflow-auto",
|
|
11886
|
-
// When other panes share the stack the sources
|
|
11887
|
-
// panel takes a fixed minimum so the source rows
|
|
11888
|
-
// stay readable; otherwise it fills the column.
|
|
11889
|
-
browserVisible || workspaceVisible ? "max-h-1/3 border-t border-line" : "h-full"
|
|
11890
|
-
),
|
|
11891
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ResearchSourcesPanel, { sources: runtime.researchSources })
|
|
11892
|
-
}
|
|
11893
12028
|
)
|
|
11894
12029
|
]
|
|
11895
12030
|
}
|
|
@@ -11900,6 +12035,27 @@ function AgentChat({
|
|
|
11900
12035
|
}
|
|
11901
12036
|
);
|
|
11902
12037
|
}
|
|
12038
|
+
function delegateTaskTargets(rawArgs) {
|
|
12039
|
+
if (!rawArgs) return [];
|
|
12040
|
+
let parsed;
|
|
12041
|
+
try {
|
|
12042
|
+
parsed = JSON.parse(rawArgs);
|
|
12043
|
+
} catch {
|
|
12044
|
+
return [];
|
|
12045
|
+
}
|
|
12046
|
+
if (!parsed || typeof parsed !== "object") return [];
|
|
12047
|
+
const out = [];
|
|
12048
|
+
const a = parsed;
|
|
12049
|
+
if (typeof a.agent_type === "string") out.push(a.agent_type);
|
|
12050
|
+
if (Array.isArray(a.goals)) {
|
|
12051
|
+
for (const g of a.goals) {
|
|
12052
|
+
if (g && typeof g === "object" && typeof g.agent_type === "string") {
|
|
12053
|
+
out.push(g.agent_type);
|
|
12054
|
+
}
|
|
12055
|
+
}
|
|
12056
|
+
}
|
|
12057
|
+
return out;
|
|
12058
|
+
}
|
|
11903
12059
|
init_utils();
|
|
11904
12060
|
var DEFAULT_LIMIT = 50;
|
|
11905
12061
|
function requireInboxAdapter(adapter) {
|
|
@@ -14052,7 +14208,7 @@ function mergeTreeNodes(groups) {
|
|
|
14052
14208
|
}
|
|
14053
14209
|
return Array.from(byId.values());
|
|
14054
14210
|
}
|
|
14055
|
-
function
|
|
14211
|
+
function collectDeletedSessionIds(nodes, deletedSessionId) {
|
|
14056
14212
|
const deletedIds = /* @__PURE__ */ new Set([deletedSessionId]);
|
|
14057
14213
|
let changed = true;
|
|
14058
14214
|
while (changed) {
|
|
@@ -14064,7 +14220,7 @@ function pruneDeletedSessionNodes(nodes, deletedSessionId) {
|
|
|
14064
14220
|
}
|
|
14065
14221
|
}
|
|
14066
14222
|
}
|
|
14067
|
-
return
|
|
14223
|
+
return deletedIds;
|
|
14068
14224
|
}
|
|
14069
14225
|
function formatSessionTime(value) {
|
|
14070
14226
|
const normalized = /[zZ]|[+-]\d{2}:?\d{2}$/.test(value) ? value : `${value}Z`;
|
|
@@ -14095,7 +14251,6 @@ function TreeNodeRow({
|
|
|
14095
14251
|
activeSessionId,
|
|
14096
14252
|
canStop,
|
|
14097
14253
|
canDelete,
|
|
14098
|
-
deletingSessionId,
|
|
14099
14254
|
onSelect,
|
|
14100
14255
|
onStop,
|
|
14101
14256
|
onDelete
|
|
@@ -14163,18 +14318,14 @@ function TreeNodeRow({
|
|
|
14163
14318
|
"button",
|
|
14164
14319
|
{
|
|
14165
14320
|
type: "button",
|
|
14166
|
-
className:
|
|
14167
|
-
"p-2 md:p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
|
|
14168
|
-
deletingSessionId === entry.id ? "opacity-100" : "opacity-60 md:opacity-50 md:group-hover:opacity-100 md:focus-visible:opacity-100"
|
|
14169
|
-
),
|
|
14321
|
+
className: "p-2 md:p-1 rounded opacity-60 md:opacity-50 md:group-hover:opacity-100 md:focus-visible:opacity-100 hover:bg-destructive/10 hover:text-destructive transition-all",
|
|
14170
14322
|
onClick: (e) => {
|
|
14171
14323
|
e.stopPropagation();
|
|
14172
14324
|
onDelete(entry.id);
|
|
14173
14325
|
},
|
|
14174
14326
|
"aria-label": "Delete session",
|
|
14175
14327
|
title: "Delete session",
|
|
14176
|
-
|
|
14177
|
-
children: deletingSessionId === entry.id ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "w-3 h-3 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2Icon, { className: "w-3 h-3" })
|
|
14328
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2Icon, { className: "w-3 h-3" })
|
|
14178
14329
|
}
|
|
14179
14330
|
)
|
|
14180
14331
|
]
|
|
@@ -14188,7 +14339,6 @@ function TreeNodeRow({
|
|
|
14188
14339
|
activeSessionId,
|
|
14189
14340
|
canStop,
|
|
14190
14341
|
canDelete,
|
|
14191
|
-
deletingSessionId,
|
|
14192
14342
|
onSelect,
|
|
14193
14343
|
onStop,
|
|
14194
14344
|
onDelete
|
|
@@ -14213,10 +14363,8 @@ function SessionTreePanel({
|
|
|
14213
14363
|
const [nodes, setNodes] = react.useState([]);
|
|
14214
14364
|
const [error, setError] = react.useState(null);
|
|
14215
14365
|
const [hasEverLoaded, setHasEverLoaded] = react.useState(false);
|
|
14216
|
-
const [deletingSessionId, setDeletingSessionId] = react.useState(
|
|
14217
|
-
null
|
|
14218
|
-
);
|
|
14219
14366
|
const mounted = react.useRef(true);
|
|
14367
|
+
const pendingDeleteIds = react.useRef(/* @__PURE__ */ new Set());
|
|
14220
14368
|
const requestId = react.useRef(0);
|
|
14221
14369
|
const lastFingerprint = react.useRef("");
|
|
14222
14370
|
const resetContext = react.useRef(null);
|
|
@@ -14241,10 +14389,23 @@ function SessionTreePanel({
|
|
|
14241
14389
|
sessionTreePromise
|
|
14242
14390
|
]);
|
|
14243
14391
|
if (!mounted.current || currentRequestId !== requestId.current) return;
|
|
14244
|
-
|
|
14392
|
+
let nextNodes = mergeTreeNodes([
|
|
14245
14393
|
sessionList?.sessions.map(sessionToTreeNode) ?? [],
|
|
14246
14394
|
sessionTree?.nodes ?? []
|
|
14247
14395
|
]);
|
|
14396
|
+
if (pendingDeleteIds.current.size > 0) {
|
|
14397
|
+
const stillReturned = /* @__PURE__ */ new Set();
|
|
14398
|
+
nextNodes = nextNodes.filter((node) => {
|
|
14399
|
+
if (!pendingDeleteIds.current.has(node.id)) return true;
|
|
14400
|
+
stillReturned.add(node.id);
|
|
14401
|
+
return false;
|
|
14402
|
+
});
|
|
14403
|
+
for (const pendingId of pendingDeleteIds.current) {
|
|
14404
|
+
if (!stillReturned.has(pendingId)) {
|
|
14405
|
+
pendingDeleteIds.current.delete(pendingId);
|
|
14406
|
+
}
|
|
14407
|
+
}
|
|
14408
|
+
}
|
|
14248
14409
|
const fp = treeFingerprint(nextNodes);
|
|
14249
14410
|
if (fp !== lastFingerprint.current) {
|
|
14250
14411
|
lastFingerprint.current = fp;
|
|
@@ -14275,6 +14436,7 @@ function SessionTreePanel({
|
|
|
14275
14436
|
setNodes([]);
|
|
14276
14437
|
setHasEverLoaded(false);
|
|
14277
14438
|
lastFingerprint.current = "";
|
|
14439
|
+
pendingDeleteIds.current.clear();
|
|
14278
14440
|
}
|
|
14279
14441
|
setError(null);
|
|
14280
14442
|
void refetch();
|
|
@@ -14311,24 +14473,31 @@ function SessionTreePanel({
|
|
|
14311
14473
|
);
|
|
14312
14474
|
const handleDelete = react.useCallback(
|
|
14313
14475
|
async (id) => {
|
|
14314
|
-
if (!adapter.deleteSession
|
|
14315
|
-
|
|
14476
|
+
if (!adapter.deleteSession) return;
|
|
14477
|
+
const deletedIds = collectDeletedSessionIds(nodes, id);
|
|
14478
|
+
for (const deletedId of deletedIds) {
|
|
14479
|
+
pendingDeleteIds.current.add(deletedId);
|
|
14480
|
+
}
|
|
14481
|
+
setNodes((current) => {
|
|
14482
|
+
const next = current.filter((node) => !deletedIds.has(node.id));
|
|
14483
|
+
lastFingerprint.current = treeFingerprint(next);
|
|
14484
|
+
return next;
|
|
14485
|
+
});
|
|
14486
|
+
onSessionDelete?.(id);
|
|
14316
14487
|
try {
|
|
14317
14488
|
await adapter.deleteSession({ sessionId: id });
|
|
14318
|
-
setNodes((current) => {
|
|
14319
|
-
const next = pruneDeletedSessionNodes(current, id);
|
|
14320
|
-
lastFingerprint.current = treeFingerprint(next);
|
|
14321
|
-
return next;
|
|
14322
|
-
});
|
|
14323
|
-
onSessionDelete?.(id);
|
|
14324
14489
|
await refetch({ silent: true });
|
|
14325
14490
|
} catch (e) {
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14491
|
+
for (const deletedId of deletedIds) {
|
|
14492
|
+
pendingDeleteIds.current.delete(deletedId);
|
|
14493
|
+
}
|
|
14494
|
+
if (mounted.current) {
|
|
14495
|
+
setError(e instanceof Error ? e.message : "Failed to delete session");
|
|
14496
|
+
}
|
|
14497
|
+
await refetch({ silent: true });
|
|
14329
14498
|
}
|
|
14330
14499
|
},
|
|
14331
|
-
[adapter,
|
|
14500
|
+
[adapter, nodes, onSessionDelete, refetch]
|
|
14332
14501
|
);
|
|
14333
14502
|
if (!hasEverLoaded) return null;
|
|
14334
14503
|
if (nodes.length === 0) return null;
|
|
@@ -14349,7 +14518,6 @@ function SessionTreePanel({
|
|
|
14349
14518
|
activeSessionId: activeSessionId ?? "",
|
|
14350
14519
|
canStop: Boolean(adapter.stopSession),
|
|
14351
14520
|
canDelete: Boolean(adapter.deleteSession),
|
|
14352
|
-
deletingSessionId,
|
|
14353
14521
|
onSelect: handleSelect,
|
|
14354
14522
|
onStop: handleStop,
|
|
14355
14523
|
onDelete: handleDelete
|