@columenlabs/lumen-ui 0.1.228 → 0.1.230
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.
|
@@ -57,6 +57,11 @@ export interface LumenAssistantProps {
|
|
|
57
57
|
tool: string;
|
|
58
58
|
mode?: string;
|
|
59
59
|
};
|
|
60
|
+
/**
|
|
61
|
+
* Where the server compacts the chat, in tokens (the agent's `compactAt()`), drawn as the tick on
|
|
62
|
+
* the context bar. 150k by default.
|
|
63
|
+
*/
|
|
64
|
+
compactAt?: number;
|
|
60
65
|
}
|
|
61
66
|
/** A composer mode: its toggle's icon and label (also its tooltip and aria-label). */
|
|
62
67
|
export interface AssistantMode {
|
|
@@ -78,7 +83,7 @@ export interface AssistantCommand {
|
|
|
78
83
|
run: (args: string) => string | undefined | Promise<string | undefined>;
|
|
79
84
|
}
|
|
80
85
|
/** The assistant's chat: header, messages and composer. */
|
|
81
|
-
export declare function LumenAssistant({ client, context, onSettings, keepDays, chatScope, onClose, chat: outside, commands, sources, images, modes, imageTool, }: LumenAssistantProps): import("react").JSX.Element;
|
|
86
|
+
export declare function LumenAssistant({ client, context, onSettings, keepDays, chatScope, onClose, chat: outside, commands, sources, images, modes, imageTool, compactAt, }: LumenAssistantProps): import("react").JSX.Element;
|
|
82
87
|
/** An allowance in its unit: `$4.20`, or `350 credits`. */
|
|
83
88
|
export declare const allowanceAmount: (u: AllowanceUnit, n: number) => string;
|
|
84
89
|
/** What the composer sends with the text: the tier picked with `#` and the things pointed at with `@`. */
|
|
@@ -51,7 +51,7 @@ export function useAssistantStatus(client) {
|
|
|
51
51
|
export { usd };
|
|
52
52
|
const seconds = (ms) => (ms < 1000 ? `${ms} ms` : `${(ms / 1000).toFixed(1)} s`);
|
|
53
53
|
/** The assistant's chat: header, messages and composer. */
|
|
54
|
-
export function LumenAssistant({ client, context, onSettings, keepDays = 30, chatScope, onClose, chat: outside, commands = [], sources = [], images = false, modes = [], imageTool, }) {
|
|
54
|
+
export function LumenAssistant({ client, context, onSettings, keepDays = 30, chatScope, onClose, chat: outside, commands = [], sources = [], images = false, modes = [], imageTool, compactAt = COMPACT_AT, }) {
|
|
55
55
|
const own = useAssistantChat(client);
|
|
56
56
|
const chat = outside ?? own;
|
|
57
57
|
const qc = useQueryClient();
|
|
@@ -115,7 +115,8 @@ export function LumenAssistant({ client, context, onSettings, keepDays = 30, cha
|
|
|
115
115
|
},
|
|
116
116
|
}
|
|
117
117
|
: null;
|
|
118
|
-
|
|
118
|
+
// The app picks the tier itself (pick_tier false): no tier menu, `#`, /model or /escalate.
|
|
119
|
+
const tiers = s?.pick_tier === false ? [] : (s?.tiers ?? []);
|
|
119
120
|
const above = tiers.slice(tiers.findIndex((t) => t.id === s?.tier) + 1);
|
|
120
121
|
// The kit's commands; the app's own (`commands`, then the server's) come first and win a name.
|
|
121
122
|
const builtIns = [
|
|
@@ -185,14 +186,14 @@ export function LumenAssistant({ client, context, onSettings, keepDays = 30, cha
|
|
|
185
186
|
allCommands.push(c);
|
|
186
187
|
const shown = useShownAssistantSources();
|
|
187
188
|
const allSources = [...shown, ...sources.filter((x) => !shown.some((y) => y.id === x.id))];
|
|
188
|
-
return (_jsxs("div", { "data-assistant": "", className: "flex h-full min-h-0 flex-col", children: [_jsxs("div", { className: "flex h-12 shrink-0 items-center gap-1 border-b px-3", children: [_jsx(SparklesIcon, { className: "size-4 text-edge" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: chat.title || s?.name || 'Assistant' }), s &&
|
|
189
|
+
return (_jsxs("div", { "data-assistant": "", className: "flex h-full min-h-0 flex-col", children: [_jsxs("div", { className: "flex h-12 shrink-0 items-center gap-1 border-b px-3", children: [_jsx(SparklesIcon, { className: "size-4 text-edge" }), _jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: chat.title || s?.name || 'Assistant' }), s && tiers.length > 1 && (_jsx(LumenSelector, { trigger: "chip", size: "sm", label: "Tier", value: s.tier, options: tiers.map((t) => ({ value: t.id, label: t.label, detail: t.model_label })), onChange: (t) => void setTier(t) })), _jsx(LumenAssistantChats, { chats: chats.data
|
|
189
190
|
?.filter((c) => !chatScope || allScopes || c.scope === chatScope.current)
|
|
190
191
|
.map((c) => ({
|
|
191
192
|
id: c.id,
|
|
192
193
|
title: c.title,
|
|
193
194
|
updated_at: new Date(c.at).toISOString(),
|
|
194
195
|
...(chatScope && allScopes && c.scope ? { where: chatScope.name?.(c.scope) } : {}),
|
|
195
|
-
})) ?? (chats.isFetched ? [] : null), value: chat.chatId ?? undefined, toggle: chatScope && { label: chatScope.label, on: allScopes, onChange: setAllScopes }, note: `Chats are kept ${keepDays} days after their last message.`, onRefresh: () => void chats.refetch(), onOpen: (c) => void chat.open(c.id) }), _jsx(IconButton, { icon: CopyIcon, label: "Copy chat", disabled: !chat.items.length, onClick: () => copyMarkdown(chatMarkdown(chat.title, chat.items, name), 'Chat') }), _jsx(IconButton, { icon: PlusIcon, label: "New chat", disabled: !chat.items.length, onClick: chat.reset }), onClose && (_jsx(IconButton, { icon: XIcon, label: `Close ${s?.name ?? 'assistant'}`, onClick: onClose }))] }), _jsx(AssistantName.Provider, { value: name, children: _jsx(Screen.Provider, { value: controls, children: _jsx(ImageTool.Provider, { value: imageTool ?? null, children: _jsx(Messages, { chat: chat, status: s, onSettings: onSettings, onRetry: (at, user) => chat.retry(at, user, extra()) }) }) }) }), _jsx(LumenComposer, { name: s?.name ?? 'the assistant', busy: chat.busy, queued: chat.queued, queue: chat.queue, canSteer: chat.canSteer, onSteerQueued: chat.steerQueued, onUnqueue: chat.unqueue, disabled: !s || !!s.wait, commands: allCommands, tiers: tiers, sources: allSources, page: context?.label, images: images, modes: modes, onSend: (text, more, how) => chat.send(text, { ...extra(), ...more }, how), onStop: chat.stop }), _jsx(UsageLine, { usage: chat.usage, client: client, spent: s?.spend.usd })] }));
|
|
196
|
+
})) ?? (chats.isFetched ? [] : null), value: chat.chatId ?? undefined, toggle: chatScope && { label: chatScope.label, on: allScopes, onChange: setAllScopes }, note: `Chats are kept ${keepDays} days after their last message.`, onRefresh: () => void chats.refetch(), onOpen: (c) => void chat.open(c.id) }), _jsx(IconButton, { icon: CopyIcon, label: "Copy chat", disabled: !chat.items.length, onClick: () => copyMarkdown(chatMarkdown(chat.title, chat.items, name), 'Chat') }), _jsx(IconButton, { icon: PlusIcon, label: "New chat", disabled: !chat.items.length, onClick: chat.reset }), onClose && (_jsx(IconButton, { icon: XIcon, label: `Close ${s?.name ?? 'assistant'}`, onClick: onClose }))] }), _jsx(AssistantName.Provider, { value: name, children: _jsx(Screen.Provider, { value: controls, children: _jsx(ImageTool.Provider, { value: imageTool ?? null, children: _jsx(Messages, { chat: chat, status: s, onSettings: onSettings, onRetry: (at, user) => chat.retry(at, user, extra()) }) }) }) }), _jsx(LumenComposer, { name: s?.name ?? 'the assistant', busy: chat.busy, queued: chat.queued, queue: chat.queue, canSteer: chat.canSteer, onSteerQueued: chat.steerQueued, onUnqueue: chat.unqueue, disabled: !s || !!s.wait, commands: allCommands, tiers: tiers, sources: allSources, page: context?.label, images: images, modes: modes, onSend: (text, more, how) => chat.send(text, { ...extra(), ...more }, how), onStop: chat.stop }), _jsx(UsageLine, { usage: chat.usage, client: client, spent: s?.spend.usd, compactAt: compactAt })] }));
|
|
196
197
|
}
|
|
197
198
|
function Messages({ chat, status, onSettings, onRetry, }) {
|
|
198
199
|
const end = useRef(null);
|
|
@@ -954,7 +955,7 @@ function MonthTotal({ client, spent, phone, className, }) {
|
|
|
954
955
|
* The chat's cost, tokens in and out and cache hit (a pop-up splits them per part, a sheet on a
|
|
955
956
|
* phone), how full the context is, and this month's total (`MonthTotal`).
|
|
956
957
|
*/
|
|
957
|
-
function UsageLine({ usage, client, spent, }) {
|
|
958
|
+
function UsageLine({ usage, client, spent, compactAt, }) {
|
|
958
959
|
const phone = useIsMobile();
|
|
959
960
|
const month = !!client.usage && spent !== undefined && spent > 0;
|
|
960
961
|
if ((!usage || !usage.calls) && !month)
|
|
@@ -964,7 +965,7 @@ function UsageLine({ usage, client, spent, }) {
|
|
|
964
965
|
if (!usage || !usage.calls)
|
|
965
966
|
return (_jsx("div", { className: "flex shrink-0 items-center gap-3 px-3 pb-2 text-muted-foreground text-xs", children: total }));
|
|
966
967
|
const trigger = (_jsxs("button", { type: "button", className: "flex min-w-0 items-center gap-2 tabular-nums hover:text-foreground", "aria-label": "This chat's usage", children: [_jsxs("span", { className: "num truncate", children: [usd(usage.usd), " \u00B7 \u2191", tokens(usage.in), " \u2193", tokens(usage.out)] }), _jsxs("span", { className: "num flex shrink-0 items-center gap-0.5", title: "Read from cache", children: [_jsx(ZapIcon, { className: "size-3", "aria-hidden": true }), hitPct(usage), "%"] })] }));
|
|
967
|
-
return (_jsxs("div", { className: "flex shrink-0 items-center gap-3 px-3 pb-2 text-muted-foreground text-xs", children: [phone ? (_jsxs(Sheet, { children: [_jsx(SheetTrigger, { asChild: true, children: trigger }), _jsxs(SheetContent, { side: "bottom", children: [_jsx(SheetHeader, { children: _jsx(SheetTitle, { children: "This chat's usage" }) }), _jsx("div", { className: "overflow-x-auto px-4 pb-6", children: _jsx(UsageTable, { usage: usage }) })] })] })) : (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: trigger }), _jsx(PopoverContent, { align: "start", className: "w-auto p-2", children: _jsx(UsageTable, { usage: usage }) })] })), ctx > 0 && (_jsxs("span", { className: "ml-auto flex items-center gap-1.5", title: `Context ${tokens(ctx)} of ${tokens(CONTEXT_MAX)}`, children: [_jsxs("span", { className: "relative h-1 w-16 overflow-hidden rounded-full bg-muted", children: [_jsx("span", { className: cn('absolute inset-y-0 left-0', ctx >
|
|
968
|
+
return (_jsxs("div", { className: "flex shrink-0 items-center gap-3 px-3 pb-2 text-muted-foreground text-xs", children: [phone ? (_jsxs(Sheet, { children: [_jsx(SheetTrigger, { asChild: true, children: trigger }), _jsxs(SheetContent, { side: "bottom", children: [_jsx(SheetHeader, { children: _jsx(SheetTitle, { children: "This chat's usage" }) }), _jsx("div", { className: "overflow-x-auto px-4 pb-6", children: _jsx(UsageTable, { usage: usage }) })] })] })) : (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: trigger }), _jsx(PopoverContent, { align: "start", className: "w-auto p-2", children: _jsx(UsageTable, { usage: usage }) })] })), ctx > 0 && (_jsxs("span", { className: "ml-auto flex items-center gap-1.5", title: `Context ${tokens(ctx)} of ${tokens(CONTEXT_MAX)}`, children: [_jsxs("span", { className: "relative h-1 w-16 overflow-hidden rounded-full bg-muted", children: [_jsx("span", { className: cn('absolute inset-y-0 left-0', ctx > compactAt ? 'bg-warning' : 'bg-primary/60'), style: { width: `${Math.min(100, (ctx / CONTEXT_MAX) * 100)}%` } }), _jsx("span", { className: "absolute inset-y-0 w-px bg-foreground/40", style: { left: `${(compactAt / CONTEXT_MAX) * 100}%` } })] }), _jsx("span", { className: "tabular-nums", children: tokens(ctx) })] })), total] }));
|
|
968
969
|
}
|
|
969
970
|
/**
|
|
970
971
|
* The assistant docked in LumenShell: put `button` in `headerActions` and `panel` in `panel`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@columenlabs/lumen-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.230",
|
|
4
4
|
"description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@codemirror/lang-javascript": "6.2.5",
|
|
50
50
|
"@codemirror/lang-json": "6.0.2",
|
|
51
51
|
"@codemirror/lang-sql": "6.10.0",
|
|
52
|
-
"@columenlabs/lumen-ui-types": "0.1.
|
|
52
|
+
"@columenlabs/lumen-ui-types": "0.1.230",
|
|
53
53
|
"@dnd-kit/core": "6.3.1",
|
|
54
54
|
"@dnd-kit/sortable": "10.0.0",
|
|
55
55
|
"@dnd-kit/utilities": "3.2.2",
|