@neuronection/assistant-ui 0.25.0 → 0.27.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/CHANGELOG.md +55 -0
- package/README.md +4 -0
- package/dist/ai-magic-fill.js +1 -1
- package/dist/chat-drawer.js +1 -1
- package/dist/chat-export.d.ts +29 -0
- package/dist/chat-export.js +3 -0
- package/dist/chat-export.js.map +1 -0
- package/dist/chat-history-button.d.ts +31 -0
- package/dist/chat-history-button.js +3 -0
- package/dist/chat-history-button.js.map +1 -0
- package/dist/chat-message.js +1 -1
- package/dist/chat-panel.d.ts +1 -1
- package/dist/chat-panel.js +1 -1
- package/dist/chat-tools-catalog.d.ts +50 -0
- package/dist/chat-tools-catalog.js +3 -0
- package/dist/chat-tools-catalog.js.map +1 -0
- package/dist/chat-trace-meta.d.ts +19 -0
- package/dist/chat-trace-meta.js +3 -0
- package/dist/chat-trace-meta.js.map +1 -0
- package/dist/chat-transcript.js +1 -1
- package/dist/chunk-DRJGZ5TB.js +47 -0
- package/dist/chunk-DRJGZ5TB.js.map +1 -0
- package/dist/{chunk-5QTHDB3D.js → chunk-EODV6JK7.js} +3 -3
- package/dist/{chunk-5QTHDB3D.js.map → chunk-EODV6JK7.js.map} +1 -1
- package/dist/{chunk-BSIWLVDX.js → chunk-FGYGWZ6S.js} +3 -3
- package/dist/{chunk-BSIWLVDX.js.map → chunk-FGYGWZ6S.js.map} +1 -1
- package/dist/{chunk-BVJT67B5.js → chunk-FS7M7PNS.js} +3 -3
- package/dist/{chunk-BVJT67B5.js.map → chunk-FS7M7PNS.js.map} +1 -1
- package/dist/{chunk-S62VJVWB.js → chunk-LFSICACE.js} +13 -5
- package/dist/chunk-LFSICACE.js.map +1 -0
- package/dist/chunk-QMQ73C23.js +41 -0
- package/dist/chunk-QMQ73C23.js.map +1 -0
- package/dist/{chunk-X3C2FBMR.js → chunk-WBSGFOSD.js} +4 -3
- package/dist/chunk-WBSGFOSD.js.map +1 -0
- package/dist/chunk-YYPO24TA.js +38 -0
- package/dist/chunk-YYPO24TA.js.map +1 -0
- package/dist/chunk-ZSCL34WT.js +149 -0
- package/dist/chunk-ZSCL34WT.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +30 -26
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +17 -1
- package/dist/chunk-S62VJVWB.js.map +0 -1
- package/dist/chunk-X3C2FBMR.js.map +0 -1
|
@@ -12,7 +12,6 @@ var ChatPanel = React.forwardRef(
|
|
|
12
12
|
"data-variant": variant,
|
|
13
13
|
className: cn(
|
|
14
14
|
"flex h-full min-h-0 w-full flex-col bg-[var(--as-surface)] text-[var(--as-fg)]",
|
|
15
|
-
variant === "page" && "mx-auto w-full max-w-3xl",
|
|
16
15
|
variant === "bubble" && "overflow-hidden",
|
|
17
16
|
className
|
|
18
17
|
),
|
|
@@ -22,8 +21,17 @@ var ChatPanel = React.forwardRef(
|
|
|
22
21
|
actions ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-0.5", children: actions }) : null
|
|
23
22
|
] }) : null,
|
|
24
23
|
banner ? /* @__PURE__ */ jsx("div", { "data-as": "chat-panel-banner", className: "shrink-0 px-3 py-1.5 text-xs text-[var(--as-muted-fg)]", children: banner }) : null,
|
|
25
|
-
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col", children:
|
|
26
|
-
|
|
24
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsx(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
className: cn(
|
|
28
|
+
"flex min-h-0 w-full flex-1 flex-col",
|
|
29
|
+
variant === "page" && "mx-auto max-w-3xl"
|
|
30
|
+
),
|
|
31
|
+
children: transcript
|
|
32
|
+
}
|
|
33
|
+
) }),
|
|
34
|
+
composer ? /* @__PURE__ */ jsx("div", { className: "shrink-0 border-t border-[var(--as-border)] p-2", children: /* @__PURE__ */ jsx("div", { className: cn(variant === "page" && "mx-auto w-full max-w-3xl"), children: composer }) }) : null,
|
|
27
35
|
footer ? /* @__PURE__ */ jsx("div", { className: "shrink-0 px-3 pb-2 pt-1 text-center text-[10px] text-[var(--as-muted-fg)]", children: footer }) : null
|
|
28
36
|
]
|
|
29
37
|
}
|
|
@@ -32,5 +40,5 @@ var ChatPanel = React.forwardRef(
|
|
|
32
40
|
);
|
|
33
41
|
|
|
34
42
|
export { ChatPanel };
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-LFSICACE.js.map
|
|
44
|
+
//# sourceMappingURL=chunk-LFSICACE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-panel/ChatPanel.tsx"],"names":["ChatPanel"],"mappings":";;;;AA6BO,IAAM,SAAA,GAAkB,KAAA,CAAA,UAAA;AAAA,EAC7B,SAASA,UAAAA,CAAU,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAU,EAAG,GAAA,EAAK;AACpG,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAQ,YAAA;AAAA,QACR,cAAA,EAAc,OAAA;AAAA,QACd,SAAA,EAAW,EAAA;AAAA,UACT,gFAAA;AAAA,UACA,YAAY,QAAA,IAAY,iBAAA;AAAA,UACxB;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,KAAA,KAAU,UAAa,OAAA,KAAY,MAAA,mBAClC,IAAA,CAAC,QAAA,EAAA,EAAO,WAAU,+EAAA,EAChB,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CAAA,EAAiD,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YACrE,0BAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EAAsC,mBAAQ,CAAA,GAAS;AAAA,WAAA,EACnF,CAAA,GACE,IAAA;AAAA,UACH,MAAA,uBACE,KAAA,EAAA,EAAI,SAAA,EAAQ,qBAAoB,SAAA,EAAU,wDAAA,EACxC,kBACH,CAAA,GACE,IAAA;AAAA,0BACJ,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,kBAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,qCAAA;AAAA,gBACA,YAAY,MAAA,IAAU;AAAA,eACxB;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA,WACH,EACF,CAAA;AAAA,UACC,QAAA,mBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,YAAY,MAAA,IAAU,0BAA0B,CAAA,EAAI,QAAA,EAAA,QAAA,EAAS,GAClF,CAAA,GACE,IAAA;AAAA,UACH,yBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2EAAA,EAA6E,kBAAO,CAAA,GACjG;AAAA;AAAA;AAAA,KACN;AAAA,EAEJ;AACF","file":"chunk-LFSICACE.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\n\nexport type ChatPanelVariant = 'page' | 'sidebar' | 'bubble'\n\nexport interface ChatPanelProps {\n /** Layout tier: full page (full-bleed shell, centered conversation column), sidebar (dense column), bubble (compact widget body). */\n variant: ChatPanelVariant\n /** Header row: title node + action nodes (session list, branch tree, expand, close). */\n title?: React.ReactNode\n actions?: React.ReactNode\n /** Status strip under the header (connection warnings, context summary). */\n banner?: React.ReactNode\n /** Usually `<ChatTranscript …/>`. */\n transcript: React.ReactNode\n /** Usually `<ChatComposer …/>`. */\n composer?: React.ReactNode\n /** Disclaimer row under the composer (health guidance, etc.). */\n footer?: React.ReactNode\n className?: string\n}\n\n/**\n * The composed chat host — the one uniform surface assembly behind the\n * family's three shapes (full page / sidepanel / bubble). Owns layout\n * only; transcript, composer and every feature slot stay app-composed\n * (ADR-006 tier 3, `RichTextEditor` precedent).\n */\nexport const ChatPanel = React.forwardRef<HTMLDivElement, ChatPanelProps>(\n function ChatPanel({ variant, title, actions, banner, transcript, composer, footer, className }, ref) {\n return (\n <div\n ref={ref}\n data-as=\"chat-panel\"\n data-variant={variant}\n className={cn(\n 'flex h-full min-h-0 w-full flex-col bg-[var(--as-surface)] text-[var(--as-fg)]',\n variant === 'bubble' && 'overflow-hidden',\n className,\n )}\n >\n {title !== undefined || actions !== undefined ? (\n <header className=\"flex shrink-0 items-center gap-2 border-b border-[var(--as-border)] px-3 py-2\">\n <div className=\"min-w-0 flex-1 truncate text-sm font-semibold\">{title}</div>\n {actions ? <div className=\"flex shrink-0 items-center gap-0.5\">{actions}</div> : null}\n </header>\n ) : null}\n {banner ? (\n <div data-as=\"chat-panel-banner\" className=\"shrink-0 px-3 py-1.5 text-xs text-[var(--as-muted-fg)]\">\n {banner}\n </div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div\n className={cn(\n 'flex min-h-0 w-full flex-1 flex-col',\n variant === 'page' && 'mx-auto max-w-3xl',\n )}\n >\n {transcript}\n </div>\n </div>\n {composer ? (\n <div className=\"shrink-0 border-t border-[var(--as-border)] p-2\">\n <div className={cn(variant === 'page' && 'mx-auto w-full max-w-3xl')}>{composer}</div>\n </div>\n ) : null}\n {footer ? (\n <div className=\"shrink-0 px-3 pb-2 pt-1 text-center text-[10px] text-[var(--as-muted-fg)]\">{footer}</div>\n ) : null}\n </div>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function formatDuration(ms) {
|
|
6
|
+
if (ms < 1e3) {
|
|
7
|
+
return `${Math.round(ms)} ms`;
|
|
8
|
+
}
|
|
9
|
+
return `${(ms / 1e3).toFixed(1)} s`;
|
|
10
|
+
}
|
|
11
|
+
var ChatTraceMeta = React.forwardRef(
|
|
12
|
+
function ChatTraceMeta2({ model, durationMs, toolCount, className }, ref) {
|
|
13
|
+
const hasModel = typeof model === "string" && model !== "";
|
|
14
|
+
const hasDuration = typeof durationMs === "number";
|
|
15
|
+
const hasTools = typeof toolCount === "number" && toolCount > 0;
|
|
16
|
+
if (!hasModel && !hasDuration && !hasTools) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return /* @__PURE__ */ jsxs(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
ref,
|
|
23
|
+
"data-as": "chat-trace-meta",
|
|
24
|
+
className: cn("mt-1 flex flex-wrap items-center gap-2 font-mono text-[10px] text-[var(--as-muted-fg)]", className),
|
|
25
|
+
children: [
|
|
26
|
+
hasModel ? /* @__PURE__ */ jsx("span", { children: model }) : null,
|
|
27
|
+
hasDuration ? /* @__PURE__ */ jsx("span", { children: formatDuration(durationMs) }) : null,
|
|
28
|
+
hasTools ? /* @__PURE__ */ jsxs("span", { children: [
|
|
29
|
+
toolCount,
|
|
30
|
+
" ",
|
|
31
|
+
toolCount === 1 ? "tool" : "tools"
|
|
32
|
+
] }) : null
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export { ChatTraceMeta };
|
|
40
|
+
//# sourceMappingURL=chunk-QMQ73C23.js.map
|
|
41
|
+
//# sourceMappingURL=chunk-QMQ73C23.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-trace-meta/ChatTraceMeta.tsx"],"names":["ChatTraceMeta"],"mappings":";;;;AAcA,SAAS,eAAe,EAAA,EAAoB;AAC1C,EAAA,IAAI,KAAK,GAAA,EAAM;AACb,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA,GAAA,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAClC;AAOO,IAAM,aAAA,GAAsB,KAAA,CAAA,UAAA;AAAA,EACjC,SAASA,eAAc,EAAE,KAAA,EAAO,YAAY,SAAA,EAAW,SAAA,IAAa,GAAA,EAAK;AACvE,IAAA,MAAM,QAAA,GAAW,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,EAAA;AACxD,IAAA,MAAM,WAAA,GAAc,OAAO,UAAA,KAAe,QAAA;AAC1C,IAAA,MAAM,QAAA,GAAW,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,GAAY,CAAA;AAC9D,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,WAAA,IAAe,CAAC,QAAA,EAAU;AAC1C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAQ,iBAAA;AAAA,QACR,SAAA,EAAW,EAAA,CAAG,wFAAA,EAA0F,SAAS,CAAA;AAAA,QAEhH,QAAA,EAAA;AAAA,UAAA,QAAA,mBAAW,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,EAAM,CAAA,GAAU,IAAA;AAAA,UAClC,8BAAc,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,cAAA,CAAe,UAAU,GAAE,CAAA,GAAU,IAAA;AAAA,UAC1D,QAAA,wBACE,MAAA,EAAA,EACE,QAAA,EAAA;AAAA,YAAA,SAAA;AAAA,YAAU,GAAA;AAAA,YAAE,SAAA,KAAc,IAAI,MAAA,GAAS;AAAA,WAAA,EAC1C,CAAA,GACE;AAAA;AAAA;AAAA,KACN;AAAA,EAEJ;AACF","file":"chunk-QMQ73C23.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatTraceMetaProps {\n /** Model identifier that produced the reply. */\n model?: string\n /** Turn elapsed time (formatted ms below 1 s, then seconds). */\n durationMs?: number\n /** Number of tools the turn executed (renders `N tools`). */\n toolCount?: number\n className?: string\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)} ms`\n }\n return `${(ms / 1000).toFixed(1)} s`\n}\n\n/**\n * Compact turn-trace badges (\"gpt-5.6 · 1.9 s · 3 tools\", career's\n * `TraceMeta`, generalized): renders nothing without data. Reads a\n * normalized view-model — parsing `metadata_json` stays app-side.\n */\nexport const ChatTraceMeta = React.forwardRef<HTMLDivElement, ChatTraceMetaProps>(\n function ChatTraceMeta({ model, durationMs, toolCount, className }, ref) {\n const hasModel = typeof model === 'string' && model !== ''\n const hasDuration = typeof durationMs === 'number'\n const hasTools = typeof toolCount === 'number' && toolCount > 0\n if (!hasModel && !hasDuration && !hasTools) {\n return null\n }\n return (\n <div\n ref={ref}\n data-as=\"chat-trace-meta\"\n className={cn('mt-1 flex flex-wrap items-center gap-2 font-mono text-[10px] text-[var(--as-muted-fg)]', className)}\n >\n {hasModel ? <span>{model}</span> : null}\n {hasDuration ? <span>{formatDuration(durationMs)}</span> : null}\n {hasTools ? (\n <span>\n {toolCount} {toolCount === 1 ? 'tool' : 'tools'}\n </span>\n ) : null}\n </div>\n )\n },\n)\n"]}
|
|
@@ -38,7 +38,7 @@ var ChatDrawer = React.forwardRef(
|
|
|
38
38
|
container,
|
|
39
39
|
overlayClassName,
|
|
40
40
|
className
|
|
41
|
-
}) {
|
|
41
|
+
}, ref) {
|
|
42
42
|
const narrow = useIsNarrow(fullScreenBreakpointPx);
|
|
43
43
|
const draggingRef = React.useRef(false);
|
|
44
44
|
const clamp = (value) => Math.min(maxWidth, Math.max(minWidth, value));
|
|
@@ -90,6 +90,7 @@ var ChatDrawer = React.forwardRef(
|
|
|
90
90
|
/* @__PURE__ */ jsxs(
|
|
91
91
|
DialogPrimitive.Content,
|
|
92
92
|
{
|
|
93
|
+
ref,
|
|
93
94
|
"data-as": "chat-drawer",
|
|
94
95
|
"data-side": side,
|
|
95
96
|
"data-full-screen": narrow || void 0,
|
|
@@ -137,5 +138,5 @@ var ChatDrawer = React.forwardRef(
|
|
|
137
138
|
);
|
|
138
139
|
|
|
139
140
|
export { ChatDrawer };
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-WBSGFOSD.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-WBSGFOSD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-drawer/ChatDrawer.tsx"],"names":["ChatDrawer"],"mappings":"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","file":"chunk-WBSGFOSD.js","sourcesContent":["import * as React from 'react'\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatDrawerProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** The sidepanel content — usually `ChatPanel variant=\"sidebar\"`. */\n panel: React.ReactNode\n side?: 'right' | 'left'\n /** Controlled width in px (persist app-side). Default 480. */\n width?: number\n onWidthChange?: (width: number) => void\n minWidth?: number\n maxWidth?: number\n resizable?: boolean\n closeLabel?: string\n resizeLabel?: string\n /** Accessible dialog name (visually hidden). Default \"Chat\". */\n title?: string\n /** Below this viewport width the drawer goes full-screen. Default 768. */\n fullScreenBreakpointPx?: number\n container?: HTMLElement | null\n overlayClassName?: string\n className?: string\n}\n\nfunction useIsNarrow(breakpointPx: number): boolean {\n const [narrow, setNarrow] = React.useState(() =>\n typeof window !== 'undefined' && window.matchMedia !== undefined\n ? window.matchMedia(`(max-width: ${breakpointPx - 1}px)`).matches\n : false,\n )\n React.useEffect(() => {\n if (typeof window === 'undefined' || window.matchMedia === undefined) {\n return\n }\n const query = window.matchMedia(`(max-width: ${breakpointPx - 1}px)`)\n const listener = (event: MediaQueryListEvent) => setNarrow(event.matches)\n query.addEventListener('change', listener)\n setNarrow(query.matches)\n return () => query.removeEventListener('change', listener)\n }, [breakpointPx])\n return narrow\n}\n\n/**\n * The resizable chat sidepanel (health's `AIDrawer` + study's resizable\n * sidebar, family-standard): portal overlay on Radix Dialog (focus trap,\n * Escape), drag + keyboard resize, full-screen below the breakpoint.\n */\nexport const ChatDrawer = React.forwardRef<HTMLDivElement, ChatDrawerProps>(\n function ChatDrawer(\n {\n open,\n onOpenChange,\n panel,\n side = 'right',\n width = 480,\n onWidthChange,\n minWidth = 320,\n maxWidth = 860,\n resizable = true,\n closeLabel = 'Close chat',\n resizeLabel = 'Resize chat panel',\n title = 'Chat',\n fullScreenBreakpointPx = 768,\n container,\n overlayClassName,\n className,\n },\n ref,\n ) {\n const narrow = useIsNarrow(fullScreenBreakpointPx)\n const draggingRef = React.useRef(false)\n\n const clamp = (value: number) => Math.min(maxWidth, Math.max(minWidth, value))\n\n const onHandleKeyDown = (event: React.KeyboardEvent) => {\n if (!resizable || narrow) {\n return\n }\n const step = event.shiftKey ? 48 : 16\n if (event.key === (side === 'right' ? 'ArrowLeft' : 'ArrowRight')) {\n event.preventDefault()\n onWidthChange?.(clamp(width + step))\n } else if (event.key === (side === 'right' ? 'ArrowRight' : 'ArrowLeft')) {\n event.preventDefault()\n onWidthChange?.(clamp(width - step))\n }\n }\n\n const onHandlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!resizable || narrow || event.button !== 0) {\n return\n }\n event.preventDefault()\n draggingRef.current = true\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n const onHandlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) {\n return\n }\n const delta = side === 'right' ? window.innerWidth - event.clientX : event.clientX\n onWidthChange?.(clamp(delta))\n }\n\n const onHandlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) {\n return\n }\n draggingRef.current = false\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n }\n\n return (\n <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal container={container}>\n <DialogPrimitive.Overlay\n data-as=\"chat-drawer-overlay\"\n className={cn('as-anim-fade fixed inset-0 z-[var(--as-z-modal)] bg-[var(--as-overlay)]', overlayClassName)}\n />\n <DialogPrimitive.Content\n ref={ref}\n data-as=\"chat-drawer\"\n data-side={side}\n data-full-screen={narrow || undefined}\n style={narrow ? undefined : { width: `${width}px`, maxWidth: '100vw' }}\n className={cn(\n 'as-anim-drawer fixed top-0 z-[var(--as-z-modal)] flex h-dvh flex-col border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] shadow-[var(--as-shadow-3)] focus:outline-none',\n narrow\n ? 'inset-x-0 bottom-0 border-t'\n : side === 'right'\n ? 'bottom-0 right-0 border-l'\n : 'bottom-0 left-0 border-r',\n className,\n )}\n >\n {resizable && !narrow ? (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={resizeLabel}\n tabIndex={0}\n onKeyDown={onHandleKeyDown}\n onPointerDown={onHandlePointerDown}\n onPointerMove={onHandlePointerMove}\n onPointerUp={onHandlePointerUp}\n onPointerCancel={onHandlePointerUp}\n className={cn(\n 'group/handle absolute top-0 z-10 h-dvh w-1.5 cursor-col-resize focus-visible:outline-2 focus-visible:outline-[var(--as-focus-ring)]',\n side === 'right' ? '-left-1' : '-right-1',\n )}\n >\n <span className=\"mx-auto block h-full w-px bg-transparent transition-colors group-hover/handle:bg-[var(--as-border)]\" />\n </div>\n ) : null}\n <DialogPrimitive.Title className=\"sr-only\">{title}</DialogPrimitive.Title>\n <div className=\"flex min-h-0 flex-1 flex-col\">{panel}</div>\n <DialogPrimitive.Close\n aria-label={closeLabel}\n className=\"absolute right-3 top-2.5 rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-secondary)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <X aria-hidden className=\"size-4\" />\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PopoverButton } from './chunk-BE3XFZWU.js';
|
|
2
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { History } from 'lucide-react';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function ChatHistoryButton({
|
|
8
|
+
children,
|
|
9
|
+
icon: Icon = History,
|
|
10
|
+
onOpen,
|
|
11
|
+
align = "end",
|
|
12
|
+
panelClassName,
|
|
13
|
+
labels,
|
|
14
|
+
className
|
|
15
|
+
}) {
|
|
16
|
+
const [closeSignal, setCloseSignal] = React.useState(0);
|
|
17
|
+
const close = React.useCallback(() => setCloseSignal((signal) => signal + 1), []);
|
|
18
|
+
return /* @__PURE__ */ jsx("span", { className: cn("inline-flex", className), "data-as": "chat-history-button", children: /* @__PURE__ */ jsx(
|
|
19
|
+
PopoverButton,
|
|
20
|
+
{
|
|
21
|
+
label: labels?.open ?? "Chat history",
|
|
22
|
+
trigger: /* @__PURE__ */ jsx(Icon, { className: "size-4", "aria-hidden": true }),
|
|
23
|
+
align,
|
|
24
|
+
closeSignal,
|
|
25
|
+
onOpenChange: (open) => {
|
|
26
|
+
if (open) {
|
|
27
|
+
onOpen?.();
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
panelClassName: cn("h-96 w-72 p-2", panelClassName),
|
|
31
|
+
children: children(close)
|
|
32
|
+
}
|
|
33
|
+
) });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { ChatHistoryButton };
|
|
37
|
+
//# sourceMappingURL=chunk-YYPO24TA.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-YYPO24TA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-history-button/ChatHistoryButton.tsx"],"names":[],"mappings":";;;;;;AAkCO,SAAS,iBAAA,CAAkB;AAAA,EAChC,QAAA;AAAA,EACA,MAAM,IAAA,GAAO,OAAA;AAAA,EACb,MAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR,cAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAU,eAAS,CAAC,CAAA;AACtD,EAAA,MAAM,KAAA,GAAc,KAAA,CAAA,WAAA,CAAY,MAAM,cAAA,CAAe,CAAC,WAAW,MAAA,GAAS,CAAC,CAAA,EAAG,EAAE,CAAA;AAChF,EAAA,uBACE,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,eAAe,SAAS,CAAA,EAAG,WAAQ,qBAAA,EACrD,QAAA,kBAAA,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,QAAQ,IAAA,IAAQ,cAAA;AAAA,MACvB,yBAAS,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,eAAW,IAAA,EAAC,CAAA;AAAA,MAC9C,KAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAA,IAAS;AAAA,QACX;AAAA,MACF,CAAA;AAAA,MACA,cAAA,EAAgB,EAAA,CAAG,eAAA,EAAiB,cAAc,CAAA;AAAA,MAEjD,mBAAS,KAAK;AAAA;AAAA,GACjB,EACF,CAAA;AAEJ","file":"chunk-YYPO24TA.js","sourcesContent":["import * as React from 'react'\nimport { History } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { PopoverButton } from '../popover-button/PopoverButton'\n\nexport interface ChatHistoryButtonLabels {\n open: string\n}\n\nexport interface ChatHistoryButtonProps {\n /**\n * Popover content, typically the app's session-list glue. Called with\n * `close` — invoke it after a pick to dismiss the popover (the\n * `closeSignal` pattern underneath).\n */\n children: (close: () => void) => React.ReactNode\n icon?: LucideIcon\n /** Called every time the popover opens — refresh the session list here. */\n onOpen?: () => void\n align?: 'start' | 'center' | 'end'\n panelClassName?: string\n labels?: Partial<ChatHistoryButtonLabels>\n className?: string\n}\n\n/**\n * Header entry point for a chat's session history (career's\n * `HistoryButton` + study's ChatPanel history popover, generalized): a\n * labelled popover trigger wrapping the app's session list. The list\n * itself (search, actions) stays app-side via\n * [`ChatSessionList`](../chat-session-list) glue.\n */\nexport function ChatHistoryButton({\n children,\n icon: Icon = History,\n onOpen,\n align = 'end',\n panelClassName,\n labels,\n className,\n}: ChatHistoryButtonProps) {\n const [closeSignal, setCloseSignal] = React.useState(0)\n const close = React.useCallback(() => setCloseSignal((signal) => signal + 1), [])\n return (\n <span className={cn('inline-flex', className)} data-as=\"chat-history-button\">\n <PopoverButton\n label={labels?.open ?? 'Chat history'}\n trigger={<Icon className=\"size-4\" aria-hidden />}\n align={align}\n closeSignal={closeSignal}\n onOpenChange={(open) => {\n if (open) {\n onOpen?.()\n }\n }}\n panelClassName={cn('h-96 w-72 p-2', panelClassName)}\n >\n {children(close)}\n </PopoverButton>\n </span>\n )\n}\n"]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { searchScore } from './chunk-B2G66OSQ.js';
|
|
2
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Search, Wrench, ChevronDown } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var ChatToolsCatalog = React.forwardRef(
|
|
8
|
+
function ChatToolsCatalog2({
|
|
9
|
+
tools,
|
|
10
|
+
searchable = true,
|
|
11
|
+
defaultOpen = false,
|
|
12
|
+
labels,
|
|
13
|
+
icon: Icon = Wrench,
|
|
14
|
+
className
|
|
15
|
+
}, ref) {
|
|
16
|
+
const uid = React.useId();
|
|
17
|
+
const [query, setQuery] = React.useState("");
|
|
18
|
+
const [openOverrides, setOpenOverrides] = React.useState({});
|
|
19
|
+
const filtered = React.useMemo(() => {
|
|
20
|
+
const trimmed = query.trim();
|
|
21
|
+
if (trimmed === "") {
|
|
22
|
+
return tools;
|
|
23
|
+
}
|
|
24
|
+
return tools.map((tool) => ({
|
|
25
|
+
tool,
|
|
26
|
+
score: Math.max(
|
|
27
|
+
searchScore(trimmed, tool.title ?? tool.name) ?? -1,
|
|
28
|
+
searchScore(trimmed, tool.name) ?? -1,
|
|
29
|
+
searchScore(trimmed, tool.description ?? "") ?? -1
|
|
30
|
+
)
|
|
31
|
+
})).filter((entry) => entry.score >= 0).sort((a, b) => b.score - a.score).map((entry) => entry.tool);
|
|
32
|
+
}, [tools, query]);
|
|
33
|
+
return /* @__PURE__ */ jsxs(
|
|
34
|
+
"div",
|
|
35
|
+
{
|
|
36
|
+
ref,
|
|
37
|
+
"data-as": "chat-tools-catalog",
|
|
38
|
+
className: cn("flex min-h-0 w-full flex-col gap-2", className),
|
|
39
|
+
children: [
|
|
40
|
+
searchable ? /* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
Search,
|
|
43
|
+
{
|
|
44
|
+
className: "pointer-events-none absolute start-2 top-1/2 size-3.5 -translate-y-1/2 text-[var(--as-muted-fg)]",
|
|
45
|
+
"aria-hidden": true
|
|
46
|
+
}
|
|
47
|
+
),
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
"input",
|
|
50
|
+
{
|
|
51
|
+
type: "search",
|
|
52
|
+
role: "searchbox",
|
|
53
|
+
value: query,
|
|
54
|
+
"aria-label": labels?.search ?? "Search tools",
|
|
55
|
+
placeholder: labels?.searchPlaceholder ?? "Search\u2026",
|
|
56
|
+
onChange: (event) => setQuery(event.target.value),
|
|
57
|
+
className: "w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] py-1.5 pe-2 ps-8 text-xs text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]"
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] }) : null,
|
|
61
|
+
/* @__PURE__ */ jsx("div", { role: "list", "aria-label": labels?.tools ?? "Tools", className: "flex flex-col gap-2", children: tools.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-1 py-3 text-xs text-[var(--as-muted-fg)]", children: labels?.empty ?? "No tools available" }) : filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-1 py-3 text-xs text-[var(--as-muted-fg)]", children: labels?.noResults ?? "No matching tools" }) : filtered.map((tool) => {
|
|
62
|
+
const open = openOverrides[tool.name] ?? defaultOpen;
|
|
63
|
+
const regionId = `${uid}-${tool.name}`;
|
|
64
|
+
const toggle = () => setOpenOverrides((current) => ({ ...current, [tool.name]: !open }));
|
|
65
|
+
return /* @__PURE__ */ jsxs(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
role: "listitem",
|
|
69
|
+
"data-as": "chat-tools-catalog-entry",
|
|
70
|
+
"data-open": open || void 0,
|
|
71
|
+
className: "rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-xs",
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsxs(
|
|
74
|
+
"button",
|
|
75
|
+
{
|
|
76
|
+
type: "button",
|
|
77
|
+
"aria-expanded": open,
|
|
78
|
+
"aria-controls": regionId,
|
|
79
|
+
onClick: toggle,
|
|
80
|
+
className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]",
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-3.5 shrink-0 text-[var(--as-muted-fg)]", "aria-hidden": true }),
|
|
83
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium text-[var(--as-fg)]", children: tool.name }),
|
|
85
|
+
tool.title ? /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-[var(--as-muted-fg)]", children: tool.title }) : null
|
|
86
|
+
] }),
|
|
87
|
+
tool.scope ? /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full bg-[var(--as-surface-raised)] px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-[var(--as-muted-fg)]", children: tool.scope }) : null,
|
|
88
|
+
/* @__PURE__ */ jsx(
|
|
89
|
+
ChevronDown,
|
|
90
|
+
{
|
|
91
|
+
className: cn(
|
|
92
|
+
"size-3.5 shrink-0 text-[var(--as-muted-fg)] transition-transform",
|
|
93
|
+
open && "rotate-180"
|
|
94
|
+
),
|
|
95
|
+
"aria-hidden": true
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
open ? /* @__PURE__ */ jsxs("div", { id: regionId, className: "flex flex-col gap-2 border-t border-[var(--as-border)] px-2.5 py-2", children: [
|
|
102
|
+
tool.description ? /* @__PURE__ */ jsx("p", { className: "text-[var(--as-fg)]", children: tool.description }) : null,
|
|
103
|
+
tool.arguments && tool.arguments.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
104
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 font-medium uppercase tracking-wide text-[var(--as-muted-fg)]", children: labels?.arguments ?? "Arguments" }),
|
|
105
|
+
/* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1.5", children: tool.arguments.map((argument) => /* @__PURE__ */ jsxs(
|
|
106
|
+
"li",
|
|
107
|
+
{
|
|
108
|
+
className: "rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] px-2 py-1.5",
|
|
109
|
+
children: [
|
|
110
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
111
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium text-[var(--as-fg)]", children: argument.name }),
|
|
112
|
+
argument.type ? /* @__PURE__ */ jsx("span", { className: "rounded-full border border-[var(--as-border)] bg-[var(--as-surface)] px-1.5 py-px font-mono text-[10px] leading-4 text-[var(--as-muted-fg)]", children: argument.type }) : null,
|
|
113
|
+
/* @__PURE__ */ jsx(
|
|
114
|
+
"span",
|
|
115
|
+
{
|
|
116
|
+
className: cn(
|
|
117
|
+
"text-[10px] font-medium uppercase tracking-wide",
|
|
118
|
+
argument.required ? "text-[var(--as-warning)]" : "text-[var(--as-muted-fg)]"
|
|
119
|
+
),
|
|
120
|
+
children: argument.required ? labels?.required ?? "required" : labels?.optional ?? "optional"
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] }),
|
|
124
|
+
argument.description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 leading-snug text-[var(--as-muted-fg)]", children: argument.description }) : null
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
argument.name
|
|
128
|
+
)) })
|
|
129
|
+
] }) : null,
|
|
130
|
+
tool.example ? /* @__PURE__ */ jsx("pre", { className: "max-h-40 overflow-auto whitespace-pre-wrap break-words rounded-[var(--as-radius-sm)] bg-[var(--as-surface-raised)] p-2 font-mono text-[11px] leading-relaxed", children: tool.example }) : null,
|
|
131
|
+
tool.response ? /* @__PURE__ */ jsxs("div", { children: [
|
|
132
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 font-medium uppercase tracking-wide text-[var(--as-muted-fg)]", children: labels?.response ?? "Response" }),
|
|
133
|
+
/* @__PURE__ */ jsx("p", { className: "text-[var(--as-fg)]", children: tool.response })
|
|
134
|
+
] }) : null
|
|
135
|
+
] }) : null
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
tool.name
|
|
139
|
+
);
|
|
140
|
+
}) })
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
export { ChatToolsCatalog };
|
|
148
|
+
//# sourceMappingURL=chunk-ZSCL34WT.js.map
|
|
149
|
+
//# sourceMappingURL=chunk-ZSCL34WT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat-tools-catalog/ChatToolsCatalog.tsx"],"names":["ChatToolsCatalog"],"mappings":"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","file":"chunk-ZSCL34WT.js","sourcesContent":["import * as React from 'react'\nimport { ChevronDown, Search, Wrench } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { searchScore } from '../../lib/fuzzy'\n\nexport interface ChatToolCatalogArgument {\n name: string\n type?: string\n required?: boolean\n description?: string | null\n}\n\nexport interface ChatToolCatalogEntry {\n /** Stable tool identifier (rendered mono). */\n name: string\n /** Human title; falls back to `name`. */\n title?: string\n description?: string\n arguments?: ChatToolCatalogArgument[]\n example?: string | null\n response?: string | null\n scope?: string | null\n}\n\nexport interface ChatToolsCatalogLabels {\n /** Accessible name of the tool list. */\n tools: string\n search: string\n searchPlaceholder: string\n arguments: string\n response: string\n required: string\n optional: string\n empty: string\n noResults: string\n}\n\nexport interface ChatToolsCatalogProps {\n tools: ChatToolCatalogEntry[]\n searchable?: boolean\n /** Expand every entry's details initially (uncontrolled per entry after that). */\n defaultOpen?: boolean\n labels?: Partial<ChatToolsCatalogLabels>\n icon?: LucideIcon\n className?: string\n}\n\n/**\n * Catalog of the tools an assistant can use (study's `ToolsDialog` body,\n * generalized): searchable disclosure cards with description, argument\n * list, example and response shape. Presentational only — fetching and\n * the surrounding modal/popover stay app-side.\n */\nexport const ChatToolsCatalog = React.forwardRef<HTMLDivElement, ChatToolsCatalogProps>(\n function ChatToolsCatalog(\n {\n tools,\n searchable = true,\n defaultOpen = false,\n labels,\n icon: Icon = Wrench,\n className,\n },\n ref,\n ) {\n const uid = React.useId()\n const [query, setQuery] = React.useState('')\n const [openOverrides, setOpenOverrides] = React.useState<Record<string, boolean>>({})\n\n const filtered = React.useMemo(() => {\n const trimmed = query.trim()\n if (trimmed === '') {\n return tools\n }\n return tools\n .map((tool) => ({\n tool,\n score: Math.max(\n searchScore(trimmed, tool.title ?? tool.name) ?? -1,\n searchScore(trimmed, tool.name) ?? -1,\n searchScore(trimmed, tool.description ?? '') ?? -1,\n ),\n }))\n .filter((entry) => entry.score >= 0)\n .sort((a, b) => b.score - a.score)\n .map((entry) => entry.tool)\n }, [tools, query])\n\n return (\n <div\n ref={ref}\n data-as=\"chat-tools-catalog\"\n className={cn('flex min-h-0 w-full flex-col gap-2', className)}\n >\n {searchable ? (\n <div className=\"relative shrink-0\">\n <Search\n className=\"pointer-events-none absolute start-2 top-1/2 size-3.5 -translate-y-1/2 text-[var(--as-muted-fg)]\"\n aria-hidden\n />\n <input\n type=\"search\"\n role=\"searchbox\"\n value={query}\n aria-label={labels?.search ?? 'Search tools'}\n placeholder={labels?.searchPlaceholder ?? 'Search…'}\n onChange={(event) => setQuery(event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] py-1.5 pe-2 ps-8 text-xs text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n />\n </div>\n ) : null}\n <div role=\"list\" aria-label={labels?.tools ?? 'Tools'} className=\"flex flex-col gap-2\">\n {tools.length === 0 ? (\n <p className=\"px-1 py-3 text-xs text-[var(--as-muted-fg)]\">\n {labels?.empty ?? 'No tools available'}\n </p>\n ) : filtered.length === 0 ? (\n <p className=\"px-1 py-3 text-xs text-[var(--as-muted-fg)]\">\n {labels?.noResults ?? 'No matching tools'}\n </p>\n ) : (\n filtered.map((tool) => {\n const open = openOverrides[tool.name] ?? defaultOpen\n const regionId = `${uid}-${tool.name}`\n const toggle = () =>\n setOpenOverrides((current) => ({ ...current, [tool.name]: !open }))\n return (\n <div\n key={tool.name}\n role=\"listitem\"\n data-as=\"chat-tools-catalog-entry\"\n data-open={open || undefined}\n className=\"rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-xs\"\n >\n <button\n type=\"button\"\n aria-expanded={open}\n aria-controls={regionId}\n onClick={toggle}\n className=\"flex w-full items-center gap-2 px-2.5 py-1.5 text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <Icon className=\"size-3.5 shrink-0 text-[var(--as-muted-fg)]\" aria-hidden />\n <span className=\"min-w-0 flex-1\">\n <span className=\"font-mono font-medium text-[var(--as-fg)]\">{tool.name}</span>\n {tool.title ? (\n <span className=\"ml-1.5 text-[var(--as-muted-fg)]\">{tool.title}</span>\n ) : null}\n </span>\n {tool.scope ? (\n <span className=\"shrink-0 rounded-full bg-[var(--as-surface-raised)] px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-[var(--as-muted-fg)]\">\n {tool.scope}\n </span>\n ) : null}\n <ChevronDown\n className={cn(\n 'size-3.5 shrink-0 text-[var(--as-muted-fg)] transition-transform',\n open && 'rotate-180',\n )}\n aria-hidden\n />\n </button>\n {open ? (\n <div id={regionId} className=\"flex flex-col gap-2 border-t border-[var(--as-border)] px-2.5 py-2\">\n {tool.description ? (\n <p className=\"text-[var(--as-fg)]\">{tool.description}</p>\n ) : null}\n {tool.arguments && tool.arguments.length > 0 ? (\n <div>\n <p className=\"mb-1 font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">\n {labels?.arguments ?? 'Arguments'}\n </p>\n <ul className=\"flex flex-col gap-1.5\">\n {tool.arguments.map((argument) => (\n <li\n key={argument.name}\n className=\"rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] px-2 py-1.5\"\n >\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1\">\n <span className=\"font-mono font-medium text-[var(--as-fg)]\">\n {argument.name}\n </span>\n {argument.type ? (\n <span className=\"rounded-full border border-[var(--as-border)] bg-[var(--as-surface)] px-1.5 py-px font-mono text-[10px] leading-4 text-[var(--as-muted-fg)]\">\n {argument.type}\n </span>\n ) : null}\n <span\n className={cn(\n 'text-[10px] font-medium uppercase tracking-wide',\n argument.required\n ? 'text-[var(--as-warning)]'\n : 'text-[var(--as-muted-fg)]',\n )}\n >\n {argument.required\n ? (labels?.required ?? 'required')\n : (labels?.optional ?? 'optional')}\n </span>\n </div>\n {argument.description ? (\n <p className=\"mt-0.5 leading-snug text-[var(--as-muted-fg)]\">\n {argument.description}\n </p>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n {tool.example ? (\n <pre className=\"max-h-40 overflow-auto whitespace-pre-wrap break-words rounded-[var(--as-radius-sm)] bg-[var(--as-surface-raised)] p-2 font-mono text-[11px] leading-relaxed\">\n {tool.example}\n </pre>\n ) : null}\n {tool.response ? (\n <div>\n <p className=\"mb-1 font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">\n {labels?.response ?? 'Response'}\n </p>\n <p className=\"text-[var(--as-fg)]\">{tool.response}</p>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n )\n })\n )}\n </div>\n </div>\n )\n },\n)\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -74,6 +74,10 @@ export { ChatComposer, ChatComposerIcons, ChatComposerLabels, ChatComposerProps
|
|
|
74
74
|
export { ChatTranscript, ChatTranscriptLabels, ChatTranscriptProps } from './chat-transcript.js';
|
|
75
75
|
export { ChatBranchTree, ChatBranchTreeIcons, ChatBranchTreeLabels, ChatBranchTreeNode, ChatBranchTreeProps } from './chat-branch-tree.js';
|
|
76
76
|
export { ChatSessionList, ChatSessionListIcons, ChatSessionListLabels, ChatSessionListProps, ChatSessionView } from './chat-session-list.js';
|
|
77
|
+
export { ChatToolCatalogArgument, ChatToolCatalogEntry, ChatToolsCatalog, ChatToolsCatalogLabels, ChatToolsCatalogProps } from './chat-tools-catalog.js';
|
|
78
|
+
export { ChatExportMessage, ChatExportOptions, buildChatMarkdown, chatExportFileName, downloadChatMarkdown } from './chat-export.js';
|
|
79
|
+
export { ChatHistoryButton, ChatHistoryButtonLabels, ChatHistoryButtonProps } from './chat-history-button.js';
|
|
80
|
+
export { ChatTraceMeta, ChatTraceMetaProps } from './chat-trace-meta.js';
|
|
77
81
|
export { ChatPanel, ChatPanelProps, ChatPanelVariant } from './chat-panel.js';
|
|
78
82
|
export { ChatDrawer, ChatDrawerProps } from './chat-drawer.js';
|
|
79
83
|
export { ChatLauncher, ChatLauncherProps } from './chat-launcher.js';
|
package/dist/index.js
CHANGED
|
@@ -1,61 +1,65 @@
|
|
|
1
|
+
export { UserMenu } from './chunk-535TM7SK.js';
|
|
2
|
+
export { ThemeScope } from './chunk-TGU3PKNM.js';
|
|
3
|
+
export { TimeList } from './chunk-GVOC3ARM.js';
|
|
4
|
+
export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
|
|
1
5
|
export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
|
|
2
6
|
export { UndoNotice } from './chunk-OUHUVACM.js';
|
|
3
7
|
export { ViewToggle } from './chunk-MXOBOS4Y.js';
|
|
4
8
|
export { Stepper, Wizard } from './chunk-YMCMUAIF.js';
|
|
9
|
+
export { ModelRegistry } from './chunk-BHHDCY2B.js';
|
|
10
|
+
export { CapabilityChips } from './chunk-G3DWN2DJ.js';
|
|
11
|
+
export { SelectionBar } from './chunk-HSUCCANX.js';
|
|
5
12
|
export { Table } from './chunk-5LRRVD27.js';
|
|
6
13
|
export { TaskAssignmentPicker } from './chunk-Q5THPPNL.js';
|
|
7
14
|
export { SettingsShell } from './chunk-ZK2V2LPA.js';
|
|
8
15
|
export { SidebarNav } from './chunk-SW3YNICQ.js';
|
|
9
|
-
export {
|
|
10
|
-
export { ThemeScope } from './chunk-TGU3PKNM.js';
|
|
11
|
-
export { TimeList } from './chunk-GVOC3ARM.js';
|
|
12
|
-
export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
|
|
16
|
+
export { ProviderForm } from './chunk-4WDXLXHL.js';
|
|
13
17
|
export { RangeBar } from './chunk-PFAH25VU.js';
|
|
14
18
|
export { ScaleSlider, scaleColorForValue } from './chunk-PSFJN7WH.js';
|
|
15
19
|
export { SearchInput } from './chunk-H5U4KNXF.js';
|
|
16
|
-
export { ModelRegistry } from './chunk-BHHDCY2B.js';
|
|
17
|
-
export { CapabilityChips } from './chunk-G3DWN2DJ.js';
|
|
18
|
-
export { SelectionBar } from './chunk-HSUCCANX.js';
|
|
19
|
-
export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee } from './chunk-RU3DEF2O.js';
|
|
20
|
-
export { ModelPicker } from './chunk-S4WHBQJ2.js';
|
|
21
|
-
export { PanelModal } from './chunk-G6557MEN.js';
|
|
22
|
-
export { ProviderForm } from './chunk-4WDXLXHL.js';
|
|
23
|
-
export { Input } from './chunk-M4V7XHL7.js';
|
|
24
20
|
export { RichTextEditor } from './chunk-AY77TWLT.js';
|
|
25
21
|
export { DictationButton, DictationStrip, useDictation } from './chunk-KAC2DOLH.js';
|
|
26
22
|
export { useAiTextTransform } from './chunk-BKAO7BTU.js';
|
|
27
23
|
export { TextDiffView, computeLineDiff, wordSegments } from './chunk-2PR6POP6.js';
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
24
|
+
export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee } from './chunk-RU3DEF2O.js';
|
|
25
|
+
export { ModelPicker } from './chunk-S4WHBQJ2.js';
|
|
26
|
+
export { PanelModal } from './chunk-G6557MEN.js';
|
|
31
27
|
export { FileQueue } from './chunk-IQKP2BWE.js';
|
|
32
|
-
export { FileCard, formatBytes } from './chunk-J4OELYDR.js';
|
|
33
28
|
export { FlowStatusCard } from './chunk-PRHTQBCP.js';
|
|
34
29
|
export { FieldLabel } from './chunk-I5J6SDLK.js';
|
|
35
30
|
export { InfoButton } from './chunk-OT6EQFMP.js';
|
|
36
|
-
export {
|
|
37
|
-
export { CheckIndicator } from './chunk-XE4TFW63.js';
|
|
38
|
-
export { ChipInput } from './chunk-HIRR2F4R.js';
|
|
39
|
-
export { Combobox, ComboboxMulti } from './chunk-WDLUZS2G.js';
|
|
31
|
+
export { Input } from './chunk-M4V7XHL7.js';
|
|
40
32
|
export { ConfirmationModal } from './chunk-2YQSA5AE.js';
|
|
41
33
|
export { ContextMenu } from './chunk-YIGLULRG.js';
|
|
42
34
|
export { ActionMenu, Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuLabel, MenuSeparator, MenuTrigger } from './chunk-XSJ3TWWZ.js';
|
|
43
35
|
export { DatePicker } from './chunk-6VCJX4CP.js';
|
|
36
|
+
export { EmptyState } from './chunk-KDJLYKR6.js';
|
|
37
|
+
export { ErrorBanner } from './chunk-BJOY3XL7.js';
|
|
38
|
+
export { ExpandableSearch } from './chunk-4SW3ESVI.js';
|
|
39
|
+
export { FileCard, formatBytes } from './chunk-J4OELYDR.js';
|
|
40
|
+
export { ChatHistoryButton } from './chunk-YYPO24TA.js';
|
|
41
|
+
export { PopoverButton } from './chunk-BE3XFZWU.js';
|
|
42
|
+
export { ChatTraceMeta } from './chunk-QMQ73C23.js';
|
|
43
|
+
export { ChatToolsCatalog } from './chunk-ZSCL34WT.js';
|
|
44
|
+
export { ConnectionTestRow } from './chunk-OGQF4XJB.js';
|
|
45
|
+
export { CheckIndicator } from './chunk-XE4TFW63.js';
|
|
46
|
+
export { ChipInput } from './chunk-HIRR2F4R.js';
|
|
47
|
+
export { Combobox, ComboboxMulti } from './chunk-WDLUZS2G.js';
|
|
44
48
|
export { ChatBranchTree } from './chunk-HQIYSW2D.js';
|
|
45
|
-
export { ChatDrawer } from './chunk-
|
|
49
|
+
export { ChatDrawer } from './chunk-WBSGFOSD.js';
|
|
46
50
|
export { ChatReasoning } from './chunk-QVDCFZSE.js';
|
|
47
51
|
export { ChatSessionList } from './chunk-NKYPNEOX.js';
|
|
48
52
|
export { ChatToolCard } from './chunk-NBT7NLNU.js';
|
|
49
53
|
export { ChatTurnStatus } from './chunk-P75QKU5J.js';
|
|
50
|
-
export {
|
|
54
|
+
export { buildChatMarkdown, chatExportFileName, downloadChatMarkdown } from './chunk-DRJGZ5TB.js';
|
|
51
55
|
export { initialLiveTurnState, liveTurnReducer, useChatStream } from './chunk-6GNLY2EB.js';
|
|
52
56
|
export { activePathSet, buildBranchTree, linearTree, variantInfo, walkActivePath } from './chunk-Z4IBQ53C.js';
|
|
53
57
|
export { ChatLauncher } from './chunk-RPLEI6LQ.js';
|
|
54
58
|
export { Portal } from './chunk-XZWLTTHA.js';
|
|
55
59
|
export { ChatComposer } from './chunk-743FJDRA.js';
|
|
56
|
-
export { ChatPanel } from './chunk-
|
|
57
|
-
export { ChatTranscript } from './chunk-
|
|
58
|
-
export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher } from './chunk-
|
|
60
|
+
export { ChatPanel } from './chunk-LFSICACE.js';
|
|
61
|
+
export { ChatTranscript } from './chunk-FS7M7PNS.js';
|
|
62
|
+
export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher } from './chunk-FGYGWZ6S.js';
|
|
59
63
|
export { MarkdownCodeBlock, MarkdownSurface, MermaidDiagram } from './chunk-DZBTJZZV.js';
|
|
60
64
|
export { CopyButton } from './chunk-3JJ2WCPN.js';
|
|
61
65
|
export { rawTokens, semanticTokens } from './chunk-GDGKARRB.js';
|
|
@@ -66,7 +70,7 @@ export { ChipList } from './chunk-QUPGIPTT.js';
|
|
|
66
70
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-RYE5YCFF.js';
|
|
67
71
|
export { AiButton } from './chunk-3VCFRIIK.js';
|
|
68
72
|
export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from './chunk-SIIY2EGI.js';
|
|
69
|
-
export { AiMagicFill } from './chunk-
|
|
73
|
+
export { AiMagicFill } from './chunk-EODV6JK7.js';
|
|
70
74
|
export { FormModal } from './chunk-62GIJMWT.js';
|
|
71
75
|
export { Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, ModalTrigger, modalContentVariants } from './chunk-Y7BKBG57.js';
|
|
72
76
|
export { Button, buttonVariants } from './chunk-GTXGTQ6F.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react'\nimport { FolderUp, Loader2, Upload } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface UploadDropzoneProps {\n onFiles: (files: File[]) => void\n uploading?: boolean\n variant?: 'block' | 'row'\n label?: string\n hint?: string\n browseLabel?: string\n folderLabel?: string\n accept?: string\n multiple?: boolean\n allowFolders?: boolean\n disabled?: boolean\n className?: string\n}\n\n/**\n * Presentational dropzone: drag events and file-picker results go out via\n * `onFiles` — uploading, storage and progress stay app-side. Pass\n * `uploading` to render a busy state and suppress input.\n */\nexport const UploadDropzone = React.forwardRef<HTMLDivElement, UploadDropzoneProps>(\n function UploadDropzone(\n {\n onFiles,\n uploading = false,\n variant = 'block',\n label = 'Drop files here or click to browse',\n hint,\n browseLabel = 'Choose files',\n folderLabel = 'Choose folder',\n accept,\n multiple = true,\n allowFolders = false,\n disabled = false,\n className,\n },\n ref,\n ) {\n const [dragging, setDragging] = React.useState(false)\n const fileInput = React.useRef<HTMLInputElement>(null)\n const folderInput = React.useRef<HTMLInputElement>(null)\n\n const active = !disabled && !uploading\n\n const emit = (list: FileList | null) => {\n if (!active || !list || list.length === 0) return\n onFiles(Array.from(list))\n }\n\n const input = allowFolders ? (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n <input\n ref={folderInput}\n type=\"file\"\n multiple\n className=\"hidden\"\n // @ts-expect-error non-standard but universally supported directory picker\n webkitdirectory=\"\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n </>\n ) : (\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n )\n\n return (\n <>\n {input}\n <div\n ref={ref}\n data-as=\"upload-dropzone\"\n data-variant={variant}\n data-dragging={dragging || undefined}\n role=\"button\"\n tabIndex={active ? 0 : -1}\n aria-label={label}\n aria-disabled={disabled || uploading || undefined}\n onClick={() => active && fileInput.current?.click()}\n onKeyDown={(event) => {\n if (active && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault()\n fileInput.current?.click()\n }\n }}\n onDragOver={(event) => {\n event.preventDefault()\n if (active) setDragging(true)\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={(event) => {\n event.preventDefault()\n setDragging(false)\n emit(event.dataTransfer.files)\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-center gap-3 border border-dashed border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] transition-colors',\n 'hover:border-[var(--as-primary)] hover:text-[var(--as-fg)]',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n variant === 'block' ? 'rounded-[var(--as-radius-lg)] p-8' : 'rounded-[var(--as-radius)] px-4 py-3',\n dragging && 'border-[var(--as-primary)] bg-[color-mix(in_srgb,var(--as-primary)_8%,transparent)] text-[var(--as-fg)]',\n uploading && 'cursor-progress opacity-70',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n >\n {uploading ? (\n <Loader2 className=\"size-5 shrink-0 animate-spin\" aria-hidden />\n ) : allowFolders ? (\n <FolderUp className=\"size-5 shrink-0\" aria-hidden />\n ) : (\n <Upload className=\"size-5 shrink-0\" aria-hidden />\n )}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-sm font-medium\" role={uploading ? 'status' : undefined}>\n {uploading ? `${browseLabel}…` : dragging ? folderLabel : label}\n </span>\n {hint ? <span className=\"truncate text-xs\">{hint}</span> : null}\n </span>\n </div>\n </>\n )\n },\n)\n"]}
|