@invergent/agent-chat-react 1.6.7 → 1.6.8
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 +204 -10
- 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 +204 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2291,10 +2291,7 @@ function WebToolBlock({ tc }) {
|
|
|
2291
2291
|
let displayText = "";
|
|
2292
2292
|
try {
|
|
2293
2293
|
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") {
|
|
2294
|
+
if (tc.toolName === "web_search") {
|
|
2298
2295
|
displayText = args.query ?? "";
|
|
2299
2296
|
} else if (tc.toolName === "web_crawl") {
|
|
2300
2297
|
displayText = args.url ?? "";
|
|
@@ -2302,12 +2299,10 @@ function WebToolBlock({ tc }) {
|
|
|
2302
2299
|
} catch {
|
|
2303
2300
|
}
|
|
2304
2301
|
const toolLabel2 = {
|
|
2305
|
-
web_extract: "Web Fetch",
|
|
2306
2302
|
web_search: "Web Search",
|
|
2307
2303
|
web_crawl: "Web Crawl"
|
|
2308
2304
|
}[tc.toolName] ?? tc.toolName;
|
|
2309
2305
|
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
2306
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: toolLabel2 }),
|
|
2312
2307
|
displayText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70 truncate text-xs", children: displayText })
|
|
2313
2308
|
] });
|
|
@@ -2327,6 +2322,89 @@ function VisionAnalyzeBlock({ tc }) {
|
|
|
2327
2322
|
] });
|
|
2328
2323
|
}
|
|
2329
2324
|
init_utils();
|
|
2325
|
+
function parseUrls(rawArgs) {
|
|
2326
|
+
try {
|
|
2327
|
+
const args = JSON.parse(rawArgs);
|
|
2328
|
+
if (Array.isArray(args.urls)) {
|
|
2329
|
+
return args.urls.filter((u) => typeof u === "string");
|
|
2330
|
+
}
|
|
2331
|
+
} catch {
|
|
2332
|
+
}
|
|
2333
|
+
return [];
|
|
2334
|
+
}
|
|
2335
|
+
function parseResult(rawResult) {
|
|
2336
|
+
const byUrl = /* @__PURE__ */ new Map();
|
|
2337
|
+
if (!rawResult) return { byUrl, toolError: null };
|
|
2338
|
+
try {
|
|
2339
|
+
const parsed = JSON.parse(rawResult);
|
|
2340
|
+
const entries = Array.isArray(parsed?.results) ? parsed.results : [];
|
|
2341
|
+
for (const entry of entries) {
|
|
2342
|
+
if (entry && typeof entry.url === "string") {
|
|
2343
|
+
byUrl.set(entry.url, entry);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
if (byUrl.size === 0 && typeof parsed?.error === "string") {
|
|
2347
|
+
return { byUrl, toolError: parsed.error };
|
|
2348
|
+
}
|
|
2349
|
+
} catch {
|
|
2350
|
+
}
|
|
2351
|
+
return { byUrl, toolError: null };
|
|
2352
|
+
}
|
|
2353
|
+
function domain(url) {
|
|
2354
|
+
try {
|
|
2355
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
2356
|
+
} catch {
|
|
2357
|
+
return url;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
function WebExtractToolBlock({ tc }) {
|
|
2361
|
+
const urls = parseUrls(tc.args);
|
|
2362
|
+
const { byUrl, toolError } = parseResult(tc.result);
|
|
2363
|
+
const isComplete = tc.status === "complete" || tc.status === "error";
|
|
2364
|
+
if (urls.length === 0) {
|
|
2365
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm py-0.5", children: [
|
|
2366
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Fetch" })
|
|
2368
|
+
] });
|
|
2369
|
+
}
|
|
2370
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
2372
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
2373
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Fetch" }),
|
|
2374
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 text-xs", children: [
|
|
2375
|
+
urls.length,
|
|
2376
|
+
" URL",
|
|
2377
|
+
urls.length !== 1 ? "s" : ""
|
|
2378
|
+
] })
|
|
2379
|
+
] }),
|
|
2380
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1 ml-5 space-y-0.5", children: urls.map((url, i) => {
|
|
2381
|
+
const entry = byUrl.get(url);
|
|
2382
|
+
const perUrlError = entry?.error;
|
|
2383
|
+
const failure = perUrlError ?? (isComplete && !entry ? toolError : null);
|
|
2384
|
+
const fetched = entry && !perUrlError;
|
|
2385
|
+
const pending = !isComplete && !entry;
|
|
2386
|
+
const row = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2387
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2388
|
+
"span",
|
|
2389
|
+
{
|
|
2390
|
+
className: cn(
|
|
2391
|
+
"truncate",
|
|
2392
|
+
pending ? "text-muted-foreground/50" : "text-muted-foreground"
|
|
2393
|
+
),
|
|
2394
|
+
children: domain(url)
|
|
2395
|
+
}
|
|
2396
|
+
),
|
|
2397
|
+
fetched && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-3 text-green-500/70 shrink-0" }),
|
|
2398
|
+
failure && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-3 text-red-500/80 shrink-0" })
|
|
2399
|
+
] });
|
|
2400
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: failure ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
2401
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: row }),
|
|
2402
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: failure })
|
|
2403
|
+
] }) : row }, `${url}-${i}`);
|
|
2404
|
+
}) })
|
|
2405
|
+
] });
|
|
2406
|
+
}
|
|
2407
|
+
init_utils();
|
|
2330
2408
|
|
|
2331
2409
|
// src/components/chat/diff-viewer.tsx
|
|
2332
2410
|
init_utils();
|
|
@@ -3015,7 +3093,7 @@ function parseArgs2(args) {
|
|
|
3015
3093
|
return { action: "unknown" };
|
|
3016
3094
|
}
|
|
3017
3095
|
}
|
|
3018
|
-
function
|
|
3096
|
+
function parseResult2(result) {
|
|
3019
3097
|
if (!result) return null;
|
|
3020
3098
|
try {
|
|
3021
3099
|
return JSON.parse(result);
|
|
@@ -3233,7 +3311,7 @@ function OutputPreview({ output }) {
|
|
|
3233
3311
|
function ProcessToolBlock({ tc }) {
|
|
3234
3312
|
const isRunning = tc.status === "running";
|
|
3235
3313
|
const args = parseArgs2(tc.args);
|
|
3236
|
-
const result =
|
|
3314
|
+
const result = parseResult2(tc.result);
|
|
3237
3315
|
const action = args.action || "unknown";
|
|
3238
3316
|
const actionLabel = {
|
|
3239
3317
|
list: "Process List",
|
|
@@ -4289,6 +4367,7 @@ function ToolCallBlock({
|
|
|
4289
4367
|
case "session_search":
|
|
4290
4368
|
return /* @__PURE__ */ jsxRuntime.jsx(SessionSearchBlock, { tc });
|
|
4291
4369
|
case "web_extract":
|
|
4370
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WebExtractToolBlock, { tc });
|
|
4292
4371
|
case "web_search":
|
|
4293
4372
|
case "web_crawl":
|
|
4294
4373
|
return /* @__PURE__ */ jsxRuntime.jsx(WebToolBlock, { tc });
|
|
@@ -4330,6 +4409,51 @@ function ToolCallBlock({
|
|
|
4330
4409
|
return /* @__PURE__ */ jsxRuntime.jsx(DefaultToolBlock, { tc });
|
|
4331
4410
|
}
|
|
4332
4411
|
}
|
|
4412
|
+
function parseQuery(rawArgs) {
|
|
4413
|
+
try {
|
|
4414
|
+
const args = JSON.parse(rawArgs);
|
|
4415
|
+
return typeof args.query === "string" ? args.query : "";
|
|
4416
|
+
} catch {
|
|
4417
|
+
return "";
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
function parseResultCount2(rawResult) {
|
|
4421
|
+
if (!rawResult) return null;
|
|
4422
|
+
try {
|
|
4423
|
+
const parsed = JSON.parse(rawResult);
|
|
4424
|
+
if (Array.isArray(parsed?.data?.web)) return parsed.data.web.length;
|
|
4425
|
+
if (Array.isArray(parsed?.results)) return parsed.results.length;
|
|
4426
|
+
} catch {
|
|
4427
|
+
}
|
|
4428
|
+
return null;
|
|
4429
|
+
}
|
|
4430
|
+
function WebSearchRow({ tc }) {
|
|
4431
|
+
const query = parseQuery(tc.args);
|
|
4432
|
+
const count = parseResultCount2(tc.result);
|
|
4433
|
+
const showCount = count !== null && tc.status === "complete";
|
|
4434
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs min-w-0", children: [
|
|
4435
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: query || "\u2014" }),
|
|
4436
|
+
showCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/50 shrink-0", children: [
|
|
4437
|
+
count,
|
|
4438
|
+
" result",
|
|
4439
|
+
count !== 1 ? "s" : ""
|
|
4440
|
+
] })
|
|
4441
|
+
] });
|
|
4442
|
+
}
|
|
4443
|
+
function WebSearchGroupBlock({ tcs }) {
|
|
4444
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4445
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
4446
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-3.5 text-muted-foreground/60 shrink-0" }),
|
|
4447
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: "Web Search" }),
|
|
4448
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground/70 text-xs", children: [
|
|
4449
|
+
tcs.length,
|
|
4450
|
+
" ",
|
|
4451
|
+
tcs.length === 1 ? "query" : "queries"
|
|
4452
|
+
] })
|
|
4453
|
+
] }),
|
|
4454
|
+
/* @__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)) })
|
|
4455
|
+
] });
|
|
4456
|
+
}
|
|
4333
4457
|
var ChatMessage = react.memo(function ChatMessage2({
|
|
4334
4458
|
message,
|
|
4335
4459
|
isLast,
|
|
@@ -5756,6 +5880,11 @@ function ChatComposerInner({
|
|
|
5756
5880
|
const builtin = [
|
|
5757
5881
|
{ value: "/clear", label: "/clear", description: "Clear conversation" },
|
|
5758
5882
|
{ value: "/compress", label: "/compress", description: "Compress context" },
|
|
5883
|
+
{ value: "/goal", label: "/goal", description: "Define an outcome goal" },
|
|
5884
|
+
{ value: "/goal status", label: "/goal status", description: "Show outcome goal status" },
|
|
5885
|
+
{ value: "/goal pause", label: "/goal pause", description: "Pause automatic goal continuation" },
|
|
5886
|
+
{ value: "/goal resume", label: "/goal resume", description: "Resume a paused goal" },
|
|
5887
|
+
{ value: "/goal clear", label: "/goal clear", description: "Clear the current goal" },
|
|
5759
5888
|
{ value: "/loop", label: "/loop", description: "Schedule recurring prompt" },
|
|
5760
5889
|
{ value: "/loop list", label: "/loop list", description: "List active loops" },
|
|
5761
5890
|
{ value: "/loop cancel", label: "/loop cancel", description: "Cancel a loop by ID" }
|
|
@@ -6589,6 +6718,33 @@ function groupBrowserActivityEntries(entries) {
|
|
|
6589
6718
|
function isBrowserToolCall(call) {
|
|
6590
6719
|
return call.toolName.startsWith("browser_");
|
|
6591
6720
|
}
|
|
6721
|
+
function groupWebSearchEntries(entries) {
|
|
6722
|
+
const grouped = [];
|
|
6723
|
+
let buffer = [];
|
|
6724
|
+
const flush = () => {
|
|
6725
|
+
if (buffer.length === 0) return;
|
|
6726
|
+
if (buffer.length === 1) {
|
|
6727
|
+
grouped.push({ kind: "tool", key: buffer[0].id, tc: buffer[0] });
|
|
6728
|
+
} else {
|
|
6729
|
+
grouped.push({
|
|
6730
|
+
kind: "web_search_group",
|
|
6731
|
+
key: `web-search-${buffer[0].id}-${buffer[buffer.length - 1].id}`,
|
|
6732
|
+
calls: buffer
|
|
6733
|
+
});
|
|
6734
|
+
}
|
|
6735
|
+
buffer = [];
|
|
6736
|
+
};
|
|
6737
|
+
for (const entry of entries) {
|
|
6738
|
+
if (entry.kind === "tool" && entry.tc.toolName === "web_search") {
|
|
6739
|
+
buffer.push(entry.tc);
|
|
6740
|
+
continue;
|
|
6741
|
+
}
|
|
6742
|
+
flush();
|
|
6743
|
+
grouped.push(entry);
|
|
6744
|
+
}
|
|
6745
|
+
flush();
|
|
6746
|
+
return grouped;
|
|
6747
|
+
}
|
|
6592
6748
|
function groupMessages(messages) {
|
|
6593
6749
|
const groups = [];
|
|
6594
6750
|
let pendingSystem = [];
|
|
@@ -6754,6 +6910,18 @@ function TimelineEntryItem({
|
|
|
6754
6910
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(BrowserActivityGroup, { calls: entry.calls }) })
|
|
6755
6911
|
] });
|
|
6756
6912
|
}
|
|
6913
|
+
if (entry.kind === "web_search_group") {
|
|
6914
|
+
const allComplete = entry.calls.every((tc) => tc.status === "complete");
|
|
6915
|
+
const anyRunning = entry.calls.some((tc) => tc.status === "running");
|
|
6916
|
+
const indicatorClass = anyRunning ? "bg-emerald-500 animate-pulse" : allComplete ? "bg-emerald-500" : "bg-red-500";
|
|
6917
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6918
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
6919
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
6920
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineIndicator, { className: cn("size-2 border-none", indicatorClass) })
|
|
6921
|
+
] }),
|
|
6922
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: /* @__PURE__ */ jsxRuntime.jsx(WebSearchGroupBlock, { tcs: entry.calls }) })
|
|
6923
|
+
] });
|
|
6924
|
+
}
|
|
6757
6925
|
if (entry.kind === "text") {
|
|
6758
6926
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6759
6927
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
@@ -6821,6 +6989,7 @@ function AssistantGroup({
|
|
|
6821
6989
|
entries.push(...messageToEntries(messages[i], isLast, artifactFallbacks));
|
|
6822
6990
|
}
|
|
6823
6991
|
entries = groupBrowserActivityEntries(entries);
|
|
6992
|
+
entries = groupWebSearchEntries(entries);
|
|
6824
6993
|
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
6825
6994
|
const lastEntry = entries[entries.length - 1];
|
|
6826
6995
|
const hasRunningTool = entries.some(
|
|
@@ -8985,11 +9154,12 @@ function useAgentChatRuntime({
|
|
|
8985
9154
|
const send = react.useCallback(
|
|
8986
9155
|
async (content, images) => {
|
|
8987
9156
|
markSending(content, images);
|
|
9157
|
+
const goal = images?.length ? null : parseGoalDefinition(content);
|
|
8988
9158
|
if (!sessionId) {
|
|
8989
9159
|
try {
|
|
8990
9160
|
const session2 = await adapter.createSession({ agentId });
|
|
8991
9161
|
onSessionChange?.(session2.id);
|
|
8992
|
-
await adapter
|
|
9162
|
+
await sendTurn(adapter, session2.id, content, images, goal);
|
|
8993
9163
|
} catch (error) {
|
|
8994
9164
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
8995
9165
|
throw error;
|
|
@@ -8998,7 +9168,7 @@ function useAgentChatRuntime({
|
|
|
8998
9168
|
}
|
|
8999
9169
|
try {
|
|
9000
9170
|
ensureStreamForNewTurn(sessionId);
|
|
9001
|
-
await adapter
|
|
9171
|
+
await sendTurn(adapter, sessionId, content, images, goal);
|
|
9002
9172
|
} catch (error) {
|
|
9003
9173
|
markSendError(error instanceof Error ? error.message : "send failed");
|
|
9004
9174
|
throw error;
|
|
@@ -9071,6 +9241,30 @@ function findLastAssistantIndex2(messages) {
|
|
|
9071
9241
|
}
|
|
9072
9242
|
return -1;
|
|
9073
9243
|
}
|
|
9244
|
+
var GOAL_RUBRIC_RE = /\n\s*(?:rubric|criteria)\s*:\s*\n/i;
|
|
9245
|
+
var GOAL_CONTROL_COMMANDS = /* @__PURE__ */ new Set(["", "status", "pause", "resume", "clear"]);
|
|
9246
|
+
async function sendTurn(adapter, sessionId, content, images, goal) {
|
|
9247
|
+
if (goal && adapter.defineOutcome) {
|
|
9248
|
+
await adapter.defineOutcome({
|
|
9249
|
+
sessionId,
|
|
9250
|
+
description: goal.description,
|
|
9251
|
+
rubric: goal.rubric
|
|
9252
|
+
});
|
|
9253
|
+
return;
|
|
9254
|
+
}
|
|
9255
|
+
await adapter.sendMessage({ sessionId, content, images });
|
|
9256
|
+
}
|
|
9257
|
+
function parseGoalDefinition(content) {
|
|
9258
|
+
const text = content.trim();
|
|
9259
|
+
if (text !== "/goal" && !text.startsWith("/goal ")) return null;
|
|
9260
|
+
const args = text.slice("/goal".length).trim();
|
|
9261
|
+
if (GOAL_CONTROL_COMMANDS.has(args.toLowerCase())) return null;
|
|
9262
|
+
const match = GOAL_RUBRIC_RE.exec(args);
|
|
9263
|
+
const description = (match ? args.slice(0, match.index) : args).trim();
|
|
9264
|
+
if (!description) return null;
|
|
9265
|
+
const rubric = match ? args.slice(match.index + match[0].length).trim() : "";
|
|
9266
|
+
return rubric ? { description, rubric } : { description };
|
|
9267
|
+
}
|
|
9074
9268
|
function AgentChat({
|
|
9075
9269
|
adapter,
|
|
9076
9270
|
agentId,
|