@chai-ui/vue 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { inject, computed, defineComponent, provide, renderSlot, watch, onScopeDispose, h, ref, openBlock, createElementBlock, createElementVNode, normalizeClass, createBlock, unref, Fragment, renderList, resolveDynamicComponent, createTextVNode, toDisplayString, createCommentVNode, normalizeStyle, createVNode, nextTick, mergeProps, onMounted, onUnmounted, withModifiers, withCtx, withDirectives, vModelText, reactive, toValue, shallowRef } from "vue";
2
- import { reasoningEngineFor, createReasoning, regionColor, composerView, composerAttachMenuItems, MAX_ANIMATE_ENHANCE_LENGTH, enhanceRevealDurationMs, composerAttachmentsFromFiles, regionBoxStyle, REGION_CORNERS, DEFAULT_MAX_REGIONS, freeRegionNumber, EDIT_ZOOM_STEPS, regionPopoverPosition, editCardWidth, newRegion, panForZoom, clampPan, fitBox, resizeBox, regionBoxForKey, panForKey, downloadMedia, downloadFilename, shareMedia, resultModelLabel, formatTokens, formatCost, formatDuration, formatAspectRatio, SUGGESTED_ANALYSIS_MODELS, DEFAULT_MAX_ATTACHMENTS_BY_KIND, isMediaAnalyzerAtCap, mediaAnalyzerModelSections, PROMPT_LENGTH_HINT, readMediaFiles, nextMediaAnalyzerAttachments, replacedNote, createComposerStore, pickReasoning, createMediaAnalyzerStore } from "@chai-ui/core";
1
+ import { inject, computed, defineComponent, provide, renderSlot, watch, onScopeDispose, h, ref, openBlock, createElementBlock, createElementVNode, normalizeClass, createBlock, unref, Fragment, renderList, resolveDynamicComponent, createTextVNode, toDisplayString, createCommentVNode, normalizeStyle, createVNode, useId, nextTick, mergeProps, onMounted, onUnmounted, withModifiers, withCtx, withDirectives, vModelText, reactive, toValue, shallowRef } from "vue";
2
+ import { reasoningEngineFor, createReasoning, regionColor, MAX_ANIMATE_ENHANCE_LENGTH, enhanceRevealDurationMs, composerView, composerAttachMenuItems, composerAttachmentsFromFiles, regionBoxStyle, REGION_CORNERS, DEFAULT_MAX_REGIONS, freeRegionNumber, EDIT_ZOOM_STEPS, regionPopoverPosition, editCardWidth, newRegion, panForZoom, clampPan, fitBox, resizeBox, regionBoxForKey, panForKey, downloadMedia, downloadFilename, shareMedia, resultModelLabel, formatTokens, formatCost, formatDuration, formatAspectRatio, SUGGESTED_ANALYSIS_MODELS, DEFAULT_MAX_ATTACHMENTS_BY_KIND, isMediaAnalyzerAtCap, mediaAnalyzerModelSections, PROMPT_LENGTH_HINT, readMediaFiles, nextMediaAnalyzerAttachments, replacedNote, createComposerStore, pickReasoning, createMediaAnalyzerStore } from "@chai-ui/core";
3
3
  import { DEFAULT_MAX_ATTACHMENTS_BY_KIND as DEFAULT_MAX_ATTACHMENTS_BY_KIND2, DEFAULT_MAX_REGIONS as DEFAULT_MAX_REGIONS2, DEFAULT_MEDIA_ANALYSIS_PROMPT_LENGTH, DEFAULT_MODEL_ID, DEFAULT_REASONING_MODEL, DEFAULT_REASONING_MODEL_BY_KIND, EDIT_IMAGE_USE_CASE, GenerationError, MEDIA_ANALYSIS_PROMPTS, MEDIA_ANALYSIS_PROMPT_LENGTHS, PRECISE_EDIT_MODELS, ROUTING_MODEL_ID, SUGGESTED_ANALYSIS_MODELS as SUGGESTED_ANALYSIS_MODELS2, SUGGESTED_EDIT_MODELS, SUGGESTED_IMAGE_MODELS, SUGGESTED_IMAGE_TO_VIDEO_MODELS, SUGGESTED_TEXT_TO_VIDEO_MODELS, TEXT_USE_CASE, buildRegionEditPrompt, checkSuggestedModels, createFalEngine, createMockEngine, createOpenRouterEngine, isMediaAnalyzerAtCap as isMediaAnalyzerAtCap2, mockEngine, nextMediaAnalyzerAttachments as nextMediaAnalyzerAttachments2, reasoningModelFor, suggestedModels } from "@chai-ui/core";
4
4
  import "@material/web/fab/fab.js";
5
5
  import "@material/web/checkbox/checkbox.js";
@@ -10,7 +10,7 @@ function useReasoning() {
10
10
  const provided = inject(reasoningKey, null);
11
11
  return computed(() => provided?.value);
12
12
  }
13
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
13
+ const _sfc_main$i = /* @__PURE__ */ defineComponent({
14
14
  __name: "ChaiProvider",
15
15
  props: {
16
16
  reasoningModel: {},
@@ -86,24 +86,25 @@ const OptimizeIcon = icon("0 0 25 24", [{ "d": "M5 19H6.425L16.2 9.225L14.775 7.
86
86
  const UndoIcon = icon("0 -960 960 960", [{ "d": "M259-200v-60h310q70 0 120.5-46.5T740-422q0-69-50.5-115.5T569-584H274l114 114-42 42-186-186 186-186 42 42-114 114h294q95 0 163.5 64T800-422q0 94-68.5 158T568-200H259Z", "fill": "currentColor" }]);
87
87
  const AttachFileIcon = icon("0 -960 960 960", [{ "d": "M728-326q0 103-72.18 174.5-72.17 71.5-175 71.5Q378-80 305.5-151.5T233-326v-380q0-72.5 51.5-123.25T408-880q72 0 123.5 50.75T583-706v360q0 42-30 72t-72.5 30q-42.5 0-72.5-29.67-30-29.68-30-72.33v-370h60v370q0 17 12.5 29.5t30.64 12.5q18.14 0 30-12.5T523-346v-360q0-48-33.5-81t-81.71-33q-48.21 0-81.5 33.06T293-706v380q0 78 54.97 132T481-140q77.92 0 132.46-54Q668-248 668-326v-390h60v390Z", "fill": "currentColor" }]);
88
88
  const ImageIcon = icon("0 -960 960 960", [{ "d": "M180-120q-24 0-42-18t-18-42v-600q0-24 18-42t42-18h600q24 0 42 18t18 42v600q0 24-18 42t-42 18H180Zm0-60h600v-600H180v600Zm56-97h489L578-473 446-302l-93-127-117 152Zm-56 97v-600 600Z", "fill": "currentColor" }]);
89
+ const GlobeIcon = icon("0 -960 960 960", [{ "d": "M480.27-80q-82.74 0-155.5-31.5Q252-143 197.5-197.5t-86-127.34Q80-397.68 80-480.5t31.5-155.66Q143-709 197.5-763t127.34-85.5Q397.68-880 480.5-880t155.66 31.5Q709-817 763-763t85.5 127Q880-563 880-480.27q0 82.74-31.5 155.5Q817-252 763-197.68q-54 54.31-127 86Q563-80 480.27-80Zm-.27-60q142.38 0 241.19-99.5T820-480v-13q-6 26-27.41 43.5Q771.19-432 742-432h-80q-33 0-56.5-23.5T582-512v-40H422v-80q0-33 23.5-56.5T502-712h40v-22q0-16 13.5-40t30.5-29q-25-8-51.36-12.5Q508.29-820 480-820q-141 0-240.5 98.81T140-480h150q66 0 113 47t47 113v40H330v105q34 17 71.7 26t78.3 9Z", "fill": "currentColor" }]);
89
90
  const VideocamIcon = icon("0 -960 960 960", [{ "d": "M140-160q-24 0-42-18t-18-42v-520q0-24 18-42t42-18h520q24 0 42 18t18 42v215l160-160v410L720-435v215q0 24-18 42t-42 18H140Zm0-60h520v-520H140v520Zm0 0v-520 520Z", "fill": "currentColor" }]);
90
91
  const ContentCutIcon = icon("0 -960 960 960", [{ "d": "M782-114 481-415 364-298q11 17 13.5 33t2.5 35q0 64-43 107T230-80q-64 0-107-43T80-230q0-64 43-107t107-43q18 0 35.5 5t36.5 15l116-116-118-118q-17 8-34.5 11t-35.5 3q-64 0-107-43T80-730q0-64 43-107t107-43q64 0 107 43t43 107q0 19-2.5 36T367-662l514 514v34h-99ZM599-527l-66-66 249-249h99v33L599-527ZM294-666q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Zm202.5 203.5Q502-468 502-476t-5.5-13.5Q491-495 483-495t-13.5 5.5Q464-484 464-476t5.5 13.5Q475-457 483-457t13.5-5.5ZM294-166q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Z", "fill": "currentColor" }]);
91
92
  const MusicNoteIcon = icon("0 -960 960 960", [{ "d": "M286.5-163.5Q243-207 243-270t43.5-106.5Q330-420 393-420q28 0 50.5 8t39.5 22v-450h234v135H543v435q0 63-43.5 106.5T393-120q-63 0-106.5-43.5Z", "fill": "currentColor" }]);
92
- const _hoisted_1$g = ["disabled", "aria-expanded", "aria-label"];
93
- const _hoisted_2$b = {
93
+ const _hoisted_1$h = ["disabled", "aria-expanded", "aria-label"];
94
+ const _hoisted_2$c = {
94
95
  key: 0,
95
96
  class: "chai-composer__attach-menu",
96
97
  role: "menu"
97
98
  };
98
- const _hoisted_3$9 = ["onClick"];
99
- const _hoisted_4$7 = { class: "chai-composer__attach-menu-icon" };
100
- const _hoisted_5$6 = {
99
+ const _hoisted_3$a = ["onClick"];
100
+ const _hoisted_4$8 = { class: "chai-composer__attach-menu-icon" };
101
+ const _hoisted_5$7 = {
101
102
  key: 0,
102
103
  class: "chai-composer__attach-menu-divider",
103
104
  role: "separator"
104
105
  };
105
- const _hoisted_6$6 = ["accept", "multiple", "disabled"];
106
- const _sfc_main$g = /* @__PURE__ */ defineComponent({
106
+ const _hoisted_6$7 = ["accept", "multiple", "disabled"];
107
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
107
108
  __name: "AttachMenu",
108
109
  props: {
109
110
  items: {},
@@ -113,7 +114,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
113
114
  emits: ["select", "files"],
114
115
  setup(__props, { emit: __emit }) {
115
116
  const emit = __emit;
116
- const ICONS = { "add-media": AttachFileIcon, "create-image": ImageIcon, "create-video": VideocamIcon, "edit-media": ContentCutIcon };
117
+ const ICONS = { "add-media": AttachFileIcon, "create-image": ImageIcon, "create-video": VideocamIcon, "create-world": GlobeIcon, "edit-media": ContentCutIcon };
117
118
  const open = ref(false);
118
119
  const root = ref();
119
120
  const input = ref();
@@ -144,8 +145,8 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
144
145
  onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
145
146
  }, [
146
147
  open.value ? (openBlock(), createBlock(unref(CloseSymbolIcon), { key: 0 })) : (openBlock(), createBlock(unref(PlusIcon), { key: 1 }))
147
- ], 10, _hoisted_1$g),
148
- open.value ? (openBlock(), createElementBlock("ul", _hoisted_2$b, [
148
+ ], 10, _hoisted_1$h),
149
+ open.value ? (openBlock(), createElementBlock("ul", _hoisted_2$c, [
149
150
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, i) => {
150
151
  return openBlock(), createElementBlock("li", {
151
152
  key: item.action,
@@ -157,12 +158,12 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
157
158
  class: "chai-composer__attach-menu-item",
158
159
  onClick: ($event) => pick(item.action)
159
160
  }, [
160
- createElementVNode("span", _hoisted_4$7, [
161
+ createElementVNode("span", _hoisted_4$8, [
161
162
  (openBlock(), createBlock(resolveDynamicComponent(ICONS[item.action])))
162
163
  ]),
163
164
  createTextVNode(toDisplayString(item.label), 1)
164
- ], 8, _hoisted_3$9),
165
- item.divider && i < __props.items.length - 1 ? (openBlock(), createElementBlock("hr", _hoisted_5$6)) : createCommentVNode("", true)
165
+ ], 8, _hoisted_3$a),
166
+ item.divider && i < __props.items.length - 1 ? (openBlock(), createElementBlock("hr", _hoisted_5$7)) : createCommentVNode("", true)
166
167
  ]);
167
168
  }), 128))
168
169
  ])) : createCommentVNode("", true),
@@ -175,18 +176,18 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
175
176
  hidden: "",
176
177
  disabled: __props.disabled,
177
178
  onChange: onFileChange
178
- }, null, 40, _hoisted_6$6)
179
+ }, null, 40, _hoisted_6$7)
179
180
  ], 512);
180
181
  };
181
182
  }
182
183
  });
183
- const _hoisted_1$f = {
184
+ const _hoisted_1$g = {
184
185
  key: 0,
185
186
  class: "chai-composer__region-badge",
186
187
  "aria-hidden": "true"
187
188
  };
188
- const _hoisted_2$a = ["disabled", "aria-label"];
189
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
189
+ const _hoisted_2$b = ["disabled", "aria-label"];
190
+ const _sfc_main$g = /* @__PURE__ */ defineComponent({
190
191
  __name: "Chip",
191
192
  props: {
192
193
  label: {},
@@ -202,7 +203,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
202
203
  class: normalizeClass(["chai-composer__chip", { "chai-composer__chip--region": __props.regionNumber != null }]),
203
204
  style: normalizeStyle(__props.regionNumber != null ? { "--chai-region-color": unref(regionColor)(__props.regionNumber) } : void 0)
204
205
  }, [
205
- __props.regionNumber != null ? (openBlock(), createElementBlock("span", _hoisted_1$f, toDisplayString(__props.regionNumber), 1)) : createCommentVNode("", true),
206
+ __props.regionNumber != null ? (openBlock(), createElementBlock("span", _hoisted_1$g, toDisplayString(__props.regionNumber), 1)) : createCommentVNode("", true),
206
207
  createTextVNode(toDisplayString(__props.label), 1),
207
208
  __props.removable ? (openBlock(), createElementBlock("button", {
208
209
  key: 1,
@@ -213,11 +214,185 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
213
214
  onClick: _cache[0] || (_cache[0] = ($event) => emit("remove"))
214
215
  }, [
215
216
  createVNode(unref(CloseSymbolIcon))
216
- ], 8, _hoisted_2$a)) : createCommentVNode("", true)
217
+ ], 8, _hoisted_2$b)) : createCommentVNode("", true)
217
218
  ], 6);
218
219
  };
219
220
  }
220
221
  });
222
+ const _hoisted_1$f = {
223
+ key: 0,
224
+ class: "chai-composer__world-field"
225
+ };
226
+ const _hoisted_2$a = { class: "chai-composer__world-field-head" };
227
+ const _hoisted_3$9 = ["for"];
228
+ const _hoisted_4$7 = ["disabled", "aria-label", "title"];
229
+ const _hoisted_5$6 = { class: "chai-composer__field chai-composer__field--boxed" };
230
+ const _hoisted_6$6 = ["id", "value", "placeholder", "aria-describedby", "disabled"];
231
+ const _hoisted_7$6 = {
232
+ key: 0,
233
+ class: "chai-composer__reveal chai-composer__type",
234
+ "aria-hidden": "true"
235
+ };
236
+ const _hoisted_8$6 = { class: "chai-composer__reveal-text" };
237
+ const _hoisted_9$6 = ["id"];
238
+ const _hoisted_10$6 = {
239
+ key: 1,
240
+ class: "chai-composer__field"
241
+ };
242
+ const _hoisted_11$5 = ["id", "value", "placeholder", "aria-label", "disabled"];
243
+ const _hoisted_12$5 = {
244
+ key: 0,
245
+ class: "chai-composer__reveal chai-composer__type",
246
+ "aria-hidden": "true"
247
+ };
248
+ const _hoisted_13$4 = { class: "chai-composer__reveal-text" };
249
+ const _hoisted_14$4 = ["disabled", "aria-label", "title"];
250
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
251
+ __name: "PromptField",
252
+ props: {
253
+ value: {},
254
+ placeholder: {},
255
+ label: {},
256
+ heading: {},
257
+ note: {},
258
+ hint: {},
259
+ onEnhance: { type: Function },
260
+ enhancing: { type: Boolean },
261
+ disabled: { type: Boolean }
262
+ },
263
+ emits: ["change"],
264
+ setup(__props, { emit: __emit }) {
265
+ const props = __props;
266
+ const emit = __emit;
267
+ const id = useId();
268
+ const textarea = ref();
269
+ watch(
270
+ () => props.value,
271
+ () => {
272
+ const el = textarea.value;
273
+ if (!el) return;
274
+ el.style.height = "auto";
275
+ el.style.height = `${el.scrollHeight}px`;
276
+ },
277
+ { flush: "post", immediate: true }
278
+ );
279
+ const originalValue = ref(null);
280
+ const enhancedValue = ref(null);
281
+ const animatingText = ref(null);
282
+ const revealedLength = ref(0);
283
+ let raf = 0;
284
+ watch(
285
+ () => props.enhancing,
286
+ (now, was) => {
287
+ if (!was || now || originalValue.value == null || props.value === originalValue.value) return;
288
+ const value = props.value;
289
+ enhancedValue.value = value;
290
+ if (value.length > MAX_ANIMATE_ENHANCE_LENGTH || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
291
+ animatingText.value = value;
292
+ revealedLength.value = 0;
293
+ const duration = enhanceRevealDurationMs(value.length);
294
+ const start = performance.now();
295
+ const tick = (time) => {
296
+ revealedLength.value = Math.min(value.length, Math.floor((time - start) / duration * value.length));
297
+ if (revealedLength.value < value.length) raf = requestAnimationFrame(tick);
298
+ else animatingText.value = null;
299
+ };
300
+ raf = requestAnimationFrame(tick);
301
+ }
302
+ );
303
+ onScopeDispose(() => cancelAnimationFrame(raf));
304
+ const animating = computed(() => animatingText.value != null);
305
+ const isEnhanced = computed(() => !animating.value && enhancedValue.value != null && props.value === enhancedValue.value);
306
+ const enhanceBusy = computed(() => props.enhancing || animating.value);
307
+ const optimizeName = computed(
308
+ () => `${isEnhanced.value ? "Revert to original" : "Optimize"} ${props.heading ? props.heading.toLowerCase() : "prompt"}`
309
+ );
310
+ function onOptimizeClick() {
311
+ if (isEnhanced.value) {
312
+ const original = originalValue.value;
313
+ enhancedValue.value = null;
314
+ originalValue.value = null;
315
+ if (original != null) emit("change", original);
316
+ return;
317
+ }
318
+ originalValue.value = props.value;
319
+ props.onEnhance?.(props.value);
320
+ }
321
+ return (_ctx, _cache) => {
322
+ return __props.heading ? (openBlock(), createElementBlock("div", _hoisted_1$f, [
323
+ createElementVNode("div", _hoisted_2$a, [
324
+ createElementVNode("label", {
325
+ for: unref(id),
326
+ class: "chai-composer__world-field-label"
327
+ }, [
328
+ createElementVNode("strong", null, toDisplayString(__props.heading), 1),
329
+ createTextVNode(" " + toDisplayString(__props.note), 1)
330
+ ], 8, _hoisted_3$9),
331
+ __props.onEnhance ? (openBlock(), createElementBlock("button", {
332
+ key: 0,
333
+ type: "button",
334
+ class: normalizeClass(["chai-composer__optimize", { "chai-composer__optimize--active": enhanceBusy.value }]),
335
+ disabled: __props.disabled || (isEnhanced.value ? false : !__props.value.trim() || enhanceBusy.value),
336
+ "aria-label": optimizeName.value,
337
+ title: optimizeName.value,
338
+ onClick: onOptimizeClick
339
+ }, [
340
+ isEnhanced.value ? (openBlock(), createBlock(unref(UndoIcon), { key: 0 })) : (openBlock(), createBlock(unref(OptimizeIcon), { key: 1 }))
341
+ ], 10, _hoisted_4$7)) : createCommentVNode("", true)
342
+ ]),
343
+ createElementVNode("div", _hoisted_5$6, [
344
+ createElementVNode("textarea", {
345
+ id: unref(id),
346
+ ref_key: "textarea",
347
+ ref: textarea,
348
+ class: normalizeClass(["chai-composer__input chai-composer__type", { "chai-composer__input--revealing": animating.value }]),
349
+ value: __props.value,
350
+ placeholder: __props.placeholder,
351
+ "aria-describedby": __props.hint ? `${unref(id)}-hint` : void 0,
352
+ rows: "1",
353
+ disabled: __props.disabled || animating.value,
354
+ onInput: _cache[0] || (_cache[0] = ($event) => emit("change", $event.target.value))
355
+ }, null, 42, _hoisted_6$6),
356
+ animating.value ? (openBlock(), createElementBlock("div", _hoisted_7$6, [
357
+ createElementVNode("span", _hoisted_8$6, toDisplayString(animatingText.value.slice(0, revealedLength.value)), 1)
358
+ ])) : createCommentVNode("", true)
359
+ ]),
360
+ __props.hint ? (openBlock(), createElementBlock("p", {
361
+ key: 0,
362
+ id: `${unref(id)}-hint`,
363
+ class: "chai-composer__field-hint"
364
+ }, toDisplayString(__props.hint), 9, _hoisted_9$6)) : createCommentVNode("", true)
365
+ ])) : (openBlock(), createElementBlock("div", _hoisted_10$6, [
366
+ createElementVNode("textarea", {
367
+ id: unref(id),
368
+ ref_key: "textarea",
369
+ ref: textarea,
370
+ class: normalizeClass(["chai-composer__input chai-composer__type", { "chai-composer__input--revealing": animating.value }]),
371
+ value: __props.value,
372
+ placeholder: __props.placeholder,
373
+ "aria-label": __props.label ?? __props.placeholder,
374
+ rows: "1",
375
+ disabled: __props.disabled || animating.value,
376
+ onInput: _cache[1] || (_cache[1] = ($event) => emit("change", $event.target.value))
377
+ }, null, 42, _hoisted_11$5),
378
+ animating.value ? (openBlock(), createElementBlock("div", _hoisted_12$5, [
379
+ createElementVNode("span", _hoisted_13$4, toDisplayString(animatingText.value.slice(0, revealedLength.value)), 1)
380
+ ])) : createCommentVNode("", true),
381
+ __props.onEnhance ? (openBlock(), createElementBlock("button", {
382
+ key: 1,
383
+ type: "button",
384
+ class: normalizeClass(["chai-composer__optimize", { "chai-composer__optimize--active": enhanceBusy.value }]),
385
+ disabled: __props.disabled || (isEnhanced.value ? false : !__props.value.trim() || enhanceBusy.value),
386
+ "aria-label": optimizeName.value,
387
+ title: optimizeName.value,
388
+ onClick: onOptimizeClick
389
+ }, [
390
+ isEnhanced.value ? (openBlock(), createBlock(unref(UndoIcon), { key: 0 })) : (openBlock(), createBlock(unref(OptimizeIcon), { key: 1 }))
391
+ ], 10, _hoisted_14$4)) : createCommentVNode("", true)
392
+ ]));
393
+ };
394
+ }
395
+ });
221
396
  const _hoisted_1$e = ["aria-label", ".selected", ".disabled"];
222
397
  const _sfc_main$e = /* @__PURE__ */ defineComponent({
223
398
  __name: "Toggle",
@@ -259,14 +434,14 @@ const _hoisted_10$5 = {
259
434
  };
260
435
  const _hoisted_11$4 = ["aria-label"];
261
436
  const _hoisted_12$4 = ["aria-pressed", "disabled", "onClick"];
262
- const _hoisted_13$4 = [".checked", ".disabled"];
263
- const _hoisted_14$4 = { class: "chai-search-menu__option-label" };
264
- const _hoisted_15$4 = {
437
+ const _hoisted_13$3 = [".checked", ".disabled"];
438
+ const _hoisted_14$3 = { class: "chai-search-menu__option-label" };
439
+ const _hoisted_15$3 = {
265
440
  key: 1,
266
441
  class: "chai-search-menu__divider",
267
442
  role: "separator"
268
443
  };
269
- const _hoisted_16$3 = {
444
+ const _hoisted_16$2 = {
270
445
  key: 0,
271
446
  class: "chai-search-menu__empty"
272
447
  };
@@ -459,17 +634,17 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
459
634
  ".disabled": __props.toggleHeader?.value ?? false,
460
635
  tabindex: "-1",
461
636
  "aria-hidden": "true"
462
- }, null, 40, _hoisted_13$4)) : createCommentVNode("", true),
463
- createElementVNode("span", _hoisted_14$4, toDisplayString(o.rowLabel ?? o.label), 1),
637
+ }, null, 40, _hoisted_13$3)) : createCommentVNode("", true),
638
+ createElementVNode("span", _hoisted_14$3, toDisplayString(o.rowLabel ?? o.label), 1),
464
639
  !__props.multiple && isSelected(o.id) ? (openBlock(), createBlock(unref(CheckIcon), { key: 1 })) : createCommentVNode("", true)
465
640
  ], 10, _hoisted_12$4)
466
641
  ]);
467
642
  }), 128))
468
643
  ], 8, _hoisted_11$4),
469
- i < groups.value.length - 1 ? (openBlock(), createElementBlock("hr", _hoisted_15$4)) : createCommentVNode("", true)
644
+ i < groups.value.length - 1 ? (openBlock(), createElementBlock("hr", _hoisted_15$3)) : createCommentVNode("", true)
470
645
  ]);
471
646
  }), 128)),
472
- !hasAnyOption.value ? (openBlock(), createElementBlock("li", _hoisted_16$3, "No matches.")) : createCommentVNode("", true)
647
+ !hasAnyOption.value ? (openBlock(), createElementBlock("li", _hoisted_16$2, "No matches.")) : createCommentVNode("", true)
473
648
  ])
474
649
  ], 12, _hoisted_3$8)) : createCommentVNode("", true)
475
650
  ], 512);
@@ -492,24 +667,19 @@ const _hoisted_6$4 = {
492
667
  class: "chai-composer__regions",
493
668
  "aria-label": "Edit regions"
494
669
  };
495
- const _hoisted_7$4 = { class: "chai-composer__field" };
496
- const _hoisted_8$4 = ["value", "placeholder", "aria-label", "disabled"];
497
- const _hoisted_9$4 = {
498
- key: 0,
499
- class: "chai-composer__reveal chai-composer__type",
500
- "aria-hidden": "true"
501
- };
502
- const _hoisted_10$4 = { class: "chai-composer__reveal-text" };
503
- const _hoisted_11$3 = ["disabled", "aria-label", "title"];
504
- const _hoisted_12$3 = {
670
+ const _hoisted_7$4 = {
505
671
  key: 2,
672
+ class: "chai-composer__world-fields"
673
+ };
674
+ const _hoisted_8$4 = {
675
+ key: 4,
506
676
  class: "chai-composer__error",
507
677
  role: "alert"
508
678
  };
509
- const _hoisted_13$3 = { class: "chai-composer__controls" };
510
- const _hoisted_14$3 = { class: "chai-composer__controls-start" };
511
- const _hoisted_15$3 = ["data-ready", "data-error", "data-stop", "aria-label", "aria-disabled"];
512
- const _hoisted_16$2 = { slot: "icon" };
679
+ const _hoisted_9$4 = { class: "chai-composer__controls" };
680
+ const _hoisted_10$4 = { class: "chai-composer__controls-start" };
681
+ const _hoisted_11$3 = ["data-ready", "data-error", "data-stop", "aria-label", "aria-disabled"];
682
+ const _hoisted_12$3 = { slot: "icon" };
513
683
  const _sfc_main$c = /* @__PURE__ */ defineComponent({
514
684
  __name: "Composer",
515
685
  props: {
@@ -539,6 +709,10 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
539
709
  "onUpdate:aspectRatio": {},
540
710
  onEnhance: {},
541
711
  enhancing: { type: Boolean },
712
+ character: { default: "" },
713
+ "onUpdate:character": {},
714
+ frameRate: { default: null },
715
+ "onUpdate:frameRate": {},
542
716
  submitError: { default: null },
543
717
  submitDisabled: { type: Boolean, default: void 0 },
544
718
  submitting: { type: Boolean },
@@ -588,56 +762,11 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
588
762
  if (view.value.multiModel) props["onUpdate:modelIds"]?.(view.value.toggledModelIds(id));
589
763
  else props["onUpdate:modelId"]?.(id);
590
764
  }
591
- const textarea = ref();
592
- watch(
593
- () => props.modelValue,
594
- () => {
595
- const el = textarea.value;
596
- if (!el) return;
597
- el.style.height = "auto";
598
- el.style.height = `${el.scrollHeight}px`;
599
- },
600
- { flush: "post", immediate: true }
601
- );
602
- const originalValue = ref(null);
603
- const enhancedValue = ref(null);
604
- const animatingText = ref(null);
605
- const revealedLength = ref(0);
606
- let raf = 0;
607
- watch(
608
- () => props.enhancing,
609
- (now, was) => {
610
- if (!was || now || originalValue.value == null || props.modelValue === originalValue.value) return;
611
- const value = props.modelValue;
612
- enhancedValue.value = value;
613
- if (value.length > MAX_ANIMATE_ENHANCE_LENGTH || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
614
- animatingText.value = value;
615
- revealedLength.value = 0;
616
- const duration = enhanceRevealDurationMs(value.length);
617
- const start = performance.now();
618
- const tick = (time) => {
619
- revealedLength.value = Math.min(value.length, Math.floor((time - start) / duration * value.length));
620
- if (revealedLength.value < value.length) raf = requestAnimationFrame(tick);
621
- else animatingText.value = null;
622
- };
623
- raf = requestAnimationFrame(tick);
624
- }
625
- );
626
- onScopeDispose(() => cancelAnimationFrame(raf));
627
- const animating = computed(() => animatingText.value != null);
628
- const isEnhanced = computed(() => !animating.value && enhancedValue.value != null && props.modelValue === enhancedValue.value);
629
- const enhanceBusy = computed(() => Boolean(props.enhancing) || animating.value);
630
- function onOptimizeClick() {
631
- if (isEnhanced.value) {
632
- const original = originalValue.value;
633
- enhancedValue.value = null;
634
- originalValue.value = null;
635
- if (original != null) emit("update:modelValue", original);
636
- return;
637
- }
638
- originalValue.value = props.modelValue;
639
- props.onEnhance?.(props.modelValue);
640
- }
765
+ const enhancingField = ref("prompt");
766
+ const enhanceField = (field) => props.onEnhance && ((current) => {
767
+ enhancingField.value = field;
768
+ props.onEnhance?.(current, field);
769
+ });
641
770
  async function onFiles(files) {
642
771
  const onAttachments = props["onUpdate:attachments"];
643
772
  if (!files || files.length === 0 || !onAttachments) return;
@@ -686,7 +815,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
686
815
  return openBlock(), createElementBlock("li", {
687
816
  key: r.id
688
817
  }, [
689
- createVNode(_sfc_main$f, {
818
+ createVNode(_sfc_main$g, {
690
819
  label: `Region ${r.number}`,
691
820
  "region-number": r.number,
692
821
  removable: Boolean(props["onUpdate:regions"]),
@@ -696,49 +825,55 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
696
825
  ]);
697
826
  }), 128))
698
827
  ])) : createCommentVNode("", true),
699
- createElementVNode("div", _hoisted_7$4, [
700
- createElementVNode("textarea", {
701
- ref_key: "textarea",
702
- ref: textarea,
703
- class: normalizeClass(["chai-composer__input chai-composer__type", { "chai-composer__input--revealing": animating.value }]),
828
+ view.value.world ? (openBlock(), createElementBlock("div", _hoisted_7$4, [
829
+ createVNode(_sfc_main$f, {
704
830
  value: __props.modelValue,
705
831
  placeholder: view.value.placeholder,
706
- "aria-label": __props.promptLabel ?? view.value.placeholder,
707
- rows: "1",
708
- disabled: __props.disabled || animating.value,
709
- onInput: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event.target.value))
710
- }, null, 42, _hoisted_8$4),
711
- animating.value ? (openBlock(), createElementBlock("div", _hoisted_9$4, [
712
- createElementVNode("span", _hoisted_10$4, toDisplayString(animatingText.value.slice(0, revealedLength.value)), 1)
713
- ])) : createCommentVNode("", true),
714
- __props.onEnhance ? (openBlock(), createElementBlock("button", {
715
- key: 1,
716
- type: "button",
717
- class: normalizeClass(["chai-composer__optimize", { "chai-composer__optimize--active": enhanceBusy.value }]),
718
- disabled: __props.disabled || (isEnhanced.value ? false : !__props.modelValue.trim() || enhanceBusy.value),
719
- "aria-label": isEnhanced.value ? "Revert to original prompt" : "Optimize prompt",
720
- title: isEnhanced.value ? "Revert to original prompt" : "Optimize prompt",
721
- onClick: onOptimizeClick
722
- }, [
723
- isEnhanced.value ? (openBlock(), createBlock(unref(UndoIcon), { key: 0 })) : (openBlock(), createBlock(unref(OptimizeIcon), { key: 1 }))
724
- ], 10, _hoisted_11$3)) : createCommentVNode("", true)
725
- ]),
726
- __props.submitError ? (openBlock(), createElementBlock("p", _hoisted_12$3, [
832
+ heading: "Environment",
833
+ note: "(required)",
834
+ hint: view.value.environmentHint,
835
+ "on-enhance": enhanceField("environment"),
836
+ enhancing: Boolean(__props.enhancing) && enhancingField.value === "environment",
837
+ disabled: __props.disabled,
838
+ onChange: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event))
839
+ }, null, 8, ["value", "placeholder", "hint", "on-enhance", "enhancing", "disabled"]),
840
+ props["onUpdate:character"] ? (openBlock(), createBlock(_sfc_main$f, {
841
+ key: 0,
842
+ value: __props.character,
843
+ placeholder: view.value.characterPlaceholder,
844
+ heading: "Character",
845
+ note: "(optional)",
846
+ "on-enhance": enhanceField("character"),
847
+ enhancing: Boolean(__props.enhancing) && enhancingField.value === "character",
848
+ disabled: __props.disabled,
849
+ onChange: _cache[1] || (_cache[1] = ($event) => props["onUpdate:character"]?.($event))
850
+ }, null, 8, ["value", "placeholder", "on-enhance", "enhancing", "disabled"])) : createCommentVNode("", true)
851
+ ])) : (openBlock(), createBlock(_sfc_main$f, {
852
+ key: 3,
853
+ value: __props.modelValue,
854
+ placeholder: view.value.placeholder,
855
+ label: __props.promptLabel,
856
+ "on-enhance": enhanceField("prompt"),
857
+ enhancing: Boolean(__props.enhancing),
858
+ disabled: __props.disabled,
859
+ onChange: _cache[2] || (_cache[2] = ($event) => emit("update:modelValue", $event))
860
+ }, null, 8, ["value", "placeholder", "label", "on-enhance", "enhancing", "disabled"])),
861
+ __props.submitError ? (openBlock(), createElementBlock("p", _hoisted_8$4, [
727
862
  createVNode(unref(ErrorIcon)),
728
863
  createTextVNode(toDisplayString(__props.submitError), 1)
729
864
  ])) : createCommentVNode("", true),
730
- createElementVNode("div", _hoisted_13$3, [
731
- createElementVNode("div", _hoisted_14$3, [
732
- menuItems.value.length > 0 ? (openBlock(), createBlock(_sfc_main$g, {
865
+ createElementVNode("div", _hoisted_9$4, [
866
+ createElementVNode("div", _hoisted_10$4, [
867
+ menuItems.value.length > 0 ? (openBlock(), createBlock(_sfc_main$h, {
733
868
  key: 0,
734
869
  items: menuItems.value,
735
870
  "images-only": view.value.editing,
736
871
  disabled: __props.disabled,
737
- onSelect: _cache[1] || (_cache[1] = ($event) => __props.onAttachMenuSelect?.($event)),
872
+ onSelect: _cache[3] || (_cache[3] = ($event) => __props.onAttachMenuSelect?.($event)),
738
873
  onFiles
739
874
  }, null, 8, ["items", "images-only", "disabled"])) : createCommentVNode("", true),
740
875
  (openBlock(true), createElementBlock(Fragment, null, renderList(view.value.pickedUseCases, (u) => {
741
- return openBlock(), createBlock(_sfc_main$f, {
876
+ return openBlock(), createBlock(_sfc_main$g, {
742
877
  key: u.kind,
743
878
  label: u.label,
744
879
  removable: Boolean(__props.multiSelectUseCases ? props["onUpdate:useCases"] : __props.onClearUseCase),
@@ -756,7 +891,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
756
891
  "trigger-variant": "text",
757
892
  disabled: __props.disabled || __props.autoSelectModel && !__props.showAutoSelectToggle,
758
893
  "panel-width": __props.showAutoSelectToggle ? 320 : void 0,
759
- onSelect: _cache[2] || (_cache[2] = ($event) => toggleModel($event.id))
894
+ onSelect: _cache[4] || (_cache[4] = ($event) => toggleModel($event.id))
760
895
  }), null, 16, ["value", "multiple", "toggle-header", "trigger-label", "menu-label", "disabled", "panel-width"])) : createCommentVNode("", true),
761
896
  view.value.showAspectRatio && view.value.aspectOptions.length > 0 && props["onUpdate:aspectRatio"] ? (openBlock(), createBlock(_sfc_main$d, {
762
897
  key: 2,
@@ -767,7 +902,18 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
767
902
  searchable: false,
768
903
  "trigger-variant": "text",
769
904
  disabled: __props.disabled,
770
- onSelect: _cache[3] || (_cache[3] = ($event) => props["onUpdate:aspectRatio"]?.($event.id))
905
+ onSelect: _cache[5] || (_cache[5] = ($event) => props["onUpdate:aspectRatio"]?.($event.id))
906
+ }, null, 8, ["options", "value", "trigger-label", "disabled"])) : createCommentVNode("", true),
907
+ view.value.frameRateOptions.length > 0 && props["onUpdate:frameRate"] ? (openBlock(), createBlock(_sfc_main$d, {
908
+ key: 3,
909
+ options: view.value.frameRateOptions.map((r) => ({ id: String(r), label: `${r}fps` })),
910
+ value: view.value.offeredFrameRate == null ? null : String(view.value.offeredFrameRate),
911
+ "trigger-label": view.value.offeredFrameRate == null ? "Frame rate" : `${view.value.offeredFrameRate}fps`,
912
+ "menu-label": "Frame rate",
913
+ searchable: false,
914
+ "trigger-variant": "text",
915
+ disabled: __props.disabled,
916
+ onSelect: _cache[6] || (_cache[6] = ($event) => props["onUpdate:frameRate"]?.(Number($event.id)))
771
917
  }, null, 8, ["options", "value", "trigger-label", "disabled"])) : createCommentVNode("", true)
772
918
  ]),
773
919
  createElementVNode("md-fab", {
@@ -782,10 +928,10 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
782
928
  "aria-disabled": view.value.showStop ? "false" : __props.submitting || view.value.isSubmitDisabled ? "true" : "false",
783
929
  onClick: onSubmitClick
784
930
  }, [
785
- createElementVNode("span", _hoisted_16$2, [
931
+ createElementVNode("span", _hoisted_12$3, [
786
932
  view.value.showStop ? (openBlock(), createBlock(unref(StopIcon), { key: 0 })) : __props.submitError ? (openBlock(), createBlock(unref(RetryIcon), { key: 1 })) : (openBlock(), createBlock(unref(ArrowForwardIcon), { key: 2 }))
787
933
  ])
788
- ], 8, _hoisted_15$3)
934
+ ], 8, _hoisted_11$3)
789
935
  ])
790
936
  ]);
791
937
  };
@@ -2477,7 +2623,7 @@ function useMediaAnalyzer(options = {}) {
2477
2623
  };
2478
2624
  }
2479
2625
  export {
2480
- _sfc_main$h as ChaiProvider,
2626
+ _sfc_main$i as ChaiProvider,
2481
2627
  _sfc_main$c as Composer,
2482
2628
  DEFAULT_MAX_ATTACHMENTS_BY_KIND2 as DEFAULT_MAX_ATTACHMENTS_BY_KIND,
2483
2629
  DEFAULT_MAX_REGIONS2 as DEFAULT_MAX_REGIONS,