@agent-native/core 0.12.31 → 0.12.32
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/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +189 -35
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/components/ui/hover-card.d.ts +7 -0
- package/dist/client/components/ui/hover-card.d.ts.map +1 -0
- package/dist/client/components/ui/hover-card.js +10 -0
- package/dist/client/components/ui/hover-card.js.map +1 -0
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +3 -2
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +42 -5
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +18 -2
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +18 -2
- package/dist/server/onboarding-html.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AA4Bf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ import { ThumbsFeedback } from "./observability/ThumbsFeedback.js";
|
|
|
23
23
|
import { TiptapComposer, } from "./composer/TiptapComposer.js";
|
|
24
24
|
import { isPastedTextAttachmentName } from "./composer/pasted-text.js";
|
|
25
25
|
import { PastedTextChip } from "./composer/PastedTextChip.js";
|
|
26
|
-
import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, IconClipboardList, } from "@tabler/icons-react";
|
|
26
|
+
import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, IconClipboardList, IconSearch, IconArrowsMaximize, IconArrowsMinimize, } from "@tabler/icons-react";
|
|
27
27
|
class BinaryDocumentAttachmentAdapter {
|
|
28
28
|
accept = "application/pdf,.pdf";
|
|
29
29
|
async add(state) {
|
|
@@ -207,6 +207,11 @@ const markdownStyles = `
|
|
|
207
207
|
.dark .agent-markdown-shiki pre { background: var(--shiki-dark-bg); color: var(--shiki-dark); }
|
|
208
208
|
.dark .agent-markdown-shiki pre span { color: var(--shiki-dark); background: var(--shiki-dark-bg); }
|
|
209
209
|
@media (prefers-color-scheme: dark) { :root:not(.light) .agent-markdown-shiki pre { background: var(--shiki-dark-bg); color: var(--shiki-dark); } :root:not(.light) .agent-markdown-shiki pre span { color: var(--shiki-dark); background: var(--shiki-dark-bg); } }
|
|
210
|
+
.agent-tool-code .agent-markdown-shiki { margin: 0; border-radius: 0; min-width: max-content; }
|
|
211
|
+
.agent-tool-code .agent-markdown-shiki pre { padding: 0.75rem; border: 0; background: transparent; }
|
|
212
|
+
.agent-tool-code .agent-markdown-shiki pre span { background: transparent; }
|
|
213
|
+
.agent-tool-code pre { margin: 0; min-width: max-content; padding: 0.75rem; background: transparent; color: inherit; }
|
|
214
|
+
.agent-tool-code mark { border-radius: 0.1875rem; background: rgba(245, 158, 11, 0.25); color: inherit; }
|
|
210
215
|
.agent-markdown hr { border: none; border-top: 1px solid hsl(var(--border, 0 0% 20%)); margin: 0.75em 0; }
|
|
211
216
|
.agent-markdown a { text-decoration: underline; text-underline-offset: 2px; }
|
|
212
217
|
.agent-markdown a.agent-markdown-cta { text-decoration: none; }
|
|
@@ -406,6 +411,7 @@ function loadHighlighter() {
|
|
|
406
411
|
import("shiki/langs/shellscript.mjs"),
|
|
407
412
|
import("shiki/langs/python.mjs"),
|
|
408
413
|
import("shiki/langs/yaml.mjs"),
|
|
414
|
+
import("shiki/langs/sql.mjs"),
|
|
409
415
|
],
|
|
410
416
|
engine: createOnigurumaEngine(import("shiki/wasm")),
|
|
411
417
|
});
|
|
@@ -430,6 +436,8 @@ const LANG_ALIASES = {
|
|
|
430
436
|
py: "python",
|
|
431
437
|
yml: "yaml",
|
|
432
438
|
md: "markdown",
|
|
439
|
+
bq: "sql",
|
|
440
|
+
bigquery: "sql",
|
|
433
441
|
};
|
|
434
442
|
function HighlightedCodeBlock({ code, lang }) {
|
|
435
443
|
const [html, setHtml] = useState(null);
|
|
@@ -582,27 +590,175 @@ function toolArgsPreview(args) {
|
|
|
582
590
|
})
|
|
583
591
|
.join(", ");
|
|
584
592
|
}
|
|
585
|
-
function
|
|
593
|
+
function looksLikeSql(text) {
|
|
594
|
+
return /^\s*(select|with|insert|update|delete|merge|create|alter|drop|explain|declare|begin)\b/i.test(text);
|
|
595
|
+
}
|
|
596
|
+
function parseJsonText(text) {
|
|
597
|
+
const trimmed = text.trim();
|
|
598
|
+
if (!trimmed || !/^[{[]/.test(trimmed))
|
|
599
|
+
return null;
|
|
600
|
+
try {
|
|
601
|
+
return JSON.parse(trimmed);
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function inferToolTextLanguage(text, key, toolName) {
|
|
608
|
+
const keyName = (key ?? "").toLowerCase();
|
|
609
|
+
const tool = (toolName ?? "").toLowerCase();
|
|
610
|
+
if (keyName === "sql" ||
|
|
611
|
+
keyName.endsWith("sql") ||
|
|
612
|
+
keyName === "query" ||
|
|
613
|
+
tool.includes("bigquery") ||
|
|
614
|
+
tool.includes("db-query") ||
|
|
615
|
+
looksLikeSql(text)) {
|
|
616
|
+
return "sql";
|
|
617
|
+
}
|
|
618
|
+
return parseJsonText(text) ? "json" : "text";
|
|
619
|
+
}
|
|
620
|
+
function formatToolTextValue(value, key, toolName) {
|
|
621
|
+
if (typeof value === "string") {
|
|
622
|
+
const parsed = parseJsonText(value);
|
|
623
|
+
if (parsed) {
|
|
624
|
+
return { text: JSON.stringify(parsed, null, 2), lang: "json" };
|
|
625
|
+
}
|
|
626
|
+
return {
|
|
627
|
+
text: value,
|
|
628
|
+
lang: inferToolTextLanguage(value, key, toolName),
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
return { text: stringifyToolValue(value, true), lang: "json" };
|
|
632
|
+
}
|
|
633
|
+
function toolInputPayload(toolName, args) {
|
|
586
634
|
const entries = Object.entries(args);
|
|
635
|
+
if (entries.length === 0)
|
|
636
|
+
return null;
|
|
587
637
|
if (entries.length === 1) {
|
|
588
638
|
const [key, value] = entries[0];
|
|
589
|
-
|
|
639
|
+
const formatted = formatToolTextValue(value, key, toolName);
|
|
640
|
+
const normalizedKey = key.toLowerCase();
|
|
641
|
+
const keyLabel = normalizedKey === "sql" || normalizedKey.endsWith("sql") ? "SQL" : key;
|
|
642
|
+
return {
|
|
643
|
+
section: "input",
|
|
644
|
+
title: `Input - ${keyLabel}`,
|
|
645
|
+
text: formatted.text,
|
|
646
|
+
copyText: typeof value === "string" ? value : stringifyToolValue(value, true),
|
|
647
|
+
lang: formatted.lang,
|
|
648
|
+
};
|
|
590
649
|
}
|
|
591
|
-
return
|
|
650
|
+
return {
|
|
651
|
+
section: "input",
|
|
652
|
+
title: "Input",
|
|
653
|
+
text: JSON.stringify(args, null, 2),
|
|
654
|
+
copyText: JSON.stringify(args, null, 2),
|
|
655
|
+
lang: "json",
|
|
656
|
+
};
|
|
592
657
|
}
|
|
593
|
-
function
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
658
|
+
function toolResultPayload(result) {
|
|
659
|
+
if (result === undefined)
|
|
660
|
+
return null;
|
|
661
|
+
const formatted = formatToolTextValue(result);
|
|
662
|
+
return {
|
|
663
|
+
section: "result",
|
|
664
|
+
title: "Result",
|
|
665
|
+
text: formatted.text,
|
|
666
|
+
copyText: result,
|
|
667
|
+
lang: formatted.lang,
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function escapeRegExp(value) {
|
|
671
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
672
|
+
}
|
|
673
|
+
function countTextMatches(text, query) {
|
|
674
|
+
const needle = query.trim();
|
|
675
|
+
if (!needle)
|
|
676
|
+
return 0;
|
|
677
|
+
return Array.from(text.matchAll(new RegExp(escapeRegExp(needle), "gi")))
|
|
678
|
+
.length;
|
|
679
|
+
}
|
|
680
|
+
function renderHighlightedSearchText(text, query) {
|
|
681
|
+
const needle = query.trim();
|
|
682
|
+
if (!needle)
|
|
683
|
+
return text;
|
|
684
|
+
const regex = new RegExp(escapeRegExp(needle), "gi");
|
|
685
|
+
const parts = [];
|
|
686
|
+
let lastIndex = 0;
|
|
687
|
+
let match;
|
|
688
|
+
while ((match = regex.exec(text))) {
|
|
689
|
+
if (match.index > lastIndex) {
|
|
690
|
+
parts.push(text.slice(lastIndex, match.index));
|
|
691
|
+
}
|
|
692
|
+
parts.push(_jsx("mark", { children: match[0] }, `${match.index}-${match[0]}`));
|
|
693
|
+
lastIndex = match.index + match[0].length;
|
|
694
|
+
if (match[0].length === 0)
|
|
695
|
+
regex.lastIndex += 1;
|
|
597
696
|
}
|
|
598
|
-
|
|
697
|
+
if (lastIndex < text.length)
|
|
698
|
+
parts.push(text.slice(lastIndex));
|
|
699
|
+
return parts;
|
|
700
|
+
}
|
|
701
|
+
function ToolDetailViewer({ payload }) {
|
|
702
|
+
const [expanded, setExpanded] = useState(false);
|
|
703
|
+
const [searchOpen, setSearchOpen] = useState(false);
|
|
704
|
+
const [search, setSearch] = useState("");
|
|
705
|
+
const [copied, setCopied] = useState(false);
|
|
706
|
+
const copyResetRef = useRef(null);
|
|
707
|
+
const matchCount = useMemo(() => countTextMatches(payload.text, search), [payload.text, search]);
|
|
708
|
+
useEffect(() => {
|
|
709
|
+
return () => {
|
|
710
|
+
if (copyResetRef.current)
|
|
711
|
+
clearTimeout(copyResetRef.current);
|
|
712
|
+
};
|
|
713
|
+
}, []);
|
|
714
|
+
const copyValue = useCallback(async () => {
|
|
715
|
+
try {
|
|
716
|
+
await navigator.clipboard.writeText(payload.copyText);
|
|
717
|
+
setCopied(true);
|
|
718
|
+
if (copyResetRef.current)
|
|
719
|
+
clearTimeout(copyResetRef.current);
|
|
720
|
+
copyResetRef.current = setTimeout(() => setCopied(false), 1200);
|
|
721
|
+
}
|
|
722
|
+
catch {
|
|
723
|
+
// Clipboard failures should not interrupt chat rendering.
|
|
724
|
+
}
|
|
725
|
+
}, [payload.copyText]);
|
|
726
|
+
return (_jsxs("div", { className: "rounded-md border border-border/50 bg-background/60", children: [_jsxs("div", { className: "flex min-h-9 flex-wrap items-center gap-2 border-b border-border/50 px-2.5 py-1.5", children: [_jsx("div", { className: "min-w-0 flex-1", children: _jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("span", { className: "truncate text-[11px] font-medium text-foreground/85", children: payload.title }), payload.lang !== "text" && (_jsx("span", { className: "shrink-0 rounded border border-border/60 px-1 py-0.5 font-mono text-[9px] uppercase leading-none text-muted-foreground", children: payload.lang }))] }) }), _jsx("button", { type: "button", onClick: () => setSearchOpen((v) => !v), "aria-label": `Search ${payload.title.toLowerCase()}`, "aria-pressed": searchOpen, className: cn("inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", searchOpen && "bg-accent text-foreground"), children: _jsx(IconSearch, { size: 12 }) }), _jsx("button", { type: "button", onClick: () => setExpanded((v) => !v), "aria-label": expanded ? "Shrink code viewer" : "Expand code viewer", "aria-pressed": expanded, className: "inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: expanded ? (_jsx(IconArrowsMinimize, { size: 12 })) : (_jsx(IconArrowsMaximize, { size: 12 })) }), _jsxs("button", { type: "button", onClick: copyValue, className: "inline-flex h-6 items-center gap-1 rounded-md px-1.5 font-sans text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 12 }) : _jsx(IconCopy, { size: 12 }), copied ? "Copied" : "Copy"] })] }), searchOpen && (_jsxs("div", { className: "flex items-center gap-2 border-b border-border/50 px-2.5 py-2", children: [_jsx("input", { value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Find", className: "h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 text-xs text-foreground outline-none placeholder:text-muted-foreground focus:ring-1 focus:ring-ring" }), _jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: search.trim() ? matchCount : "" })] })), _jsx("div", { className: cn("agent-tool-code overflow-auto font-mono text-[11px] leading-relaxed text-foreground", expanded ? "max-h-[70vh]" : "max-h-72"), children: search.trim() ? (_jsx("pre", { children: _jsx("code", { children: renderHighlightedSearchText(payload.text, search) }) })) : (_jsx(HighlightedCodeBlock, { code: payload.text, lang: payload.lang })) })] }));
|
|
727
|
+
}
|
|
728
|
+
function activityTrailFromMetadata(message) {
|
|
729
|
+
const meta = message?.metadata;
|
|
730
|
+
const raw = meta?.custom?.activityTrail ?? meta?.activityTrail;
|
|
731
|
+
if (!Array.isArray(raw))
|
|
732
|
+
return [];
|
|
733
|
+
return raw
|
|
734
|
+
.map((item, index) => {
|
|
735
|
+
if (!item || typeof item !== "object")
|
|
736
|
+
return null;
|
|
737
|
+
const label = item.label;
|
|
738
|
+
const tool = item.tool;
|
|
739
|
+
if (typeof label !== "string" || !label.trim())
|
|
740
|
+
return null;
|
|
741
|
+
return {
|
|
742
|
+
id: `trail-${index}-${label}`,
|
|
743
|
+
label: label.trim(),
|
|
744
|
+
...(typeof tool === "string" && tool.trim()
|
|
745
|
+
? { tool: tool.trim() }
|
|
746
|
+
: {}),
|
|
747
|
+
};
|
|
748
|
+
})
|
|
749
|
+
.filter((item) => item !== null);
|
|
750
|
+
}
|
|
751
|
+
function RunActivityTrail({ steps }) {
|
|
752
|
+
const [open, setOpen] = useState(false);
|
|
753
|
+
if (steps.length === 0)
|
|
754
|
+
return null;
|
|
755
|
+
const visibleSteps = steps.slice(-6);
|
|
756
|
+
return (_jsxs("div", { className: "mt-1.5", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), "aria-expanded": open, className: "inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", open && "rotate-180") }), "Steps"] }), open && (_jsx("div", { className: "mt-1 rounded-md border border-border/60 bg-muted/25 px-2.5 py-2 text-[11px] text-muted-foreground", children: _jsx("div", { className: "space-y-1", children: visibleSteps.map((step) => (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(IconCheck, { className: "h-3 w-3 shrink-0 text-emerald-500" }), _jsx("span", { className: "truncate", children: step.label })] }, step.id))) }) }))] }));
|
|
599
757
|
}
|
|
600
758
|
function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
601
759
|
const streamRef = useRef(null);
|
|
602
760
|
const isAgentCall = toolName.startsWith("agent:");
|
|
603
761
|
const [expanded, setExpanded] = useState(isAgentCall);
|
|
604
|
-
const [copiedSection, setCopiedSection] = useState(null);
|
|
605
|
-
const copyResetRef = useRef(null);
|
|
606
762
|
const agentName = isAgentCall ? toolName.slice(6) : null;
|
|
607
763
|
const isAgentError = isAgentCall && result === "Error calling agent";
|
|
608
764
|
const agentStreamText = isAgentCall ? (argsText ?? "") : "";
|
|
@@ -614,24 +770,6 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
|
614
770
|
streamRef.current.scrollTop = streamRef.current.scrollHeight;
|
|
615
771
|
}
|
|
616
772
|
}, [agentStreamText, isAgentCall, isRunning]);
|
|
617
|
-
useEffect(() => {
|
|
618
|
-
return () => {
|
|
619
|
-
if (copyResetRef.current)
|
|
620
|
-
clearTimeout(copyResetRef.current);
|
|
621
|
-
};
|
|
622
|
-
}, []);
|
|
623
|
-
const copyToolDetail = useCallback(async (section, text) => {
|
|
624
|
-
try {
|
|
625
|
-
await navigator.clipboard.writeText(text);
|
|
626
|
-
setCopiedSection(section);
|
|
627
|
-
if (copyResetRef.current)
|
|
628
|
-
clearTimeout(copyResetRef.current);
|
|
629
|
-
copyResetRef.current = setTimeout(() => setCopiedSection(null), 1200);
|
|
630
|
-
}
|
|
631
|
-
catch {
|
|
632
|
-
// Clipboard failures should not interrupt chat rendering.
|
|
633
|
-
}
|
|
634
|
-
}, []);
|
|
635
773
|
// Render connect-builder as ConnectBuilderCard once the result is available
|
|
636
774
|
if (toolName === "connect-builder" && result) {
|
|
637
775
|
try {
|
|
@@ -671,9 +809,8 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
|
671
809
|
}
|
|
672
810
|
}
|
|
673
811
|
const argsStr = isAgentCall ? "" : toolArgsPreview(args);
|
|
674
|
-
const
|
|
675
|
-
const
|
|
676
|
-
const resultDisplay = result !== undefined ? stringifyToolValue(result, true) : "";
|
|
812
|
+
const inputPayload = hasArgs ? toolInputPayload(toolName, args) : null;
|
|
813
|
+
const resultPayload = toolResultPayload(result);
|
|
677
814
|
const displayName = isAgentCall
|
|
678
815
|
? isRunning
|
|
679
816
|
? `Asking ${agentName}...`
|
|
@@ -687,7 +824,7 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
|
687
824
|
const isExpanded = isAgentCall ? hasStreamText && expanded : expanded;
|
|
688
825
|
return (_jsxs("div", { className: "my-1 overflow-hidden", children: [_jsxs("button", { onClick: () => canExpand && setExpanded(!isExpanded), "aria-expanded": canExpand ? isExpanded : undefined, className: cn("flex items-center gap-2 rounded-md px-2.5 py-1.5 text-xs font-mono w-full text-left overflow-hidden", isRunning
|
|
689
826
|
? "bg-muted text-muted-foreground"
|
|
690
|
-
: "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: agentStreamText }) })), isExpanded && !isAgentCall && (hasArgs || result !== undefined) && (_jsxs("div", { className: "mt-1 space-y-2 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground", children: [
|
|
827
|
+
: "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: agentStreamText }) })), isExpanded && !isAgentCall && (hasArgs || result !== undefined) && (_jsxs("div", { className: "mt-1 space-y-2 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground", children: [inputPayload && _jsx(ToolDetailViewer, { payload: inputPayload }), resultPayload && _jsx(ToolDetailViewer, { payload: resultPayload })] }))] }));
|
|
691
828
|
}
|
|
692
829
|
function ToolCallFallback({ toolName, args, argsText, result, }) {
|
|
693
830
|
const chatRunning = React.useContext(ChatRunningContext);
|
|
@@ -915,6 +1052,7 @@ function AssistantMessage() {
|
|
|
915
1052
|
const chatRunning = React.useContext(ChatRunningContext);
|
|
916
1053
|
const msg = messageRuntime.getState();
|
|
917
1054
|
const timestamp = formatMessageTimestamp(msg.createdAt);
|
|
1055
|
+
const activityTrail = activityTrailFromMetadata(msg);
|
|
918
1056
|
const isLast = thread.messages.length > 0 &&
|
|
919
1057
|
thread.messages[thread.messages.length - 1].id === msg.id;
|
|
920
1058
|
const isComplete = !isLast || !chatRunning;
|
|
@@ -970,7 +1108,7 @@ function AssistantMessage() {
|
|
|
970
1108
|
tools: {
|
|
971
1109
|
Fallback: ToolCallFallback,
|
|
972
1110
|
},
|
|
973
|
-
} }) }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), timestamp && (_jsx(MessageTimestamp, { timestamp: timestamp, className: "opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100" }))] }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : (_jsx(ThumbsFeedback, { threadId: cpCtx?.threadId ?? "", runId: (() => {
|
|
1111
|
+
} }) }), isComplete && activityTrail.length > 0 && (_jsx(RunActivityTrail, { steps: activityTrail })), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), timestamp && (_jsx(MessageTimestamp, { timestamp: timestamp, className: "opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100" }))] }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : (_jsx(ThumbsFeedback, { threadId: cpCtx?.threadId ?? "", runId: (() => {
|
|
974
1112
|
const meta = messageRuntime.getState().metadata;
|
|
975
1113
|
return ((typeof meta?.custom?.runId === "string" &&
|
|
976
1114
|
meta.custom.runId) ||
|
|
@@ -1101,6 +1239,20 @@ function isBuilderReconnectRunError(info) {
|
|
|
1101
1239
|
message.includes("builder authentication failed") ||
|
|
1102
1240
|
(isAuthCode && message.includes("invalid token")));
|
|
1103
1241
|
}
|
|
1242
|
+
function isProviderQueryRunError(info) {
|
|
1243
|
+
const text = [info.errorCode, info.message, info.details]
|
|
1244
|
+
.filter(Boolean)
|
|
1245
|
+
.join("\n")
|
|
1246
|
+
.toLowerCase();
|
|
1247
|
+
return (text.includes("bigquery") ||
|
|
1248
|
+
text.includes("sql") ||
|
|
1249
|
+
text.includes("query") ||
|
|
1250
|
+
text.includes("schema") ||
|
|
1251
|
+
text.includes("syntax") ||
|
|
1252
|
+
text.includes("unknown column") ||
|
|
1253
|
+
text.includes("unknown table") ||
|
|
1254
|
+
text.includes("type mismatch"));
|
|
1255
|
+
}
|
|
1104
1256
|
function getMessageText(message) {
|
|
1105
1257
|
const msg = message?.message ?? message;
|
|
1106
1258
|
const content = msg?.content;
|
|
@@ -1118,6 +1270,8 @@ function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDismiss, })
|
|
|
1118
1270
|
const [copied, setCopied] = useState(false);
|
|
1119
1271
|
const canRecover = info.recoverable === true;
|
|
1120
1272
|
const shouldShowBuilderReconnect = isBuilderReconnectRunError(info);
|
|
1273
|
+
const isQueryError = isProviderQueryRunError(info);
|
|
1274
|
+
const copyLabel = info.runId || info.errorCode || info.details ? "Copy debug" : "Copy";
|
|
1121
1275
|
const copyDetails = useCallback(() => {
|
|
1122
1276
|
const text = [
|
|
1123
1277
|
info.message,
|
|
@@ -1133,7 +1287,7 @@ function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDismiss, })
|
|
|
1133
1287
|
}, [info]);
|
|
1134
1288
|
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: canRecover
|
|
1135
1289
|
? "The agent stopped before finishing"
|
|
1136
|
-
: "The agent hit an error" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && (_jsxs("a", { href: agentNativePath("/_agent-native/builder/connect"), target: "_blank", rel: "noreferrer", className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconExternalLink, { size: 13 }), "Reconnect Builder.io"] })), canRecover && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), "Retry"] })] })), canRecover && onFork && (_jsxs("button", { type: "button", onClick: onFork, title: "Fork this conversation into a separate chat thread.", "aria-label": "Fork this conversation into a separate chat thread", className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork chat"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" :
|
|
1290
|
+
: "The agent hit an error" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && (_jsxs("a", { href: agentNativePath("/_agent-native/builder/connect"), target: "_blank", rel: "noreferrer", className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconExternalLink, { size: 13 }), "Reconnect Builder.io"] })), canRecover && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), isQueryError ? "Diagnose and retry" : "Retry"] })] })), canRecover && onFork && (_jsxs("button", { type: "button", onClick: onFork, title: "Fork this conversation into a separate chat thread.", "aria-label": "Fork this conversation into a separate chat thread", className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork chat"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" : copyLabel] })] })] }));
|
|
1137
1291
|
}
|
|
1138
1292
|
function LoopLimitContinueCard({ info, onContinue, }) {
|
|
1139
1293
|
const [settings, setSettings] = useState(null);
|