@tangle-network/agent-app 0.45.64 → 0.45.66

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.
@@ -1,6 +1,4 @@
1
1
  import {
2
- CADENCES,
3
- DESTINATIONS,
4
2
  IMAGE_QUALITIES,
5
3
  IMAGE_SIZE_HINT,
6
4
  IMAGE_SIZE_PATTERN,
@@ -10,15 +8,12 @@ import {
10
8
  VIDEO_DURATIONS,
11
9
  VIDEO_RESOLUTIONS,
12
10
  buildGenerationRequestBody,
13
- buildPublishPackage,
14
11
  failedOptimisticGeneration,
15
12
  generationError,
16
13
  generationStatus,
17
14
  generationVaultPath,
18
- isDestinationConnected,
19
15
  isGenerationType,
20
16
  isLocalGeneration,
21
- isPublishPackage,
22
17
  latestBatchOf,
23
18
  mergeLiveGeneration,
24
19
  mergeLoaderAndLive,
@@ -30,7 +25,7 @@ import {
30
25
  relativeTime,
31
26
  selectedModelsWithDefaults,
32
27
  userSafeGenerationMessage
33
- } from "../chunk-HSBJB46C.js";
28
+ } from "../chunk-E2CWFUUP.js";
34
29
  import {
35
30
  ProviderLogo
36
31
  } from "../chunk-MLG6XKPV.js";
@@ -38,7 +33,7 @@ import {
38
33
  // src/studio-react/studio-workspace.tsx
39
34
  import { useRef as useRef3, useState as useState3 } from "react";
40
35
  import { useSearchParams } from "react-router";
41
- import { Button as Button6 } from "@tangle-network/sandbox-ui/primitives";
36
+ import { Button as Button5 } from "@tangle-network/sandbox-ui/primitives";
42
37
  import { Images as Images2 } from "lucide-react";
43
38
 
44
39
  // src/studio-react/use-studio-generations.ts
@@ -98,20 +93,18 @@ function useStudioGenerations(loaderGenerations, options = {}) {
98
93
  }
99
94
 
100
95
  // src/studio-react/composer-hero.tsx
101
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
96
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
102
97
  import {
103
- Badge as Badge2,
104
- Button as Button2,
105
- Input as Input7,
98
+ Button,
99
+ Input as Input4,
106
100
  Label as Label2,
107
- Textarea as Textarea2,
101
+ Textarea,
108
102
  Select,
109
103
  SelectContent,
110
104
  SelectItem,
111
105
  SelectTrigger,
112
106
  SelectValue
113
107
  } from "@tangle-network/sandbox-ui/primitives";
114
- import { useIntegrations } from "@tangle-network/sandbox-ui/integrations";
115
108
  import { Sparkles } from "lucide-react";
116
109
 
117
110
  // src/studio-react/type-config.ts
@@ -264,170 +257,9 @@ function SpeechComposer({
264
257
  return /* @__PURE__ */ jsx4(Field, { label: "Voice", children: /* @__PURE__ */ jsx4(Input3, { value: voice, onChange: (event) => onVoiceChange(event.target.value), className: "bg-background" }) });
265
258
  }
266
259
 
267
- // src/studio-react/avatar-composer.tsx
268
- import { Input as Input4 } from "@tangle-network/sandbox-ui/primitives";
269
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
270
- function AvatarComposer({
271
- audioUrl,
272
- imageUrl,
273
- avatarId,
274
- onAudioUrlChange,
275
- onImageUrlChange,
276
- onAvatarIdChange
277
- }) {
278
- return /* @__PURE__ */ jsxs4("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
279
- /* @__PURE__ */ jsx5(Field, { label: "Audio URL", htmlFor: "studio-audio-url", children: /* @__PURE__ */ jsx5(
280
- Input4,
281
- {
282
- id: "studio-audio-url",
283
- value: audioUrl,
284
- onChange: (event) => onAudioUrlChange(event.target.value),
285
- placeholder: "https://cdn.example.com/source-audio.mp3",
286
- className: "bg-background"
287
- }
288
- ) }),
289
- /* @__PURE__ */ jsx5(Field, { label: "Image URL", htmlFor: "studio-avatar-image-url", children: /* @__PURE__ */ jsx5(
290
- Input4,
291
- {
292
- id: "studio-avatar-image-url",
293
- value: imageUrl,
294
- onChange: (event) => onImageUrlChange(event.target.value),
295
- placeholder: "https://cdn.example.com/portrait.png",
296
- className: "bg-background"
297
- }
298
- ) }),
299
- /* @__PURE__ */ jsx5(Field, { label: "Avatar ID", htmlFor: "studio-avatar-id", children: /* @__PURE__ */ jsx5(
300
- Input4,
301
- {
302
- id: "studio-avatar-id",
303
- value: avatarId,
304
- onChange: (event) => onAvatarIdChange(event.target.value),
305
- placeholder: "Optional provider avatar id",
306
- className: "bg-background"
307
- }
308
- ) })
309
- ] });
310
- }
311
-
312
- // src/studio-react/transcription-composer.tsx
313
- import { Input as Input5 } from "@tangle-network/sandbox-ui/primitives";
314
- import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
315
- function TranscriptionComposer({
316
- audioUrl,
317
- language,
318
- onAudioUrlChange,
319
- onLanguageChange
320
- }) {
321
- return /* @__PURE__ */ jsxs5("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
322
- /* @__PURE__ */ jsx6(Field, { label: "Audio URL", htmlFor: "studio-audio-url", children: /* @__PURE__ */ jsx6(
323
- Input5,
324
- {
325
- id: "studio-audio-url",
326
- value: audioUrl,
327
- onChange: (event) => onAudioUrlChange(event.target.value),
328
- placeholder: "https://cdn.example.com/source-audio.mp3",
329
- className: "bg-background"
330
- }
331
- ) }),
332
- /* @__PURE__ */ jsx6(Field, { label: "Language", htmlFor: "studio-transcription-language", children: /* @__PURE__ */ jsx6(
333
- Input5,
334
- {
335
- id: "studio-transcription-language",
336
- value: language,
337
- onChange: (event) => onLanguageChange(event.target.value),
338
- placeholder: "en",
339
- className: "bg-background"
340
- }
341
- ) })
342
- ] });
343
- }
344
- function TranscriptionOptions({
345
- responseFormat,
346
- temperature,
347
- onResponseFormatChange,
348
- onTemperatureChange
349
- }) {
350
- return /* @__PURE__ */ jsxs5(Fragment, { children: [
351
- /* @__PURE__ */ jsx6(Field, { label: "Response format", children: /* @__PURE__ */ jsxs5(NativeSelect, { value: responseFormat, onChange: (event) => onResponseFormatChange(event.target.value), children: [
352
- /* @__PURE__ */ jsx6("option", { value: "json", children: "JSON" }),
353
- /* @__PURE__ */ jsx6("option", { value: "text", children: "Text" }),
354
- /* @__PURE__ */ jsx6("option", { value: "srt", children: "SRT" }),
355
- /* @__PURE__ */ jsx6("option", { value: "verbose_json", children: "Verbose JSON" }),
356
- /* @__PURE__ */ jsx6("option", { value: "vtt", children: "VTT" })
357
- ] }) }),
358
- /* @__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-background" }) })
359
- ] });
360
- }
361
-
362
- // src/studio-react/publish-package-composer.tsx
363
- import { Link } from "react-router";
364
- import { Badge, Button, Input as Input6, Textarea } from "@tangle-network/sandbox-ui/primitives";
365
- import { ProviderIcon } from "@tangle-network/sandbox-ui/integrations";
366
- import { AlertTriangle, Check } from "lucide-react";
367
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
368
- function PublishPackageComposer({
369
- caption,
370
- postDescription,
371
- mentions,
372
- cadence,
373
- selectedDestinations,
374
- connections,
375
- connectionError,
376
- connectionsLoading,
377
- integrationsHref,
378
- canManageIntegrations,
379
- onCaptionChange,
380
- onDescriptionChange,
381
- onMentionsChange,
382
- onCadenceChange,
383
- onDestinationToggle
384
- }) {
385
- return /* @__PURE__ */ jsxs6("div", { className: "space-y-3", children: [
386
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
387
- connectionError ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-md border border-warning/25 bg-warning/10 px-2.5 py-1.5 text-xs text-warning", children: [
388
- /* @__PURE__ */ jsx7(AlertTriangle, { className: "h-3.5 w-3.5 shrink-0" }),
389
- "Couldn't load connected apps. Check Integrations."
390
- ] }) : /* @__PURE__ */ jsx7("p", { className: "text-xs text-muted-foreground", children: connectionsLoading ? "Checking connected apps\u2026" : "Saved with the generated asset." }),
391
- integrationsHref && canManageIntegrations && /* @__PURE__ */ jsx7(Link, { to: integrationsHref, prefetch: "intent", className: "shrink-0", children: /* @__PURE__ */ jsx7(Button, { variant: "outline", size: "sm", children: "Connect" }) })
392
- ] }),
393
- /* @__PURE__ */ jsx7("div", { className: "grid gap-2", children: DESTINATIONS.map((destination) => {
394
- const connected = isDestinationConnected(destination, connections);
395
- const active = connected && selectedDestinations.includes(destination.id);
396
- return /* @__PURE__ */ jsxs6(
397
- "button",
398
- {
399
- type: "button",
400
- disabled: !connected,
401
- "aria-pressed": active,
402
- onClick: () => onDestinationToggle(destination.id),
403
- className: `rounded-md border p-2 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${active ? "border-primary bg-primary/10 ring-1 ring-primary/20" : "border-border bg-background hover:bg-accent"}`,
404
- children: [
405
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
406
- /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1.5 text-xs font-medium text-foreground", children: [
407
- active && /* @__PURE__ */ jsx7(Check, { className: "h-3.5 w-3.5 text-primary" }),
408
- /* @__PURE__ */ jsx7(ProviderIcon, { id: destination.providerIds[0] ?? destination.id, displayName: destination.label, size: 16, className: "rounded" }),
409
- destination.label
410
- ] }),
411
- /* @__PURE__ */ jsx7(Badge, { variant: active || connected ? "default" : "outline", children: active ? "Selected" : connected ? "Ready" : "Not connected" })
412
- ] }),
413
- /* @__PURE__ */ jsx7("p", { className: "mt-1 text-xs text-muted-foreground", children: destination.fields })
414
- ]
415
- },
416
- destination.id
417
- );
418
- }) }),
419
- /* @__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-background" }) }),
420
- /* @__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-background" }) }),
421
- /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-2 gap-3", children: [
422
- /* @__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-background" }) }),
423
- /* @__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)) }) })
424
- ] })
425
- ] });
426
- }
427
-
428
260
  // src/studio-react/composer-hero.tsx
429
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
430
- var HUB_BASE_URL = "/api/integrations/hub";
261
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
262
+ var COMPOSER_TYPES = ["image", "video", "speech"];
431
263
  var SUGGESTIONS = [
432
264
  {
433
265
  label: "Storyboard frame",
@@ -443,17 +275,10 @@ var SUGGESTIONS = [
443
275
  label: "Scratch voiceover",
444
276
  type: "speech",
445
277
  prompt: "A confident 12-second scratch voiceover for a product launch teaser: warm tone, conversational pace."
446
- },
447
- {
448
- label: "Transcribe dailies",
449
- type: "transcription",
450
- prompt: "Transcribe the latest dailies recording with timestamps, speaker labels, and key story beats highlighted."
451
278
  }
452
279
  ];
453
280
  function ComposerHero({
454
281
  workspaceId,
455
- integrationsHref,
456
- canManageIntegrations,
457
282
  align = "start",
458
283
  surfaceClassName = "bg-card",
459
284
  onGenerated
@@ -462,11 +287,6 @@ function ComposerHero({
462
287
  const [prompt, setPrompt] = useState2("");
463
288
  const [negativePrompt, setNegativePrompt] = useState2("");
464
289
  const [outputPath, setOutputPath] = useState2(outputPathFor("image"));
465
- const [caption, setCaption] = useState2("");
466
- const [postDescription, setPostDescription] = useState2("");
467
- const [mentions, setMentions] = useState2("");
468
- const [cadence, setCadence] = useState2(CADENCES[0] ?? "Manual approval");
469
- const [selectedDestinations, setSelectedDestinations] = useState2([]);
470
290
  const [size, setSize] = useState2("1536x1024");
471
291
  const [quality, setQuality] = useState2("high");
472
292
  const [imageCount, setImageCount] = useState2(1);
@@ -475,13 +295,6 @@ function ComposerHero({
475
295
  const [aspectRatio, setAspectRatio] = useState2("16:9");
476
296
  const [referenceImageUrl, setReferenceImageUrl] = useState2("");
477
297
  const [voice, setVoice] = useState2("alloy");
478
- const [avatarAudioUrl, setAvatarAudioUrl] = useState2("");
479
- const [avatarImageUrl, setAvatarImageUrl] = useState2("");
480
- const [avatarId, setAvatarId] = useState2("");
481
- const [transcriptionAudioUrl, setTranscriptionAudioUrl] = useState2("");
482
- const [transcriptionLanguage, setTranscriptionLanguage] = useState2("");
483
- const [transcriptionResponseFormat, setTranscriptionResponseFormat] = useState2("json");
484
- const [transcriptionTemperature, setTranscriptionTemperature] = useState2("0");
485
298
  const [mediaModels, setMediaModels] = useState2(null);
486
299
  const [mediaModelsLoading, setMediaModelsLoading] = useState2(false);
487
300
  const [mediaModelsError, setMediaModelsError] = useState2(null);
@@ -493,13 +306,8 @@ function ComposerHero({
493
306
  const selectedModel = selectedModels[type] ?? preferredModelId(type, mediaModels) ?? "";
494
307
  const selectedModelOption = modelsForType.find((model) => model.id === selectedModel);
495
308
  const modelReady = Boolean(selectedModelOption) && selectedModelOption?.status !== "unavailable" && !mediaModelsLoading && !mediaModelsError;
496
- const hasRequiredInput = type === "transcription" ? Boolean(transcriptionAudioUrl.trim()) : type === "avatar" ? Boolean(avatarAudioUrl.trim()) : Boolean(prompt.trim());
309
+ const hasRequiredInput = Boolean(prompt.trim());
497
310
  const canSubmit = Boolean(workspaceId) && modelReady && hasRequiredInput && !isSubmitting;
498
- const integrations = useIntegrations({ apiBaseUrl: HUB_BASE_URL });
499
- const selectedConnectedDestinations = useMemo2(() => selectedDestinations.filter((destinationId) => {
500
- const destination = DESTINATIONS.find((item) => item.id === destinationId);
501
- return Boolean(destination && isDestinationConnected(destination, integrations.connections));
502
- }), [integrations.connections, selectedDestinations]);
503
311
  useEffect2(() => {
504
312
  if (!workspaceId) return;
505
313
  let cancelled = false;
@@ -531,28 +339,14 @@ function ComposerHero({
531
339
  async function generate() {
532
340
  if (!workspaceId || submitLockRef.current) return;
533
341
  const promptText = prompt.trim();
534
- const avatarAudioUrlText = avatarAudioUrl.trim();
535
- const transcriptionAudioUrlText = transcriptionAudioUrl.trim();
536
- if (type !== "transcription" && type !== "avatar" && !promptText) {
342
+ if (!promptText) {
537
343
  setError("prompt is required");
538
344
  return;
539
345
  }
540
- if (type === "avatar" && !avatarAudioUrlText) {
541
- setError("audioUrl is required");
542
- return;
543
- }
544
- if (type === "transcription" && !transcriptionAudioUrlText) {
545
- setError("audioUrl is required");
546
- return;
547
- }
548
346
  if (!selectedModelOption || selectedModelOption.status === "unavailable") {
549
347
  setError(`Select an available ${typeConfigFor(type).label} model`);
550
348
  return;
551
349
  }
552
- if (cadence === "Publish now" && selectedConnectedDestinations.length === 0) {
553
- setError("Select a connected destination to publish now");
554
- return;
555
- }
556
350
  submitLockRef.current = true;
557
351
  setIsSubmitting(true);
558
352
  setError(null);
@@ -561,9 +355,7 @@ function ComposerHero({
561
355
  if (type === "image" && requestedImageCount !== imageCount) setImageCount(requestedImageCount);
562
356
  const localGenerations = Array.from({ length: requestedImageCount }, (_, outputIndex) => optimisticGeneration({
563
357
  type,
564
- // avatar hides the prompt field (promptText is stale); transcription's is
565
- // an optional vocab hint. Never surface the source audio URL as the prompt.
566
- prompt: type === "avatar" ? "" : promptText,
358
+ prompt: promptText,
567
359
  model: selectedModel,
568
360
  clientRequestId,
569
361
  outputIndex: type === "image" ? outputIndex : void 0,
@@ -581,23 +373,9 @@ function ComposerHero({
581
373
  prompt,
582
374
  negativePrompt,
583
375
  outputPath,
584
- publishPackage: buildPublishPackage({
585
- caption,
586
- postDescription,
587
- mentions,
588
- cadence,
589
- destinations: selectedConnectedDestinations
590
- }),
591
376
  image: { size, quality, count: requestedImageCount },
592
377
  video: { duration, resolution, aspectRatio, referenceImageUrl },
593
- speech: { voice },
594
- avatar: { audioUrl: avatarAudioUrl, imageUrl: avatarImageUrl, avatarId },
595
- transcription: {
596
- audioUrl: transcriptionAudioUrl,
597
- language: transcriptionLanguage,
598
- responseFormat: transcriptionResponseFormat,
599
- temperature: transcriptionTemperature
600
- }
378
+ speech: { voice }
601
379
  });
602
380
  const res = await fetch("/api/generate", {
603
381
  method: "POST",
@@ -619,19 +397,19 @@ function ComposerHero({
619
397
  setIsSubmitting(false);
620
398
  }
621
399
  }
622
- const mediaTypes = Object.entries(TYPE_CONFIG);
623
- return /* @__PURE__ */ jsxs7("section", { className: `rounded-2xl border border-border p-5 shadow-sm ${surfaceClassName}`, children: [
624
- /* @__PURE__ */ jsx8("div", { className: `mb-5 ${align === "center" ? "text-center" : "text-left"}`, children: /* @__PURE__ */ jsx8(
400
+ const mediaTypes = COMPOSER_TYPES.map((key) => [key, typeConfigFor(key)]);
401
+ return /* @__PURE__ */ jsxs4("section", { className: `rounded-2xl border border-border p-5 shadow-sm ${surfaceClassName}`, children: [
402
+ /* @__PURE__ */ jsx5("div", { className: `mb-5 ${align === "center" ? "text-center" : "text-left"}`, children: /* @__PURE__ */ jsx5(
625
403
  "h2",
626
404
  {
627
405
  className: `font-semibold tracking-tight text-foreground transition-all duration-300 ${align === "center" ? "text-xl" : "text-base"}`,
628
406
  children: "Media Generation"
629
407
  }
630
408
  ) }),
631
- /* @__PURE__ */ jsx8("div", { role: "tablist", "aria-label": "Generation type", className: "grid grid-cols-5 gap-1.5", children: mediaTypes.map(([key, cfg]) => {
409
+ /* @__PURE__ */ jsx5("div", { role: "tablist", "aria-label": "Generation type", className: "grid grid-cols-3 gap-1.5", children: mediaTypes.map(([key, cfg]) => {
632
410
  const Icon = cfg.icon;
633
411
  const active = type === key;
634
- return /* @__PURE__ */ jsxs7(
412
+ return /* @__PURE__ */ jsxs4(
635
413
  "button",
636
414
  {
637
415
  type: "button",
@@ -640,15 +418,15 @@ function ComposerHero({
640
418
  onClick: () => changeType(key),
641
419
  className: `flex flex-col items-center gap-1.5 rounded-lg border px-1 pb-2 pt-2.5 text-xs 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"}`,
642
420
  children: [
643
- /* @__PURE__ */ jsx8(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
644
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: cfg.label })
421
+ /* @__PURE__ */ jsx5(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
422
+ /* @__PURE__ */ jsx5("span", { className: "truncate", children: cfg.label })
645
423
  ]
646
424
  },
647
425
  key
648
426
  );
649
427
  }) }),
650
- type !== "avatar" && /* @__PURE__ */ jsxs7("div", { className: "mt-5", children: [
651
- /* @__PURE__ */ jsx8(
428
+ /* @__PURE__ */ jsxs4("div", { className: "mt-5", children: [
429
+ /* @__PURE__ */ jsx5(
652
430
  Label2,
653
431
  {
654
432
  htmlFor: "studio-prompt",
@@ -656,8 +434,8 @@ function ComposerHero({
656
434
  children: "Prompt"
657
435
  }
658
436
  ),
659
- /* @__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: [
660
- /* @__PURE__ */ jsx8(
437
+ /* @__PURE__ */ jsxs4("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: [
438
+ /* @__PURE__ */ jsx5(
661
439
  "textarea",
662
440
  {
663
441
  id: "studio-prompt",
@@ -670,11 +448,11 @@ function ComposerHero({
670
448
  }
671
449
  },
672
450
  rows: 4,
673
- placeholder: type === "transcription" ? "Optional vocabulary, speaker names, timestamp style, or context..." : "A vertical hero frame for a product launch teaser, dark cinematic lighting...",
451
+ placeholder: "A vertical hero frame for a product launch teaser, dark cinematic lighting...",
674
452
  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"
675
453
  }
676
454
  ),
677
- /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap items-center gap-1.5 px-2.5 pb-2.5", children: SUGGESTIONS.map((suggestion) => /* @__PURE__ */ jsx8(
455
+ /* @__PURE__ */ jsx5("div", { className: "flex flex-wrap items-center gap-1.5 px-2.5 pb-2.5", children: SUGGESTIONS.map((suggestion) => /* @__PURE__ */ jsx5(
678
456
  "button",
679
457
  {
680
458
  type: "button",
@@ -687,63 +465,42 @@ function ComposerHero({
687
465
  },
688
466
  suggestion.label
689
467
  )) })
690
- ] }),
691
- type === "transcription" && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-xs text-muted-foreground", children: "Optional \u2014 biases spelling, vocabulary, and speaker names (not an instruction)." })
468
+ ] })
692
469
  ] }),
693
- type === "avatar" && /* @__PURE__ */ jsx8(
694
- AvatarComposer,
695
- {
696
- audioUrl: avatarAudioUrl,
697
- imageUrl: avatarImageUrl,
698
- avatarId,
699
- onAudioUrlChange: setAvatarAudioUrl,
700
- onImageUrlChange: setAvatarImageUrl,
701
- onAvatarIdChange: setAvatarId
702
- }
703
- ),
704
- type === "transcription" && /* @__PURE__ */ jsx8(
705
- TranscriptionComposer,
706
- {
707
- audioUrl: transcriptionAudioUrl,
708
- language: transcriptionLanguage,
709
- onAudioUrlChange: setTranscriptionAudioUrl,
710
- onLanguageChange: setTranscriptionLanguage
711
- }
712
- ),
713
- /* @__PURE__ */ jsxs7("div", { className: "mt-5 space-y-3", children: [
714
- /* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
715
- /* @__PURE__ */ jsx8(Field, { label: "Model", htmlFor: "studio-media-model", children: /* @__PURE__ */ jsxs7(
470
+ /* @__PURE__ */ jsxs4("div", { className: "mt-5 space-y-3", children: [
471
+ /* @__PURE__ */ jsxs4("div", { className: "space-y-1.5", children: [
472
+ /* @__PURE__ */ jsx5(Field, { label: "Model", htmlFor: "studio-media-model", children: /* @__PURE__ */ jsxs4(
716
473
  Select,
717
474
  {
718
475
  value: selectedModel || void 0,
719
476
  onValueChange: (value) => setSelectedModels((current) => ({ ...current, [type]: value })),
720
477
  disabled: mediaModelsLoading || Boolean(mediaModelsError) || modelsForType.length === 0,
721
478
  children: [
722
- /* @__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: [
723
- selectedModelOption.provider && /* @__PURE__ */ jsx8(ProviderLogo, { provider: selectedModelOption.provider, size: 14 }),
724
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: selectedModelOption.name || selectedModelOption.id }),
725
- selectedModelOption.provider && /* @__PURE__ */ jsxs7("span", { className: "shrink-0 text-muted-foreground", children: [
479
+ /* @__PURE__ */ jsx5(SelectTrigger, { id: "studio-media-model", className: "h-9 w-full bg-background", children: selectedModelOption ? /* @__PURE__ */ jsxs4("span", { className: "flex min-w-0 items-center gap-2", children: [
480
+ selectedModelOption.provider && /* @__PURE__ */ jsx5(ProviderLogo, { provider: selectedModelOption.provider, size: 14 }),
481
+ /* @__PURE__ */ jsx5("span", { className: "truncate", children: selectedModelOption.name || selectedModelOption.id }),
482
+ selectedModelOption.provider && /* @__PURE__ */ jsxs4("span", { className: "shrink-0 text-muted-foreground", children: [
726
483
  "\xB7 ",
727
484
  selectedModelOption.provider
728
485
  ] }),
729
- selectedModelOption.status !== "available" && /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 text-xs font-semibold uppercase tracking-[0.05em] text-warning", children: selectedModelOption.status })
730
- ] }) : /* @__PURE__ */ jsx8(SelectValue, { placeholder: mediaModelsLoading ? "Loading models\u2026" : "Select a model" }) }),
731
- /* @__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: [
732
- /* @__PURE__ */ jsxs7("span", { className: "flex min-w-0 items-center gap-2", children: [
733
- model.provider && /* @__PURE__ */ jsx8(ProviderLogo, { provider: model.provider, size: 14 }),
734
- /* @__PURE__ */ jsxs7("span", { className: "truncate", children: [
486
+ selectedModelOption.status !== "available" && /* @__PURE__ */ jsx5("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 text-xs font-semibold uppercase tracking-[0.05em] text-warning", children: selectedModelOption.status })
487
+ ] }) : /* @__PURE__ */ jsx5(SelectValue, { placeholder: mediaModelsLoading ? "Loading models\u2026" : "Select a model" }) }),
488
+ /* @__PURE__ */ jsx5(SelectContent, { className: "bg-background", children: modelsForType.map((model) => /* @__PURE__ */ jsx5(SelectItem, { value: model.id, disabled: model.status === "unavailable", children: /* @__PURE__ */ jsxs4("span", { className: "flex w-full items-center justify-between gap-3", children: [
489
+ /* @__PURE__ */ jsxs4("span", { className: "flex min-w-0 items-center gap-2", children: [
490
+ model.provider && /* @__PURE__ */ jsx5(ProviderLogo, { provider: model.provider, size: 14 }),
491
+ /* @__PURE__ */ jsxs4("span", { className: "truncate", children: [
735
492
  model.name || model.id,
736
493
  model.provider ? ` \xB7 ${model.provider}` : ""
737
494
  ] })
738
495
  ] }),
739
- model.status !== "available" && /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs capitalize text-muted-foreground", children: model.status })
496
+ model.status !== "available" && /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs capitalize text-muted-foreground", children: model.status })
740
497
  ] }) }, model.id)) })
741
498
  ]
742
499
  }
743
500
  ) }),
744
- (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) })
501
+ (mediaModelsError || modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length)) && /* @__PURE__ */ jsx5("p", { className: `text-xs ${mediaModelsError || selectedModelOption?.status === "unavailable" ? "text-destructive" : "text-muted-foreground"}`, children: mediaModelsError ?? modelMessage(selectedModelOption, mediaModelsLoading, modelsForType.length) })
745
502
  ] }),
746
- type === "image" && /* @__PURE__ */ jsx8(
503
+ type === "image" && /* @__PURE__ */ jsx5(
747
504
  ImageComposer,
748
505
  {
749
506
  size,
@@ -754,7 +511,7 @@ function ComposerHero({
754
511
  onImageCountChange: setImageCount
755
512
  }
756
513
  ),
757
- type === "video" && /* @__PURE__ */ jsx8(
514
+ type === "video" && /* @__PURE__ */ jsx5(
758
515
  VideoComposer,
759
516
  {
760
517
  duration,
@@ -767,77 +524,33 @@ function ComposerHero({
767
524
  onReferenceImageUrlChange: setReferenceImageUrl
768
525
  }
769
526
  ),
770
- type === "speech" && /* @__PURE__ */ jsx8(SpeechComposer, { voice, onVoiceChange: setVoice })
527
+ type === "speech" && /* @__PURE__ */ jsx5(SpeechComposer, { voice, onVoiceChange: setVoice })
771
528
  ] }),
772
- /* @__PURE__ */ jsxs7("div", { className: "mt-4 space-y-2", children: [
773
- /* @__PURE__ */ jsx8(ComposerDisclosure, { summary: "Advanced options", children: /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 sm:grid-cols-2", children: [
774
- /* @__PURE__ */ jsx8(Field, { label: "Negative prompt", children: /* @__PURE__ */ jsx8(
775
- Textarea2,
776
- {
777
- value: negativePrompt,
778
- onChange: (event) => setNegativePrompt(event.target.value),
779
- rows: 2,
780
- placeholder: "Avoid artifacts, off-style composition...",
781
- className: "bg-background"
782
- }
783
- ) }),
784
- /* @__PURE__ */ jsx8(Field, { label: "Save to", children: /* @__PURE__ */ jsx8(Input7, { value: outputPath, onChange: (event) => setOutputPath(event.target.value), className: "bg-background" }) }),
785
- type === "transcription" && /* @__PURE__ */ jsx8(
786
- TranscriptionOptions,
787
- {
788
- responseFormat: transcriptionResponseFormat,
789
- temperature: transcriptionTemperature,
790
- onResponseFormatChange: setTranscriptionResponseFormat,
791
- onTemperatureChange: setTranscriptionTemperature
792
- }
793
- )
794
- ] }) }),
795
- /* @__PURE__ */ jsx8(
796
- ComposerDisclosure,
529
+ /* @__PURE__ */ jsx5("div", { className: "mt-4 space-y-2", children: /* @__PURE__ */ jsx5(ComposerDisclosure, { summary: "Advanced options", children: /* @__PURE__ */ jsxs4("div", { className: "grid gap-3 sm:grid-cols-2", children: [
530
+ /* @__PURE__ */ jsx5(Field, { label: "Negative prompt", children: /* @__PURE__ */ jsx5(
531
+ Textarea,
797
532
  {
798
- summary: /* @__PURE__ */ jsxs7(Fragment2, { children: [
799
- "Schedule a post",
800
- selectedConnectedDestinations.length > 0 && /* @__PURE__ */ jsx8(Badge2, { variant: "outline", className: "ml-1 text-xs", children: selectedConnectedDestinations.length })
801
- ] }),
802
- children: /* @__PURE__ */ jsx8(
803
- PublishPackageComposer,
804
- {
805
- caption,
806
- postDescription,
807
- mentions,
808
- cadence,
809
- selectedDestinations,
810
- connections: integrations.connections,
811
- connectionError: integrations.error,
812
- connectionsLoading: integrations.isLoading,
813
- integrationsHref,
814
- canManageIntegrations,
815
- onCaptionChange: setCaption,
816
- onDescriptionChange: setPostDescription,
817
- onMentionsChange: setMentions,
818
- onCadenceChange: setCadence,
819
- onDestinationToggle: (destination) => {
820
- const destinationConfig = DESTINATIONS.find((item) => item.id === destination);
821
- if (!destinationConfig || !isDestinationConnected(destinationConfig, integrations.connections)) return;
822
- setSelectedDestinations((current) => current.includes(destination) ? current.filter((item) => item !== destination) : [...current, destination]);
823
- }
824
- }
825
- )
533
+ value: negativePrompt,
534
+ onChange: (event) => setNegativePrompt(event.target.value),
535
+ rows: 2,
536
+ placeholder: "Avoid artifacts, off-style composition...",
537
+ className: "bg-background"
826
538
  }
827
- )
828
- ] }),
829
- error && /* @__PURE__ */ jsx8("div", { className: "mt-4 rounded-md border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
830
- /* @__PURE__ */ jsxs7(
831
- Button2,
539
+ ) }),
540
+ /* @__PURE__ */ jsx5(Field, { label: "Save to", children: /* @__PURE__ */ jsx5(Input4, { value: outputPath, onChange: (event) => setOutputPath(event.target.value), className: "bg-background" }) })
541
+ ] }) }) }),
542
+ error && /* @__PURE__ */ jsx5("div", { className: "mt-4 rounded-md border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive", children: error }),
543
+ /* @__PURE__ */ jsxs4(
544
+ Button,
832
545
  {
833
546
  onClick: generate,
834
547
  disabled: !canSubmit,
835
548
  size: "lg",
836
549
  className: "mt-5 w-full disabled:bg-muted disabled:text-muted-foreground disabled:opacity-100",
837
550
  children: [
838
- /* @__PURE__ */ jsx8(Sparkles, { className: "mr-2 h-4 w-4" }),
551
+ /* @__PURE__ */ jsx5(Sparkles, { className: "mr-2 h-4 w-4" }),
839
552
  "Generate",
840
- /* @__PURE__ */ jsx8("span", { className: "ml-2 text-xs opacity-60", children: "\u2318\u21B5" })
553
+ /* @__PURE__ */ jsx5("span", { className: "ml-2 text-xs opacity-60", children: "\u2318\u21B5" })
841
554
  ]
842
555
  }
843
556
  )
@@ -845,31 +558,31 @@ function ComposerHero({
845
558
  }
846
559
 
847
560
  // src/studio-react/studio-header.tsx
848
- import { Button as Button3 } from "@tangle-network/sandbox-ui/primitives";
561
+ import { Button as Button2 } from "@tangle-network/sandbox-ui/primitives";
849
562
  import { Images } from "lucide-react";
850
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
563
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
851
564
  function StudioHeader({
852
565
  count,
853
566
  onOpenLibrary,
854
567
  canGenerate
855
568
  }) {
856
- return /* @__PURE__ */ jsx9("header", { className: "sticky top-0 z-20 border-b border-border bg-card", children: /* @__PURE__ */ jsxs8("div", { className: "mx-auto flex w-full max-w-3xl items-center justify-between gap-3 px-4 py-3 sm:px-6", children: [
857
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
858
- /* @__PURE__ */ jsx9("h1", { className: "text-lg font-semibold tracking-tight text-foreground", children: "Studio" }),
859
- /* @__PURE__ */ jsx9("p", { className: "truncate text-xs text-muted-foreground", children: canGenerate ? "Generate images, video, voice, avatars, and transcripts." : "Browse your team's generations." })
569
+ return /* @__PURE__ */ jsx6("header", { className: "sticky top-0 z-20 border-b border-border bg-card", children: /* @__PURE__ */ jsxs5("div", { className: "mx-auto flex w-full max-w-3xl items-center justify-between gap-3 px-4 py-3 sm:px-6", children: [
570
+ /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
571
+ /* @__PURE__ */ jsx6("h1", { className: "text-lg font-semibold tracking-tight text-foreground", children: "Studio" }),
572
+ /* @__PURE__ */ jsx6("p", { className: "truncate text-xs text-muted-foreground", children: canGenerate ? "Generate images, video, voice, avatars, and transcripts." : "Browse your team's generations." })
860
573
  ] }),
861
- /* @__PURE__ */ jsxs8(Button3, { size: "sm", variant: "outline", onClick: onOpenLibrary, className: "shrink-0", children: [
862
- /* @__PURE__ */ jsx9(Images, { className: "mr-1.5 h-4 w-4" }),
574
+ /* @__PURE__ */ jsxs5(Button2, { size: "sm", variant: "outline", onClick: onOpenLibrary, className: "shrink-0", children: [
575
+ /* @__PURE__ */ jsx6(Images, { className: "mr-1.5 h-4 w-4" }),
863
576
  "Library",
864
- count > 0 && /* @__PURE__ */ jsx9("span", { className: "ml-2 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary/15 px-1.5 text-xs font-semibold text-primary", children: count })
577
+ count > 0 && /* @__PURE__ */ jsx6("span", { className: "ml-2 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary/15 px-1.5 text-xs font-semibold text-primary", children: count })
865
578
  ] })
866
579
  ] }) });
867
580
  }
868
581
 
869
582
  // src/studio-react/result-canvas.tsx
870
- import { Badge as Badge3 } from "@tangle-network/sandbox-ui/primitives";
583
+ import { Badge } from "@tangle-network/sandbox-ui/primitives";
871
584
  import { ArrowRight, Sparkles as Sparkles2 } from "lucide-react";
872
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
585
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
873
586
  function ResultCanvas({
874
587
  batch,
875
588
  onOpenLibrary,
@@ -877,10 +590,10 @@ function ResultCanvas({
877
590
  }) {
878
591
  const cardClass = "rounded-xl border border-border bg-card shadow-sm";
879
592
  if (batch.length === 0) {
880
- return /* @__PURE__ */ jsxs9("section", { className: `${cardClass} flex min-h-[180px] flex-col items-center justify-center gap-2 p-8 text-center`, children: [
881
- /* @__PURE__ */ jsx10("div", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx10(Sparkles2, { className: "h-6 w-6 text-muted-foreground/40" }) }),
882
- /* @__PURE__ */ jsx10("p", { className: "text-sm font-medium text-foreground", children: "Your creations appear here" }),
883
- /* @__PURE__ */ jsx10("p", { className: "max-w-xs text-xs text-muted-foreground", children: "Generate above \u2014 results appear here and are saved to your library." })
593
+ return /* @__PURE__ */ jsxs6("section", { className: `${cardClass} flex min-h-[180px] flex-col items-center justify-center gap-2 p-8 text-center`, children: [
594
+ /* @__PURE__ */ jsx7("div", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx7(Sparkles2, { className: "h-6 w-6 text-muted-foreground/40" }) }),
595
+ /* @__PURE__ */ jsx7("p", { className: "text-sm font-medium text-foreground", children: "Your creations appear here" }),
596
+ /* @__PURE__ */ jsx7("p", { className: "max-w-xs text-xs text-muted-foreground", children: "Generate above \u2014 results appear here and are saved to your library." })
884
597
  ] });
885
598
  }
886
599
  const cfg = typeConfigFor(batch[0]?.type ?? "image");
@@ -888,17 +601,17 @@ function ResultCanvas({
888
601
  const statuses = batch.map(generationStatus);
889
602
  const runLabel = statuses.some((s) => s === "pending" || s === "running") ? "Generating\u2026" : statuses.every((s) => s === "failed") ? "Last run failed" : "Latest creation";
890
603
  const isWorking = statuses.some((s) => s === "pending" || s === "running");
891
- return /* @__PURE__ */ jsxs9("section", { className: `${cardClass} p-5`, children: [
892
- /* @__PURE__ */ jsxs9("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
893
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
894
- /* @__PURE__ */ jsxs9(Badge3, { variant: "outline", className: `${cfg.color} gap-1 text-xs`, children: [
895
- /* @__PURE__ */ jsx10(Icon, { className: "h-3 w-3" }),
604
+ return /* @__PURE__ */ jsxs6("section", { className: `${cardClass} p-5`, children: [
605
+ /* @__PURE__ */ jsxs6("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
606
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
607
+ /* @__PURE__ */ jsxs6(Badge, { variant: "outline", className: `${cfg.color} gap-1 text-xs`, children: [
608
+ /* @__PURE__ */ jsx7(Icon, { className: "h-3 w-3" }),
896
609
  cfg.label
897
610
  ] }),
898
- /* @__PURE__ */ jsx10("span", { className: "text-sm font-medium text-foreground", children: runLabel }),
899
- isWorking && /* @__PURE__ */ jsx10("span", { className: "h-2 w-2 animate-pulse rounded-full bg-primary" })
611
+ /* @__PURE__ */ jsx7("span", { className: "text-sm font-medium text-foreground", children: runLabel }),
612
+ isWorking && /* @__PURE__ */ jsx7("span", { className: "h-2 w-2 animate-pulse rounded-full bg-primary" })
900
613
  ] }),
901
- /* @__PURE__ */ jsxs9(
614
+ /* @__PURE__ */ jsxs6(
902
615
  "button",
903
616
  {
904
617
  type: "button",
@@ -906,22 +619,22 @@ function ResultCanvas({
906
619
  className: "flex items-center gap-1 text-xs font-medium text-primary transition-colors hover:text-primary/80",
907
620
  children: [
908
621
  "View in Library",
909
- /* @__PURE__ */ jsx10(ArrowRight, { className: "h-3.5 w-3.5" })
622
+ /* @__PURE__ */ jsx7(ArrowRight, { className: "h-3.5 w-3.5" })
910
623
  ]
911
624
  }
912
625
  )
913
626
  ] }),
914
- /* @__PURE__ */ jsx10("div", { className: `grid gap-3 ${batch.length === 1 ? "grid-cols-1" : "grid-cols-2"}`, children: batch.map((generation) => /* @__PURE__ */ jsx10(
627
+ /* @__PURE__ */ jsx7("div", { className: `grid gap-3 ${batch.length === 1 ? "grid-cols-1" : "grid-cols-2"}`, children: batch.map((generation) => /* @__PURE__ */ jsx7(
915
628
  "button",
916
629
  {
917
630
  type: "button",
918
631
  onClick: () => onSelect(generation),
919
632
  className: "studio-bloom group relative aspect-video overflow-hidden rounded-lg border border-border bg-secondary transition-colors hover:border-primary/40",
920
- children: /* @__PURE__ */ jsx10(CanvasTile, { generation })
633
+ children: /* @__PURE__ */ jsx7(CanvasTile, { generation })
921
634
  },
922
635
  generation.id
923
636
  )) }),
924
- batch.length > 1 && !isWorking && /* @__PURE__ */ jsxs9("p", { className: "mt-2 text-xs text-muted-foreground", children: [
637
+ batch.length > 1 && !isWorking && /* @__PURE__ */ jsxs6("p", { className: "mt-2 text-xs text-muted-foreground", children: [
925
638
  batch.length,
926
639
  " results from this run"
927
640
  ] })
@@ -932,34 +645,34 @@ function CanvasTile({ generation }) {
932
645
  const Icon = cfg.icon;
933
646
  const status = generationStatus(generation);
934
647
  if (status === "pending" || status === "running") {
935
- return /* @__PURE__ */ jsx10("div", { className: "studio-shimmer absolute inset-0 h-full w-full" });
648
+ return /* @__PURE__ */ jsx7("div", { className: "studio-shimmer absolute inset-0 h-full w-full" });
936
649
  }
937
650
  if (status === "failed") {
938
- return /* @__PURE__ */ jsxs9("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-2 p-4 text-center", children: [
939
- /* @__PURE__ */ jsx10(Icon, { className: "h-6 w-6 text-destructive/50" }),
940
- /* @__PURE__ */ jsx10("p", { className: "line-clamp-3 text-xs text-destructive", children: generationError(generation) ?? "Generation failed" })
651
+ return /* @__PURE__ */ jsxs6("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-2 p-4 text-center", children: [
652
+ /* @__PURE__ */ jsx7(Icon, { className: "h-6 w-6 text-destructive/50" }),
653
+ /* @__PURE__ */ jsx7("p", { className: "line-clamp-3 text-xs text-destructive", children: generationError(generation) ?? "Generation failed" })
941
654
  ] });
942
655
  }
943
656
  if (generation.type === "image" && generation.result) {
944
- return /* @__PURE__ */ jsx10("img", { src: generation.result, alt: generation.prompt, className: "absolute inset-0 h-full w-full object-contain" });
657
+ return /* @__PURE__ */ jsx7("img", { src: generation.result, alt: generation.prompt, className: "absolute inset-0 h-full w-full object-contain" });
945
658
  }
946
659
  if ((generation.type === "video" || generation.type === "avatar") && generation.result) {
947
- return /* @__PURE__ */ jsx10("video", { src: generation.result, controls: true, className: "absolute inset-0 h-full w-full object-contain" });
660
+ return /* @__PURE__ */ jsx7("video", { src: generation.result, controls: true, className: "absolute inset-0 h-full w-full object-contain" });
948
661
  }
949
662
  if (generation.type === "speech" && generation.result) {
950
- return /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 flex items-center justify-center p-4", children: /* @__PURE__ */ jsx10("audio", { src: generation.result, controls: true, className: "w-full" }) });
663
+ return /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center justify-center p-4", children: /* @__PURE__ */ jsx7("audio", { src: generation.result, controls: true, className: "w-full" }) });
951
664
  }
952
665
  if (generation.type === "transcription" && generation.result) {
953
- return /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 overflow-y-auto p-4", children: /* @__PURE__ */ jsx10("p", { className: "whitespace-pre-wrap text-xs text-foreground", children: generation.result }) });
666
+ return /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 overflow-y-auto p-4", children: /* @__PURE__ */ jsx7("p", { className: "whitespace-pre-wrap text-xs text-foreground", children: generation.result }) });
954
667
  }
955
- return /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx10(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) });
668
+ return /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx7(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) });
956
669
  }
957
670
 
958
671
  // src/studio-react/library-drawer.tsx
959
- import { useMemo as useMemo3 } from "react";
960
- import { Link as Link3 } from "react-router";
672
+ import { useMemo as useMemo2 } from "react";
673
+ import { Link as Link2 } from "react-router";
961
674
  import {
962
- Button as Button5,
675
+ Button as Button4,
963
676
  Tabs,
964
677
  TabsList,
965
678
  TabsTrigger
@@ -968,22 +681,22 @@ import { ArrowLeft, DollarSign, FolderOpen as FolderOpen2, X } from "lucide-reac
968
681
 
969
682
  // src/studio-react/studio-sheet.tsx
970
683
  import * as Dialog from "@radix-ui/react-dialog";
971
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
684
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
972
685
  function StudioSheet({
973
686
  open,
974
687
  onOpenChange,
975
688
  title,
976
689
  children
977
690
  }) {
978
- return /* @__PURE__ */ jsx11(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs10(Dialog.Portal, { children: [
979
- /* @__PURE__ */ jsx11(Dialog.Overlay, { className: "studio-sheet-overlay fixed inset-0 z-50 bg-black/50" }),
980
- /* @__PURE__ */ jsxs10(
691
+ return /* @__PURE__ */ jsx8(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs7(Dialog.Portal, { children: [
692
+ /* @__PURE__ */ jsx8(Dialog.Overlay, { className: "studio-sheet-overlay fixed inset-0 z-50 bg-black/50" }),
693
+ /* @__PURE__ */ jsxs7(
981
694
  Dialog.Content,
982
695
  {
983
696
  className: "studio-sheet-content fixed inset-y-0 right-0 z-50 flex w-[min(92vw,30rem)] flex-col border-l border-card-edge bg-popover shadow-[var(--shadow-overlay)] focus:outline-none",
984
697
  "aria-describedby": void 0,
985
698
  children: [
986
- /* @__PURE__ */ jsx11(Dialog.Title, { className: "sr-only", children: title }),
699
+ /* @__PURE__ */ jsx8(Dialog.Title, { className: "sr-only", children: title }),
987
700
  children
988
701
  ]
989
702
  }
@@ -996,9 +709,8 @@ import { EmptyState } from "@tangle-network/sandbox-ui/primitives";
996
709
  import { Film, Sparkles as Sparkles3 } from "lucide-react";
997
710
 
998
711
  // src/studio-react/generation-card.tsx
999
- import { Card, CardContent, Badge as Badge4 } from "@tangle-network/sandbox-ui/primitives";
1000
- import { Send } from "lucide-react";
1001
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
712
+ import { Card, CardContent, Badge as Badge2 } from "@tangle-network/sandbox-ui/primitives";
713
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1002
714
  function GenerationCard({
1003
715
  generation,
1004
716
  onSelect
@@ -1006,35 +718,27 @@ function GenerationCard({
1006
718
  const cfg = typeConfigFor(generation.type);
1007
719
  const Icon = cfg.icon;
1008
720
  const status = generationStatus(generation);
1009
- const publishPackage = generation.metadata?.publishPackage;
1010
- return /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => onSelect(generation), className: "group text-left animate-row-in", children: /* @__PURE__ */ jsxs11(Card, { className: "overflow-hidden transition-all group-hover:border-primary/50 group-hover:shadow-md", children: [
1011
- /* @__PURE__ */ jsxs11("div", { className: "relative aspect-video bg-secondary", children: [
1012
- generation.type === "image" && generation.result ? /* @__PURE__ */ jsx12("img", { src: generation.result, alt: generation.prompt, className: "h-full w-full object-cover" }) : (generation.type === "video" || generation.type === "avatar") && generation.result ? /* @__PURE__ */ jsx12("video", { src: generation.result, className: "h-full w-full object-cover", muted: true }) : generation.type === "speech" && generation.result ? /* @__PURE__ */ jsx12("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx12(Icon, { className: "h-6 w-6 text-muted-foreground/40" }) }) : generation.type === "transcription" && generation.result ? /* @__PURE__ */ jsx12("div", { className: "flex h-full items-center justify-center p-4", children: /* @__PURE__ */ jsx12("p", { className: "line-clamp-5 text-xs text-muted-foreground", children: generation.result }) }) : status === "pending" || status === "running" ? /* @__PURE__ */ jsx12("div", { className: "shimmer h-full w-full" }) : /* @__PURE__ */ jsx12("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx12(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) }),
1013
- /* @__PURE__ */ jsx12("div", { className: "absolute left-2 top-2", children: /* @__PURE__ */ jsxs11(Badge4, { variant: "outline", className: `${cfg.color} gap-1 text-xs`, children: [
1014
- /* @__PURE__ */ jsx12(Icon, { className: "h-3 w-3" }),
721
+ return /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => onSelect(generation), className: "group text-left animate-row-in", children: /* @__PURE__ */ jsxs8(Card, { className: "overflow-hidden transition-all group-hover:border-primary/50 group-hover:shadow-md", children: [
722
+ /* @__PURE__ */ jsxs8("div", { className: "relative aspect-video bg-secondary", children: [
723
+ generation.type === "image" && generation.result ? /* @__PURE__ */ jsx9("img", { src: generation.result, alt: generation.prompt, className: "h-full w-full object-cover" }) : (generation.type === "video" || generation.type === "avatar") && generation.result ? /* @__PURE__ */ jsx9("video", { src: generation.result, className: "h-full w-full object-cover", muted: true }) : generation.type === "speech" && generation.result ? /* @__PURE__ */ jsx9("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx9(Icon, { className: "h-6 w-6 text-muted-foreground/40" }) }) : generation.type === "transcription" && generation.result ? /* @__PURE__ */ jsx9("div", { className: "flex h-full items-center justify-center p-4", children: /* @__PURE__ */ jsx9("p", { className: "line-clamp-5 text-xs text-muted-foreground", children: generation.result }) }) : status === "pending" || status === "running" ? /* @__PURE__ */ jsx9("div", { className: "shimmer h-full w-full" }) : /* @__PURE__ */ jsx9("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx9(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) }),
724
+ /* @__PURE__ */ jsx9("div", { className: "absolute left-2 top-2", children: /* @__PURE__ */ jsxs8(Badge2, { variant: "outline", className: `${cfg.color} gap-1 text-xs`, children: [
725
+ /* @__PURE__ */ jsx9(Icon, { className: "h-3 w-3" }),
1015
726
  cfg.label
1016
727
  ] }) }),
1017
- /* @__PURE__ */ jsx12(GenerationStatusBadge, { generation })
728
+ /* @__PURE__ */ jsx9(GenerationStatusBadge, { generation })
1018
729
  ] }),
1019
- /* @__PURE__ */ jsxs11(CardContent, { className: "p-3", children: [
1020
- /* @__PURE__ */ jsx12("p", { className: "mb-2 line-clamp-2 text-sm font-medium text-foreground", children: generation.prompt }),
1021
- status === "failed" && /* @__PURE__ */ jsx12("p", { className: "mb-2 line-clamp-2 text-xs text-destructive", children: generationError(generation) }),
1022
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
1023
- generation.model && /* @__PURE__ */ jsx12("span", { className: "truncate text-xs text-muted-foreground", children: generation.model }),
1024
- /* @__PURE__ */ jsxs11("div", { className: "flex shrink-0 items-center gap-2", children: [
1025
- generation.cost != null && /* @__PURE__ */ jsxs11("span", { className: "text-xs text-muted-foreground", children: [
730
+ /* @__PURE__ */ jsxs8(CardContent, { className: "p-3", children: [
731
+ /* @__PURE__ */ jsx9("p", { className: "mb-2 line-clamp-2 text-sm font-medium text-foreground", children: generation.prompt }),
732
+ status === "failed" && /* @__PURE__ */ jsx9("p", { className: "mb-2 line-clamp-2 text-xs text-destructive", children: generationError(generation) }),
733
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
734
+ generation.model && /* @__PURE__ */ jsx9("span", { className: "truncate text-xs text-muted-foreground", children: generation.model }),
735
+ /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-2", children: [
736
+ generation.cost != null && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground", children: [
1026
737
  "$",
1027
738
  generation.cost.toFixed(3)
1028
739
  ] }),
1029
- /* @__PURE__ */ jsx12("span", { className: "text-xs text-muted-foreground", children: relativeTime(generation.createdAt) })
740
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: relativeTime(generation.createdAt) })
1030
741
  ] })
1031
- ] }),
1032
- isPublishPackage(publishPackage) && /* @__PURE__ */ jsxs11("div", { className: "mt-3 rounded-md border border-border bg-secondary p-2", children: [
1033
- /* @__PURE__ */ jsxs11("div", { className: "mb-1 flex items-center gap-1.5 text-xs font-medium text-foreground", children: [
1034
- /* @__PURE__ */ jsx12(Send, { className: "h-3 w-3" }),
1035
- (publishPackage.destinations ?? []).map((id) => DESTINATIONS.find((destination) => destination.id === id)?.label ?? id).join(", ") || "Publish package"
1036
- ] }),
1037
- /* @__PURE__ */ jsx12("p", { className: "line-clamp-2 text-xs text-muted-foreground", children: publishPackage.caption || "Caption pending" })
1038
742
  ] })
1039
743
  ] })
1040
744
  ] }) });
@@ -1047,11 +751,11 @@ function GenerationStatusBadge({
1047
751
  if (status === "succeeded") return null;
1048
752
  const label = status === "failed" ? "Failed" : status === "running" ? "Running" : "Pending";
1049
753
  const className = status === "failed" ? "border-destructive/30 bg-[color-mix(in_srgb,hsl(var(--destructive))_10%,hsl(var(--card)))] text-destructive" : "border-warning/30 bg-[color-mix(in_srgb,hsl(var(--warning))_10%,hsl(var(--card)))] text-warning";
1050
- return /* @__PURE__ */ jsx12("div", { className: inline ? "" : "absolute bottom-2 left-2", children: /* @__PURE__ */ jsx12(Badge4, { variant: "outline", className: `${className} text-xs`, children: label }) });
754
+ return /* @__PURE__ */ jsx9("div", { className: inline ? "" : "absolute bottom-2 left-2", children: /* @__PURE__ */ jsx9(Badge2, { variant: "outline", className: `${className} text-xs`, children: label }) });
1051
755
  }
1052
756
 
1053
757
  // src/studio-react/generation-grid.tsx
1054
- import { jsx as jsx13 } from "react/jsx-runtime";
758
+ import { jsx as jsx10 } from "react/jsx-runtime";
1055
759
  function filterGenerations(generations, typeFilter) {
1056
760
  if (!typeFilter || !isGenerationType(typeFilter)) return generations;
1057
761
  return generations.filter((generation) => generation.type === typeFilter);
@@ -1062,24 +766,24 @@ function GenerationGrid({
1062
766
  onSelect
1063
767
  }) {
1064
768
  if (generations.length === 0) {
1065
- return /* @__PURE__ */ jsx13(
769
+ return /* @__PURE__ */ jsx10(
1066
770
  EmptyState,
1067
771
  {
1068
- icon: typeFilter ? /* @__PURE__ */ jsx13(Film, { className: "h-8 w-8 text-muted-foreground/30" }) : /* @__PURE__ */ jsx13(Sparkles3, { className: "h-10 w-10 text-muted-foreground/30" }),
772
+ icon: typeFilter ? /* @__PURE__ */ jsx10(Film, { className: "h-8 w-8 text-muted-foreground/30" }) : /* @__PURE__ */ jsx10(Sparkles3, { className: "h-10 w-10 text-muted-foreground/30" }),
1069
773
  title: typeFilter ? `No ${TYPE_CONFIG[typeFilter]?.label ?? typeFilter} generations` : "No generations yet",
1070
774
  description: typeFilter ? "Try a different filter or change the type in the composer." : "Everything you and the agent create lives here.",
1071
775
  className: "py-16"
1072
776
  }
1073
777
  );
1074
778
  }
1075
- 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)) });
779
+ return /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: generations.map((generation) => /* @__PURE__ */ jsx10(GenerationCard, { generation, onSelect }, generation.id)) });
1076
780
  }
1077
781
 
1078
782
  // src/studio-react/generation-detail.tsx
1079
- import { Link as Link2 } from "react-router";
1080
- import { Badge as Badge5, Button as Button4 } from "@tangle-network/sandbox-ui/primitives";
783
+ import { Link } from "react-router";
784
+ import { Badge as Badge3, Button as Button3 } from "@tangle-network/sandbox-ui/primitives";
1081
785
  import { FolderOpen } from "lucide-react";
1082
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
786
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1083
787
  function GenerationDetail({
1084
788
  generation,
1085
789
  vaultHref,
@@ -1089,50 +793,50 @@ function GenerationDetail({
1089
793
  const Icon = cfg.icon;
1090
794
  const vaultPath = generationVaultPath(generation);
1091
795
  const href = vaultHref && vaultPath ? vaultHref(vaultPath) : null;
1092
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
1093
- /* @__PURE__ */ jsx14("div", { className: "overflow-hidden rounded-lg bg-secondary", 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" }) }) }),
1094
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", children: [
1095
- /* @__PURE__ */ jsxs12(Badge5, { variant: "outline", className: `${cfg.color} gap-1`, children: [
1096
- /* @__PURE__ */ jsx14(Icon, { className: "h-3 w-3" }),
796
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
797
+ /* @__PURE__ */ jsx11("div", { className: "overflow-hidden rounded-lg bg-secondary", children: generation.type === "image" && generation.result ? /* @__PURE__ */ jsx11("img", { src: generation.result, alt: generation.prompt, className: "max-h-[420px] w-full object-contain" }) : (generation.type === "video" || generation.type === "avatar") && generation.result ? /* @__PURE__ */ jsx11("video", { src: generation.result, controls: true, className: "max-h-[420px] w-full" }) : generation.type === "speech" && generation.result ? /* @__PURE__ */ jsx11("div", { className: "p-6", children: /* @__PURE__ */ jsx11("audio", { src: generation.result, controls: true, className: "w-full" }) }) : /* @__PURE__ */ jsx11("div", { className: "flex h-32 items-center justify-center", children: /* @__PURE__ */ jsx11(Icon, { className: "h-8 w-8 text-muted-foreground/20" }) }) }),
798
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2", children: [
799
+ /* @__PURE__ */ jsxs9(Badge3, { variant: "outline", className: `${cfg.color} gap-1`, children: [
800
+ /* @__PURE__ */ jsx11(Icon, { className: "h-3 w-3" }),
1097
801
  cfg.label
1098
802
  ] }),
1099
- /* @__PURE__ */ jsx14(GenerationStatusBadge, { generation, inline: true }),
1100
- generationError(generation) && /* @__PURE__ */ jsx14("span", { className: "text-xs text-destructive", children: generationError(generation) })
803
+ /* @__PURE__ */ jsx11(GenerationStatusBadge, { generation, inline: true }),
804
+ generationError(generation) && /* @__PURE__ */ jsx11("span", { className: "text-xs text-destructive", children: generationError(generation) })
1101
805
  ] }),
1102
- /* @__PURE__ */ jsxs12("div", { children: [
1103
- /* @__PURE__ */ jsx14("span", { className: "mb-1 block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Prompt" }),
1104
- /* @__PURE__ */ jsx14("p", { className: "text-sm text-foreground", children: generation.prompt })
806
+ /* @__PURE__ */ jsxs9("div", { children: [
807
+ /* @__PURE__ */ jsx11("span", { className: "mb-1 block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Prompt" }),
808
+ /* @__PURE__ */ jsx11("p", { className: "text-sm text-foreground", children: generation.prompt })
1105
809
  ] }),
1106
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-4", children: [
1107
- generation.model && /* @__PURE__ */ jsxs12("div", { children: [
1108
- /* @__PURE__ */ jsx14("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Model" }),
1109
- /* @__PURE__ */ jsx14("span", { className: "text-xs text-foreground", children: generation.model })
810
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-4", children: [
811
+ generation.model && /* @__PURE__ */ jsxs9("div", { children: [
812
+ /* @__PURE__ */ jsx11("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Model" }),
813
+ /* @__PURE__ */ jsx11("span", { className: "text-xs text-foreground", children: generation.model })
1110
814
  ] }),
1111
- generation.cost != null && /* @__PURE__ */ jsxs12("div", { children: [
1112
- /* @__PURE__ */ jsx14("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Cost" }),
1113
- /* @__PURE__ */ jsxs12("span", { className: "text-xs text-foreground", children: [
815
+ generation.cost != null && /* @__PURE__ */ jsxs9("div", { children: [
816
+ /* @__PURE__ */ jsx11("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Cost" }),
817
+ /* @__PURE__ */ jsxs9("span", { className: "text-xs text-foreground", children: [
1114
818
  "$",
1115
819
  generation.cost.toFixed(3)
1116
820
  ] })
1117
821
  ] }),
1118
- generation.createdAt && /* @__PURE__ */ jsxs12("div", { children: [
1119
- /* @__PURE__ */ jsx14("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Created" }),
1120
- /* @__PURE__ */ jsx14("span", { className: "text-xs text-foreground", children: new Date(generation.createdAt).toLocaleString("en-US", { dateStyle: "medium", timeStyle: "short" }) })
822
+ generation.createdAt && /* @__PURE__ */ jsxs9("div", { children: [
823
+ /* @__PURE__ */ jsx11("span", { className: "block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Created" }),
824
+ /* @__PURE__ */ jsx11("span", { className: "text-xs text-foreground", children: new Date(generation.createdAt).toLocaleString("en-US", { dateStyle: "medium", timeStyle: "short" }) })
1121
825
  ] })
1122
826
  ] }),
1123
- generation.type === "transcription" && generation.result && /* @__PURE__ */ jsxs12("div", { children: [
1124
- /* @__PURE__ */ jsx14("span", { className: "mb-1 block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Transcription" }),
1125
- /* @__PURE__ */ jsx14("pre", { className: "max-h-64 overflow-y-auto whitespace-pre-wrap rounded-lg bg-secondary p-4 font-mono text-[13px] tabular-nums text-foreground", children: generation.result })
827
+ generation.type === "transcription" && generation.result && /* @__PURE__ */ jsxs9("div", { children: [
828
+ /* @__PURE__ */ jsx11("span", { className: "mb-1 block text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Transcription" }),
829
+ /* @__PURE__ */ jsx11("pre", { className: "max-h-64 overflow-y-auto whitespace-pre-wrap rounded-lg bg-secondary p-4 font-mono text-[13px] tabular-nums text-foreground", children: generation.result })
1126
830
  ] }),
1127
- 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: [
1128
- /* @__PURE__ */ jsx14(FolderOpen, { className: "mr-1.5 h-3.5 w-3.5" }),
831
+ href && /* @__PURE__ */ jsx11("div", { className: "border-t border-border pt-2", children: /* @__PURE__ */ jsx11(Link, { to: href, prefetch: "intent", onClick: onNavigate, children: /* @__PURE__ */ jsxs9(Button3, { size: "sm", variant: "outline", children: [
832
+ /* @__PURE__ */ jsx11(FolderOpen, { className: "mr-1.5 h-3.5 w-3.5" }),
1129
833
  "Open in Vault"
1130
834
  ] }) }) })
1131
835
  ] });
1132
836
  }
1133
837
 
1134
838
  // src/studio-react/library-drawer.tsx
1135
- import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
839
+ import { Fragment, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1136
840
  function LibraryDrawer({
1137
841
  open,
1138
842
  onOpenChange,
@@ -1144,79 +848,78 @@ function LibraryDrawer({
1144
848
  selected,
1145
849
  onSelect
1146
850
  }) {
1147
- const visible = useMemo3(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
1148
- return /* @__PURE__ */ jsxs13(StudioSheet, { open, onOpenChange, title: "Asset library", children: [
1149
- /* @__PURE__ */ jsxs13("header", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
1150
- selected ? /* @__PURE__ */ jsxs13(
851
+ const visible = useMemo2(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
852
+ return /* @__PURE__ */ jsxs10(StudioSheet, { open, onOpenChange, title: "Asset library", children: [
853
+ /* @__PURE__ */ jsxs10("header", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3", children: [
854
+ selected ? /* @__PURE__ */ jsxs10(
1151
855
  "button",
1152
856
  {
1153
857
  type: "button",
1154
858
  onClick: () => onSelect(null),
1155
859
  className: "flex items-center gap-1.5 text-sm font-medium text-foreground transition-colors hover:text-primary",
1156
860
  children: [
1157
- /* @__PURE__ */ jsx15(ArrowLeft, { className: "h-4 w-4" }),
861
+ /* @__PURE__ */ jsx12(ArrowLeft, { className: "h-4 w-4" }),
1158
862
  "Back to library"
1159
863
  ]
1160
864
  }
1161
- ) : /* @__PURE__ */ jsx15("h2", { className: "text-sm font-semibold text-foreground", children: "Asset library" }),
1162
- /* @__PURE__ */ jsx15(
865
+ ) : /* @__PURE__ */ jsx12("h2", { className: "text-sm font-semibold text-foreground", children: "Asset library" }),
866
+ /* @__PURE__ */ jsx12(
1163
867
  "button",
1164
868
  {
1165
869
  type: "button",
1166
870
  "aria-label": "Close library",
1167
871
  onClick: () => onOpenChange(false),
1168
872
  className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
1169
- children: /* @__PURE__ */ jsx15(X, { className: "h-4 w-4" })
873
+ children: /* @__PURE__ */ jsx12(X, { className: "h-4 w-4" })
1170
874
  }
1171
875
  )
1172
876
  ] }),
1173
- selected ? /* @__PURE__ */ jsx15("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx15(
877
+ selected ? /* @__PURE__ */ jsx12("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx12(
1174
878
  GenerationDetail,
1175
879
  {
1176
880
  generation: selected,
1177
881
  vaultHref,
1178
882
  onNavigate: () => onOpenChange(false)
1179
883
  }
1180
- ) }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
1181
- /* @__PURE__ */ jsxs13("div", { className: "shrink-0 border-b border-border px-4 pt-3", children: [
1182
- /* @__PURE__ */ jsxs13("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
1183
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
1184
- /* @__PURE__ */ jsxs13("span", { children: [
884
+ ) }) : /* @__PURE__ */ jsxs10(Fragment, { children: [
885
+ /* @__PURE__ */ jsxs10("div", { className: "shrink-0 border-b border-border px-4 pt-3", children: [
886
+ /* @__PURE__ */ jsxs10("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
887
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
888
+ /* @__PURE__ */ jsxs10("span", { children: [
1185
889
  visible.length,
1186
890
  " generation",
1187
891
  visible.length !== 1 ? "s" : ""
1188
892
  ] }),
1189
- /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-0.5", children: [
1190
- /* @__PURE__ */ jsx15(DollarSign, { className: "h-3 w-3" }),
893
+ /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-0.5", children: [
894
+ /* @__PURE__ */ jsx12(DollarSign, { className: "h-3 w-3" }),
1191
895
  totalCost.toFixed(2),
1192
896
  " spent"
1193
897
  ] })
1194
898
  ] }),
1195
- vaultHref && /* @__PURE__ */ jsx15(Link3, { to: vaultHref(), prefetch: "intent", onClick: () => onOpenChange(false), children: /* @__PURE__ */ jsxs13(Button5, { size: "sm", variant: "outline", children: [
1196
- /* @__PURE__ */ jsx15(FolderOpen2, { className: "mr-1.5 h-3.5 w-3.5" }),
899
+ vaultHref && /* @__PURE__ */ jsx12(Link2, { to: vaultHref(), prefetch: "intent", onClick: () => onOpenChange(false), children: /* @__PURE__ */ jsxs10(Button4, { size: "sm", variant: "outline", children: [
900
+ /* @__PURE__ */ jsx12(FolderOpen2, { className: "mr-1.5 h-3.5 w-3.5" }),
1197
901
  "Vault"
1198
902
  ] }) })
1199
903
  ] }),
1200
- /* @__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: [
1201
- /* @__PURE__ */ jsx15(TabsTrigger, { value: "all", className: "text-xs", children: "All" }),
1202
- Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx15(TabsTrigger, { value: key, className: "text-xs", children: cfg.label }, key))
904
+ /* @__PURE__ */ jsx12(Tabs, { value: typeFilter ?? "all", onValueChange: (v) => onFilterChange(v === "all" ? null : v), children: /* @__PURE__ */ jsxs10(TabsList, { className: "h-9 w-full justify-start gap-1 overflow-x-auto bg-transparent", children: [
905
+ /* @__PURE__ */ jsx12(TabsTrigger, { value: "all", className: "text-xs", children: "All" }),
906
+ Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx12(TabsTrigger, { value: key, className: "text-xs", children: cfg.label }, key))
1203
907
  ] }) })
1204
908
  ] }),
1205
- /* @__PURE__ */ jsx15("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx15(GenerationGrid, { generations: visible, typeFilter, onSelect }) })
909
+ /* @__PURE__ */ jsx12("div", { className: "flex-1 overflow-y-auto p-4", children: /* @__PURE__ */ jsx12(GenerationGrid, { generations: visible, typeFilter, onSelect }) })
1206
910
  ] })
1207
911
  ] });
1208
912
  }
1209
913
 
1210
914
  // src/studio-react/studio-workspace.tsx
1211
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
915
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1212
916
  function StudioWorkspace({
1213
917
  generations,
1214
918
  totalCost,
1215
919
  workspaceId,
1216
920
  role,
1217
921
  generationsEndpoint,
1218
- vaultHref,
1219
- integrationsHref
922
+ vaultHref
1220
923
  }) {
1221
924
  const [searchParams, setSearchParams] = useSearchParams();
1222
925
  const typeFilter = searchParams.get("type");
@@ -1224,9 +927,7 @@ function StudioWorkspace({
1224
927
  const [selected, setSelected] = useState3(null);
1225
928
  const canvasRef = useRef3(null);
1226
929
  const canGenerate = role !== "viewer";
1227
- const canManageIntegrations = role === "owner" || role === "admin";
1228
930
  const resolvedVaultHref = vaultHref ?? (workspaceId ? (filePath) => filePath ? `/app/${workspaceId}/vault?file=${encodeURIComponent(filePath)}` : `/app/${workspaceId}/vault` : void 0);
1229
- const resolvedIntegrationsHref = integrationsHref ?? (workspaceId ? `/app/${workspaceId}/integrations` : void 0);
1230
931
  const { mergedGenerations, latestBatch, onGenerated } = useStudioGenerations(generations, {
1231
932
  workspaceId,
1232
933
  generationsEndpoint
@@ -1243,8 +944,8 @@ function StudioWorkspace({
1243
944
  setSelected(generation);
1244
945
  setDrawerOpen(true);
1245
946
  }
1246
- return /* @__PURE__ */ jsxs14("div", { className: "min-h-0 flex-1 overflow-y-auto bg-background", children: [
1247
- /* @__PURE__ */ jsx16(
947
+ return /* @__PURE__ */ jsxs11("div", { className: "min-h-0 flex-1 overflow-y-auto bg-background", children: [
948
+ /* @__PURE__ */ jsx13(
1248
949
  StudioHeader,
1249
950
  {
1250
951
  count: mergedGenerations.length,
@@ -1252,13 +953,11 @@ function StudioWorkspace({
1252
953
  onOpenLibrary: openLibrary
1253
954
  }
1254
955
  ),
1255
- /* @__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: [
1256
- /* @__PURE__ */ jsx16(
956
+ /* @__PURE__ */ jsx13("div", { className: "mx-auto w-full max-w-3xl space-y-4 px-4 py-6 sm:px-6", children: canGenerate ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
957
+ /* @__PURE__ */ jsx13(
1257
958
  ComposerHero,
1258
959
  {
1259
960
  workspaceId,
1260
- integrationsHref: resolvedIntegrationsHref,
1261
- canManageIntegrations,
1262
961
  onGenerated: (generation) => {
1263
962
  onGenerated(generation);
1264
963
  requestAnimationFrame(() => {
@@ -1267,7 +966,7 @@ function StudioWorkspace({
1267
966
  }
1268
967
  }
1269
968
  ),
1270
- /* @__PURE__ */ jsx16("div", { ref: canvasRef, children: /* @__PURE__ */ jsx16(
969
+ /* @__PURE__ */ jsx13("div", { ref: canvasRef, children: /* @__PURE__ */ jsx13(
1271
970
  ResultCanvas,
1272
971
  {
1273
972
  batch: latestBatch,
@@ -1275,16 +974,16 @@ function StudioWorkspace({
1275
974
  onSelect: openDetail
1276
975
  }
1277
976
  ) })
1278
- ] }) : /* @__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: [
1279
- /* @__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" }) }),
1280
- /* @__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" }),
1281
- /* @__PURE__ */ jsx16("p", { className: "max-w-sm text-xs text-muted-foreground", children: "Team generations appear in the library." }),
1282
- /* @__PURE__ */ jsxs14(Button6, { size: "sm", variant: "outline", onClick: openLibrary, children: [
1283
- /* @__PURE__ */ jsx16(Images2, { className: "mr-1.5 h-4 w-4" }),
977
+ ] }) : /* @__PURE__ */ jsxs11("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: [
978
+ /* @__PURE__ */ jsx13("div", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx13(Images2, { className: "h-6 w-6 text-muted-foreground/40" }) }),
979
+ /* @__PURE__ */ jsx13("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" }),
980
+ /* @__PURE__ */ jsx13("p", { className: "max-w-sm text-xs text-muted-foreground", children: "Team generations appear in the library." }),
981
+ /* @__PURE__ */ jsxs11(Button5, { size: "sm", variant: "outline", onClick: openLibrary, children: [
982
+ /* @__PURE__ */ jsx13(Images2, { className: "mr-1.5 h-4 w-4" }),
1284
983
  "Open library"
1285
984
  ] })
1286
985
  ] }) }),
1287
- /* @__PURE__ */ jsx16(
986
+ /* @__PURE__ */ jsx13(
1288
987
  LibraryDrawer,
1289
988
  {
1290
989
  open: drawerOpen,
@@ -1308,14 +1007,14 @@ function StudioWorkspace({
1308
1007
  }
1309
1008
 
1310
1009
  // src/studio-react/library-panel.tsx
1311
- import { useMemo as useMemo4 } from "react";
1010
+ import { useMemo as useMemo3 } from "react";
1312
1011
  import {
1313
1012
  Tabs as Tabs2,
1314
1013
  TabsList as TabsList2,
1315
1014
  TabsTrigger as TabsTrigger2
1316
1015
  } from "@tangle-network/sandbox-ui/primitives";
1317
1016
  import { DollarSign as DollarSign2 } from "lucide-react";
1318
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1017
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1319
1018
  function LibraryPanel({
1320
1019
  generations,
1321
1020
  totalCost,
@@ -1323,11 +1022,11 @@ function LibraryPanel({
1323
1022
  onFilterChange,
1324
1023
  onSelect
1325
1024
  }) {
1326
- const visible = useMemo4(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
1327
- return /* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 flex-col", children: [
1328
- /* @__PURE__ */ jsxs15("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [
1329
- /* @__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-background p-1", children: [
1330
- /* @__PURE__ */ jsx17(
1025
+ const visible = useMemo3(() => filterGenerations(generations, typeFilter), [generations, typeFilter]);
1026
+ return /* @__PURE__ */ jsxs12("div", { className: "flex min-w-0 flex-col", children: [
1027
+ /* @__PURE__ */ jsxs12("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [
1028
+ /* @__PURE__ */ jsx14(Tabs2, { value: typeFilter ?? "all", onValueChange: (v) => onFilterChange(v === "all" ? null : v), children: /* @__PURE__ */ jsxs12(TabsList2, { className: "h-9 justify-start gap-1 overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-background p-1", children: [
1029
+ /* @__PURE__ */ jsx14(
1331
1030
  TabsTrigger2,
1332
1031
  {
1333
1032
  value: "all",
@@ -1335,7 +1034,7 @@ function LibraryPanel({
1335
1034
  children: "All"
1336
1035
  }
1337
1036
  ),
1338
- Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx17(
1037
+ Object.entries(TYPE_CONFIG).map(([key, cfg]) => /* @__PURE__ */ jsx14(
1339
1038
  TabsTrigger2,
1340
1039
  {
1341
1040
  value: key,
@@ -1345,39 +1044,134 @@ function LibraryPanel({
1345
1044
  key
1346
1045
  ))
1347
1046
  ] }) }),
1348
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
1349
- /* @__PURE__ */ jsxs15("span", { children: [
1047
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
1048
+ /* @__PURE__ */ jsxs12("span", { children: [
1350
1049
  visible.length,
1351
1050
  " generation",
1352
1051
  visible.length !== 1 ? "s" : ""
1353
1052
  ] }),
1354
- /* @__PURE__ */ jsxs15("span", { className: "flex items-center gap-0.5", children: [
1355
- /* @__PURE__ */ jsx17(DollarSign2, { className: "h-3 w-3" }),
1053
+ /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-0.5", children: [
1054
+ /* @__PURE__ */ jsx14(DollarSign2, { className: "h-3 w-3" }),
1356
1055
  totalCost.toFixed(2),
1357
1056
  " spent"
1358
1057
  ] })
1359
1058
  ] })
1360
1059
  ] }),
1361
- /* @__PURE__ */ jsx17(GenerationGrid, { generations: visible, typeFilter, onSelect })
1060
+ /* @__PURE__ */ jsx14(GenerationGrid, { generations: visible, typeFilter, onSelect })
1362
1061
  ] });
1363
1062
  }
1364
1063
 
1365
1064
  // src/studio-react/generation-detail-modal.tsx
1366
1065
  import { Dialog as Dialog2, DialogContent, DialogHeader, DialogTitle } from "@tangle-network/sandbox-ui/primitives";
1367
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1066
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1368
1067
  function GenerationDetailModal({
1369
1068
  generation,
1370
1069
  vaultHref,
1371
1070
  onClose
1372
1071
  }) {
1373
1072
  const cfg = generation ? typeConfigFor(generation.type) : null;
1374
- return /* @__PURE__ */ jsx18(Dialog2, { open: generation != null, onOpenChange: (open) => {
1073
+ return /* @__PURE__ */ jsx15(Dialog2, { open: generation != null, onOpenChange: (open) => {
1375
1074
  if (!open) onClose();
1376
- }, children: /* @__PURE__ */ jsxs16(DialogContent, { className: "max-h-[85vh] max-w-2xl overflow-y-auto border-card-edge bg-popover shadow-[var(--shadow-overlay)]", children: [
1377
- /* @__PURE__ */ jsx18(DialogHeader, { children: /* @__PURE__ */ jsx18(DialogTitle, { className: "text-left text-[15px] font-semibold", children: cfg ? `${cfg.label} generation` : "Generation" }) }),
1378
- generation && /* @__PURE__ */ jsx18(GenerationDetail, { generation, vaultHref, onNavigate: onClose })
1075
+ }, children: /* @__PURE__ */ jsxs13(DialogContent, { className: "max-h-[85vh] max-w-2xl overflow-y-auto border-card-edge bg-popover shadow-[var(--shadow-overlay)]", children: [
1076
+ /* @__PURE__ */ jsx15(DialogHeader, { children: /* @__PURE__ */ jsx15(DialogTitle, { className: "text-left text-[15px] font-semibold", children: cfg ? `${cfg.label} generation` : "Generation" }) }),
1077
+ generation && /* @__PURE__ */ jsx15(GenerationDetail, { generation, vaultHref, onNavigate: onClose })
1379
1078
  ] }) });
1380
1079
  }
1080
+
1081
+ // src/studio-react/avatar-composer.tsx
1082
+ import { Input as Input5 } from "@tangle-network/sandbox-ui/primitives";
1083
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1084
+ function AvatarComposer({
1085
+ audioUrl,
1086
+ imageUrl,
1087
+ avatarId,
1088
+ onAudioUrlChange,
1089
+ onImageUrlChange,
1090
+ onAvatarIdChange
1091
+ }) {
1092
+ return /* @__PURE__ */ jsxs14("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
1093
+ /* @__PURE__ */ jsx16(Field, { label: "Audio URL", htmlFor: "studio-audio-url", children: /* @__PURE__ */ jsx16(
1094
+ Input5,
1095
+ {
1096
+ id: "studio-audio-url",
1097
+ value: audioUrl,
1098
+ onChange: (event) => onAudioUrlChange(event.target.value),
1099
+ placeholder: "https://cdn.example.com/source-audio.mp3",
1100
+ className: "bg-background"
1101
+ }
1102
+ ) }),
1103
+ /* @__PURE__ */ jsx16(Field, { label: "Image URL", htmlFor: "studio-avatar-image-url", children: /* @__PURE__ */ jsx16(
1104
+ Input5,
1105
+ {
1106
+ id: "studio-avatar-image-url",
1107
+ value: imageUrl,
1108
+ onChange: (event) => onImageUrlChange(event.target.value),
1109
+ placeholder: "https://cdn.example.com/portrait.png",
1110
+ className: "bg-background"
1111
+ }
1112
+ ) }),
1113
+ /* @__PURE__ */ jsx16(Field, { label: "Avatar ID", htmlFor: "studio-avatar-id", children: /* @__PURE__ */ jsx16(
1114
+ Input5,
1115
+ {
1116
+ id: "studio-avatar-id",
1117
+ value: avatarId,
1118
+ onChange: (event) => onAvatarIdChange(event.target.value),
1119
+ placeholder: "Optional provider avatar id",
1120
+ className: "bg-background"
1121
+ }
1122
+ ) })
1123
+ ] });
1124
+ }
1125
+
1126
+ // src/studio-react/transcription-composer.tsx
1127
+ import { Input as Input6 } from "@tangle-network/sandbox-ui/primitives";
1128
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1129
+ function TranscriptionComposer({
1130
+ audioUrl,
1131
+ language,
1132
+ onAudioUrlChange,
1133
+ onLanguageChange
1134
+ }) {
1135
+ return /* @__PURE__ */ jsxs15("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
1136
+ /* @__PURE__ */ jsx17(Field, { label: "Audio URL", htmlFor: "studio-audio-url", children: /* @__PURE__ */ jsx17(
1137
+ Input6,
1138
+ {
1139
+ id: "studio-audio-url",
1140
+ value: audioUrl,
1141
+ onChange: (event) => onAudioUrlChange(event.target.value),
1142
+ placeholder: "https://cdn.example.com/source-audio.mp3",
1143
+ className: "bg-background"
1144
+ }
1145
+ ) }),
1146
+ /* @__PURE__ */ jsx17(Field, { label: "Language", htmlFor: "studio-transcription-language", children: /* @__PURE__ */ jsx17(
1147
+ Input6,
1148
+ {
1149
+ id: "studio-transcription-language",
1150
+ value: language,
1151
+ onChange: (event) => onLanguageChange(event.target.value),
1152
+ placeholder: "en",
1153
+ className: "bg-background"
1154
+ }
1155
+ ) })
1156
+ ] });
1157
+ }
1158
+ function TranscriptionOptions({
1159
+ responseFormat,
1160
+ temperature,
1161
+ onResponseFormatChange,
1162
+ onTemperatureChange
1163
+ }) {
1164
+ return /* @__PURE__ */ jsxs15(Fragment3, { children: [
1165
+ /* @__PURE__ */ jsx17(Field, { label: "Response format", children: /* @__PURE__ */ jsxs15(NativeSelect, { value: responseFormat, onChange: (event) => onResponseFormatChange(event.target.value), children: [
1166
+ /* @__PURE__ */ jsx17("option", { value: "json", children: "JSON" }),
1167
+ /* @__PURE__ */ jsx17("option", { value: "text", children: "Text" }),
1168
+ /* @__PURE__ */ jsx17("option", { value: "srt", children: "SRT" }),
1169
+ /* @__PURE__ */ jsx17("option", { value: "verbose_json", children: "Verbose JSON" }),
1170
+ /* @__PURE__ */ jsx17("option", { value: "vtt", children: "VTT" })
1171
+ ] }) }),
1172
+ /* @__PURE__ */ jsx17(Field, { label: "Temperature", children: /* @__PURE__ */ jsx17(Input6, { type: "number", min: "0", max: "1", step: "0.1", value: temperature, onChange: (event) => onTemperatureChange(event.target.value), className: "bg-background" }) })
1173
+ ] });
1174
+ }
1381
1175
  export {
1382
1176
  AvatarComposer,
1383
1177
  ComposerDisclosure,
@@ -1392,7 +1186,6 @@ export {
1392
1186
  LibraryDrawer,
1393
1187
  LibraryPanel,
1394
1188
  NativeSelect,
1395
- PublishPackageComposer,
1396
1189
  ResultCanvas,
1397
1190
  SpeechComposer,
1398
1191
  Stepper,