@tangle-network/agent-app 0.43.21 → 0.43.22
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.
|
@@ -121,7 +121,7 @@ function typeConfigFor(type) {
|
|
|
121
121
|
|
|
122
122
|
// src/studio-react/composer-shell.tsx
|
|
123
123
|
import { Label } from "@tangle-network/sandbox-ui/primitives";
|
|
124
|
-
import { ChevronRight } from "lucide-react";
|
|
124
|
+
import { ChevronRight, Minus, Plus } from "lucide-react";
|
|
125
125
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
126
126
|
function Field({
|
|
127
127
|
label,
|
|
@@ -130,12 +130,51 @@ function Field({
|
|
|
130
130
|
children
|
|
131
131
|
}) {
|
|
132
132
|
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
133
|
-
/* @__PURE__ */ jsx(
|
|
133
|
+
/* @__PURE__ */ jsx(
|
|
134
|
+
Label,
|
|
135
|
+
{
|
|
136
|
+
htmlFor,
|
|
137
|
+
className: "text-[10.5px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",
|
|
138
|
+
children: label
|
|
139
|
+
}
|
|
140
|
+
),
|
|
134
141
|
children
|
|
135
142
|
] });
|
|
136
143
|
}
|
|
144
|
+
function Stepper({
|
|
145
|
+
value,
|
|
146
|
+
min,
|
|
147
|
+
max,
|
|
148
|
+
onChange
|
|
149
|
+
}) {
|
|
150
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-9 items-center justify-between rounded-md border border-input bg-background px-1.5", children: [
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
"button",
|
|
153
|
+
{
|
|
154
|
+
type: "button",
|
|
155
|
+
"aria-label": "Decrease",
|
|
156
|
+
onClick: () => onChange(Math.max(min, value - 1)),
|
|
157
|
+
disabled: value <= min,
|
|
158
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40",
|
|
159
|
+
children: /* @__PURE__ */ jsx(Minus, { className: "h-3.5 w-3.5" })
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium tabular-nums", children: value }),
|
|
163
|
+
/* @__PURE__ */ jsx(
|
|
164
|
+
"button",
|
|
165
|
+
{
|
|
166
|
+
type: "button",
|
|
167
|
+
"aria-label": "Increase",
|
|
168
|
+
onClick: () => onChange(Math.min(max, value + 1)),
|
|
169
|
+
disabled: value >= max,
|
|
170
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40",
|
|
171
|
+
children: /* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" })
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
137
176
|
function ComposerDisclosure({ summary, children }) {
|
|
138
|
-
return /* @__PURE__ */ jsxs("details", { className: "group rounded-lg border border-border bg-
|
|
177
|
+
return /* @__PURE__ */ jsxs("details", { className: "group rounded-lg border border-border bg-background transition-colors", children: [
|
|
139
178
|
/* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-1.5 px-3 py-2.5 text-xs font-medium text-foreground/80 transition-colors hover:text-foreground [&::-webkit-details-marker]:hidden", children: [
|
|
140
179
|
/* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 text-muted-foreground transition-transform group-open:rotate-90" }),
|
|
141
180
|
summary
|
|
@@ -144,12 +183,12 @@ function ComposerDisclosure({ summary, children }) {
|
|
|
144
183
|
] });
|
|
145
184
|
}
|
|
146
185
|
function NativeSelect(props) {
|
|
147
|
-
return /* @__PURE__ */ jsx("select", { ...props, className: "h-9 w-full rounded-md border border-input bg-
|
|
186
|
+
return /* @__PURE__ */ jsx("select", { ...props, className: "h-9 w-full rounded-md border border-input bg-[var(--md3-surface-container-low)] px-3 text-sm" });
|
|
148
187
|
}
|
|
149
188
|
|
|
150
189
|
// src/studio-react/image-composer.tsx
|
|
151
190
|
import { Input } from "@tangle-network/sandbox-ui/primitives";
|
|
152
|
-
import {
|
|
191
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
153
192
|
function ImageComposer({
|
|
154
193
|
size,
|
|
155
194
|
quality,
|
|
@@ -158,16 +197,26 @@ function ImageComposer({
|
|
|
158
197
|
onQualityChange,
|
|
159
198
|
onImageCountChange
|
|
160
199
|
}) {
|
|
161
|
-
return /* @__PURE__ */ jsxs2(
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
-
|
|
164
|
-
|
|
200
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-3", children: [
|
|
201
|
+
/* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
202
|
+
/* @__PURE__ */ jsx2(Field, { label: "Size", children: /* @__PURE__ */ jsx2(Input, { value: size, onChange: (event) => onSizeChange(event.target.value), className: "bg-background" }) }),
|
|
203
|
+
/* @__PURE__ */ jsx2(Field, { label: "Quality", children: /* @__PURE__ */ jsx2(Input, { value: quality, onChange: (event) => onQualityChange(event.target.value), className: "bg-background" }) })
|
|
204
|
+
] }),
|
|
205
|
+
/* @__PURE__ */ jsx2(Field, { label: "Images", children: /* @__PURE__ */ jsx2(
|
|
206
|
+
Stepper,
|
|
207
|
+
{
|
|
208
|
+
value: imageCount,
|
|
209
|
+
min: MIN_IMAGE_COUNT,
|
|
210
|
+
max: MAX_IMAGE_COUNT,
|
|
211
|
+
onChange: (value) => onImageCountChange(normalizeImageCount(value))
|
|
212
|
+
}
|
|
213
|
+
) })
|
|
165
214
|
] });
|
|
166
215
|
}
|
|
167
216
|
|
|
168
217
|
// src/studio-react/video-composer.tsx
|
|
169
218
|
import { Input as Input2 } from "@tangle-network/sandbox-ui/primitives";
|
|
170
|
-
import {
|
|
219
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
171
220
|
function VideoComposer({
|
|
172
221
|
duration,
|
|
173
222
|
resolution,
|
|
@@ -178,11 +227,11 @@ function VideoComposer({
|
|
|
178
227
|
onAspectRatioChange,
|
|
179
228
|
onReferenceImageUrlChange
|
|
180
229
|
}) {
|
|
181
|
-
return /* @__PURE__ */ jsxs3(
|
|
182
|
-
/* @__PURE__ */ jsx3(Field, { label: "Duration (s)", children: /* @__PURE__ */ jsx3(Input2, { value: duration, onChange: (event) => onDurationChange(event.target.value) }) }),
|
|
183
|
-
/* @__PURE__ */ jsx3(Field, { label: "Resolution", children: /* @__PURE__ */ jsx3(Input2, { value: resolution, onChange: (event) => onResolutionChange(event.target.value) }) }),
|
|
184
|
-
/* @__PURE__ */ jsx3(Field, { label: "Aspect ratio", children: /* @__PURE__ */ jsx3(Input2, { value: aspectRatio, onChange: (event) => onAspectRatioChange(event.target.value) }) }),
|
|
185
|
-
/* @__PURE__ */ jsx3(Field, { label: "Reference image URL", children: /* @__PURE__ */ jsx3(Input2, { value: referenceImageUrl, onChange: (event) => onReferenceImageUrlChange(event.target.value) }) })
|
|
230
|
+
return /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
231
|
+
/* @__PURE__ */ jsx3(Field, { label: "Duration (s)", children: /* @__PURE__ */ jsx3(Input2, { value: duration, onChange: (event) => onDurationChange(event.target.value), className: "bg-background" }) }),
|
|
232
|
+
/* @__PURE__ */ jsx3(Field, { label: "Resolution", children: /* @__PURE__ */ jsx3(Input2, { value: resolution, onChange: (event) => onResolutionChange(event.target.value), className: "bg-background" }) }),
|
|
233
|
+
/* @__PURE__ */ jsx3(Field, { label: "Aspect ratio", children: /* @__PURE__ */ jsx3(Input2, { value: aspectRatio, onChange: (event) => onAspectRatioChange(event.target.value), className: "bg-background" }) }),
|
|
234
|
+
/* @__PURE__ */ jsx3(Field, { label: "Reference image URL", children: /* @__PURE__ */ jsx3(Input2, { value: referenceImageUrl, onChange: (event) => onReferenceImageUrlChange(event.target.value), className: "bg-background" }) })
|
|
186
235
|
] });
|
|
187
236
|
}
|
|
188
237
|
|
|
@@ -193,7 +242,7 @@ function SpeechComposer({
|
|
|
193
242
|
voice,
|
|
194
243
|
onVoiceChange
|
|
195
244
|
}) {
|
|
196
|
-
return /* @__PURE__ */ jsx4(Field, { label: "Voice", children: /* @__PURE__ */ jsx4(Input3, { value: voice, onChange: (event) => onVoiceChange(event.target.value) }) });
|
|
245
|
+
return /* @__PURE__ */ jsx4(Field, { label: "Voice", children: /* @__PURE__ */ jsx4(Input3, { value: voice, onChange: (event) => onVoiceChange(event.target.value), className: "bg-background" }) });
|
|
197
246
|
}
|
|
198
247
|
|
|
199
248
|
// src/studio-react/avatar-composer.tsx
|
|
@@ -214,7 +263,8 @@ function AvatarComposer({
|
|
|
214
263
|
id: "studio-audio-url",
|
|
215
264
|
value: audioUrl,
|
|
216
265
|
onChange: (event) => onAudioUrlChange(event.target.value),
|
|
217
|
-
placeholder: "https://cdn.example.com/source-audio.mp3"
|
|
266
|
+
placeholder: "https://cdn.example.com/source-audio.mp3",
|
|
267
|
+
className: "bg-background"
|
|
218
268
|
}
|
|
219
269
|
) }),
|
|
220
270
|
/* @__PURE__ */ jsx5(Field, { label: "Image URL", htmlFor: "studio-avatar-image-url", children: /* @__PURE__ */ jsx5(
|
|
@@ -223,7 +273,8 @@ function AvatarComposer({
|
|
|
223
273
|
id: "studio-avatar-image-url",
|
|
224
274
|
value: imageUrl,
|
|
225
275
|
onChange: (event) => onImageUrlChange(event.target.value),
|
|
226
|
-
placeholder: "https://cdn.example.com/portrait.png"
|
|
276
|
+
placeholder: "https://cdn.example.com/portrait.png",
|
|
277
|
+
className: "bg-background"
|
|
227
278
|
}
|
|
228
279
|
) }),
|
|
229
280
|
/* @__PURE__ */ jsx5(Field, { label: "Avatar ID", htmlFor: "studio-avatar-id", children: /* @__PURE__ */ jsx5(
|
|
@@ -232,7 +283,8 @@ function AvatarComposer({
|
|
|
232
283
|
id: "studio-avatar-id",
|
|
233
284
|
value: avatarId,
|
|
234
285
|
onChange: (event) => onAvatarIdChange(event.target.value),
|
|
235
|
-
placeholder: "Optional provider avatar id"
|
|
286
|
+
placeholder: "Optional provider avatar id",
|
|
287
|
+
className: "bg-background"
|
|
236
288
|
}
|
|
237
289
|
) })
|
|
238
290
|
] });
|
|
@@ -240,7 +292,7 @@ function AvatarComposer({
|
|
|
240
292
|
|
|
241
293
|
// src/studio-react/transcription-composer.tsx
|
|
242
294
|
import { Input as Input5 } from "@tangle-network/sandbox-ui/primitives";
|
|
243
|
-
import { Fragment
|
|
295
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
244
296
|
function TranscriptionComposer({
|
|
245
297
|
audioUrl,
|
|
246
298
|
language,
|
|
@@ -254,7 +306,8 @@ function TranscriptionComposer({
|
|
|
254
306
|
id: "studio-audio-url",
|
|
255
307
|
value: audioUrl,
|
|
256
308
|
onChange: (event) => onAudioUrlChange(event.target.value),
|
|
257
|
-
placeholder: "https://cdn.example.com/source-audio.mp3"
|
|
309
|
+
placeholder: "https://cdn.example.com/source-audio.mp3",
|
|
310
|
+
className: "bg-background"
|
|
258
311
|
}
|
|
259
312
|
) }),
|
|
260
313
|
/* @__PURE__ */ jsx6(Field, { label: "Language", htmlFor: "studio-transcription-language", children: /* @__PURE__ */ jsx6(
|
|
@@ -263,7 +316,8 @@ function TranscriptionComposer({
|
|
|
263
316
|
id: "studio-transcription-language",
|
|
264
317
|
value: language,
|
|
265
318
|
onChange: (event) => onLanguageChange(event.target.value),
|
|
266
|
-
placeholder: "en"
|
|
319
|
+
placeholder: "en",
|
|
320
|
+
className: "bg-background"
|
|
267
321
|
}
|
|
268
322
|
) })
|
|
269
323
|
] });
|
|
@@ -274,7 +328,7 @@ function TranscriptionOptions({
|
|
|
274
328
|
onResponseFormatChange,
|
|
275
329
|
onTemperatureChange
|
|
276
330
|
}) {
|
|
277
|
-
return /* @__PURE__ */ jsxs5(
|
|
331
|
+
return /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
278
332
|
/* @__PURE__ */ jsx6(Field, { label: "Response format", children: /* @__PURE__ */ jsxs5(NativeSelect, { value: responseFormat, onChange: (event) => onResponseFormatChange(event.target.value), children: [
|
|
279
333
|
/* @__PURE__ */ jsx6("option", { value: "json", children: "JSON" }),
|
|
280
334
|
/* @__PURE__ */ jsx6("option", { value: "text", children: "Text" }),
|
|
@@ -282,7 +336,7 @@ function TranscriptionOptions({
|
|
|
282
336
|
/* @__PURE__ */ jsx6("option", { value: "verbose_json", children: "Verbose JSON" }),
|
|
283
337
|
/* @__PURE__ */ jsx6("option", { value: "vtt", children: "VTT" })
|
|
284
338
|
] }) }),
|
|
285
|
-
/* @__PURE__ */ jsx6(Field, { label: "Temperature", children: /* @__PURE__ */ jsx6(Input5, { type: "number", min: "0", max: "1", step: "0.1", value: temperature, onChange: (event) => onTemperatureChange(event.target.value) }) })
|
|
339
|
+
/* @__PURE__ */ jsx6(Field, { label: "Temperature", children: /* @__PURE__ */ jsx6(Input5, { type: "number", min: "0", max: "1", step: "0.1", value: temperature, onChange: (event) => onTemperatureChange(event.target.value), className: "bg-[var(--md3-surface-container-low)]" }) })
|
|
286
340
|
] });
|
|
287
341
|
}
|
|
288
342
|
|
|
@@ -326,7 +380,7 @@ function PublishPackageComposer({
|
|
|
326
380
|
disabled: !connected,
|
|
327
381
|
"aria-pressed": active,
|
|
328
382
|
onClick: () => onDestinationToggle(destination.id),
|
|
329
|
-
className: `rounded-md border p-2 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${active ? "border-primary bg-primary/5 ring-1 ring-primary/20" : "border-border hover:bg-muted/50"}`,
|
|
383
|
+
className: `rounded-md border p-2 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${active ? "border-primary bg-primary/5 ring-1 ring-primary/20" : "border-border bg-[var(--md3-surface-container-low)] hover:bg-muted/50"}`,
|
|
330
384
|
children: [
|
|
331
385
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
332
386
|
/* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1.5 text-xs font-medium text-foreground", children: [
|
|
@@ -341,10 +395,10 @@ function PublishPackageComposer({
|
|
|
341
395
|
destination.id
|
|
342
396
|
);
|
|
343
397
|
}) }),
|
|
344
|
-
/* @__PURE__ */ jsx7(Field, { label: "Caption", className: "space-y-2", children: /* @__PURE__ */ jsx7(Textarea, { value: caption, onChange: (event) => onCaptionChange(event.target.value), rows: 3, placeholder: "Write or generate the caption for selected destinations..." }) }),
|
|
345
|
-
/* @__PURE__ */ jsx7(Field, { label: "Description / CTA", className: "space-y-2", children: /* @__PURE__ */ jsx7(Textarea, { value: postDescription, onChange: (event) => onDescriptionChange(event.target.value), rows: 2, placeholder: "Release note, product context, link, or approval instruction..." }) }),
|
|
398
|
+
/* @__PURE__ */ jsx7(Field, { label: "Caption", className: "space-y-2", children: /* @__PURE__ */ jsx7(Textarea, { value: caption, onChange: (event) => onCaptionChange(event.target.value), rows: 3, placeholder: "Write or generate the caption for selected destinations...", className: "bg-[var(--md3-surface-container-low)]" }) }),
|
|
399
|
+
/* @__PURE__ */ jsx7(Field, { label: "Description / CTA", className: "space-y-2", children: /* @__PURE__ */ jsx7(Textarea, { value: postDescription, onChange: (event) => onDescriptionChange(event.target.value), rows: 2, placeholder: "Release note, product context, link, or approval instruction...", className: "bg-[var(--md3-surface-container-low)]" }) }),
|
|
346
400
|
/* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
347
|
-
/* @__PURE__ */ jsx7(Field, { label: "Mentions", className: "space-y-2", children: /* @__PURE__ */ jsx7(Input6, { value: mentions, onChange: (event) => onMentionsChange(event.target.value), placeholder: "@creator, @partner" }) }),
|
|
401
|
+
/* @__PURE__ */ jsx7(Field, { label: "Mentions", className: "space-y-2", children: /* @__PURE__ */ jsx7(Input6, { value: mentions, onChange: (event) => onMentionsChange(event.target.value), placeholder: "@creator, @partner", className: "bg-[var(--md3-surface-container-low)]" }) }),
|
|
348
402
|
/* @__PURE__ */ jsx7(Field, { label: "Cadence", className: "space-y-2", children: /* @__PURE__ */ jsx7(NativeSelect, { value: cadence, onChange: (event) => onCadenceChange(event.target.value), children: CADENCES.map((option) => /* @__PURE__ */ jsx7("option", { value: option, children: option }, option)) }) })
|
|
349
403
|
] }),
|
|
350
404
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-md bg-muted/40 p-2 text-xs text-muted-foreground", children: [
|
|
@@ -355,7 +409,7 @@ function PublishPackageComposer({
|
|
|
355
409
|
}
|
|
356
410
|
|
|
357
411
|
// src/studio-react/composer-hero.tsx
|
|
358
|
-
import { Fragment as
|
|
412
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
359
413
|
var HUB_BASE_URL = "/api/integrations/hub";
|
|
360
414
|
var SUGGESTIONS = [
|
|
361
415
|
{
|
|
@@ -383,6 +437,8 @@ function ComposerHero({
|
|
|
383
437
|
workspaceId,
|
|
384
438
|
integrationsHref,
|
|
385
439
|
canManageIntegrations,
|
|
440
|
+
align = "start",
|
|
441
|
+
surfaceClassName = "bg-card",
|
|
386
442
|
onGenerated
|
|
387
443
|
}) {
|
|
388
444
|
const [type, setType] = useState2("image");
|
|
@@ -547,57 +603,61 @@ function ComposerHero({
|
|
|
547
603
|
}
|
|
548
604
|
}
|
|
549
605
|
const mediaTypes = Object.entries(TYPE_CONFIG);
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
"div",
|
|
606
|
+
return /* @__PURE__ */ jsxs7("section", { className: `rounded-2xl border border-border p-5 shadow-sm ${surfaceClassName}`, children: [
|
|
607
|
+
/* @__PURE__ */ jsx8("div", { className: `mb-5 ${align === "center" ? "text-center" : "text-left"}`, children: /* @__PURE__ */ jsx8(
|
|
608
|
+
"h1",
|
|
554
609
|
{
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
className: "grid grid-cols-5 gap-1 rounded-lg border border-border bg-muted/40 p-1",
|
|
558
|
-
children: mediaTypes.map(([key, cfg]) => {
|
|
559
|
-
const Icon = cfg.icon;
|
|
560
|
-
const active = type === key;
|
|
561
|
-
return /* @__PURE__ */ jsxs7(
|
|
562
|
-
"button",
|
|
563
|
-
{
|
|
564
|
-
type: "button",
|
|
565
|
-
role: "tab",
|
|
566
|
-
"aria-selected": active,
|
|
567
|
-
onClick: () => changeType(key),
|
|
568
|
-
className: `flex items-center justify-center gap-1.5 rounded-md px-2 py-2 text-xs font-medium transition-all ${active ? "bg-primary/15 text-primary shadow-sm ring-1 ring-inset ring-primary/30" : "text-muted-foreground hover:bg-foreground/[0.04] hover:text-foreground"}`,
|
|
569
|
-
children: [
|
|
570
|
-
/* @__PURE__ */ jsx8(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
571
|
-
/* @__PURE__ */ jsx8("span", { className: "truncate", children: cfg.label })
|
|
572
|
-
]
|
|
573
|
-
},
|
|
574
|
-
key
|
|
575
|
-
);
|
|
576
|
-
})
|
|
610
|
+
className: `font-semibold tracking-tight text-foreground transition-all duration-300 ${align === "center" ? "text-xl" : "text-base"}`,
|
|
611
|
+
children: "Media Generation"
|
|
577
612
|
}
|
|
578
613
|
) }),
|
|
579
|
-
|
|
580
|
-
|
|
614
|
+
/* @__PURE__ */ jsx8("div", { role: "tablist", "aria-label": "Generation type", className: "grid grid-cols-5 gap-1.5", children: mediaTypes.map(([key, cfg]) => {
|
|
615
|
+
const Icon = cfg.icon;
|
|
616
|
+
const active = type === key;
|
|
617
|
+
return /* @__PURE__ */ jsxs7(
|
|
618
|
+
"button",
|
|
619
|
+
{
|
|
620
|
+
type: "button",
|
|
621
|
+
role: "tab",
|
|
622
|
+
"aria-selected": active,
|
|
623
|
+
onClick: () => changeType(key),
|
|
624
|
+
className: `flex flex-col items-center gap-1.5 rounded-lg border px-1 pb-2 pt-2.5 text-[11px] transition-all ${active ? "border-primary/30 bg-primary/10 font-semibold text-primary" : "border-border bg-background font-medium text-muted-foreground hover:border-foreground/20 hover:text-foreground"}`,
|
|
625
|
+
children: [
|
|
626
|
+
/* @__PURE__ */ jsx8(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
|
|
627
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate", children: cfg.label })
|
|
628
|
+
]
|
|
629
|
+
},
|
|
630
|
+
key
|
|
631
|
+
);
|
|
632
|
+
}) }),
|
|
633
|
+
type !== "avatar" && /* @__PURE__ */ jsxs7("div", { className: "mt-5", children: [
|
|
581
634
|
/* @__PURE__ */ jsx8(
|
|
582
|
-
|
|
635
|
+
Label2,
|
|
583
636
|
{
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
onKeyDown: (event) => {
|
|
588
|
-
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
589
|
-
event.preventDefault();
|
|
590
|
-
void generate();
|
|
591
|
-
}
|
|
592
|
-
},
|
|
593
|
-
rows: 4,
|
|
594
|
-
placeholder: type === "transcription" ? "Optional vocabulary, speaker names, timestamp style, or context..." : "A vertical hero frame for a product launch teaser, dark cinematic lighting...",
|
|
595
|
-
className: "resize-none text-sm"
|
|
637
|
+
htmlFor: "studio-prompt",
|
|
638
|
+
className: "mb-1.5 block text-[10.5px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",
|
|
639
|
+
children: "Prompt"
|
|
596
640
|
}
|
|
597
641
|
),
|
|
598
|
-
/* @__PURE__ */ jsxs7("div", { className: "
|
|
599
|
-
/* @__PURE__ */ jsx8(
|
|
600
|
-
|
|
642
|
+
/* @__PURE__ */ jsxs7("div", { className: "rounded-xl border border-border bg-background transition-colors focus-within:border-primary/30 focus-within:ring-[3px] focus-within:ring-primary/10", children: [
|
|
643
|
+
/* @__PURE__ */ jsx8(
|
|
644
|
+
"textarea",
|
|
645
|
+
{
|
|
646
|
+
id: "studio-prompt",
|
|
647
|
+
value: prompt,
|
|
648
|
+
onChange: (event) => setPrompt(event.target.value),
|
|
649
|
+
onKeyDown: (event) => {
|
|
650
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
651
|
+
event.preventDefault();
|
|
652
|
+
void generate();
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
rows: 4,
|
|
656
|
+
placeholder: type === "transcription" ? "Optional vocabulary, speaker names, timestamp style, or context..." : "A vertical hero frame for a product launch teaser, dark cinematic lighting...",
|
|
657
|
+
className: "block min-h-[96px] w-full resize-none border-0 bg-transparent px-3.5 pb-1.5 pt-3 text-sm leading-relaxed outline-none placeholder:text-muted-foreground"
|
|
658
|
+
}
|
|
659
|
+
),
|
|
660
|
+
/* @__PURE__ */ jsx8("div", { className: "flex flex-wrap items-center gap-1.5 px-2.5 pb-2.5", children: SUGGESTIONS.map((suggestion) => /* @__PURE__ */ jsx8(
|
|
601
661
|
"button",
|
|
602
662
|
{
|
|
603
663
|
type: "button",
|
|
@@ -605,13 +665,13 @@ function ComposerHero({
|
|
|
605
665
|
setPrompt(suggestion.prompt);
|
|
606
666
|
changeType(suggestion.type);
|
|
607
667
|
},
|
|
608
|
-
className: "rounded-full border border-border bg-background px-2.5 py-1 text-
|
|
668
|
+
className: "rounded-full border border-border bg-background px-2.5 py-1 text-[11px] font-medium text-muted-foreground transition-colors hover:border-primary/30 hover:text-primary",
|
|
609
669
|
children: suggestion.label
|
|
610
670
|
},
|
|
611
671
|
suggestion.label
|
|
612
|
-
))
|
|
672
|
+
)) })
|
|
613
673
|
] }),
|
|
614
|
-
type === "transcription" && /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: "Optional \u2014 biases the transcript's spelling, vocabulary, and speaker names. It isn't an instruction for the model to follow." })
|
|
674
|
+
type === "transcription" && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-xs text-muted-foreground", children: "Optional \u2014 biases the transcript's spelling, vocabulary, and speaker names. It isn't an instruction for the model to follow." })
|
|
615
675
|
] }),
|
|
616
676
|
type === "avatar" && /* @__PURE__ */ jsx8(
|
|
617
677
|
AvatarComposer,
|
|
@@ -633,33 +693,35 @@ function ComposerHero({
|
|
|
633
693
|
onLanguageChange: setTranscriptionLanguage
|
|
634
694
|
}
|
|
635
695
|
),
|
|
636
|
-
/* @__PURE__ */ jsxs7("div", { className: "mt-
|
|
637
|
-
/* @__PURE__ */
|
|
638
|
-
Field,
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
model.
|
|
657
|
-
] })
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
696
|
+
/* @__PURE__ */ jsxs7("div", { className: "mt-5 space-y-3", children: [
|
|
697
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
|
|
698
|
+
/* @__PURE__ */ jsx8(Field, { label: "Model", htmlFor: "studio-media-model", children: /* @__PURE__ */ jsxs7(
|
|
699
|
+
Select,
|
|
700
|
+
{
|
|
701
|
+
value: selectedModel || void 0,
|
|
702
|
+
onValueChange: (value) => setSelectedModels((current) => ({ ...current, [type]: value })),
|
|
703
|
+
disabled: mediaModelsLoading || Boolean(mediaModelsError) || modelsForType.length === 0,
|
|
704
|
+
children: [
|
|
705
|
+
/* @__PURE__ */ jsx8(SelectTrigger, { id: "studio-media-model", className: "h-9 w-full bg-background", children: selectedModelOption ? /* @__PURE__ */ jsxs7("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
706
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate", children: selectedModelOption.name || selectedModelOption.id }),
|
|
707
|
+
selectedModelOption.provider && /* @__PURE__ */ jsxs7("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
708
|
+
"\xB7 ",
|
|
709
|
+
selectedModelOption.provider
|
|
710
|
+
] }),
|
|
711
|
+
selectedModelOption.status !== "available" && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-warning", children: selectedModelOption.status })
|
|
712
|
+
] }) : /* @__PURE__ */ jsx8(SelectValue, { placeholder: mediaModelsLoading ? "Loading models\u2026" : "Select a model" }) }),
|
|
713
|
+
/* @__PURE__ */ jsx8(SelectContent, { className: "bg-background", children: modelsForType.map((model) => /* @__PURE__ */ jsx8(SelectItem, { value: model.id, disabled: model.status === "unavailable", children: /* @__PURE__ */ jsxs7("span", { className: "flex w-full items-center justify-between gap-3", children: [
|
|
714
|
+
/* @__PURE__ */ jsxs7("span", { className: "truncate", children: [
|
|
715
|
+
model.name || model.id,
|
|
716
|
+
model.provider ? ` \xB7 ${model.provider}` : ""
|
|
717
|
+
] }),
|
|
718
|
+
model.status !== "available" && /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] capitalize text-muted-foreground", children: model.status })
|
|
719
|
+
] }) }, model.id)) })
|
|
720
|
+
]
|
|
721
|
+
}
|
|
722
|
+
) }),
|
|
723
|
+
(mediaModelsError || modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length)) && /* @__PURE__ */ jsx8("p", { className: `text-xs ${mediaModelsError || selectedModelOption?.status === "unavailable" ? "text-destructive" : "text-muted-foreground"}`, children: mediaModelsError ?? modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length) })
|
|
724
|
+
] }),
|
|
663
725
|
type === "image" && /* @__PURE__ */ jsx8(
|
|
664
726
|
ImageComposer,
|
|
665
727
|
{
|
|
@@ -686,8 +748,6 @@ function ComposerHero({
|
|
|
686
748
|
),
|
|
687
749
|
type === "speech" && /* @__PURE__ */ jsx8(SpeechComposer, { voice, onVoiceChange: setVoice })
|
|
688
750
|
] }),
|
|
689
|
-
(mediaModelsError || modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length)) && /* @__PURE__ */ jsx8("p", { className: `mt-2 text-xs ${mediaModelsError || selectedModelOption?.status === "unavailable" ? "text-destructive" : "text-muted-foreground"}`, children: mediaModelsError ?? modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length) }),
|
|
690
|
-
error && /* @__PURE__ */ jsx8("div", { className: "mt-3 rounded-md border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
691
751
|
/* @__PURE__ */ jsxs7("div", { className: "mt-4 space-y-2", children: [
|
|
692
752
|
/* @__PURE__ */ jsx8(ComposerDisclosure, { summary: "Advanced options", children: /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
693
753
|
/* @__PURE__ */ jsx8(Field, { label: "Negative prompt", children: /* @__PURE__ */ jsx8(
|
|
@@ -696,10 +756,11 @@ function ComposerHero({
|
|
|
696
756
|
value: negativePrompt,
|
|
697
757
|
onChange: (event) => setNegativePrompt(event.target.value),
|
|
698
758
|
rows: 2,
|
|
699
|
-
placeholder: "Avoid artifacts, off-style composition..."
|
|
759
|
+
placeholder: "Avoid artifacts, off-style composition...",
|
|
760
|
+
className: "bg-[var(--md3-surface-container-low)]"
|
|
700
761
|
}
|
|
701
762
|
) }),
|
|
702
|
-
/* @__PURE__ */ jsx8(Field, { label: "Save to", children: /* @__PURE__ */ jsx8(Input7, { value: outputPath, onChange: (event) => setOutputPath(event.target.value) }) }),
|
|
763
|
+
/* @__PURE__ */ jsx8(Field, { label: "Save to", children: /* @__PURE__ */ jsx8(Input7, { value: outputPath, onChange: (event) => setOutputPath(event.target.value), className: "bg-[var(--md3-surface-container-low)]" }) }),
|
|
703
764
|
type === "transcription" && /* @__PURE__ */ jsx8(
|
|
704
765
|
TranscriptionOptions,
|
|
705
766
|
{
|
|
@@ -713,7 +774,7 @@ function ComposerHero({
|
|
|
713
774
|
/* @__PURE__ */ jsx8(
|
|
714
775
|
ComposerDisclosure,
|
|
715
776
|
{
|
|
716
|
-
summary: /* @__PURE__ */ jsxs7(
|
|
777
|
+
summary: /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
717
778
|
"Schedule a post",
|
|
718
779
|
selectedConnectedDestinations.length > 0 && /* @__PURE__ */ jsx8(Badge2, { variant: "outline", className: "ml-1 text-[10px]", children: selectedConnectedDestinations.length })
|
|
719
780
|
] }),
|
|
@@ -744,7 +805,8 @@ function ComposerHero({
|
|
|
744
805
|
}
|
|
745
806
|
)
|
|
746
807
|
] }),
|
|
747
|
-
/* @__PURE__ */
|
|
808
|
+
error && /* @__PURE__ */ jsx8("div", { className: "mt-4 rounded-md border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
|
|
809
|
+
/* @__PURE__ */ jsxs7(Button2, { onClick: generate, disabled: !canSubmit, size: "lg", className: "mt-5 w-full", children: [
|
|
748
810
|
/* @__PURE__ */ jsx8(Sparkles, { className: "mr-2 h-4 w-4" }),
|
|
749
811
|
"Generate",
|
|
750
812
|
/* @__PURE__ */ jsx8("span", { className: "ml-2 text-[10px] opacity-60", children: "\u2318\u21B5" })
|
|
@@ -864,12 +926,11 @@ import { useMemo as useMemo3 } from "react";
|
|
|
864
926
|
import { Link as Link3 } from "react-router";
|
|
865
927
|
import {
|
|
866
928
|
Button as Button5,
|
|
867
|
-
EmptyState,
|
|
868
929
|
Tabs,
|
|
869
930
|
TabsList,
|
|
870
931
|
TabsTrigger
|
|
871
932
|
} from "@tangle-network/sandbox-ui/primitives";
|
|
872
|
-
import { ArrowLeft, DollarSign,
|
|
933
|
+
import { ArrowLeft, DollarSign, FolderOpen as FolderOpen2, X } from "lucide-react";
|
|
873
934
|
|
|
874
935
|
// src/studio-react/studio-sheet.tsx
|
|
875
936
|
import * as Dialog from "@radix-ui/react-dialog";
|
|
@@ -896,6 +957,10 @@ function StudioSheet({
|
|
|
896
957
|
] }) });
|
|
897
958
|
}
|
|
898
959
|
|
|
960
|
+
// src/studio-react/generation-grid.tsx
|
|
961
|
+
import { EmptyState } from "@tangle-network/sandbox-ui/primitives";
|
|
962
|
+
import { Film as Film2, Sparkles as Sparkles3 } from "lucide-react";
|
|
963
|
+
|
|
899
964
|
// src/studio-react/generation-card.tsx
|
|
900
965
|
import { Card, CardContent, Badge as Badge4 } from "@tangle-network/sandbox-ui/primitives";
|
|
901
966
|
import { Send } from "lucide-react";
|
|
@@ -951,11 +1016,36 @@ function GenerationStatusBadge({
|
|
|
951
1016
|
return /* @__PURE__ */ jsx12("div", { className: inline ? "" : "absolute bottom-2 left-2", children: /* @__PURE__ */ jsx12(Badge4, { variant: "outline", className: `${className} text-[10px] backdrop-blur-sm`, children: label }) });
|
|
952
1017
|
}
|
|
953
1018
|
|
|
1019
|
+
// src/studio-react/generation-grid.tsx
|
|
1020
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1021
|
+
function filterGenerations(generations, typeFilter) {
|
|
1022
|
+
if (!typeFilter || !isGenerationType(typeFilter)) return generations;
|
|
1023
|
+
return generations.filter((generation) => generation.type === typeFilter);
|
|
1024
|
+
}
|
|
1025
|
+
function GenerationGrid({
|
|
1026
|
+
generations,
|
|
1027
|
+
typeFilter,
|
|
1028
|
+
onSelect
|
|
1029
|
+
}) {
|
|
1030
|
+
if (generations.length === 0) {
|
|
1031
|
+
return /* @__PURE__ */ jsx13(
|
|
1032
|
+
EmptyState,
|
|
1033
|
+
{
|
|
1034
|
+
icon: typeFilter ? /* @__PURE__ */ jsx13(Film2, { className: "h-8 w-8 text-muted-foreground/30" }) : /* @__PURE__ */ jsx13(Sparkles3, { className: "h-10 w-10 text-muted-foreground/30" }),
|
|
1035
|
+
title: typeFilter ? `No ${TYPE_CONFIG[typeFilter]?.label ?? typeFilter} generations` : "No generations yet",
|
|
1036
|
+
description: typeFilter ? "Try a different filter or change the type in the composer." : "Everything you and the agent create lives here.",
|
|
1037
|
+
className: "py-16"
|
|
1038
|
+
}
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
return /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: generations.map((generation) => /* @__PURE__ */ jsx13(GenerationCard, { generation, onSelect }, generation.id)) });
|
|
1042
|
+
}
|
|
1043
|
+
|
|
954
1044
|
// src/studio-react/generation-detail.tsx
|
|
955
1045
|
import { Link as Link2 } from "react-router";
|
|
956
1046
|
import { Badge as Badge5, Button as Button4 } from "@tangle-network/sandbox-ui/primitives";
|
|
957
1047
|
import { FolderOpen } from "lucide-react";
|
|
958
|
-
import { jsx as
|
|
1048
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
959
1049
|
function GenerationDetail({
|
|
960
1050
|
generation,
|
|
961
1051
|
vaultHref,
|
|
@@ -966,46 +1056,46 @@ function GenerationDetail({
|
|
|
966
1056
|
const vaultPath = generationVaultPath(generation);
|
|
967
1057
|
const href = vaultHref && vaultPath ? vaultHref(vaultPath) : null;
|
|
968
1058
|
return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
|
|
969
|
-
/* @__PURE__ */
|
|
1059
|
+
/* @__PURE__ */ jsx14("div", { className: "overflow-hidden rounded-lg bg-muted/50", children: generation.type === "image" && generation.result ? /* @__PURE__ */ jsx14("img", { src: generation.result, alt: generation.prompt, className: "max-h-[420px] w-full object-contain" }) : (generation.type === "video" || generation.type === "avatar") && generation.result ? /* @__PURE__ */ jsx14("video", { src: generation.result, controls: true, className: "max-h-[420px] w-full" }) : generation.type === "speech" && generation.result ? /* @__PURE__ */ jsx14("div", { className: "p-6", children: /* @__PURE__ */ jsx14("audio", { src: generation.result, controls: true, className: "w-full" }) }) : /* @__PURE__ */ jsx14("div", { className: "flex h-32 items-center justify-center", children: /* @__PURE__ */ jsx14(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) }) }),
|
|
970
1060
|
/* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
/* @__PURE__ */
|
|
973
|
-
generationError(generation) && /* @__PURE__ */
|
|
1061
|
+
/* @__PURE__ */ jsx14(Badge5, { variant: "outline", className: cfg.color, children: cfg.label }),
|
|
1062
|
+
/* @__PURE__ */ jsx14(GenerationStatusBadge, { generation, inline: true }),
|
|
1063
|
+
generationError(generation) && /* @__PURE__ */ jsx14("span", { className: "text-xs text-destructive", children: generationError(generation) })
|
|
974
1064
|
] }),
|
|
975
1065
|
/* @__PURE__ */ jsxs12("div", { children: [
|
|
976
|
-
/* @__PURE__ */
|
|
977
|
-
/* @__PURE__ */
|
|
1066
|
+
/* @__PURE__ */ jsx14("span", { className: "mb-1 block text-xs font-medium text-muted-foreground", children: "Prompt" }),
|
|
1067
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm text-foreground", children: generation.prompt })
|
|
978
1068
|
] }),
|
|
979
1069
|
/* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-4", children: [
|
|
980
1070
|
generation.model && /* @__PURE__ */ jsxs12("div", { children: [
|
|
981
|
-
/* @__PURE__ */
|
|
982
|
-
/* @__PURE__ */
|
|
1071
|
+
/* @__PURE__ */ jsx14("span", { className: "block text-[10px] font-medium text-muted-foreground", children: "Model" }),
|
|
1072
|
+
/* @__PURE__ */ jsx14("span", { className: "text-xs text-foreground", children: generation.model })
|
|
983
1073
|
] }),
|
|
984
1074
|
generation.cost != null && /* @__PURE__ */ jsxs12("div", { children: [
|
|
985
|
-
/* @__PURE__ */
|
|
1075
|
+
/* @__PURE__ */ jsx14("span", { className: "block text-[10px] font-medium text-muted-foreground", children: "Cost" }),
|
|
986
1076
|
/* @__PURE__ */ jsxs12("span", { className: "text-xs text-foreground", children: [
|
|
987
1077
|
"$",
|
|
988
1078
|
generation.cost.toFixed(4)
|
|
989
1079
|
] })
|
|
990
1080
|
] }),
|
|
991
1081
|
generation.createdAt && /* @__PURE__ */ jsxs12("div", { children: [
|
|
992
|
-
/* @__PURE__ */
|
|
993
|
-
/* @__PURE__ */
|
|
1082
|
+
/* @__PURE__ */ jsx14("span", { className: "block text-[10px] font-medium text-muted-foreground", children: "Created" }),
|
|
1083
|
+
/* @__PURE__ */ jsx14("span", { className: "text-xs text-foreground", children: new Date(generation.createdAt).toLocaleString() })
|
|
994
1084
|
] })
|
|
995
1085
|
] }),
|
|
996
1086
|
generation.type === "transcription" && generation.result && /* @__PURE__ */ jsxs12("div", { children: [
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
1087
|
+
/* @__PURE__ */ jsx14("span", { className: "mb-1 block text-xs font-medium text-muted-foreground", children: "Transcription" }),
|
|
1088
|
+
/* @__PURE__ */ jsx14("pre", { className: "max-h-64 overflow-y-auto whitespace-pre-wrap rounded-lg bg-muted/50 p-4 text-sm text-foreground", children: generation.result })
|
|
999
1089
|
] }),
|
|
1000
|
-
href && /* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1090
|
+
href && /* @__PURE__ */ jsx14("div", { className: "border-t border-border pt-2", children: /* @__PURE__ */ jsx14(Link2, { to: href, prefetch: "intent", onClick: onNavigate, children: /* @__PURE__ */ jsxs12(Button4, { size: "sm", variant: "outline", children: [
|
|
1091
|
+
/* @__PURE__ */ jsx14(FolderOpen, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
1002
1092
|
"Open in Vault"
|
|
1003
1093
|
] }) }) })
|
|
1004
1094
|
] });
|
|
1005
1095
|
}
|
|
1006
1096
|
|
|
1007
1097
|
// src/studio-react/library-drawer.tsx
|
|
1008
|
-
import { Fragment as
|
|
1098
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1009
1099
|
function LibraryDrawer({
|
|
1010
1100
|
open,
|
|
1011
1101
|
onOpenChange,
|
|
@@ -1017,10 +1107,7 @@ function LibraryDrawer({
|
|
|
1017
1107
|
selected,
|
|
1018
1108
|
onSelect
|
|
1019
1109
|
}) {
|
|
1020
|
-
const visible = useMemo3(() =>
|
|
1021
|
-
if (!typeFilter || !isGenerationType(typeFilter)) return generations;
|
|
1022
|
-
return generations.filter((generation) => generation.type === typeFilter);
|
|
1023
|
-
}, [generations, typeFilter]);
|
|
1110
|
+
const visible = useMemo3(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
|
|
1024
1111
|
return /* @__PURE__ */ jsxs13(StudioSheet, { open, onOpenChange, title: "Asset library", children: [
|
|
1025
1112
|
/* @__PURE__ */ jsxs13("header", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
|
|
1026
1113
|
selected ? /* @__PURE__ */ jsxs13(
|
|
@@ -1030,30 +1117,30 @@ function LibraryDrawer({
|
|
|
1030
1117
|
onClick: () => onSelect(null),
|
|
1031
1118
|
className: "flex items-center gap-1.5 text-sm font-medium text-foreground transition-colors hover:text-primary",
|
|
1032
1119
|
children: [
|
|
1033
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx15(ArrowLeft, { className: "h-4 w-4" }),
|
|
1034
1121
|
"Back to library"
|
|
1035
1122
|
]
|
|
1036
1123
|
}
|
|
1037
|
-
) : /* @__PURE__ */
|
|
1038
|
-
/* @__PURE__ */
|
|
1124
|
+
) : /* @__PURE__ */ jsx15("h2", { className: "text-sm font-semibold text-foreground", children: "Asset library" }),
|
|
1125
|
+
/* @__PURE__ */ jsx15(
|
|
1039
1126
|
"button",
|
|
1040
1127
|
{
|
|
1041
1128
|
type: "button",
|
|
1042
1129
|
"aria-label": "Close library",
|
|
1043
1130
|
onClick: () => onOpenChange(false),
|
|
1044
1131
|
className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
1045
|
-
children: /* @__PURE__ */
|
|
1132
|
+
children: /* @__PURE__ */ jsx15(X, { className: "h-4 w-4" })
|
|
1046
1133
|
}
|
|
1047
1134
|
)
|
|
1048
1135
|
] }),
|
|
1049
|
-
selected ? /* @__PURE__ */
|
|
1136
|
+
selected ? /* @__PURE__ */ jsx15("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx15(
|
|
1050
1137
|
GenerationDetail,
|
|
1051
1138
|
{
|
|
1052
1139
|
generation: selected,
|
|
1053
1140
|
vaultHref,
|
|
1054
1141
|
onNavigate: () => onOpenChange(false)
|
|
1055
1142
|
}
|
|
1056
|
-
) }) : /* @__PURE__ */ jsxs13(
|
|
1143
|
+
) }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1057
1144
|
/* @__PURE__ */ jsxs13("div", { className: "shrink-0 border-b border-border px-4 pt-3", children: [
|
|
1058
1145
|
/* @__PURE__ */ jsxs13("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
|
|
1059
1146
|
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
@@ -1063,36 +1150,28 @@ function LibraryDrawer({
|
|
|
1063
1150
|
visible.length !== 1 ? "s" : ""
|
|
1064
1151
|
] }),
|
|
1065
1152
|
/* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-0.5", children: [
|
|
1066
|
-
/* @__PURE__ */
|
|
1153
|
+
/* @__PURE__ */ jsx15(DollarSign, { className: "h-3 w-3" }),
|
|
1067
1154
|
totalCost.toFixed(2),
|
|
1068
1155
|
" spent"
|
|
1069
1156
|
] })
|
|
1070
1157
|
] }),
|
|
1071
|
-
vaultHref && /* @__PURE__ */
|
|
1072
|
-
/* @__PURE__ */
|
|
1158
|
+
vaultHref && /* @__PURE__ */ jsx15(Link3, { to: vaultHref(), prefetch: "intent", onClick: () => onOpenChange(false), children: /* @__PURE__ */ jsxs13(Button5, { size: "sm", variant: "outline", children: [
|
|
1159
|
+
/* @__PURE__ */ jsx15(FolderOpen2, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
1073
1160
|
"Vault"
|
|
1074
1161
|
] }) })
|
|
1075
1162
|
] }),
|
|
1076
|
-
/* @__PURE__ */
|
|
1077
|
-
/* @__PURE__ */
|
|
1078
|
-
Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */
|
|
1163
|
+
/* @__PURE__ */ jsx15(Tabs, { value: typeFilter ?? "all", onValueChange: (v) => onFilterChange(v === "all" ? null : v), children: /* @__PURE__ */ jsxs13(TabsList, { className: "h-9 w-full justify-start gap-1 overflow-x-auto bg-transparent", children: [
|
|
1164
|
+
/* @__PURE__ */ jsx15(TabsTrigger, { value: "all", className: "text-xs", children: "All" }),
|
|
1165
|
+
Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx15(TabsTrigger, { value: key, className: "text-xs", children: cfg.label }, key))
|
|
1079
1166
|
] }) })
|
|
1080
1167
|
] }),
|
|
1081
|
-
/* @__PURE__ */
|
|
1082
|
-
EmptyState,
|
|
1083
|
-
{
|
|
1084
|
-
icon: typeFilter ? /* @__PURE__ */ jsx14(Film2, { className: "h-8 w-8 text-muted-foreground/30" }) : /* @__PURE__ */ jsx14(Sparkles3, { className: "h-10 w-10 text-muted-foreground/30" }),
|
|
1085
|
-
title: typeFilter ? `No ${TYPE_CONFIG[typeFilter]?.label ?? typeFilter} generations` : "No generations yet",
|
|
1086
|
-
description: typeFilter ? "Try a different filter or change the type in the composer." : "Everything you and the agent create lives here.",
|
|
1087
|
-
className: "py-16"
|
|
1088
|
-
}
|
|
1089
|
-
) : /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: visible.map((generation) => /* @__PURE__ */ jsx14(GenerationCard, { generation, onSelect }, generation.id)) }) })
|
|
1168
|
+
/* @__PURE__ */ jsx15("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx15(GenerationGrid, { generations: visible, typeFilter, onSelect }) })
|
|
1090
1169
|
] })
|
|
1091
1170
|
] });
|
|
1092
1171
|
}
|
|
1093
1172
|
|
|
1094
1173
|
// src/studio-react/studio-workspace.tsx
|
|
1095
|
-
import { Fragment as
|
|
1174
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1096
1175
|
function StudioWorkspace({
|
|
1097
1176
|
generations,
|
|
1098
1177
|
totalCost,
|
|
@@ -1128,7 +1207,7 @@ function StudioWorkspace({
|
|
|
1128
1207
|
setDrawerOpen(true);
|
|
1129
1208
|
}
|
|
1130
1209
|
return /* @__PURE__ */ jsxs14("div", { className: "min-h-0 flex-1 overflow-y-auto bg-background", children: [
|
|
1131
|
-
/* @__PURE__ */
|
|
1210
|
+
/* @__PURE__ */ jsx16(
|
|
1132
1211
|
StudioHeader,
|
|
1133
1212
|
{
|
|
1134
1213
|
count: mergedGenerations.length,
|
|
@@ -1136,8 +1215,8 @@ function StudioWorkspace({
|
|
|
1136
1215
|
onOpenLibrary: openLibrary
|
|
1137
1216
|
}
|
|
1138
1217
|
),
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1218
|
+
/* @__PURE__ */ jsx16("div", { className: "mx-auto w-full max-w-3xl space-y-4 px-4 py-6 sm:px-6", children: canGenerate ? /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
1219
|
+
/* @__PURE__ */ jsx16(
|
|
1141
1220
|
ComposerHero,
|
|
1142
1221
|
{
|
|
1143
1222
|
workspaceId,
|
|
@@ -1151,7 +1230,7 @@ function StudioWorkspace({
|
|
|
1151
1230
|
}
|
|
1152
1231
|
}
|
|
1153
1232
|
),
|
|
1154
|
-
/* @__PURE__ */
|
|
1233
|
+
/* @__PURE__ */ jsx16("div", { ref: canvasRef, children: /* @__PURE__ */ jsx16(
|
|
1155
1234
|
ResultCanvas,
|
|
1156
1235
|
{
|
|
1157
1236
|
batch: latestBatch,
|
|
@@ -1160,15 +1239,15 @@ function StudioWorkspace({
|
|
|
1160
1239
|
}
|
|
1161
1240
|
) })
|
|
1162
1241
|
] }) : /* @__PURE__ */ jsxs14("section", { className: "flex flex-col items-center justify-center gap-3 rounded-xl border border-border bg-card p-10 text-center shadow-sm", children: [
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1242
|
+
/* @__PURE__ */ jsx16("div", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx16(Images2, { className: "h-6 w-6 text-muted-foreground/40" }) }),
|
|
1243
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm font-medium text-foreground", children: mergedGenerations.length > 0 ? `${mergedGenerations.length} asset${mergedGenerations.length !== 1 ? "s" : ""} in this workspace` : "No generations yet" }),
|
|
1244
|
+
/* @__PURE__ */ jsx16("p", { className: "max-w-sm text-xs text-muted-foreground", children: "When workspace members generate images, video, voice, avatars, or transcripts, they appear in the library." }),
|
|
1166
1245
|
/* @__PURE__ */ jsxs14(Button6, { size: "sm", variant: "outline", onClick: openLibrary, children: [
|
|
1167
|
-
/* @__PURE__ */
|
|
1246
|
+
/* @__PURE__ */ jsx16(Images2, { className: "mr-1.5 h-4 w-4" }),
|
|
1168
1247
|
"Open library"
|
|
1169
1248
|
] })
|
|
1170
1249
|
] }) }),
|
|
1171
|
-
/* @__PURE__ */
|
|
1250
|
+
/* @__PURE__ */ jsx16(
|
|
1172
1251
|
LibraryDrawer,
|
|
1173
1252
|
{
|
|
1174
1253
|
open: drawerOpen,
|
|
@@ -1190,6 +1269,78 @@ function StudioWorkspace({
|
|
|
1190
1269
|
)
|
|
1191
1270
|
] });
|
|
1192
1271
|
}
|
|
1272
|
+
|
|
1273
|
+
// src/studio-react/library-panel.tsx
|
|
1274
|
+
import { useMemo as useMemo4 } from "react";
|
|
1275
|
+
import {
|
|
1276
|
+
Tabs as Tabs2,
|
|
1277
|
+
TabsList as TabsList2,
|
|
1278
|
+
TabsTrigger as TabsTrigger2
|
|
1279
|
+
} from "@tangle-network/sandbox-ui/primitives";
|
|
1280
|
+
import { DollarSign as DollarSign2 } from "lucide-react";
|
|
1281
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1282
|
+
function LibraryPanel({
|
|
1283
|
+
generations,
|
|
1284
|
+
totalCost,
|
|
1285
|
+
typeFilter,
|
|
1286
|
+
onFilterChange,
|
|
1287
|
+
onSelect
|
|
1288
|
+
}) {
|
|
1289
|
+
const visible = useMemo4(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
|
|
1290
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 flex-col", children: [
|
|
1291
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [
|
|
1292
|
+
/* @__PURE__ */ jsx17(Tabs2, { value: typeFilter ?? "all", onValueChange: (v) => onFilterChange(v === "all" ? null : v), children: /* @__PURE__ */ jsxs15(TabsList2, { className: "h-9 justify-start gap-1 overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-[var(--md3-surface-container-low)] p-1", children: [
|
|
1293
|
+
/* @__PURE__ */ jsx17(
|
|
1294
|
+
TabsTrigger2,
|
|
1295
|
+
{
|
|
1296
|
+
value: "all",
|
|
1297
|
+
className: "rounded-md px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground data-[state=active]:bg-primary/10 data-[state=active]:font-semibold data-[state=active]:text-primary data-[state=active]:shadow-none",
|
|
1298
|
+
children: "All"
|
|
1299
|
+
}
|
|
1300
|
+
),
|
|
1301
|
+
Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx17(
|
|
1302
|
+
TabsTrigger2,
|
|
1303
|
+
{
|
|
1304
|
+
value: key,
|
|
1305
|
+
className: "rounded-md px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground data-[state=active]:bg-primary/10 data-[state=active]:font-semibold data-[state=active]:text-primary data-[state=active]:shadow-none",
|
|
1306
|
+
children: cfg.label
|
|
1307
|
+
},
|
|
1308
|
+
key
|
|
1309
|
+
))
|
|
1310
|
+
] }) }),
|
|
1311
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
1312
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
1313
|
+
visible.length,
|
|
1314
|
+
" generation",
|
|
1315
|
+
visible.length !== 1 ? "s" : ""
|
|
1316
|
+
] }),
|
|
1317
|
+
/* @__PURE__ */ jsxs15("span", { className: "flex items-center gap-0.5", children: [
|
|
1318
|
+
/* @__PURE__ */ jsx17(DollarSign2, { className: "h-3 w-3" }),
|
|
1319
|
+
totalCost.toFixed(2),
|
|
1320
|
+
" spent"
|
|
1321
|
+
] })
|
|
1322
|
+
] })
|
|
1323
|
+
] }),
|
|
1324
|
+
/* @__PURE__ */ jsx17(GenerationGrid, { generations: visible, typeFilter, onSelect })
|
|
1325
|
+
] });
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// src/studio-react/generation-detail-modal.tsx
|
|
1329
|
+
import { Dialog as Dialog2, DialogContent, DialogHeader, DialogTitle } from "@tangle-network/sandbox-ui/primitives";
|
|
1330
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1331
|
+
function GenerationDetailModal({
|
|
1332
|
+
generation,
|
|
1333
|
+
vaultHref,
|
|
1334
|
+
onClose
|
|
1335
|
+
}) {
|
|
1336
|
+
const cfg = generation ? typeConfigFor(generation.type) : null;
|
|
1337
|
+
return /* @__PURE__ */ jsx18(Dialog2, { open: generation != null, onOpenChange: (open) => {
|
|
1338
|
+
if (!open) onClose();
|
|
1339
|
+
}, children: /* @__PURE__ */ jsxs16(DialogContent, { className: "max-h-[85vh] max-w-2xl overflow-y-auto", children: [
|
|
1340
|
+
/* @__PURE__ */ jsx18(DialogHeader, { children: /* @__PURE__ */ jsx18(DialogTitle, { className: "text-left text-base", children: cfg?.label ?? "Generation" }) }),
|
|
1341
|
+
generation && /* @__PURE__ */ jsx18(GenerationDetail, { generation, vaultHref, onNavigate: onClose })
|
|
1342
|
+
] }) });
|
|
1343
|
+
}
|
|
1193
1344
|
export {
|
|
1194
1345
|
AvatarComposer,
|
|
1195
1346
|
ComposerDisclosure,
|
|
@@ -1197,13 +1348,17 @@ export {
|
|
|
1197
1348
|
Field,
|
|
1198
1349
|
GenerationCard,
|
|
1199
1350
|
GenerationDetail,
|
|
1351
|
+
GenerationDetailModal,
|
|
1352
|
+
GenerationGrid,
|
|
1200
1353
|
GenerationStatusBadge,
|
|
1201
1354
|
ImageComposer,
|
|
1202
1355
|
LibraryDrawer,
|
|
1356
|
+
LibraryPanel,
|
|
1203
1357
|
NativeSelect,
|
|
1204
1358
|
PublishPackageComposer,
|
|
1205
1359
|
ResultCanvas,
|
|
1206
1360
|
SpeechComposer,
|
|
1361
|
+
Stepper,
|
|
1207
1362
|
StudioHeader,
|
|
1208
1363
|
StudioSheet,
|
|
1209
1364
|
StudioWorkspace,
|
|
@@ -1211,6 +1366,7 @@ export {
|
|
|
1211
1366
|
TranscriptionComposer,
|
|
1212
1367
|
TranscriptionOptions,
|
|
1213
1368
|
VideoComposer,
|
|
1369
|
+
filterGenerations,
|
|
1214
1370
|
typeConfigFor,
|
|
1215
1371
|
useStudioGenerations
|
|
1216
1372
|
};
|