@columenlabs/lumen-ui 0.1.244 → 0.1.246
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.
|
@@ -22,10 +22,10 @@ import { cardsOnScreen, kindName, pointAt, sectionsOnScreen, targetEl, textOf, }
|
|
|
22
22
|
import { Alert, AlertDescription } from '../ui/alert.js';
|
|
23
23
|
import { Button } from '../ui/button.js';
|
|
24
24
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible.js';
|
|
25
|
+
import { InputGroup, InputGroupAddon, InputGroupTextarea } from '../ui/input-group.js';
|
|
25
26
|
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover.js';
|
|
26
27
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../ui/sheet.js';
|
|
27
28
|
import { Spinner } from '../ui/spinner.js';
|
|
28
|
-
import { Textarea } from '../ui/textarea.js';
|
|
29
29
|
import { ChatImage } from './chat-image.js';
|
|
30
30
|
import { chatMarkdown, chatTurns, copyMarkdown, turnMarkdown } from './copy.js';
|
|
31
31
|
import { ImageCard, ImagePending, toolIs } from './image-card.js';
|
|
@@ -880,7 +880,7 @@ export function LumenComposer({ name, busy, queued, queue, canSteer = false, onS
|
|
|
880
880
|
const r = sourceItems.get(o.value)?.();
|
|
881
881
|
if (r)
|
|
882
882
|
setRefs((p) => [...p, r]);
|
|
883
|
-
}, onClose: () => setClosed(`${text}|${caret}`) })), quote && _jsx(QuoteLine, { quote: quote, onRemove: () => setQuote(null) }), images.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", "aria-label": "Images going with your message", children: images.map((img, i) => (_jsxs("span", { className: "relative", children: [_jsx("img", { src: imageUrl(img), alt: `Pasted ${i + 1}`, className: "size-12 rounded-md border object-cover" }), _jsx("button", { type: "button", "aria-label": `Remove image ${i + 1}`, className: "absolute -top-1.5 -right-1.5 grid size-4 place-items-center rounded-full border bg-background text-muted-foreground hover:text-foreground", onClick: () => setImages((p) => p.filter((_, j) => j !== i)), children: _jsx(XIcon, { className: "size-3" }) })] }, `${i}:${img.data.length}`))) })), (tierLabel || refs.length > 0) && (_jsxs("div", { className: "mb-2 flex flex-wrap gap-1", children: [tierLabel && (_jsx(ComposerChip, { sign: TIER, label: tierLabel, onRemove: () => setTier(null) })), refs.map((r, i) => (_jsx(ComposerChip, { sign: POINT, label: r.label, onRemove: () => setRefs((p) => p.filter((_, j) => j !== i)) }, `${r.kind}:${r.label}:${i}`)))] })), _jsxs(
|
|
883
|
+
}, onClose: () => setClosed(`${text}|${caret}`) })), quote && _jsx(QuoteLine, { quote: quote, onRemove: () => setQuote(null) }), images.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", "aria-label": "Images going with your message", children: images.map((img, i) => (_jsxs("span", { className: "relative", children: [_jsx("img", { src: imageUrl(img), alt: `Pasted ${i + 1}`, className: "size-12 rounded-md border object-cover" }), _jsx("button", { type: "button", "aria-label": `Remove image ${i + 1}`, className: "absolute -top-1.5 -right-1.5 grid size-4 place-items-center rounded-full border bg-background text-muted-foreground hover:text-foreground", onClick: () => setImages((p) => p.filter((_, j) => j !== i)), children: _jsx(XIcon, { className: "size-3" }) })] }, `${i}:${img.data.length}`))) })), (tierLabel || refs.length > 0) && (_jsxs("div", { className: "mb-2 flex flex-wrap gap-1", children: [tierLabel && (_jsx(ComposerChip, { sign: TIER, label: tierLabel, onRemove: () => setTier(null) })), refs.map((r, i) => (_jsx(ComposerChip, { sign: POINT, label: r.label, onRemove: () => setRefs((p) => p.filter((_, j) => j !== i)) }, `${r.kind}:${r.label}:${i}`)))] })), _jsxs(InputGroup, { children: [_jsx(InputGroupTextarea, { ref: box, "aria-label": `Message ${name}`, placeholder: `Ask ${name}…${hints.length ? ` (${hints.join(' ')})` : ''}`, className: "max-h-48 min-h-11", value: text, disabled: disabled, onChange: (e) => {
|
|
884
884
|
setText(e.target.value);
|
|
885
885
|
setCaret(e.target.selectionStart);
|
|
886
886
|
}, onSelect: (e) => setCaret(e.currentTarget.selectionStart), onPaste: (e) => {
|
|
@@ -900,11 +900,11 @@ export function LumenComposer({ name, busy, queued, queue, canSteer = false, onS
|
|
|
900
900
|
e.preventDefault();
|
|
901
901
|
send(e.altKey ? 'queue' : undefined);
|
|
902
902
|
}
|
|
903
|
-
} }), (
|
|
903
|
+
} }), _jsxs(InputGroupAddon, { align: "block-end", className: "gap-0.5 px-1.5 pb-1.5", children: [canAttach && (_jsxs(_Fragment, { children: [_jsx(IconButton, { icon: PaperclipIcon, label: "Attach images", size: "icon-xs", disabled: disabled, onClick: () => filePick.current?.click() }), _jsx("input", { ref: filePick, type: "file", accept: "image/*", multiple: true, hidden: true, onChange: (e) => {
|
|
904
904
|
if (e.target.files)
|
|
905
905
|
attach(e.target.files);
|
|
906
906
|
e.target.value = '';
|
|
907
|
-
} })] })), modes.map((md) => (_jsx(IconButton, { icon: md.icon, label: md.label, size: "icon-xs", variant: use === md.id ? 'secondary' : 'ghost', "aria-pressed": use === md.id, className: cn(use === md.id && 'text-primary'), disabled: disabled, onClick: () => setUse((u) => (u === md.id ? null : md.id)) }, md.id)))
|
|
907
|
+
} })] })), modes.map((md) => (_jsx(IconButton, { icon: md.icon, label: md.label, size: "icon-xs", variant: use === md.id ? 'secondary' : 'ghost', "aria-pressed": use === md.id, className: cn(use === md.id && 'text-primary'), disabled: disabled, onClick: () => setUse((u) => (u === md.id ? null : md.id)) }, md.id))), _jsx("div", { className: "ml-auto", children: busy && !text.trim() ? (_jsx(IconButton, { icon: SquareIcon, label: "Stop", variant: "outline", size: "icon-xs", onClick: onStop })) : busy ? (_jsxs("span", { className: "flex gap-1", children: [_jsx(IconButton, { icon: ListPlusIcon, label: canSteer ? 'Queue for after (⌥↩)' : 'Queue for after (↩)', variant: canSteer ? 'outline' : 'default', size: "icon-xs", disabled: disabled, onClick: () => send('queue') }), canSteer && (_jsx(IconButton, { icon: CornerDownRightIcon, label: "Steer now (\u21A9)", variant: "default", size: "icon-xs", disabled: disabled, onClick: () => send('steer') }))] })) : (_jsx(IconButton, { icon: ArrowUpIcon, label: "Send", variant: "default", size: "icon-xs", disabled: !text.trim() || disabled, onClick: () => send() })) })] })] })] }));
|
|
908
908
|
}
|
|
909
909
|
/**
|
|
910
910
|
* What waits above the box while an answer runs: steering messages until the answer reads them,
|
|
@@ -114,7 +114,6 @@ const wayTest = (k, plan = false) => k?.test
|
|
|
114
114
|
}
|
|
115
115
|
: null;
|
|
116
116
|
/** A provider's mark: its initial on a tile. */
|
|
117
|
-
const mark = (label) => _jsx(ConnectionLogo, { text: label.charAt(0) });
|
|
118
117
|
/**
|
|
119
118
|
* Whether the app lets this person use `w` of their own on `p` (the app's `ownWays`, the same
|
|
120
119
|
* rule the server pays by). A way it does not allow never shows, even when one is still stored:
|
|
@@ -161,7 +160,7 @@ function OwnProviderKey({ client, p }) {
|
|
|
161
160
|
onRemove: () => apply(`own:${p.id}`, () => client.ownKey(p.id, null), 'Key removed'),
|
|
162
161
|
removeTitle: `Remove your ${p.label} key?`,
|
|
163
162
|
});
|
|
164
|
-
return (_jsx(LumenConnection, { id: p.id, name: p.label,
|
|
163
|
+
return (_jsx(LumenConnection, { id: p.id, name: p.label, ways: ways, use: p.use, onUse: (use) => apply(`use:${p.id}`, () => client.settings({ own_use: { [p.id]: use } })) }));
|
|
165
164
|
}
|
|
166
165
|
/** A person's own keys, one row a provider, and what they may spend on them. */
|
|
167
166
|
function Providers({ client }) {
|
|
@@ -171,10 +170,7 @@ function Providers({ client }) {
|
|
|
171
170
|
// is exactly what the server may pay with.
|
|
172
171
|
const rows = s.providers.filter((p) => !p.own_ways || p.own_ways.length > 0);
|
|
173
172
|
const ownSet = rows.some(ownUsable);
|
|
174
|
-
return (_jsxs("div", { className: "flex flex-col", children: [_jsx(LumenExpandList, { children: rows.map((p) => (_jsx(OwnProviderKey, { client: client, p: p }, p.id))) }), ownSet && (_jsx(SettingField, { label: "Answers run on", info: "Your own key or plan first, with the shared credits behind it; or the shared credits first.", children:
|
|
175
|
-
{ value: 'own', label: 'Your own first' },
|
|
176
|
-
{ value: 'app', label: 'Shared credits first' },
|
|
177
|
-
], onChange: (pay) => void apply('pay', () => client.settings({ pay: pay })) }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), ownSet && _jsx(OwnCapUse, { s: s }), _jsx(OwnKeyUsage, { client: client, always: ownSet })] }));
|
|
173
|
+
return (_jsxs("div", { className: "flex flex-col", children: [_jsx(LumenExpandList, { children: rows.map((p) => (_jsx(OwnProviderKey, { client: client, p: p }, p.id))) }), ownSet && (_jsx(SettingField, { label: "Answers run on", info: "Your own key or plan first, with the shared credits behind it; or the shared credits first.", children: _jsxs(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: s.pay, "aria-label": "Answers run on", onValueChange: (pay) => pay && void apply('pay', () => client.settings({ pay: pay })), children: [_jsx(ToggleGroupItem, { value: "own", children: "Your own first" }), _jsx(ToggleGroupItem, { value: "app", children: "Credits first" })] }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), ownSet && _jsx(OwnCapUse, { s: s }), _jsx(OwnKeyUsage, { client: client, always: ownSet })] }));
|
|
178
174
|
} }));
|
|
179
175
|
}
|
|
180
176
|
/**
|
|
@@ -195,7 +191,7 @@ function OwnCapUse({ s }) {
|
|
|
195
191
|
function SharedProviderKey({ client, p }) {
|
|
196
192
|
const { apply, refresh } = useApply(client);
|
|
197
193
|
const env = !p.app.set && !!p.app.from_env;
|
|
198
|
-
return (_jsx(LumenConnection, { id: p.id, name: p.label,
|
|
194
|
+
return (_jsx(LumenConnection, { id: p.id, name: p.label, ways: [
|
|
199
195
|
{
|
|
200
196
|
id: 'key',
|
|
201
197
|
label: 'Shared key',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@columenlabs/lumen-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.246",
|
|
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.246",
|
|
53
53
|
"@dnd-kit/core": "6.3.1",
|
|
54
54
|
"@dnd-kit/sortable": "10.0.0",
|
|
55
55
|
"@dnd-kit/utilities": "3.2.2",
|