@invergent/agent-chat-react 2.4.12 → 2.5.0
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 +347 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -2
- package/dist/index.d.ts +55 -2
- package/dist/index.js +345 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4473,6 +4473,51 @@ function DefaultToolBlock({ tc }) {
|
|
|
4473
4473
|
] })
|
|
4474
4474
|
] });
|
|
4475
4475
|
}
|
|
4476
|
+
function ResearchOutlineBlock({ tc }) {
|
|
4477
|
+
const args = parseArgs(tc.args) ?? {};
|
|
4478
|
+
const result = tc.result ? parseArgs(tc.result) ?? {} : {};
|
|
4479
|
+
const outline = args.action === "set" ? args.outline ?? "" : result.outline ?? "";
|
|
4480
|
+
const sections = result.sections ?? [];
|
|
4481
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-sm border border-border bg-muted/40 p-2 text-xs", children: [
|
|
4482
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 font-semibold uppercase tracking-widest text-muted-foreground", children: [
|
|
4483
|
+
"Research outline",
|
|
4484
|
+
sections.length ? ` \xB7 ${sections.length} sections` : ""
|
|
4485
|
+
] }),
|
|
4486
|
+
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
|
+
] });
|
|
4488
|
+
}
|
|
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
|
+
}
|
|
4476
4521
|
function ToolCallBlock({
|
|
4477
4522
|
tc,
|
|
4478
4523
|
resolvedArtifactName,
|
|
@@ -4525,6 +4570,10 @@ function ToolCallBlock({
|
|
|
4525
4570
|
return /* @__PURE__ */ jsxRuntime.jsx(DelegateToolBlock, { tc });
|
|
4526
4571
|
case "memory":
|
|
4527
4572
|
return /* @__PURE__ */ jsxRuntime.jsx(MemoryToolBlock, { tc });
|
|
4573
|
+
case "research_outline":
|
|
4574
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ResearchOutlineBlock, { tc });
|
|
4575
|
+
case "research_memory":
|
|
4576
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ResearchMemoryBlock, { tc });
|
|
4528
4577
|
case "spawn_worker":
|
|
4529
4578
|
case "send_worker_message":
|
|
4530
4579
|
case "stop_worker":
|
|
@@ -6073,6 +6122,7 @@ function ChatComposerInner({
|
|
|
6073
6122
|
onToggleWorkspace,
|
|
6074
6123
|
canShowBrowser = false,
|
|
6075
6124
|
canShowWorkspace = false,
|
|
6125
|
+
deepResearchEnabled = false,
|
|
6076
6126
|
viewMode = "simple",
|
|
6077
6127
|
onViewModeChange
|
|
6078
6128
|
}) {
|
|
@@ -6102,24 +6152,34 @@ function ChatComposerInner({
|
|
|
6102
6152
|
}
|
|
6103
6153
|
}, [adapter, showSlashMenu, menuMode]);
|
|
6104
6154
|
const builtinCommands = react.useMemo(
|
|
6105
|
-
() =>
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6155
|
+
() => {
|
|
6156
|
+
const base = [
|
|
6157
|
+
{ value: "/clear", label: "/clear", description: "Clear conversation" },
|
|
6158
|
+
{ value: "/compress", label: "/compress", description: "Compress context" },
|
|
6159
|
+
{ value: "/goal", label: "/goal", description: "Define an outcome goal" },
|
|
6160
|
+
{ value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
|
|
6161
|
+
{ value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
|
|
6162
|
+
{ value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
|
|
6163
|
+
{ value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
|
|
6164
|
+
{ value: "/mission ", label: "/mission", description: "Start an orchestrated rubric-judged mission" },
|
|
6165
|
+
{ value: "/mission status", label: "/mission status", description: "Show current mission status" },
|
|
6166
|
+
{ value: "/mission pause", label: "/mission pause", description: "Pause the mission evaluator" },
|
|
6167
|
+
{ value: "/mission resume", label: "/mission resume", description: "Resume a paused mission" },
|
|
6168
|
+
{ value: "/mission cancel", label: "/mission cancel", description: "Cancel the mission" },
|
|
6169
|
+
{ value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
|
|
6170
|
+
{ value: "/loop list", label: "/loop list", description: "List active loops" },
|
|
6171
|
+
{ value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
|
|
6172
|
+
];
|
|
6173
|
+
if (deepResearchEnabled) {
|
|
6174
|
+
base.push({
|
|
6175
|
+
value: "/deep-research ",
|
|
6176
|
+
label: "/deep-research",
|
|
6177
|
+
description: "Delegate a topic to the deep-research workflow"
|
|
6178
|
+
});
|
|
6179
|
+
}
|
|
6180
|
+
return base;
|
|
6181
|
+
},
|
|
6182
|
+
[deepResearchEnabled]
|
|
6123
6183
|
);
|
|
6124
6184
|
const scheduledExamples = react.useMemo(
|
|
6125
6185
|
() => [
|
|
@@ -8256,6 +8316,20 @@ function ArtifactRow({
|
|
|
8256
8316
|
// src/components/chat/chat-thread.tsx
|
|
8257
8317
|
init_utils();
|
|
8258
8318
|
var WORKING_ON_IT_DELAY_MS = 250;
|
|
8319
|
+
function hasUserFacingAskContent(msg) {
|
|
8320
|
+
return !!msg.toolCalls?.some((tc) => tc.toolName === "ask_user_question");
|
|
8321
|
+
}
|
|
8322
|
+
function isAwaitingUserInput(messages) {
|
|
8323
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8324
|
+
const m = messages[i];
|
|
8325
|
+
if (m.role === "user") return false;
|
|
8326
|
+
if (m.role !== "assistant") continue;
|
|
8327
|
+
return !!m.toolCalls?.some(
|
|
8328
|
+
(tc) => tc.toolName === "ask_user_question" && tc.status === "running"
|
|
8329
|
+
);
|
|
8330
|
+
}
|
|
8331
|
+
return false;
|
|
8332
|
+
}
|
|
8259
8333
|
function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
8260
8334
|
if (msg.role === "system") {
|
|
8261
8335
|
if (msg.systemKind === "skill_invoked") {
|
|
@@ -8280,6 +8354,14 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
8280
8354
|
version
|
|
8281
8355
|
}];
|
|
8282
8356
|
}
|
|
8357
|
+
if (msg.systemKind === "browser_marker" || msg.systemKind === "browser_marker_warning") {
|
|
8358
|
+
return [{
|
|
8359
|
+
kind: "browser_marker",
|
|
8360
|
+
key: msg.id,
|
|
8361
|
+
content: msg.content,
|
|
8362
|
+
warning: msg.systemKind === "browser_marker_warning"
|
|
8363
|
+
}];
|
|
8364
|
+
}
|
|
8283
8365
|
return [];
|
|
8284
8366
|
}
|
|
8285
8367
|
const entries = [];
|
|
@@ -8296,12 +8378,22 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
8296
8378
|
});
|
|
8297
8379
|
}
|
|
8298
8380
|
if (hasContent && hasToolCalls) {
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8381
|
+
if (hasUserFacingAskContent(msg)) {
|
|
8382
|
+
entries.push({
|
|
8383
|
+
kind: "text",
|
|
8384
|
+
key: `${msg.id}-text`,
|
|
8385
|
+
content: msg.content,
|
|
8386
|
+
isStreaming: false,
|
|
8387
|
+
msg
|
|
8388
|
+
});
|
|
8389
|
+
} else {
|
|
8390
|
+
entries.push({
|
|
8391
|
+
kind: "narration",
|
|
8392
|
+
key: `${msg.id}-narration`,
|
|
8393
|
+
text: msg.content,
|
|
8394
|
+
isStreaming: isStreaming && !effectiveHasContent
|
|
8395
|
+
});
|
|
8396
|
+
}
|
|
8305
8397
|
}
|
|
8306
8398
|
if (hasToolCalls) {
|
|
8307
8399
|
for (const tc of msg.toolCalls) {
|
|
@@ -8465,6 +8557,23 @@ function OrphanSystemMarker({
|
|
|
8465
8557
|
}
|
|
8466
8558
|
);
|
|
8467
8559
|
}
|
|
8560
|
+
if (message.systemKind === "browser_marker" || message.systemKind === "browser_marker_warning") {
|
|
8561
|
+
const warning = message.systemKind === "browser_marker_warning";
|
|
8562
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8563
|
+
"div",
|
|
8564
|
+
{
|
|
8565
|
+
className: cn(
|
|
8566
|
+
"my-2 flex items-center gap-2 px-4 text-xs",
|
|
8567
|
+
warning ? "text-amber-600" : "text-foreground/60"
|
|
8568
|
+
),
|
|
8569
|
+
role: warning ? "alert" : "status",
|
|
8570
|
+
children: [
|
|
8571
|
+
warning ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5 shrink-0", "aria-hidden": true }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2 rounded-full bg-foreground/30" }),
|
|
8572
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: message.content })
|
|
8573
|
+
]
|
|
8574
|
+
}
|
|
8575
|
+
);
|
|
8576
|
+
}
|
|
8468
8577
|
if (message.systemKind === "error" && message.errorInfo) {
|
|
8469
8578
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto my-2 w-full max-w-4xl", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { errorInfo: message.errorInfo, onRetry }) });
|
|
8470
8579
|
}
|
|
@@ -8565,6 +8674,36 @@ function TimelineEntryItem({
|
|
|
8565
8674
|
if (entry.kind === "narration") {
|
|
8566
8675
|
return /* @__PURE__ */ jsxRuntime.jsx(NarrationEntry, { entry, step });
|
|
8567
8676
|
}
|
|
8677
|
+
if (entry.kind === "browser_marker") {
|
|
8678
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
8679
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
8680
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8681
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8682
|
+
TimelineIndicator,
|
|
8683
|
+
{
|
|
8684
|
+
className: cn(
|
|
8685
|
+
"size-2 border-none",
|
|
8686
|
+
entry.warning ? "bg-amber-500" : "bg-foreground/30"
|
|
8687
|
+
)
|
|
8688
|
+
}
|
|
8689
|
+
)
|
|
8690
|
+
] }),
|
|
8691
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8692
|
+
"div",
|
|
8693
|
+
{
|
|
8694
|
+
className: cn(
|
|
8695
|
+
"flex items-center gap-1.5 py-1 text-sm",
|
|
8696
|
+
entry.warning ? "text-amber-600" : "text-foreground/60"
|
|
8697
|
+
),
|
|
8698
|
+
role: entry.warning ? "alert" : "status",
|
|
8699
|
+
children: [
|
|
8700
|
+
entry.warning && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5 shrink-0", "aria-hidden": true }),
|
|
8701
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: entry.content })
|
|
8702
|
+
]
|
|
8703
|
+
}
|
|
8704
|
+
) })
|
|
8705
|
+
] });
|
|
8706
|
+
}
|
|
8568
8707
|
if (entry.kind === "skill_invoked") {
|
|
8569
8708
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
8570
8709
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
@@ -8722,11 +8861,11 @@ function extractToolDetail(tc) {
|
|
|
8722
8861
|
}
|
|
8723
8862
|
case "terminal": {
|
|
8724
8863
|
const cmd = stringArg("command");
|
|
8725
|
-
return cmd ?
|
|
8864
|
+
return cmd ? truncate3(cmd, 40) : null;
|
|
8726
8865
|
}
|
|
8727
8866
|
case "execute_code": {
|
|
8728
8867
|
const code3 = stringArg("code");
|
|
8729
|
-
return code3 ?
|
|
8868
|
+
return code3 ? truncate3(code3.split("\n")[0] ?? "", 40) : null;
|
|
8730
8869
|
}
|
|
8731
8870
|
case "web_search":
|
|
8732
8871
|
case "web_crawl":
|
|
@@ -8751,7 +8890,7 @@ function lastPathSegment(path) {
|
|
|
8751
8890
|
const idx = cleaned.lastIndexOf("/");
|
|
8752
8891
|
return idx >= 0 ? cleaned.slice(idx + 1) : cleaned;
|
|
8753
8892
|
}
|
|
8754
|
-
function
|
|
8893
|
+
function truncate3(s, max) {
|
|
8755
8894
|
return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
8756
8895
|
}
|
|
8757
8896
|
var _SIMPLE_MODE_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -8944,13 +9083,13 @@ function IterationGroup({
|
|
|
8944
9083
|
}) {
|
|
8945
9084
|
const summary = message.iterationSummary?.summary;
|
|
8946
9085
|
const [open, setOpen] = react.useState(false);
|
|
9086
|
+
const askCall = (message.toolCalls ?? []).find(
|
|
9087
|
+
(tc) => tc.toolName === "ask_user_question"
|
|
9088
|
+
);
|
|
9089
|
+
if (askCall) {
|
|
9090
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 py-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(AskUserQuestionToolBlock, { tc: askCall }) });
|
|
9091
|
+
}
|
|
8947
9092
|
if (isIterationLive(message)) {
|
|
8948
|
-
const askCall = (message.toolCalls ?? []).find(
|
|
8949
|
-
(tc) => tc.toolName === "ask_user_question" && tc.status === "running"
|
|
8950
|
-
);
|
|
8951
|
-
if (askCall) {
|
|
8952
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 py-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(AskUserQuestionToolBlock, { tc: askCall }) });
|
|
8953
|
-
}
|
|
8954
9093
|
const label2 = liveIterationLabel(message);
|
|
8955
9094
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-0.5 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "text-sm", children: label2 }) });
|
|
8956
9095
|
}
|
|
@@ -9009,6 +9148,14 @@ function deriveFileArtifactsFromMessages(messages) {
|
|
|
9009
9148
|
const seen = /* @__PURE__ */ new Set();
|
|
9010
9149
|
const out = [];
|
|
9011
9150
|
for (const msg of messages) {
|
|
9151
|
+
if (msg.role === "system") {
|
|
9152
|
+
if (msg.systemKind !== "artifact") continue;
|
|
9153
|
+
const { artifactId, name } = unpackArtifactMeta(msg.systemMeta, msg.content);
|
|
9154
|
+
if (!artifactId || seen.has(`artifact:${artifactId}`)) continue;
|
|
9155
|
+
seen.add(`artifact:${artifactId}`);
|
|
9156
|
+
out.push({ kind: "artifact", label: name, ref: artifactId });
|
|
9157
|
+
continue;
|
|
9158
|
+
}
|
|
9012
9159
|
if (msg.role !== "assistant" || !msg.toolCalls) continue;
|
|
9013
9160
|
for (const tc of msg.toolCalls) {
|
|
9014
9161
|
const status = effectiveStatus(tc);
|
|
@@ -9028,16 +9175,6 @@ function deriveFileArtifactsFromMessages(messages) {
|
|
|
9028
9175
|
});
|
|
9029
9176
|
continue;
|
|
9030
9177
|
}
|
|
9031
|
-
if (tc.toolName === "create_artifact") {
|
|
9032
|
-
const name = typeof args.name === "string" ? args.name : "";
|
|
9033
|
-
if (!name || seen.has(`artifact:${name}`)) continue;
|
|
9034
|
-
seen.add(`artifact:${name}`);
|
|
9035
|
-
out.push({
|
|
9036
|
-
kind: "artifact",
|
|
9037
|
-
label: name,
|
|
9038
|
-
ref: name
|
|
9039
|
-
});
|
|
9040
|
-
}
|
|
9041
9178
|
}
|
|
9042
9179
|
}
|
|
9043
9180
|
return out;
|
|
@@ -9063,15 +9200,18 @@ function SimpleAssistantGroup({
|
|
|
9063
9200
|
if (fromHarness && fromHarness.artifacts.length > 0) {
|
|
9064
9201
|
return fromHarness;
|
|
9065
9202
|
}
|
|
9203
|
+
if (turnComplete) {
|
|
9204
|
+
const derived = deriveFileArtifactsFromMessages(messages);
|
|
9205
|
+
if (derived.length > 0) {
|
|
9206
|
+
return {
|
|
9207
|
+
turnId: fromHarness?.turnId ?? "",
|
|
9208
|
+
recap: summaryPref === "show" ? fromHarness?.recap ?? "" : "",
|
|
9209
|
+
artifacts: derived
|
|
9210
|
+
};
|
|
9211
|
+
}
|
|
9212
|
+
}
|
|
9066
9213
|
if (summaryPref === "hide") return null;
|
|
9067
|
-
|
|
9068
|
-
const derived = deriveFileArtifactsFromMessages(messages);
|
|
9069
|
-
if (derived.length === 0) return fromHarness;
|
|
9070
|
-
return {
|
|
9071
|
-
turnId: fromHarness?.turnId ?? "",
|
|
9072
|
-
recap: fromHarness?.recap ?? "",
|
|
9073
|
-
artifacts: derived
|
|
9074
|
-
};
|
|
9214
|
+
return fromHarness;
|
|
9075
9215
|
})();
|
|
9076
9216
|
return /* @__PURE__ */ jsxRuntime.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntime.jsxs(MessageContent, { children: [
|
|
9077
9217
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: messages.map((message) => {
|
|
@@ -9089,10 +9229,11 @@ function SimpleAssistantGroup({
|
|
|
9089
9229
|
}
|
|
9090
9230
|
if (message === tail && tailIsTextOnly && finalText) return null;
|
|
9091
9231
|
const rawContent = (message.content ?? "").trim();
|
|
9092
|
-
const { action, inferredNarration } = stripAndParseNextAction(rawContent);
|
|
9232
|
+
const { action, inferredNarration, cleaned } = stripAndParseNextAction(rawContent);
|
|
9093
9233
|
const narrationLine = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
9234
|
+
const askBody = hasUserFacingAskContent(message) ? cleaned : null;
|
|
9094
9235
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
9095
|
-
narrationLine
|
|
9236
|
+
askBody ? /* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children: askBody }) : narrationLine ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: narrationLine }) : null,
|
|
9096
9237
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9097
9238
|
IterationGroup,
|
|
9098
9239
|
{
|
|
@@ -9157,7 +9298,7 @@ function AssistantGroup({
|
|
|
9157
9298
|
entries = groupWebSearchEntries(entries);
|
|
9158
9299
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
9159
9300
|
const entry = entries[i];
|
|
9160
|
-
if (entry?.kind === "text") {
|
|
9301
|
+
if (entry?.kind === "text" && !hasUserFacingAskContent(entry.msg)) {
|
|
9161
9302
|
entries[i] = { ...entry, isFinalTurnText: true };
|
|
9162
9303
|
break;
|
|
9163
9304
|
}
|
|
@@ -9250,10 +9391,14 @@ function ChatThread({
|
|
|
9250
9391
|
canShowBrowser = false,
|
|
9251
9392
|
canShowWorkspace = false,
|
|
9252
9393
|
viewMode = "simple",
|
|
9253
|
-
onViewModeChange
|
|
9394
|
+
onViewModeChange,
|
|
9395
|
+
deepResearchEnabled = false
|
|
9254
9396
|
}) {
|
|
9255
9397
|
const groups = react.useMemo(() => groupMessages(messages), [messages]);
|
|
9256
|
-
const
|
|
9398
|
+
const awaitingInput = react.useMemo(() => isAwaitingUserInput(messages), [messages]);
|
|
9399
|
+
const showWorkingOnIt = useDelayedRunningIndicator(isRunning) && !awaitingInput;
|
|
9400
|
+
const composerDisabled = disabled || awaitingInput;
|
|
9401
|
+
const composerDisabledReason = awaitingInput ? "Answer the question above to continue." : disabledReason;
|
|
9257
9402
|
const artifactFallbacks = react.useMemo(() => {
|
|
9258
9403
|
const fallbacks = {};
|
|
9259
9404
|
const createArtifactToolCallIds = [];
|
|
@@ -9356,12 +9501,12 @@ function ChatThread({
|
|
|
9356
9501
|
] }),
|
|
9357
9502
|
/* @__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: [
|
|
9358
9503
|
retryIndicator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(RetryBanner, { indicator: retryIndicator }) }),
|
|
9359
|
-
|
|
9504
|
+
composerDisabled && composerDisabledReason ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9360
9505
|
"div",
|
|
9361
9506
|
{
|
|
9362
9507
|
className: "rounded border border-line bg-muted/40 px-3 py-2 text-sm text-foreground/60",
|
|
9363
9508
|
role: "status",
|
|
9364
|
-
children:
|
|
9509
|
+
children: composerDisabledReason
|
|
9365
9510
|
}
|
|
9366
9511
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
9367
9512
|
ChatComposer,
|
|
@@ -9369,8 +9514,8 @@ function ChatThread({
|
|
|
9369
9514
|
onSend,
|
|
9370
9515
|
onStop,
|
|
9371
9516
|
isRunning,
|
|
9372
|
-
disabled,
|
|
9373
|
-
disabledReason,
|
|
9517
|
+
disabled: composerDisabled,
|
|
9518
|
+
disabledReason: composerDisabledReason,
|
|
9374
9519
|
tokenUsage,
|
|
9375
9520
|
onComposerError,
|
|
9376
9521
|
showBrowser,
|
|
@@ -9380,12 +9525,51 @@ function ChatThread({
|
|
|
9380
9525
|
canShowBrowser,
|
|
9381
9526
|
canShowWorkspace,
|
|
9382
9527
|
viewMode,
|
|
9383
|
-
onViewModeChange
|
|
9528
|
+
onViewModeChange,
|
|
9529
|
+
deepResearchEnabled
|
|
9384
9530
|
}
|
|
9385
9531
|
)
|
|
9386
9532
|
] })
|
|
9387
9533
|
] });
|
|
9388
9534
|
}
|
|
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
|
+
}
|
|
9389
9573
|
|
|
9390
9574
|
// src/components/ai-elements/file-tree.tsx
|
|
9391
9575
|
init_utils();
|
|
@@ -10132,7 +10316,8 @@ function createInitialAgentChatState(options = {}) {
|
|
|
10132
10316
|
terminal: false,
|
|
10133
10317
|
workspaceRefreshKey: 0,
|
|
10134
10318
|
browser: null,
|
|
10135
|
-
viewMode: options.viewMode ?? "simple"
|
|
10319
|
+
viewMode: options.viewMode ?? "simple",
|
|
10320
|
+
researchSources: []
|
|
10136
10321
|
};
|
|
10137
10322
|
}
|
|
10138
10323
|
function applyAgentChatEvent(state, event) {
|
|
@@ -10218,11 +10403,12 @@ function applyAgentChatEvent(state, event) {
|
|
|
10218
10403
|
const toolName = findToolNameById(nextState.messages, toolCallId);
|
|
10219
10404
|
const messages = applyToolResult(nextState.messages, event.data);
|
|
10220
10405
|
const mutatesWorkspace = toolName !== null && WORKSPACE_MUTATING_TOOLS.has(toolName);
|
|
10221
|
-
|
|
10406
|
+
const withResult = {
|
|
10222
10407
|
...nextState,
|
|
10223
10408
|
messages,
|
|
10224
10409
|
workspaceRefreshKey: mutatesWorkspace ? nextState.workspaceRefreshKey + 1 : nextState.workspaceRefreshKey
|
|
10225
10410
|
};
|
|
10411
|
+
return collectResearchSource(withResult, toolName, event.data);
|
|
10226
10412
|
}
|
|
10227
10413
|
case "harness.wake":
|
|
10228
10414
|
case "llm.request":
|
|
@@ -10954,6 +11140,32 @@ function findToolNameById(messages, toolCallId) {
|
|
|
10954
11140
|
}
|
|
10955
11141
|
return null;
|
|
10956
11142
|
}
|
|
11143
|
+
function collectResearchSource(state, toolName, data) {
|
|
11144
|
+
if (toolName !== "research_memory") return state;
|
|
11145
|
+
const rawResult = data.content ?? data.result;
|
|
11146
|
+
const resultText = typeof rawResult === "string" ? rawResult : JSON.stringify(rawResult ?? {});
|
|
11147
|
+
let parsed;
|
|
11148
|
+
try {
|
|
11149
|
+
parsed = JSON.parse(resultText);
|
|
11150
|
+
} catch {
|
|
11151
|
+
return state;
|
|
11152
|
+
}
|
|
11153
|
+
if (!parsed.success || !parsed.source_id || !parsed.url) return state;
|
|
11154
|
+
if (state.researchSources.some((s) => s.sourceId === parsed.source_id)) {
|
|
11155
|
+
return state;
|
|
11156
|
+
}
|
|
11157
|
+
return {
|
|
11158
|
+
...state,
|
|
11159
|
+
researchSources: [
|
|
11160
|
+
...state.researchSources,
|
|
11161
|
+
{
|
|
11162
|
+
sourceId: parsed.source_id,
|
|
11163
|
+
url: parsed.url,
|
|
11164
|
+
title: parsed.title ?? ""
|
|
11165
|
+
}
|
|
11166
|
+
]
|
|
11167
|
+
};
|
|
11168
|
+
}
|
|
10957
11169
|
function findLatestConsultExpertCall(messages) {
|
|
10958
11170
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
10959
11171
|
const msg = messages[i];
|
|
@@ -11403,7 +11615,8 @@ function useAgentChatRuntime({
|
|
|
11403
11615
|
markSending,
|
|
11404
11616
|
markSendError,
|
|
11405
11617
|
viewMode: state.viewMode,
|
|
11406
|
-
setViewMode
|
|
11618
|
+
setViewMode,
|
|
11619
|
+
researchSources: state.researchSources
|
|
11407
11620
|
};
|
|
11408
11621
|
}
|
|
11409
11622
|
function parseEventData(data) {
|
|
@@ -11462,7 +11675,8 @@ function AgentChat({
|
|
|
11462
11675
|
onFileSelect,
|
|
11463
11676
|
onMessagesChange,
|
|
11464
11677
|
disabled,
|
|
11465
|
-
onComposerError
|
|
11678
|
+
onComposerError,
|
|
11679
|
+
deepResearchEnabled = false
|
|
11466
11680
|
}) {
|
|
11467
11681
|
const [workspacePath, setWorkspacePath] = react.useState(null);
|
|
11468
11682
|
const [mobileView, setMobileView] = react.useState("chat");
|
|
@@ -11485,7 +11699,8 @@ function AgentChat({
|
|
|
11485
11699
|
const browserVisible = browserAvailable && showBrowser;
|
|
11486
11700
|
const workspaceAvailable = !!sessionId;
|
|
11487
11701
|
const workspaceVisible = workspaceAvailable && showWorkspace;
|
|
11488
|
-
const
|
|
11702
|
+
const sourcesVisible = runtime.researchSources.length > 0;
|
|
11703
|
+
const rightStackVisible = browserVisible || workspaceVisible || sourcesVisible;
|
|
11489
11704
|
const bothPanesVisible = browserVisible && workspaceVisible;
|
|
11490
11705
|
react.useEffect(() => {
|
|
11491
11706
|
onMessagesChange?.(runtime.messages);
|
|
@@ -11600,7 +11815,8 @@ function AgentChat({
|
|
|
11600
11815
|
canShowBrowser: browserAvailable,
|
|
11601
11816
|
canShowWorkspace: workspaceAvailable,
|
|
11602
11817
|
viewMode: runtime.viewMode,
|
|
11603
|
-
onViewModeChange: runtime.setViewMode
|
|
11818
|
+
onViewModeChange: runtime.setViewMode,
|
|
11819
|
+
deepResearchEnabled
|
|
11604
11820
|
}
|
|
11605
11821
|
)
|
|
11606
11822
|
}
|
|
@@ -11660,6 +11876,20 @@ function AgentChat({
|
|
|
11660
11876
|
}
|
|
11661
11877
|
)
|
|
11662
11878
|
}
|
|
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
|
+
}
|
|
11663
11893
|
)
|
|
11664
11894
|
]
|
|
11665
11895
|
}
|
|
@@ -12409,7 +12639,7 @@ function groupMissionTasksByBucket(tasks) {
|
|
|
12409
12639
|
function deriveMissionWorkerActivityLabel(worker) {
|
|
12410
12640
|
const kind = worker.latestEventKind;
|
|
12411
12641
|
if (kind === "tool.call" && worker.latestEventSummary) {
|
|
12412
|
-
return `tool: ${
|
|
12642
|
+
return `tool: ${truncate4(worker.latestEventSummary, 80)}`;
|
|
12413
12643
|
}
|
|
12414
12644
|
if (kind === "llm.response") {
|
|
12415
12645
|
return "thinking";
|
|
@@ -12418,11 +12648,11 @@ function deriveMissionWorkerActivityLabel(worker) {
|
|
|
12418
12648
|
return "received tool result";
|
|
12419
12649
|
}
|
|
12420
12650
|
if (kind && worker.latestEventSummary) {
|
|
12421
|
-
return `${kind}: ${
|
|
12651
|
+
return `${kind}: ${truncate4(worker.latestEventSummary, 60)}`;
|
|
12422
12652
|
}
|
|
12423
12653
|
return worker.sessionStatus || "active";
|
|
12424
12654
|
}
|
|
12425
|
-
function
|
|
12655
|
+
function truncate4(s, max) {
|
|
12426
12656
|
if (s.length <= max) return s;
|
|
12427
12657
|
return `${s.slice(0, max - 1)}\u2026`;
|
|
12428
12658
|
}
|
|
@@ -13410,6 +13640,50 @@ function MissionsPanel({
|
|
|
13410
13640
|
)) })
|
|
13411
13641
|
] });
|
|
13412
13642
|
}
|
|
13643
|
+
var CITATION_RE = /\[(S\d+(?:\s*,\s*S\d+)*)\]/g;
|
|
13644
|
+
function splitCitations(text) {
|
|
13645
|
+
if (!text) return [];
|
|
13646
|
+
const segments = [];
|
|
13647
|
+
let lastIndex = 0;
|
|
13648
|
+
for (const match of text.matchAll(CITATION_RE)) {
|
|
13649
|
+
const start = match.index ?? 0;
|
|
13650
|
+
if (start > lastIndex) {
|
|
13651
|
+
segments.push({ kind: "text", value: text.slice(lastIndex, start) });
|
|
13652
|
+
}
|
|
13653
|
+
for (const id of match[1].split(",")) {
|
|
13654
|
+
segments.push({ kind: "cite", value: id.trim() });
|
|
13655
|
+
}
|
|
13656
|
+
lastIndex = start + match[0].length;
|
|
13657
|
+
}
|
|
13658
|
+
if (lastIndex < text.length) {
|
|
13659
|
+
segments.push({ kind: "text", value: text.slice(lastIndex) });
|
|
13660
|
+
}
|
|
13661
|
+
return segments;
|
|
13662
|
+
}
|
|
13663
|
+
function CitationText({
|
|
13664
|
+
text,
|
|
13665
|
+
sources,
|
|
13666
|
+
onCitationClick
|
|
13667
|
+
}) {
|
|
13668
|
+
const byId = new Map(sources.map((s) => [s.sourceId, s]));
|
|
13669
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: splitCitations(text).map((seg, i) => {
|
|
13670
|
+
if (seg.kind === "text") {
|
|
13671
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: seg.value }, i);
|
|
13672
|
+
}
|
|
13673
|
+
const src = byId.get(seg.value);
|
|
13674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13675
|
+
"button",
|
|
13676
|
+
{
|
|
13677
|
+
type: "button",
|
|
13678
|
+
title: src ? `${src.title} \u2014 ${src.url}` : seg.value,
|
|
13679
|
+
onClick: () => onCitationClick?.(seg.value),
|
|
13680
|
+
className: "mx-0.5 inline-flex items-center rounded-sm bg-muted px-1 text-[10px] font-semibold text-primary hover:bg-primary/10",
|
|
13681
|
+
children: seg.value
|
|
13682
|
+
},
|
|
13683
|
+
i
|
|
13684
|
+
);
|
|
13685
|
+
}) });
|
|
13686
|
+
}
|
|
13413
13687
|
init_utils();
|
|
13414
13688
|
var DEFAULT_LIMIT2 = 50;
|
|
13415
13689
|
var DEFAULT_POLL_INTERVAL_MS3 = 3e4;
|
|
@@ -14088,16 +14362,19 @@ function SessionTreePanel({
|
|
|
14088
14362
|
exports.ACTIVE_MISSION_STATUSES = ACTIVE_MISSION_STATUSES;
|
|
14089
14363
|
exports.AgentChat = AgentChat;
|
|
14090
14364
|
exports.AgentChatAdapterProvider = AgentChatAdapterProvider;
|
|
14365
|
+
exports.CitationText = CitationText;
|
|
14091
14366
|
exports.InboxPanel = InboxPanel;
|
|
14092
14367
|
exports.MessageResponse = MessageResponse;
|
|
14093
14368
|
exports.MissionDashboard = MissionDashboard;
|
|
14094
14369
|
exports.MissionsPanel = MissionsPanel;
|
|
14370
|
+
exports.ResearchSourcesPanel = ResearchSourcesPanel;
|
|
14095
14371
|
exports.ScheduledWorkPanel = ScheduledWorkPanel;
|
|
14096
14372
|
exports.SessionTreePanel = SessionTreePanel;
|
|
14097
14373
|
exports.deriveMissionWorkerActivityLabel = deriveMissionWorkerActivityLabel;
|
|
14098
14374
|
exports.groupMissionTasksByBucket = groupMissionTasksByBucket;
|
|
14099
14375
|
exports.isTerminalMissionStatus = isTerminalMissionStatus;
|
|
14100
14376
|
exports.missionTaskBucket = missionTaskBucket;
|
|
14377
|
+
exports.splitCitations = splitCitations;
|
|
14101
14378
|
exports.useAgentChatAdapterContext = useAgentChatAdapterContext;
|
|
14102
14379
|
exports.useAgentChatRuntime = useAgentChatRuntime;
|
|
14103
14380
|
exports.useChatViewMode = useChatViewMode;
|