@invergent/agent-chat-react 1.6.7 → 1.6.9
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 +226 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +227 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -908,8 +908,7 @@ var useReasoning = () => {
|
|
|
908
908
|
}
|
|
909
909
|
return context;
|
|
910
910
|
};
|
|
911
|
-
var
|
|
912
|
-
var AUTO_OPEN_DELAY = 100;
|
|
911
|
+
var MIN_DURATION_MS = 100;
|
|
913
912
|
var MS_IN_S = 1e3;
|
|
914
913
|
var Reasoning = react.memo(
|
|
915
914
|
({
|
|
@@ -923,7 +922,6 @@ var Reasoning = react.memo(
|
|
|
923
922
|
...props
|
|
924
923
|
}) => {
|
|
925
924
|
const resolvedDefaultOpen = defaultOpen ?? false;
|
|
926
|
-
const isExplicitlyClosed = defaultOpen === false;
|
|
927
925
|
const [isOpen, setIsOpen] = reactUseControllableState.useControllableState({
|
|
928
926
|
defaultProp: resolvedDefaultOpen,
|
|
929
927
|
onChange: onOpenChange,
|
|
@@ -933,8 +931,6 @@ var Reasoning = react.memo(
|
|
|
933
931
|
defaultProp: void 0,
|
|
934
932
|
prop: durationProp
|
|
935
933
|
});
|
|
936
|
-
const hasEverStreamedRef = react.useRef(false);
|
|
937
|
-
const [hasAutoClosed, setHasAutoClosed] = react.useState(false);
|
|
938
934
|
const startTimeRef = react.useRef(null);
|
|
939
935
|
react.useEffect(() => {
|
|
940
936
|
if (isStreaming) {
|
|
@@ -944,29 +940,11 @@ var Reasoning = react.memo(
|
|
|
944
940
|
} else if (startTimeRef.current !== null) {
|
|
945
941
|
const elapsed = Date.now() - startTimeRef.current;
|
|
946
942
|
startTimeRef.current = null;
|
|
947
|
-
if (elapsed >=
|
|
948
|
-
hasEverStreamedRef.current = true;
|
|
943
|
+
if (elapsed >= MIN_DURATION_MS) {
|
|
949
944
|
setDuration(Math.ceil(elapsed / MS_IN_S));
|
|
950
945
|
}
|
|
951
946
|
}
|
|
952
947
|
}, [isStreaming, setDuration]);
|
|
953
|
-
react.useEffect(() => {
|
|
954
|
-
if (!isStreaming || isOpen || isExplicitlyClosed) return;
|
|
955
|
-
const timer = setTimeout(() => {
|
|
956
|
-
hasEverStreamedRef.current = true;
|
|
957
|
-
setIsOpen(true);
|
|
958
|
-
}, AUTO_OPEN_DELAY);
|
|
959
|
-
return () => clearTimeout(timer);
|
|
960
|
-
}, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);
|
|
961
|
-
react.useEffect(() => {
|
|
962
|
-
if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {
|
|
963
|
-
const timer = setTimeout(() => {
|
|
964
|
-
setIsOpen(false);
|
|
965
|
-
setHasAutoClosed(true);
|
|
966
|
-
}, AUTO_CLOSE_DELAY);
|
|
967
|
-
return () => clearTimeout(timer);
|
|
968
|
-
}
|
|
969
|
-
}, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);
|
|
970
948
|
const handleOpenChange = react.useCallback(
|
|
971
949
|
(newOpen) => {
|
|
972
950
|
setIsOpen(newOpen);
|
|
@@ -1392,7 +1370,7 @@ function TerminalCollapsible({ command, output, isRunning, hasError }) {
|
|
|
1392
1370
|
className: "not-prose w-full",
|
|
1393
1371
|
children: [
|
|
1394
1372
|
/* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
|
|
1395
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : hasError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-destructive", children: "Command failed" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "Command
|
|
1373
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : hasError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-destructive", children: "Command failed" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "Command" }) }),
|
|
1396
1374
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1397
1375
|
lucideReact.ChevronDownIcon,
|
|
1398
1376
|
{
|
|
@@ -1443,14 +1421,16 @@ function TerminalToolBlock({ tc }) {
|
|
|
1443
1421
|
const isRunning = tc.status === "running";
|
|
1444
1422
|
const result = parseTerminalResult(tc.result, tc.args);
|
|
1445
1423
|
if (result) {
|
|
1446
|
-
const
|
|
1424
|
+
const hasError = result.exit_code !== 0 || Boolean(result.error);
|
|
1425
|
+
if (hasError) return null;
|
|
1426
|
+
const output = result.output || "";
|
|
1447
1427
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1448
1428
|
TerminalCollapsible,
|
|
1449
1429
|
{
|
|
1450
1430
|
command: result.command,
|
|
1451
1431
|
output,
|
|
1452
1432
|
isRunning,
|
|
1453
|
-
hasError:
|
|
1433
|
+
hasError: false
|
|
1454
1434
|
}
|
|
1455
1435
|
);
|
|
1456
1436
|
}
|
|
@@ -2291,10 +2271,7 @@ function WebToolBlock({ tc }) {
|
|
|
2291
2271
|
let displayText = "";
|
|
2292
2272
|
try {
|
|
2293
2273
|
const args = JSON.parse(tc.args);
|
|
2294
|
-
if (tc.toolName === "
|
|
2295
|
-
const urls = args.urls ?? [];
|
|
2296
|
-
displayText = urls[0] ?? "";
|
|
2297
|
-
} else if (tc.toolName === "web_search") {
|
|
2274
|
+
if (tc.toolName === "web_search") {
|
|
2298
2275
|
displayText = args.query ?? "";
|
|
2299
2276
|
} else if (tc.toolName === "web_crawl") {
|
|
2300
2277
|
displayText = args.url ?? "";
|
|
@@ -2302,12 +2279,10 @@ function WebToolBlock({ tc }) {
|
|
|
2302
2279
|
} catch {
|
|
2303
2280
|
}
|
|
2304
2281
|
const toolLabel2 = {
|
|
2305
|
-
web_extract: "Web Fetch",
|
|
2306
2282
|
web_search: "Web Search",
|
|
2307
2283
|
web_crawl: "Web Crawl"
|
|
2308
2284
|
}[tc.toolName] ?? tc.toolName;
|
|
2309
2285
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm py-0.5", children: [
|
|
2310
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2311
2286
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: toolLabel2 }),
|
|
2312
2287
|
displayText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70 truncate text-xs", children: displayText })
|
|
2313
2288
|
] });
|
|
@@ -2327,6 +2302,89 @@ function VisionAnalyzeBlock({ tc }) {
|
|
|
2327
2302
|
] });
|
|
2328
2303
|
}
|
|
2329
2304
|
init_utils();
|
|
2305
|
+
function parseUrls(rawArgs) {
|
|
2306
|
+
try {
|
|
2307
|
+
const args = JSON.parse(rawArgs);
|
|
2308
|
+
if (Array.isArray(args.urls)) {
|
|
2309
|
+
return args.urls.filter((u) => typeof u === "string");
|
|
2310
|
+
}
|
|
2311
|
+
} catch {
|
|
2312
|
+
}
|
|
2313
|
+
return [];
|
|
2314
|
+
}
|
|
2315
|
+
function parseResult(rawResult) {
|
|
2316
|
+
const byUrl = /* @__PURE__ */ new Map();
|
|
2317
|
+
if (!rawResult) return { byUrl, toolError: null };
|
|
2318
|
+
try {
|
|
2319
|
+
const parsed = JSON.parse(rawResult);
|
|
2320
|
+
const entries = Array.isArray(parsed?.results) ? parsed.results : [];
|
|
2321
|
+
for (const entry of entries) {
|
|
2322
|
+
if (entry && typeof entry.url === "string") {
|
|
2323
|
+
byUrl.set(entry.url, entry);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
if (byUrl.size === 0 && typeof parsed?.error === "string") {
|
|
2327
|
+
return { byUrl, toolError: parsed.error };
|
|
2328
|
+
}
|
|
2329
|
+
} catch {
|
|
2330
|
+
}
|
|
2331
|
+
return { byUrl, toolError: null };
|
|
2332
|
+
}
|
|
2333
|
+
function domain(url) {
|
|
2334
|
+
try {
|
|
2335
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
2336
|
+
} catch {
|
|
2337
|
+
return url;
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
function WebExtractToolBlock({ tc }) {
|
|
2341
|
+
const urls = parseUrls(tc.args);
|
|
2342
|
+
const { byUrl, toolError } = parseResult(tc.result);
|
|
2343
|
+
const isComplete = tc.status === "complete" || tc.status === "error";
|
|
2344
|
+
if (urls.length === 0) {
|
|
2345
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm py-0.5", children: [
|
|
2346
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2347
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Fetch" })
|
|
2348
|
+
] });
|
|
2349
|
+
}
|
|
2350
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
2352
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Fetch" }),
|
|
2354
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 text-xs", children: [
|
|
2355
|
+
urls.length,
|
|
2356
|
+
" URL",
|
|
2357
|
+
urls.length !== 1 ? "s" : ""
|
|
2358
|
+
] })
|
|
2359
|
+
] }),
|
|
2360
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1 ml-5 space-y-0.5", children: urls.map((url, i) => {
|
|
2361
|
+
const entry = byUrl.get(url);
|
|
2362
|
+
const perUrlError = entry?.error;
|
|
2363
|
+
const failure = perUrlError ?? (isComplete && !entry ? toolError : null);
|
|
2364
|
+
const fetched = entry && !perUrlError;
|
|
2365
|
+
const pending = !isComplete && !entry;
|
|
2366
|
+
const row = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2368
|
+
"span",
|
|
2369
|
+
{
|
|
2370
|
+
className: cn(
|
|
2371
|
+
"truncate",
|
|
2372
|
+
pending ? "text-muted-foreground/50" : "text-muted-foreground"
|
|
2373
|
+
),
|
|
2374
|
+
children: domain(url)
|
|
2375
|
+
}
|
|
2376
|
+
),
|
|
2377
|
+
fetched && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-3 text-green-500/70 shrink-0" }),
|
|
2378
|
+
failure && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-3 text-red-500/80 shrink-0" })
|
|
2379
|
+
] });
|
|
2380
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: failure ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
2381
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: row }),
|
|
2382
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: failure })
|
|
2383
|
+
] }) : row }, `${url}-${i}`);
|
|
2384
|
+
}) })
|
|
2385
|
+
] });
|
|
2386
|
+
}
|
|
2387
|
+
init_utils();
|
|
2330
2388
|
|
|
2331
2389
|
// src/components/chat/diff-viewer.tsx
|
|
2332
2390
|
init_utils();
|
|
@@ -3015,7 +3073,7 @@ function parseArgs2(args) {
|
|
|
3015
3073
|
return { action: "unknown" };
|
|
3016
3074
|
}
|
|
3017
3075
|
}
|
|
3018
|
-
function
|
|
3076
|
+
function parseResult2(result) {
|
|
3019
3077
|
if (!result) return null;
|
|
3020
3078
|
try {
|
|
3021
3079
|
return JSON.parse(result);
|
|
@@ -3233,7 +3291,7 @@ function OutputPreview({ output }) {
|
|
|
3233
3291
|
function ProcessToolBlock({ tc }) {
|
|
3234
3292
|
const isRunning = tc.status === "running";
|
|
3235
3293
|
const args = parseArgs2(tc.args);
|
|
3236
|
-
const result =
|
|
3294
|
+
const result = parseResult2(tc.result);
|
|
3237
3295
|
const action = args.action || "unknown";
|
|
3238
3296
|
const actionLabel = {
|
|
3239
3297
|
list: "Process List",
|
|
@@ -4289,6 +4347,7 @@ function ToolCallBlock({
|
|
|
4289
4347
|
case "session_search":
|
|
4290
4348
|
return /* @__PURE__ */ jsxRuntime.jsx(SessionSearchBlock, { tc });
|
|
4291
4349
|
case "web_extract":
|
|
4350
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WebExtractToolBlock, { tc });
|
|
4292
4351
|
case "web_search":
|
|
4293
4352
|
case "web_crawl":
|
|
4294
4353
|
return /* @__PURE__ */ jsxRuntime.jsx(WebToolBlock, { tc });
|
|
@@ -4330,6 +4389,51 @@ function ToolCallBlock({
|
|
|
4330
4389
|
return /* @__PURE__ */ jsxRuntime.jsx(DefaultToolBlock, { tc });
|
|
4331
4390
|
}
|
|
4332
4391
|
}
|
|
4392
|
+
function parseQuery(rawArgs) {
|
|
4393
|
+
try {
|
|
4394
|
+
const args = JSON.parse(rawArgs);
|
|
4395
|
+
return typeof args.query === "string" ? args.query : "";
|
|
4396
|
+
} catch {
|
|
4397
|
+
return "";
|
|
4398
|
+
}
|
|
4399
|
+
}
|
|
4400
|
+
function parseResultCount2(rawResult) {
|
|
4401
|
+
if (!rawResult) return null;
|
|
4402
|
+
try {
|
|
4403
|
+
const parsed = JSON.parse(rawResult);
|
|
4404
|
+
if (Array.isArray(parsed?.data?.web)) return parsed.data.web.length;
|
|
4405
|
+
if (Array.isArray(parsed?.results)) return parsed.results.length;
|
|
4406
|
+
} catch {
|
|
4407
|
+
}
|
|
4408
|
+
return null;
|
|
4409
|
+
}
|
|
4410
|
+
function WebSearchRow({ tc }) {
|
|
4411
|
+
const query = parseQuery(tc.args);
|
|
4412
|
+
const count = parseResultCount2(tc.result);
|
|
4413
|
+
const showCount = count !== null && tc.status === "complete";
|
|
4414
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs min-w-0", children: [
|
|
4415
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: query || "\u2014" }),
|
|
4416
|
+
showCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/50 shrink-0", children: [
|
|
4417
|
+
count,
|
|
4418
|
+
" result",
|
|
4419
|
+
count !== 1 ? "s" : ""
|
|
4420
|
+
] })
|
|
4421
|
+
] });
|
|
4422
|
+
}
|
|
4423
|
+
function WebSearchGroupBlock({ tcs }) {
|
|
4424
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4425
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
4426
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
4427
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Search" }),
|
|
4428
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 text-xs", children: [
|
|
4429
|
+
tcs.length,
|
|
4430
|
+
" ",
|
|
4431
|
+
tcs.length === 1 ? "query" : "queries"
|
|
4432
|
+
] })
|
|
4433
|
+
] }),
|
|
4434
|
+
/* @__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)) })
|
|
4435
|
+
] });
|
|
4436
|
+
}
|
|
4333
4437
|
var ChatMessage = react.memo(function ChatMessage2({
|
|
4334
4438
|
message,
|
|
4335
4439
|
isLast,
|
|
@@ -5756,6 +5860,11 @@ function ChatComposerInner({
|
|
|
5756
5860
|
const builtin = [
|
|
5757
5861
|
{ value: "/clear", label: "/clear", description: "Clear conversation" },
|
|
5758
5862
|
{ value: "/compress", label: "/compress", description: "Compress context" },
|
|
5863
|
+
{ value: "/goal", label: "/goal", description: "Define an outcome goal" },
|
|
5864
|
+
{ value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
|
|
5865
|
+
{ value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
|
|
5866
|
+
{ value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
|
|
5867
|
+
{ value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
|
|
5759
5868
|
{ value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
|
|
5760
5869
|
{ value: "/loop list", label: "/loop list", description: "List active loops" },
|
|
5761
5870
|
{ value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
|
|
@@ -6549,6 +6658,10 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
6549
6658
|
});
|
|
6550
6659
|
continue;
|
|
6551
6660
|
}
|
|
6661
|
+
if (tc.toolName === "terminal" && tc.status !== "running") {
|
|
6662
|
+
const parsed = parseTerminalResult(tc.result, tc.args);
|
|
6663
|
+
if (parsed && (parsed.exit_code !== 0 || parsed.error)) continue;
|
|
6664
|
+
}
|
|
6552
6665
|
entries.push({ kind: "tool", key: tc.id, tc });
|
|
6553
6666
|
}
|
|
6554
6667
|
}
|
|
@@ -6589,6 +6702,33 @@ function groupBrowserActivityEntries(entries) {
|
|
|
6589
6702
|
function isBrowserToolCall(call) {
|
|
6590
6703
|
return call.toolName.startsWith("browser_");
|
|
6591
6704
|
}
|
|
6705
|
+
function groupWebSearchEntries(entries) {
|
|
6706
|
+
const grouped = [];
|
|
6707
|
+
let buffer = [];
|
|
6708
|
+
const flush = () => {
|
|
6709
|
+
if (buffer.length === 0) return;
|
|
6710
|
+
if (buffer.length === 1) {
|
|
6711
|
+
grouped.push({ kind: "tool", key: buffer[0].id, tc: buffer[0] });
|
|
6712
|
+
} else {
|
|
6713
|
+
grouped.push({
|
|
6714
|
+
kind: "web_search_group",
|
|
6715
|
+
key: `web-search-${buffer[0].id}-${buffer[buffer.length - 1].id}`,
|
|
6716
|
+
calls: buffer
|
|
6717
|
+
});
|
|
6718
|
+
}
|
|
6719
|
+
buffer = [];
|
|
6720
|
+
};
|
|
6721
|
+
for (const entry of entries) {
|
|
6722
|
+
if (entry.kind === "tool" && entry.tc.toolName === "web_search") {
|
|
6723
|
+
buffer.push(entry.tc);
|
|
6724
|
+
continue;
|
|
6725
|
+
}
|
|
6726
|
+
flush();
|
|
6727
|
+
grouped.push(entry);
|
|
6728
|
+
}
|
|
6729
|
+
flush();
|
|
6730
|
+
return grouped;
|
|
6731
|
+
}
|
|
6592
6732
|
function groupMessages(messages) {
|
|
6593
6733
|
const groups = [];
|
|
6594
6734
|
let pendingSystem = [];
|
|
@@ -6754,6 +6894,18 @@ function TimelineEntryItem({
|
|
|
6754
6894
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(BrowserActivityGroup, { calls: entry.calls }) })
|
|
6755
6895
|
] });
|
|
6756
6896
|
}
|
|
6897
|
+
if (entry.kind === "web_search_group") {
|
|
6898
|
+
const allComplete = entry.calls.every((tc) => tc.status === "complete");
|
|
6899
|
+
const anyRunning = entry.calls.some((tc) => tc.status === "running");
|
|
6900
|
+
const indicatorClass = anyRunning ? "bg-emerald-500 animate-pulse" : allComplete ? "bg-emerald-500" : "bg-red-500";
|
|
6901
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6902
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
6903
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
6904
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineIndicator, { className: cn("size-2 border-none", indicatorClass) })
|
|
6905
|
+
] }),
|
|
6906
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(WebSearchGroupBlock, { tcs: entry.calls }) })
|
|
6907
|
+
] });
|
|
6908
|
+
}
|
|
6757
6909
|
if (entry.kind === "text") {
|
|
6758
6910
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6759
6911
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
@@ -6821,6 +6973,7 @@ function AssistantGroup({
|
|
|
6821
6973
|
entries.push(...messageToEntries(messages[i], isLast, artifactFallbacks));
|
|
6822
6974
|
}
|
|
6823
6975
|
entries = groupBrowserActivityEntries(entries);
|
|
6976
|
+
entries = groupWebSearchEntries(entries);
|
|
6824
6977
|
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
6825
6978
|
const lastEntry = entries[entries.length - 1];
|
|
6826
6979
|
const hasRunningTool = entries.some(
|
|
@@ -8985,11 +9138,12 @@ function useAgentChatRuntime({
|
|
|
8985
9138
|
const send = react.useCallback(
|
|
8986
9139
|
async (content, images) => {
|
|
8987
9140
|
markSending(content, images);
|
|
9141
|
+
const goal = images?.length ? null : parseGoalDefinition(content);
|
|
8988
9142
|
if (!sessionId) {
|
|
8989
9143
|
try {
|
|
8990
9144
|
const session2 = await adapter.createSession({ agentId });
|
|
8991
9145
|
onSessionChange?.(session2.id);
|
|
8992
|
-
await adapter
|
|
9146
|
+
await sendTurn(adapter, session2.id, content, images, goal);
|
|
8993
9147
|
} catch (error) {
|
|
8994
9148
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
8995
9149
|
throw error;
|
|
@@ -8998,7 +9152,7 @@ function useAgentChatRuntime({
|
|
|
8998
9152
|
}
|
|
8999
9153
|
try {
|
|
9000
9154
|
ensureStreamForNewTurn(sessionId);
|
|
9001
|
-
await adapter
|
|
9155
|
+
await sendTurn(adapter, sessionId, content, images, goal);
|
|
9002
9156
|
} catch (error) {
|
|
9003
9157
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
9004
9158
|
throw error;
|
|
@@ -9071,6 +9225,30 @@ function findLastAssistantIndex2(messages) {
|
|
|
9071
9225
|
}
|
|
9072
9226
|
return -1;
|
|
9073
9227
|
}
|
|
9228
|
+
var GOAL_RUBRIC_RE = /\n\s*(?:rubric|criteria)\s*:\s*\n/i;
|
|
9229
|
+
var GOAL_CONTROL_COMMANDS = /* @__PURE__ */ new Set(["", "status", "pause", "resume", "clear"]);
|
|
9230
|
+
async function sendTurn(adapter, sessionId, content, images, goal) {
|
|
9231
|
+
if (goal && adapter.defineOutcome) {
|
|
9232
|
+
await adapter.defineOutcome({
|
|
9233
|
+
sessionId,
|
|
9234
|
+
description: goal.description,
|
|
9235
|
+
rubric: goal.rubric
|
|
9236
|
+
});
|
|
9237
|
+
return;
|
|
9238
|
+
}
|
|
9239
|
+
await adapter.sendMessage({ sessionId, content, images });
|
|
9240
|
+
}
|
|
9241
|
+
function parseGoalDefinition(content) {
|
|
9242
|
+
const text = content.trim();
|
|
9243
|
+
if (text !== "/goal" && !text.startsWith("/goal ")) return null;
|
|
9244
|
+
const args = text.slice("/goal".length).trim();
|
|
9245
|
+
if (GOAL_CONTROL_COMMANDS.has(args.toLowerCase())) return null;
|
|
9246
|
+
const match = GOAL_RUBRIC_RE.exec(args);
|
|
9247
|
+
const description = (match ? args.slice(0, match.index) : args).trim();
|
|
9248
|
+
if (!description) return null;
|
|
9249
|
+
const rubric = match ? args.slice(match.index + match[0].length).trim() : "";
|
|
9250
|
+
return rubric ? { description, rubric } : { description };
|
|
9251
|
+
}
|
|
9074
9252
|
function AgentChat({
|
|
9075
9253
|
adapter,
|
|
9076
9254
|
agentId,
|
|
@@ -9168,7 +9346,7 @@ function AgentChat({
|
|
|
9168
9346
|
"div",
|
|
9169
9347
|
{
|
|
9170
9348
|
"data-testid": "workspace-panel-frame",
|
|
9171
|
-
className: hasBrowserPanel ? "h-1/2 min-h-0 w-full overflow-hidden" : "min-h-0",
|
|
9349
|
+
className: hasBrowserPanel ? "h-1/2 min-h-0 w-full overflow-hidden" : "min-h-0 h-full",
|
|
9172
9350
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9173
9351
|
WorkspacePanel,
|
|
9174
9352
|
{
|
|
@@ -9887,10 +10065,11 @@ function formatKind(value) {
|
|
|
9887
10065
|
if (!value) return "Scheduled";
|
|
9888
10066
|
return value.split(/[_-]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
9889
10067
|
}
|
|
9890
|
-
function formatRelative2(value, label) {
|
|
10068
|
+
function formatRelative2(value, label, future = false) {
|
|
9891
10069
|
if (!value) return null;
|
|
9892
10070
|
const date = new Date(value);
|
|
9893
10071
|
if (Number.isNaN(date.getTime())) return null;
|
|
10072
|
+
if (future && date.getTime() <= Date.now()) return `${label} due now`;
|
|
9894
10073
|
return `${label} ${dateFns.formatDistanceToNow(date, { addSuffix: true })}`;
|
|
9895
10074
|
}
|
|
9896
10075
|
function formatRuns(count) {
|
|
@@ -9937,10 +10116,10 @@ function ScheduledWorkRow({
|
|
|
9937
10116
|
const lastSessionId = item.lastSessionId ?? null;
|
|
9938
10117
|
const meta = [
|
|
9939
10118
|
scheduleDisplay(item),
|
|
9940
|
-
formatRelative2(item.nextRunAt, "Next"),
|
|
10119
|
+
formatRelative2(item.nextRunAt, "Next", true),
|
|
9941
10120
|
formatRelative2(item.lastRunAt, "Last"),
|
|
9942
10121
|
formatRuns(item.runCount),
|
|
9943
|
-
item.expiresAt ? formatRelative2(item.expiresAt, "Expires") : null
|
|
10122
|
+
item.expiresAt ? formatRelative2(item.expiresAt, "Expires", true) : null
|
|
9944
10123
|
].filter(Boolean);
|
|
9945
10124
|
const openLastRun = () => {
|
|
9946
10125
|
if (lastSessionId) onOpenLastRun(lastSessionId);
|
|
@@ -10292,8 +10471,7 @@ function TreeNodeRow({
|
|
|
10292
10471
|
const title = entry.title ?? fallbackSessionTitle(entry);
|
|
10293
10472
|
const subtitle = [
|
|
10294
10473
|
formatRunKind(entry.runKind),
|
|
10295
|
-
entry.agentType,
|
|
10296
|
-
entry.model ?? "default",
|
|
10474
|
+
entry.model ?? entry.agentType,
|
|
10297
10475
|
formatSessionTime(entry.updatedAt)
|
|
10298
10476
|
].filter(Boolean).join(" \xB7 ");
|
|
10299
10477
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -10348,7 +10526,10 @@ function TreeNodeRow({
|
|
|
10348
10526
|
"button",
|
|
10349
10527
|
{
|
|
10350
10528
|
type: "button",
|
|
10351
|
-
className:
|
|
10529
|
+
className: cn(
|
|
10530
|
+
"p-1 rounded hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none transition-all",
|
|
10531
|
+
deletingSessionId === entry.id ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"
|
|
10532
|
+
),
|
|
10352
10533
|
onClick: (e) => {
|
|
10353
10534
|
e.stopPropagation();
|
|
10354
10535
|
onDelete(entry.id);
|
|
@@ -10356,7 +10537,7 @@ function TreeNodeRow({
|
|
|
10356
10537
|
"aria-label": "Delete session",
|
|
10357
10538
|
title: "Delete session",
|
|
10358
10539
|
disabled: deletingSessionId === entry.id,
|
|
10359
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2Icon, { className: "w-3 h-3" })
|
|
10540
|
+
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" })
|
|
10360
10541
|
}
|
|
10361
10542
|
)
|
|
10362
10543
|
]
|