@tangle-network/agent-app 0.46.6 → 0.46.7
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/studio-react/composer-option-controls.d.ts +7 -2
- package/dist/studio-react/generation-notice.d.ts +3 -4
- package/dist/studio-react/index.js +93 -32
- package/dist/studio-react/index.js.map +1 -1
- package/dist/studio-react/studio-generation-screen.d.ts +8 -0
- package/dist/theme/tokens.css +0 -2
- package/package.json +1 -1
|
@@ -51,17 +51,21 @@ export declare function ComposerBand({ bandRef, resetKey, children, }: {
|
|
|
51
51
|
export interface OptionChoice {
|
|
52
52
|
value: ModelOptionValue;
|
|
53
53
|
label: string;
|
|
54
|
+
icon?: LucideIcon;
|
|
54
55
|
}
|
|
55
56
|
/** A standalone enum picker using the studio composer's pill and menu grammar. */
|
|
56
|
-
export declare function MenuPill<T extends string>({ label, value, choices, onSelect, className, }: {
|
|
57
|
+
export declare function MenuPill<T extends string>({ label, value, choices, onSelect, className, icon: Icon, trigger, }: {
|
|
57
58
|
label: string;
|
|
58
59
|
value: T;
|
|
59
60
|
choices: readonly {
|
|
60
61
|
value: T;
|
|
61
62
|
label: string;
|
|
63
|
+
icon?: LucideIcon;
|
|
62
64
|
}[];
|
|
63
65
|
onSelect: (value: T) => void;
|
|
64
66
|
className?: string;
|
|
67
|
+
icon?: LucideIcon;
|
|
68
|
+
trigger?: 'pill' | 'text';
|
|
65
69
|
}): JSX.Element;
|
|
66
70
|
/**
|
|
67
71
|
* A value pill and the menu it opens.
|
|
@@ -71,12 +75,13 @@ export declare function MenuPill<T extends string>({ label, value, choices, onSe
|
|
|
71
75
|
* and "5s" alone tells a screen-reader user nothing about which parameter it
|
|
72
76
|
* belongs to.
|
|
73
77
|
*/
|
|
74
|
-
export declare function OptionPill({ label, value, choices, onSelect, bandRef, custom, }: {
|
|
78
|
+
export declare function OptionPill({ label, value, choices, onSelect, bandRef, custom, icon: Icon, }: {
|
|
75
79
|
label: string;
|
|
76
80
|
value: ModelOptionValue | undefined;
|
|
77
81
|
choices: readonly OptionChoice[];
|
|
78
82
|
onSelect: (value: ModelOptionValue) => void;
|
|
79
83
|
bandRef: RefObject<HTMLDivElement | null>;
|
|
84
|
+
icon?: LucideIcon;
|
|
80
85
|
/** A trailing row that swaps the menu to a form (the gpt-image-2 custom
|
|
81
86
|
* size). Absent for every parameter whose values are an enum. */
|
|
82
87
|
custom?: {
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* A chat card sets the expectation that the thing on the other side remembers
|
|
6
6
|
* the conversation. This one does not, and the cost of learning that by
|
|
7
|
-
* experiment is a wasted generation.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* page.
|
|
7
|
+
* experiment is a wasted generation. The chip is a soft brand-tinted hint: its
|
|
8
|
+
* primary-tinted surface and primary icon keep it noticeable, while the hard
|
|
9
|
+
* border and shadow read as an alert and were cut after gtm QA (issue #465).
|
|
11
10
|
*
|
|
12
11
|
* The icon is INLINE in the text flow rather than a flex sibling, so a narrow
|
|
13
12
|
* viewport wraps it with the sentence instead of stranding a lone glyph beside
|
|
@@ -108,7 +108,22 @@ function useStudioGenerations(loaderGenerations, options = {}) {
|
|
|
108
108
|
|
|
109
109
|
// src/studio-react/studio-composer.tsx
|
|
110
110
|
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
|
|
111
|
-
import {
|
|
111
|
+
import {
|
|
112
|
+
AudioLines,
|
|
113
|
+
ArrowUp,
|
|
114
|
+
Clock,
|
|
115
|
+
Copy,
|
|
116
|
+
Gauge,
|
|
117
|
+
Image as ImageIcon,
|
|
118
|
+
Mic,
|
|
119
|
+
Monitor,
|
|
120
|
+
Ratio,
|
|
121
|
+
Scaling,
|
|
122
|
+
SlidersHorizontal,
|
|
123
|
+
Sparkles,
|
|
124
|
+
TriangleAlert as TriangleAlert2,
|
|
125
|
+
Video
|
|
126
|
+
} from "lucide-react";
|
|
112
127
|
|
|
113
128
|
// src/studio-react/composer-option-controls.tsx
|
|
114
129
|
import {
|
|
@@ -120,6 +135,7 @@ import {
|
|
|
120
135
|
import { ImagePlus, TriangleAlert, Volume2, VolumeX, X } from "lucide-react";
|
|
121
136
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
122
137
|
var PILL = "inline-flex h-7 flex-none items-center gap-1.5 whitespace-nowrap rounded-full border border-border bg-card px-2.5 text-[12.5px] font-medium text-foreground transition hover:bg-accent";
|
|
138
|
+
var PILL_LABEL = "[text-box:trim-both_cap_alphabetic]";
|
|
123
139
|
var MENU_PANEL = `flex min-w-[184px] flex-col overflow-y-auto rounded-xl border border-border bg-popover p-1 text-popover-foreground ${OVERLAY_SHADOW}`;
|
|
124
140
|
var MENU_HEADER = "px-2.5 pb-1 pt-1.5 text-[10.5px] font-semibold uppercase tracking-[0.08em] text-muted-foreground";
|
|
125
141
|
function menuRowClass(selected) {
|
|
@@ -223,28 +239,34 @@ function MenuRows({
|
|
|
223
239
|
choices,
|
|
224
240
|
onSelect
|
|
225
241
|
}) {
|
|
226
|
-
return choices.map((choice) =>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
242
|
+
return choices.map((choice) => {
|
|
243
|
+
const Icon = choice.icon;
|
|
244
|
+
return /* @__PURE__ */ jsxs(
|
|
245
|
+
"button",
|
|
246
|
+
{
|
|
247
|
+
type: "button",
|
|
248
|
+
role: "menuitemradio",
|
|
249
|
+
"aria-checked": choice.value === value,
|
|
250
|
+
onClick: () => onSelect(choice.value),
|
|
251
|
+
className: menuRowClass(choice.value === value),
|
|
252
|
+
children: [
|
|
253
|
+
Icon && /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-3.5 w-3.5 shrink-0", strokeWidth: 1.5 }),
|
|
254
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: choice.label }),
|
|
255
|
+
choice.value === value && /* @__PURE__ */ jsx(CheckGlyph, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-primary" })
|
|
256
|
+
]
|
|
257
|
+
},
|
|
258
|
+
String(choice.value)
|
|
259
|
+
);
|
|
260
|
+
});
|
|
241
261
|
}
|
|
242
262
|
function MenuPill({
|
|
243
263
|
label,
|
|
244
264
|
value,
|
|
245
265
|
choices,
|
|
246
266
|
onSelect,
|
|
247
|
-
className
|
|
267
|
+
className,
|
|
268
|
+
icon: Icon,
|
|
269
|
+
trigger = "pill"
|
|
248
270
|
}) {
|
|
249
271
|
const [open, setOpen] = useState2(false);
|
|
250
272
|
const { containerRef, triggerRef, panelRef, triggerProps } = usePopover(open, setOpen);
|
|
@@ -260,10 +282,11 @@ function MenuPill({
|
|
|
260
282
|
title: label,
|
|
261
283
|
"aria-label": label,
|
|
262
284
|
onClick: () => setOpen(!open),
|
|
263
|
-
className: `${PILL} ${className ?? ""}`,
|
|
285
|
+
className: `${trigger === "text" ? "inline-flex h-7 flex-none items-center gap-1 whitespace-nowrap rounded-full px-2 text-[12.5px] font-medium text-primary transition hover:bg-accent" : PILL} ${className ?? ""}`,
|
|
264
286
|
children: [
|
|
265
|
-
/* @__PURE__ */ jsx(
|
|
266
|
-
/* @__PURE__ */ jsx(
|
|
287
|
+
Icon && /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", strokeWidth: 1.5 }),
|
|
288
|
+
/* @__PURE__ */ jsx("span", { className: PILL_LABEL, children: selected?.label ?? "\u2014" }),
|
|
289
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `h-3 w-3 shrink-0 ${trigger === "text" ? "text-primary" : "text-muted-foreground"}` })
|
|
267
290
|
]
|
|
268
291
|
}
|
|
269
292
|
),
|
|
@@ -300,7 +323,8 @@ function OptionPill({
|
|
|
300
323
|
choices,
|
|
301
324
|
onSelect,
|
|
302
325
|
bandRef,
|
|
303
|
-
custom
|
|
326
|
+
custom,
|
|
327
|
+
icon: Icon
|
|
304
328
|
}) {
|
|
305
329
|
const [open, setOpen] = useState2(false);
|
|
306
330
|
const [customOpen, setCustomOpen] = useState2(false);
|
|
@@ -327,7 +351,8 @@ function OptionPill({
|
|
|
327
351
|
},
|
|
328
352
|
className: PILL,
|
|
329
353
|
children: [
|
|
330
|
-
/* @__PURE__ */ jsx(
|
|
354
|
+
Icon && /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", strokeWidth: 1.5 }),
|
|
355
|
+
/* @__PURE__ */ jsx("span", { className: PILL_LABEL, children: selected?.label ?? "\u2014" }),
|
|
331
356
|
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground" })
|
|
332
357
|
]
|
|
333
358
|
}
|
|
@@ -452,7 +477,7 @@ function AudioTogglePill({ on, onToggle }) {
|
|
|
452
477
|
className: `${PILL} ${on ? "" : "text-muted-foreground"}`,
|
|
453
478
|
children: [
|
|
454
479
|
on ? /* @__PURE__ */ jsx(Volume2, { className: "h-4 w-4 shrink-0", strokeWidth: 1.5 }) : /* @__PURE__ */ jsx(VolumeX, { className: "h-4 w-4 shrink-0", strokeWidth: 1.5 }),
|
|
455
|
-
/* @__PURE__ */ jsx("span", { children: on ? "Audio on" : "Audio off" })
|
|
480
|
+
/* @__PURE__ */ jsx("span", { className: PILL_LABEL, children: on ? "Audio on" : "Audio off" })
|
|
456
481
|
]
|
|
457
482
|
}
|
|
458
483
|
);
|
|
@@ -473,7 +498,7 @@ function ReferencePill({
|
|
|
473
498
|
if (url) {
|
|
474
499
|
return /* @__PURE__ */ jsxs("div", { className: `${PILL} border-primary bg-primary/10 pr-1.5 text-primary hover:bg-primary/10`, children: [
|
|
475
500
|
/* @__PURE__ */ jsx("img", { src: url, alt: "", className: "h-[18px] w-[18px] shrink-0 rounded-[5px] object-cover" }),
|
|
476
|
-
/* @__PURE__ */ jsx("span", { children: "Reference" }),
|
|
501
|
+
/* @__PURE__ */ jsx("span", { className: PILL_LABEL, children: "Reference" }),
|
|
477
502
|
/* @__PURE__ */ jsx(
|
|
478
503
|
"button",
|
|
479
504
|
{
|
|
@@ -517,7 +542,7 @@ function ReferencePill({
|
|
|
517
542
|
className: PILL,
|
|
518
543
|
children: [
|
|
519
544
|
/* @__PURE__ */ jsx(ImagePlus, { className: "h-4 w-4 shrink-0 text-muted-foreground", strokeWidth: 1.5 }),
|
|
520
|
-
/* @__PURE__ */ jsx("span", { children: "Reference image" })
|
|
545
|
+
/* @__PURE__ */ jsx("span", { className: PILL_LABEL, children: "Reference image" })
|
|
521
546
|
]
|
|
522
547
|
}
|
|
523
548
|
),
|
|
@@ -600,7 +625,7 @@ function ModelPill({
|
|
|
600
625
|
children: [
|
|
601
626
|
unavailable && /* @__PURE__ */ jsx(TriangleAlert, { "aria-hidden": true, className: "h-3.5 w-3.5 shrink-0 text-warning", strokeWidth: 2 }),
|
|
602
627
|
provider && /* @__PURE__ */ jsx(ProviderLogo, { provider, size: 14 }),
|
|
603
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
628
|
+
/* @__PURE__ */ jsx("span", { className: `max-w-[168px] truncate ${PILL_LABEL}`, children: displayName }),
|
|
604
629
|
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground" })
|
|
605
630
|
]
|
|
606
631
|
}
|
|
@@ -683,6 +708,17 @@ var PARAM_LABELS = {
|
|
|
683
708
|
voice: "Voice",
|
|
684
709
|
speed: "Speed"
|
|
685
710
|
};
|
|
711
|
+
var PARAM_ICONS = {
|
|
712
|
+
size: Scaling,
|
|
713
|
+
quality: Sparkles,
|
|
714
|
+
n: Copy,
|
|
715
|
+
duration: Clock,
|
|
716
|
+
resolution: Monitor,
|
|
717
|
+
aspect_ratio: Ratio,
|
|
718
|
+
mode: SlidersHorizontal,
|
|
719
|
+
voice: Mic,
|
|
720
|
+
speed: Gauge
|
|
721
|
+
};
|
|
686
722
|
var SPEED_PRESETS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4];
|
|
687
723
|
function choicesFor(param, meta) {
|
|
688
724
|
const { min, max } = meta;
|
|
@@ -940,6 +976,7 @@ function StudioComposer({
|
|
|
940
976
|
OptionPill,
|
|
941
977
|
{
|
|
942
978
|
label: PARAM_LABELS[param] ?? param,
|
|
979
|
+
icon: PARAM_ICONS[param] ?? SlidersHorizontal,
|
|
943
980
|
value: values[param],
|
|
944
981
|
choices: choicesForPill(param, options?.[param], values[param]),
|
|
945
982
|
onSelect: (value) => setOption(param, value),
|
|
@@ -1019,8 +1056,8 @@ function GenerationNoticeChip({ className }) {
|
|
|
1019
1056
|
return /* @__PURE__ */ jsxs3(
|
|
1020
1057
|
"p",
|
|
1021
1058
|
{
|
|
1022
|
-
className: `inline-block rounded-full
|
|
1023
|
-
style: { background: "var(--studio-notice-bg)"
|
|
1059
|
+
className: `inline-block rounded-full px-3.5 py-1.5 text-center text-[12px] leading-relaxed text-muted-foreground ${className ?? ""}`,
|
|
1060
|
+
style: { background: "var(--studio-notice-bg)" },
|
|
1024
1061
|
children: [
|
|
1025
1062
|
/* @__PURE__ */ jsx3(Info, { className: "mr-1.5 inline-block h-[14px] w-[14px] align-[-2px] text-primary", strokeWidth: 1.5, "aria-hidden": true }),
|
|
1026
1063
|
"Each prompt starts a new generation \u2014 this chat does not remember the last one."
|
|
@@ -2190,6 +2227,7 @@ function StudioToast({ record, leave }) {
|
|
|
2190
2227
|
function StudioToastProvider({ children }) {
|
|
2191
2228
|
const [toasts, setToasts] = useState8([]);
|
|
2192
2229
|
const [dockLift, setDockLift] = useState8(null);
|
|
2230
|
+
const [mounted, setMounted] = useState8(false);
|
|
2193
2231
|
const sequence = useRef7(0);
|
|
2194
2232
|
const dismissed = useRef7(/* @__PURE__ */ new Set());
|
|
2195
2233
|
const records = useRef7(/* @__PURE__ */ new Map());
|
|
@@ -2214,9 +2252,10 @@ function StudioToastProvider({ children }) {
|
|
|
2214
2252
|
}, []);
|
|
2215
2253
|
const dismiss = useCallback5((id) => leave(id, "dismissed"), [leave]);
|
|
2216
2254
|
const value = useMemo5(() => ({ toast, dismiss, setDockLift }), [dismiss, toast]);
|
|
2255
|
+
useEffect9(() => setMounted(true), []);
|
|
2217
2256
|
return /* @__PURE__ */ jsxs8(StudioToastContext.Provider, { value, children: [
|
|
2218
2257
|
children,
|
|
2219
|
-
|
|
2258
|
+
mounted && createPortal3(
|
|
2220
2259
|
/* @__PURE__ */ jsx9(
|
|
2221
2260
|
"div",
|
|
2222
2261
|
{
|
|
@@ -2671,7 +2710,18 @@ import {
|
|
|
2671
2710
|
useMemo as useMemo9,
|
|
2672
2711
|
useState as useState13
|
|
2673
2712
|
} from "react";
|
|
2674
|
-
import {
|
|
2713
|
+
import {
|
|
2714
|
+
ArrowLeft as ArrowLeft2,
|
|
2715
|
+
AudioLines as AudioLines2,
|
|
2716
|
+
Download as Download3,
|
|
2717
|
+
FolderPlus as FolderPlus3,
|
|
2718
|
+
Image,
|
|
2719
|
+
LayoutGrid,
|
|
2720
|
+
Search,
|
|
2721
|
+
Trash2 as Trash23,
|
|
2722
|
+
Video as Video2,
|
|
2723
|
+
X as X4
|
|
2724
|
+
} from "lucide-react";
|
|
2675
2725
|
|
|
2676
2726
|
// src/studio-react/use-generation-history.ts
|
|
2677
2727
|
import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef11, useState as useState12 } from "react";
|
|
@@ -2816,6 +2866,16 @@ var MORE_SKELETONS = 4;
|
|
|
2816
2866
|
var BAR = "flex min-h-[44px] flex-wrap items-center justify-between gap-3 px-6 pb-[18px] pt-0.5 max-[900px]:px-4";
|
|
2817
2867
|
var SEARCH_INPUT = "h-8 w-[260px] max-w-[52vw] rounded-full border border-border bg-card pl-8 pr-3 text-[13px] text-foreground outline-none placeholder:text-muted-foreground focus:border-primary focus:ring-[3px] focus:ring-ring/30 max-[640px]:w-full max-[640px]:max-w-none";
|
|
2818
2868
|
var OUTLINE_PILL = "inline-flex h-8 items-center gap-1.5 rounded-full border border-border px-3 text-[12.5px] font-medium hover:bg-accent disabled:cursor-not-allowed disabled:opacity-40";
|
|
2869
|
+
var FILTER_ICONS = {
|
|
2870
|
+
all: LayoutGrid,
|
|
2871
|
+
image: Image,
|
|
2872
|
+
video: Video2,
|
|
2873
|
+
speech: AudioLines2
|
|
2874
|
+
};
|
|
2875
|
+
var FILTER_CHOICES = MEDIA_TYPE_FILTERS.map((choice) => ({
|
|
2876
|
+
...choice,
|
|
2877
|
+
icon: FILTER_ICONS[choice.value]
|
|
2878
|
+
}));
|
|
2819
2879
|
var TYPE_NOUNS = {
|
|
2820
2880
|
image: "images",
|
|
2821
2881
|
video: "videos",
|
|
@@ -3066,8 +3126,9 @@ function StudioHistoryScreen({
|
|
|
3066
3126
|
{
|
|
3067
3127
|
label: "Filter by media type",
|
|
3068
3128
|
value: type,
|
|
3069
|
-
choices:
|
|
3070
|
-
onSelect: setType
|
|
3129
|
+
choices: FILTER_CHOICES,
|
|
3130
|
+
onSelect: setType,
|
|
3131
|
+
trigger: "text"
|
|
3071
3132
|
}
|
|
3072
3133
|
)
|
|
3073
3134
|
] })
|