wizards 0.2.7 → 0.2.8

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.
Files changed (67) hide show
  1. package/apps/runtime/dist/env.js +4 -0
  2. package/apps/runtime/dist/media/generate.js +2 -2
  3. package/apps/runtime/dist/media/transcribe.js +18 -6
  4. package/apps/runtime/dist/models.js +566 -218
  5. package/apps/runtime/dist/routes/studio.js +152 -10
  6. package/apps/web/dist/assets/Account-YJEQEo5k.js +1 -0
  7. package/apps/web/dist/assets/{ChangelogDialog-DEfZRDK3.js → ChangelogDialog-BNQ9yup8.js} +1 -1
  8. package/apps/web/dist/assets/{ChatPanel-CNiFyu_w.js → ChatPanel-CtE1wcUD.js} +1 -1
  9. package/apps/web/dist/assets/{CreditsDialog-CUvc2iPM.js → CreditsDialog-DSjsgLoo.js} +1 -1
  10. package/apps/web/dist/assets/EditorPage-CAxamSak.js +2 -0
  11. package/apps/web/dist/assets/{FlowPreview-BC25OUH0.js → FlowPreview-B3IxmikV.js} +1 -1
  12. package/apps/web/dist/assets/Harness-Bo-kwm1H.js +16 -0
  13. package/apps/web/dist/assets/HomePage-BdIa2zcg.js +1 -0
  14. package/apps/web/dist/assets/ImportWizard-DMea5ZH1.js +1 -0
  15. package/apps/web/dist/assets/LocalRuntime-DFswQjxc.js +1 -0
  16. package/apps/web/dist/assets/NewWizardPage-Cnb6UYme.js +2 -0
  17. package/apps/web/dist/assets/ProjectPage-CR_FIUya.js +2 -0
  18. package/apps/web/dist/assets/{PublicRunner-BCrmXPkr.js → PublicRunner-CIHEMLlN.js} +1 -1
  19. package/apps/web/dist/assets/{ReadOnly-CvmN9XW4.js → ReadOnly-B0-ReU_0.js} +1 -1
  20. package/apps/web/dist/assets/RunnerView-COKGppwq.js +2 -0
  21. package/apps/web/dist/assets/SettingsPage-BqAogRSI.js +1 -0
  22. package/apps/web/dist/assets/SetupPage-Bk4qXYZV.js +1 -0
  23. package/apps/web/dist/assets/{SharePage-BqwqI3Ga.js → SharePage-ChEtCkhn.js} +1 -1
  24. package/apps/web/dist/assets/{api-Bf-l9Sd8.js → api-u3nydnnp.js} +1 -1
  25. package/apps/web/dist/assets/changelog-C03GWYid.js +1 -0
  26. package/apps/web/dist/assets/circle-alert-B76z9TWZ.js +1 -0
  27. package/apps/web/dist/assets/definition-Co2Mg1qo.js +55 -0
  28. package/apps/web/dist/assets/esm-Rtjq9ReB.js +7 -0
  29. package/apps/web/dist/assets/image-BShbErBm.js +1 -0
  30. package/apps/web/dist/assets/index-BAQ2e4is.js +10 -0
  31. package/apps/web/dist/assets/index-CQQD8QNR.css +1 -0
  32. package/apps/web/dist/assets/meta-MVWkLr9H.js +1 -0
  33. package/apps/web/dist/assets/oss-credits-CIxnNZor.js +1 -0
  34. package/apps/web/dist/assets/{outputs-CsESg-Eg.js → outputs-s8BpXH6V.js} +1 -1
  35. package/apps/web/dist/assets/{video-CjgmvRDk.js → pen-line-NK46C_nG.js} +1 -1
  36. package/apps/web/dist/assets/refresh-cw-Cmk7VCe0.js +1 -0
  37. package/apps/web/dist/assets/ui-gGAdXx-P.js +1 -0
  38. package/apps/web/dist/assets/video-DBmwF1Jm.js +1 -0
  39. package/apps/web/dist/assets/volume-2-Bp2tyaKE.js +1 -0
  40. package/apps/web/dist/index.html +4 -7
  41. package/apps/web/dist/mcp/flow.html +2 -2
  42. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +75 -0
  43. package/node_modules/@engenty-wizards/shared/dist/providers.js +339 -0
  44. package/package.json +5 -1
  45. package/apps/web/dist/assets/Account-DLLeEwJL.js +0 -1
  46. package/apps/web/dist/assets/EditorPage-CZuCz7lB.js +0 -2
  47. package/apps/web/dist/assets/HomePage-DQKuhMFZ.js +0 -1
  48. package/apps/web/dist/assets/ImportWizard-BockXJXm.js +0 -1
  49. package/apps/web/dist/assets/LocalRuntime-C199bg_B.js +0 -16
  50. package/apps/web/dist/assets/NewWizardPage-C4cde8FO.js +0 -2
  51. package/apps/web/dist/assets/ProjectPage-DJC1K4w_.js +0 -2
  52. package/apps/web/dist/assets/RunnerView-CCe8-k9Q.js +0 -2
  53. package/apps/web/dist/assets/SettingsPage-BuocMkLt.js +0 -1
  54. package/apps/web/dist/assets/SetupPage-o6Jim2Pu.js +0 -1
  55. package/apps/web/dist/assets/changelog-CFeEzKqb.js +0 -1
  56. package/apps/web/dist/assets/cloud-off-D--dZLDw.js +0 -1
  57. package/apps/web/dist/assets/definition-DndaH5Ow.js +0 -55
  58. package/apps/web/dist/assets/esm-rJY59Ixx.js +0 -7
  59. package/apps/web/dist/assets/globe-ffVj8XwO.js +0 -1
  60. package/apps/web/dist/assets/index-B8n2AYO0.css +0 -1
  61. package/apps/web/dist/assets/index-BR5ELbeZ.js +0 -10
  62. package/apps/web/dist/assets/meta-CKE9QceT.js +0 -1
  63. package/apps/web/dist/assets/oss-credits-C-U2Tlpn.js +0 -1
  64. package/apps/web/dist/assets/react-dom-DenslgJm.js +0 -1
  65. package/apps/web/dist/assets/session-C7LDDcj7.js +0 -1
  66. package/apps/web/dist/assets/ui-BT0Y_Hci.js +0 -1
  67. /package/apps/web/dist/assets/{LocalRuntime-BrP-ENHg.css → Harness-BrP-ENHg.css} +0 -0
@@ -0,0 +1,75 @@
1
+ import type { ModelClass, TextClass } from "./definition.js";
2
+ /**
3
+ * What a wizard asks models for, as a person thinks of it. Each stands for model classes; the
4
+ * names are the marketplace's capabilities.
5
+ */
6
+ export declare const MODEL_CAPABILITIES: readonly ["text", "image", "video", "speech", "listening"];
7
+ export type ModelCapability = (typeof MODEL_CAPABILITIES)[number];
8
+ export declare const CAPABILITY_CLASSES: Record<ModelCapability, readonly ModelClass[]>;
9
+ export declare function capabilityOf(cls: ModelClass): ModelCapability;
10
+ /**
11
+ * A binding that sends a class to the credits of the account (or of the team in the cloud),
12
+ * whatever keys are there; engenty picks the model. `credits:<model>` names the model, as the
13
+ * gateway lists it (`fal:fal-ai/flux/schnell`, `elevenlabs:eleven_multilingual_v2`,
14
+ * `google/veo-3.1-fast-generate-001`).
15
+ */
16
+ export declare const CREDITS = "credits";
17
+ /** A binding to the credits: the class's model (`credits`) or a model named (`credits:<id>`). */
18
+ export declare function isCreditsRef(ref: string | undefined): boolean;
19
+ /** The model a credits binding names; null where engenty picks it. */
20
+ export declare function creditsModelOf(ref: string | undefined): string | null;
21
+ export declare function creditsRef(model: string | null): string;
22
+ /** A media model the credits pay for, as the model-gateway lists it (`/v1/models`, `models`). */
23
+ export interface CreditModel {
24
+ id: string;
25
+ name: string;
26
+ /** Who serves it: `ai-gateway`, `fal`, `elevenlabs`. */
27
+ source: string;
28
+ /** Who made it: `google`, `bfl`, `fal`, `elevenlabs` … */
29
+ provider: string;
30
+ kind: "image" | "video" | "speech" | "transcription";
31
+ creditsPerImage?: number;
32
+ creditsPerSecond?: number;
33
+ creditsPer1kCharacters?: number;
34
+ creditsPerMinute?: number;
35
+ }
36
+ /** The capability a credit model serves. */
37
+ export declare function capabilityOfKind(kind: CreditModel["kind"]): ModelCapability;
38
+ /** The providers whose API key a person can bring. */
39
+ export declare const PROVIDER_IDS: readonly ["openai", "anthropic", "google", "fal", "elevenlabs", "replicate", "gateway"];
40
+ export type ProviderId = (typeof PROVIDER_IDS)[number];
41
+ interface Labels {
42
+ de: string;
43
+ en: string;
44
+ }
45
+ export interface ModelOption {
46
+ /** The binding: `<provider>:<the provider's model id>`. */
47
+ ref: string;
48
+ /** The model's own name; not translated. */
49
+ label: string;
50
+ note?: Labels;
51
+ }
52
+ export interface ProviderInfo {
53
+ id: ProviderId;
54
+ name: string;
55
+ /** One line on what it is, for someone who never heard of it. */
56
+ about: Labels;
57
+ /** Where a person makes a key. */
58
+ keyUrl: string;
59
+ /** How a key looks, for the input's placeholder. */
60
+ keyPlaceholder: string;
61
+ /** The models offered per capability, the first one is taken when the provider is picked. */
62
+ models: Partial<Record<ModelCapability, ModelOption[]>>;
63
+ /** For text: the model of each class when this provider thinks. */
64
+ text?: Record<TextClass, string>;
65
+ }
66
+ export declare const PROVIDERS: readonly ProviderInfo[];
67
+ export declare function providerInfo(id: string): ProviderInfo | null;
68
+ /**
69
+ * The provider a binding goes to: `fal:…` names it, a binding without one (`google/veo-…`) goes
70
+ * through the AI Gateway. Null for an installed client (`codex/…`), a local model and credits.
71
+ */
72
+ export declare function providerOfRef(ref: string): ProviderId | null;
73
+ /** The name of a bound model as a person reads it: the offered label, else the provider's id. */
74
+ export declare function modelLabel(ref: string): string;
75
+ export {};
@@ -0,0 +1,339 @@
1
+ /**
2
+ * What a wizard asks models for, as a person thinks of it. Each stands for model classes; the
3
+ * names are the marketplace's capabilities.
4
+ */
5
+ export const MODEL_CAPABILITIES = ["text", "image", "video", "speech", "listening"];
6
+ export const CAPABILITY_CLASSES = {
7
+ text: ["classifier", "standard", "high", "highest"],
8
+ image: ["image"],
9
+ video: ["video"],
10
+ speech: ["speech"],
11
+ listening: ["audio"],
12
+ };
13
+ export function capabilityOf(cls) {
14
+ return Object.keys(CAPABILITY_CLASSES).find((c) => CAPABILITY_CLASSES[c].includes(cls));
15
+ }
16
+ /**
17
+ * A binding that sends a class to the credits of the account (or of the team in the cloud),
18
+ * whatever keys are there; engenty picks the model. `credits:<model>` names the model, as the
19
+ * gateway lists it (`fal:fal-ai/flux/schnell`, `elevenlabs:eleven_multilingual_v2`,
20
+ * `google/veo-3.1-fast-generate-001`).
21
+ */
22
+ export const CREDITS = "credits";
23
+ const CREDITS_PREFIX = `${CREDITS}:`;
24
+ /** A binding to the credits: the class's model (`credits`) or a model named (`credits:<id>`). */
25
+ export function isCreditsRef(ref) {
26
+ return ref === CREDITS || Boolean(ref?.startsWith(CREDITS_PREFIX));
27
+ }
28
+ /** The model a credits binding names; null where engenty picks it. */
29
+ export function creditsModelOf(ref) {
30
+ return ref?.startsWith(CREDITS_PREFIX) ? ref.slice(CREDITS_PREFIX.length) || null : null;
31
+ }
32
+ export function creditsRef(model) {
33
+ return model ? `${CREDITS_PREFIX}${model}` : CREDITS;
34
+ }
35
+ /** The capability a credit model serves. */
36
+ export function capabilityOfKind(kind) {
37
+ return kind === "transcription" ? "listening" : kind;
38
+ }
39
+ /** The providers whose API key a person can bring. */
40
+ export const PROVIDER_IDS = [
41
+ "openai",
42
+ "anthropic",
43
+ "google",
44
+ "fal",
45
+ "elevenlabs",
46
+ "replicate",
47
+ "gateway",
48
+ ];
49
+ const note = (de, en) => ({ de, en });
50
+ export const PROVIDERS = [
51
+ {
52
+ id: "openai",
53
+ name: "OpenAI",
54
+ about: note("GPT-Modelle, GPT Image und Stimmen.", "GPT models, GPT Image and voices."),
55
+ keyUrl: "https://platform.openai.com/api-keys",
56
+ keyPlaceholder: "sk-…",
57
+ text: {
58
+ classifier: "openai:gpt-5.4-mini",
59
+ standard: "openai:gpt-5.4-mini",
60
+ high: "openai:gpt-5.5",
61
+ highest: "openai:gpt-5.5",
62
+ },
63
+ models: {
64
+ text: [
65
+ { ref: "openai:gpt-5.4-mini", label: "GPT-5.4 mini", note: note("schnell", "fast") },
66
+ { ref: "openai:gpt-5.5", label: "GPT-5.5", note: note("gründlich", "thorough") },
67
+ ],
68
+ image: [
69
+ { ref: "openai:gpt-image-2", label: "GPT Image 2", note: note("vielseitig", "versatile") },
70
+ {
71
+ ref: "openai:gpt-image-1-mini",
72
+ label: "GPT Image 1 mini",
73
+ note: note("günstig", "low cost"),
74
+ },
75
+ ],
76
+ speech: [
77
+ {
78
+ ref: "openai:gpt-4o-mini-tts",
79
+ label: "GPT-4o mini TTS",
80
+ note: note("günstig", "low cost"),
81
+ },
82
+ ],
83
+ listening: [
84
+ {
85
+ ref: "openai:gpt-4o-mini-transcribe",
86
+ label: "GPT-4o mini Transcribe",
87
+ note: note("schnell, günstig", "fast, low cost"),
88
+ },
89
+ { ref: "openai:whisper-1", label: "Whisper" },
90
+ ],
91
+ },
92
+ },
93
+ {
94
+ id: "anthropic",
95
+ name: "Anthropic",
96
+ about: note("Die Claude-Modelle.", "The Claude models."),
97
+ keyUrl: "https://console.anthropic.com/settings/keys",
98
+ keyPlaceholder: "sk-ant-…",
99
+ text: {
100
+ classifier: "anthropic:claude-haiku-4-5",
101
+ standard: "anthropic:claude-haiku-4-5",
102
+ high: "anthropic:claude-sonnet-5-5",
103
+ highest: "anthropic:claude-opus-5-5",
104
+ },
105
+ models: {
106
+ text: [
107
+ {
108
+ ref: "anthropic:claude-haiku-4-5",
109
+ label: "Claude Haiku 4.5",
110
+ note: note("schnell", "fast"),
111
+ },
112
+ { ref: "anthropic:claude-sonnet-5-5", label: "Claude Sonnet 5.5" },
113
+ {
114
+ ref: "anthropic:claude-opus-5-5",
115
+ label: "Claude Opus 5.5",
116
+ note: note("am stärksten", "strongest"),
117
+ },
118
+ ],
119
+ },
120
+ },
121
+ {
122
+ id: "google",
123
+ name: "Google Gemini",
124
+ about: note("Gemini, Veo für Videos und Stimmen – ein Key aus dem AI Studio.", "Gemini, Veo for video and voices – one key from AI Studio."),
125
+ keyUrl: "https://aistudio.google.com/apikey",
126
+ keyPlaceholder: "AIza…",
127
+ text: {
128
+ classifier: "google:gemini-flash-lite-latest",
129
+ standard: "google:gemini-flash-latest",
130
+ high: "google:gemini-pro-latest",
131
+ highest: "google:gemini-pro-latest",
132
+ },
133
+ models: {
134
+ text: [
135
+ {
136
+ ref: "google:gemini-flash-lite-latest",
137
+ label: "Gemini Flash-Lite",
138
+ note: note("günstig", "low cost"),
139
+ },
140
+ { ref: "google:gemini-flash-latest", label: "Gemini Flash" },
141
+ {
142
+ ref: "google:gemini-pro-latest",
143
+ label: "Gemini Pro",
144
+ note: note("gründlich", "thorough"),
145
+ },
146
+ ],
147
+ image: [
148
+ {
149
+ ref: "google:gemini-3.1-flash-image-preview",
150
+ label: "Gemini 3.1 Flash Image",
151
+ note: note("schnell, bearbeitet Fotos", "fast, edits photos"),
152
+ },
153
+ {
154
+ ref: "google:gemini-3-pro-image-preview",
155
+ label: "Gemini 3 Pro Image",
156
+ note: note("beste Qualität", "best quality"),
157
+ },
158
+ ],
159
+ video: [
160
+ {
161
+ ref: "google:veo-3.1-fast-generate-preview",
162
+ label: "Veo 3.1 Fast",
163
+ note: note("mit Ton", "with sound"),
164
+ },
165
+ {
166
+ ref: "google:veo-3.1-generate-preview",
167
+ label: "Veo 3.1",
168
+ note: note("beste Qualität", "best quality"),
169
+ },
170
+ ],
171
+ speech: [{ ref: "google:gemini-3.8-flash-tts", label: "Gemini Flash TTS" }],
172
+ listening: [{ ref: "google:gemini-flash-lite-latest", label: "Gemini Flash-Lite" }],
173
+ },
174
+ },
175
+ {
176
+ id: "fal",
177
+ name: "fal.ai",
178
+ about: note("Hunderte Bild-, Video- und Audio-Modelle mit einem Key: FLUX, Recraft, Veo, Luma, MiniMax.", "Hundreds of image, video and audio models with one key: FLUX, Recraft, Veo, Luma, MiniMax."),
179
+ keyUrl: "https://fal.ai/dashboard/keys",
180
+ keyPlaceholder: "xxxxxxxx-…:…",
181
+ models: {
182
+ image: [
183
+ {
184
+ ref: "fal:fal-ai/flux/schnell",
185
+ label: "FLUX.1 schnell",
186
+ note: note("schnell, günstig", "fast, low cost"),
187
+ },
188
+ {
189
+ ref: "fal:fal-ai/flux-pro/v1.1",
190
+ label: "FLUX 1.1 pro",
191
+ note: note("hohe Qualität", "high quality"),
192
+ },
193
+ {
194
+ ref: "fal:fal-ai/recraft/v3/text-to-image",
195
+ label: "Recraft V3",
196
+ note: note("Grafiken, Logos, Text im Bild", "graphics, logos, text in images"),
197
+ },
198
+ {
199
+ ref: "fal:fal-ai/imagen4/preview",
200
+ label: "Imagen 4",
201
+ note: note("fotorealistisch", "photorealistic"),
202
+ },
203
+ ],
204
+ video: [
205
+ { ref: "fal:veo3/fast", label: "Veo 3 Fast", note: note("mit Ton", "with sound") },
206
+ { ref: "fal:luma-ray-2-flash", label: "Luma Ray 2 Flash", note: note("schnell", "fast") },
207
+ { ref: "fal:minimax-video", label: "MiniMax Hailuo" },
208
+ ],
209
+ speech: [
210
+ {
211
+ ref: "fal:fal-ai/minimax/speech-02-turbo",
212
+ label: "MiniMax Speech-02 Turbo",
213
+ note: note("schnell", "fast"),
214
+ },
215
+ { ref: "fal:fal-ai/minimax/speech-02-hd", label: "MiniMax Speech-02 HD" },
216
+ ],
217
+ listening: [
218
+ { ref: "fal:wizper", label: "Wizper", note: note("schnell", "fast") },
219
+ { ref: "fal:whisper", label: "Whisper" },
220
+ ],
221
+ },
222
+ },
223
+ {
224
+ id: "elevenlabs",
225
+ name: "ElevenLabs",
226
+ about: note("Natürliche Stimmen in vielen Sprachen und genaue Transkripte.", "Natural voices in many languages and accurate transcripts."),
227
+ keyUrl: "https://elevenlabs.io/app/settings/api-keys",
228
+ keyPlaceholder: "sk_…",
229
+ models: {
230
+ speech: [
231
+ {
232
+ ref: "elevenlabs:eleven_multilingual_v2",
233
+ label: "Multilingual v2",
234
+ note: note("natürlich, viele Sprachen", "natural, many languages"),
235
+ },
236
+ {
237
+ ref: "elevenlabs:eleven_flash_v2_5",
238
+ label: "Flash v2.5",
239
+ note: note("schnell, günstig", "fast, low cost"),
240
+ },
241
+ {
242
+ ref: "elevenlabs:eleven_v3",
243
+ label: "Eleven v3",
244
+ note: note("ausdrucksstark", "expressive"),
245
+ },
246
+ ],
247
+ listening: [
248
+ {
249
+ ref: "elevenlabs:scribe_v2",
250
+ label: "Scribe v2",
251
+ note: note("sehr genau", "very accurate"),
252
+ },
253
+ ],
254
+ },
255
+ },
256
+ {
257
+ id: "replicate",
258
+ name: "Replicate",
259
+ about: note("Offene Bild- und Video-Modelle, abgerechnet pro Lauf.", "Open image and video models, billed per run."),
260
+ keyUrl: "https://replicate.com/account/api-tokens",
261
+ keyPlaceholder: "r8_…",
262
+ models: {
263
+ image: [
264
+ {
265
+ ref: "replicate:black-forest-labs/flux-schnell",
266
+ label: "FLUX.1 schnell",
267
+ note: note("schnell, günstig", "fast, low cost"),
268
+ },
269
+ { ref: "replicate:black-forest-labs/flux-1.1-pro", label: "FLUX 1.1 pro" },
270
+ { ref: "replicate:recraft-ai/recraft-v3", label: "Recraft V3" },
271
+ ],
272
+ video: [{ ref: "replicate:minimax/video-01", label: "MiniMax Video-01" }],
273
+ },
274
+ },
275
+ {
276
+ id: "gateway",
277
+ name: "Vercel AI Gateway",
278
+ about: note("Ein Key für die Modelle vieler Anbieter, abgerechnet bei Vercel.", "One key for many providers' models, billed by Vercel."),
279
+ keyUrl: "https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai-gateway%2Fapi-keys",
280
+ keyPlaceholder: "vck_…",
281
+ text: {
282
+ classifier: "anthropic/claude-haiku-4.5",
283
+ standard: "anthropic/claude-haiku-4.5",
284
+ high: "anthropic/claude-sonnet-5.5",
285
+ highest: "anthropic/claude-sonnet-5.5",
286
+ },
287
+ models: {
288
+ text: [
289
+ {
290
+ ref: "anthropic/claude-haiku-4.5",
291
+ label: "Claude Haiku 4.5",
292
+ note: note("schnell", "fast"),
293
+ },
294
+ { ref: "anthropic/claude-sonnet-5.5", label: "Claude Sonnet 5.5" },
295
+ { ref: "openai/gpt-5.5", label: "GPT-5.5" },
296
+ { ref: "google/gemini-3.5-flash", label: "Gemini 3.5 Flash" },
297
+ ],
298
+ image: [{ ref: "google/gemini-3.1-flash-image", label: "Gemini 3.1 Flash Image" }],
299
+ video: [
300
+ {
301
+ ref: "google/veo-3.1-fast-generate-001",
302
+ label: "Veo 3.1 Fast",
303
+ note: note("mit Ton", "with sound"),
304
+ },
305
+ ],
306
+ speech: [{ ref: "google/gemini-3.8-flash-tts", label: "Gemini Flash TTS" }],
307
+ listening: [{ ref: "google/gemini-3.5-flash-lite", label: "Gemini 3.5 Flash-Lite" }],
308
+ },
309
+ },
310
+ ];
311
+ export function providerInfo(id) {
312
+ return PROVIDERS.find((p) => p.id === id) ?? null;
313
+ }
314
+ /**
315
+ * The provider a binding goes to: `fal:…` names it, a binding without one (`google/veo-…`) goes
316
+ * through the AI Gateway. Null for an installed client (`codex/…`), a local model and credits.
317
+ */
318
+ export function providerOfRef(ref) {
319
+ if (isCreditsRef(ref)) {
320
+ return null;
321
+ }
322
+ const prefix = /^([a-z]+):/.exec(ref)?.[1];
323
+ if (prefix) {
324
+ return PROVIDER_IDS.includes(prefix) ? prefix : null;
325
+ }
326
+ return ref?.includes("/") ? "gateway" : null;
327
+ }
328
+ /** The name of a bound model as a person reads it: the offered label, else the provider's id. */
329
+ export function modelLabel(ref) {
330
+ for (const p of PROVIDERS) {
331
+ for (const list of Object.values(p.models)) {
332
+ const hit = list?.find((m) => m.ref === ref);
333
+ if (hit) {
334
+ return hit.label;
335
+ }
336
+ }
337
+ }
338
+ return ref.replace(/^[a-z]+:/, "");
339
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Make a wish. Get your wizard. It guides you step by step. Let AI do the work. Runs on your machine, on the AI subscription you already have.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "homepage": "https://engenty.ai",
@@ -23,8 +23,12 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@ai-sdk/anthropic": "4.0.54",
26
+ "@ai-sdk/elevenlabs": "3.0.42",
27
+ "@ai-sdk/fal": "3.0.42",
26
28
  "@ai-sdk/gateway": "4.0.82",
29
+ "@ai-sdk/google": "4.0.72",
27
30
  "@ai-sdk/openai": "4.0.67",
31
+ "@ai-sdk/replicate": "3.0.42",
28
32
  "@clack/prompts": "1.8.1",
29
33
  "@engenty-wizards/plugin-sdk": "0.1.0",
30
34
  "@engenty-wizards/shared": "0.1.0",
@@ -1 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,j as i,n as a,nt as o}from"./api-Bf-l9Sd8.js";import{f as s,t as c}from"./session-C7LDDcj7.js";import{t as l}from"./createLucideIcon-q3MZMmnf.js";import{t as u}from"./check-CUpby_J9.js";import{n as d,r as f}from"./upload-DNRENWzQ.js";import{t as p}from"./external-link-MAL7vJYj.js";import{_ as m,c as h,d as g,h as _,m as ee,n as v,o as y,r as b,s as x,t as S,y as C}from"./ui-BT0Y_Hci.js";import{_ as w,b as T,c as E,d as D,i as O,u as k}from"./index-BR5ELbeZ.js";import{r as A}from"./LocalRuntime-C199bg_B.js";var j={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};j.node;var M=l(j),N={name:`layout-grid`,size:24,node:[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]};N.node;var P=l(N),F={name:`list`,size:24,node:[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]};F.node;var I=l(F),L=e(t(),1),R=e=>[`project-files`,e];function z(e){return i({queryKey:R(e),queryFn:()=>a.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function B(e,t){return r(`/api/studio/projects/${e}/files/${t}/content`)}function V(e,t=!1){let n=o(),[r,i]=(0,L.useState)(!1),[s,c]=(0,L.useState)(null),l=()=>n.invalidateQueries({queryKey:R(e)}),u=async e=>{c(null);try{await e()}catch(e){c(e.message)}finally{await l()}};return{busy:r,error:s,readOnly:t,upload:async(t,n)=>{i(!0),await u(async()=>{for(let r of n)await a.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await l()}),i(!1)},describe:(t,n)=>u(()=>a.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>u(()=>a.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>u(()=>a.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>u(()=>a.put(`/api/studio/projects/${e}/files/order`,{kind:t,ids:n}))}}function H(e,t){let n=`wz.layout.${e}`,[r,i]=(0,L.useState)(()=>{try{let e=localStorage.getItem(n);return e===`list`||e===`cards`?e:t}catch{return t}});return[r,()=>i(e=>{let t=e===`list`?`cards`:`list`;try{localStorage.setItem(n,t)}catch{}return t})]}function U(e,t,n=700){let[r,i]=(0,L.useState)(`idle`),[a,o]=(0,L.useState)(null),s=JSON.stringify(e),c=(0,L.useRef)(s),l=(0,L.useRef)({value:e,json:s,save:t});l.current={value:e,json:s,save:t};let u=(0,L.useRef)(Promise.resolve()),d=(0,L.useCallback)(()=>{let e=l.current;e.json!==c.current&&(c.current=e.json,i(`saving`),u.current=u.current.then(async()=>{try{await e.save(e.value),o(null),i(`saved`)}catch(e){c.current=``,o(e.message),i(`error`)}}))},[]);return(0,L.useEffect)(()=>{if(s===c.current)return;let e=setTimeout(d,n);return()=>clearTimeout(e)},[s,n,d]),(0,L.useEffect)(()=>d,[d]),{state:r,error:a}}function W(e){return e<1e6?`${Math.max(1,Math.round(e/1e3))} KB`:`${(e/1e6).toFixed(1)} MB`}var G=e(n(),1);function K({title:e,hint:t,save:n,action:r,locked:i,children:a}){return(0,G.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-start justify-between gap-4 px-1`,children:[(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsx)(`h2`,{className:`font-display font-semibold text-lg leading-tight`,children:e}),n?.state===`saving`?(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[12px] text-ink-3`,children:[(0,G.jsx)(g,{className:`size-3`}),` `,C(`project.saving`)]}):n?.state===`saved`?(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[12px] text-moss`,children:[(0,G.jsx)(u,{className:`size-3.5`}),` `,C(`settings.saved`)]}):null]}),t?(0,G.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-snug`,children:t}):null]}),r?(0,G.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),(0,G.jsxs)(v,{className:`p-5`,children:[i?(0,G.jsx)(`fieldset`,{disabled:!0,className:`min-w-0`,children:a}):a,n?.state===`error`&&n.error?(0,G.jsx)(`p`,{className:`mt-4 text-[14px] text-rose`,children:n.error}):null]})]})}function q({children:e,layout:t,onToggle:n}){return(0,G.jsxs)(`div`,{className:`mb-3 flex items-start gap-2`,children:[(0,G.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,G.jsx)(`div`,{className:`w-56 max-w-full transition-[width] duration-200 focus-within:w-full has-[input:not(:placeholder-shown)]:w-full`,children:e})}),(0,G.jsx)(y,{label:C(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,G.jsx)(P,{className:`size-4`}):(0,G.jsx)(I,{className:`size-4`})})]})}function J({value:e,onChange:t,onEnter:n,placeholder:r,busy:i}){return(0,G.jsxs)(`div`,{className:`relative`,children:[(0,G.jsx)(d,{className:`-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 size-4 text-ink-4`}),(0,G.jsx)(`input`,{type:`search`,value:e,placeholder:r,onChange:e=>t(e.target.value),onKeyDown:e=>e.key===`Enter`&&n?.(),className:`h-9 w-full rounded-lg border border-input bg-card pr-3 pl-9 text-[14px] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,G.jsx)(g,{className:`-translate-y-1/2 absolute top-1/2 right-3 size-4 text-ink-3`}):null]})}function Y({onFiles:e,accept:t,multiple:n=!0,className:r,children:i}){return(0,G.jsxs)(`label`,{onDragOver:e=>{e.preventDefault(),e.currentTarget.dataset.over=`1`},onDragLeave:e=>{delete e.currentTarget.dataset.over},onDrop:t=>{t.preventDefault(),delete t.currentTarget.dataset.over;let r=Array.from(t.dataTransfer.files);r.length&&e(n?r:r.slice(0,1))},className:_(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[14px] text-ink-3 transition focus-within:border-focus focus-within:ring-4 focus-within:ring-focus-glow hover:border-ink-4 hover:text-ink data-[over]:border-focus data-[over]:bg-paper-2 data-[over]:text-ink`,r),children:[i,(0,G.jsx)(`input`,{className:`sr-only`,type:`file`,accept:t,multiple:n,onChange:t=>{let n=Array.from(t.target.files??[]);t.target.value=``,n.length&&e(n)}})]})}var X=`mt-1.5 text-[13px] text-ink-3`;function Z(e){let t=o(),[n,r]=(0,L.useState)(!1),i=s({mutationFn:e=>a.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{A(e),r(!0)}});return(0,L.useEffect)(()=>{if(!n)return;let e=setInterval(()=>void t.invalidateQueries({queryKey:[`me`]}),2e3),i=setTimeout(()=>r(!1),3e5);return()=>{clearInterval(e),clearTimeout(i)}},[n,t]),(0,L.useEffect)(()=>{e&&r(!1)},[e]),{link:i,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,G.jsx)(`p`,{className:`text-[13px] text-rose`,children:C(`local.accountFailed`)}):t?(0,G.jsxs)(`p`,{className:`flex items-center gap-2 text-[13px] text-ink-3`,children:[(0,G.jsx)(g,{className:`size-3.5`}),` `,C(`local.accountWaiting`)]}):null}function te(){let e=Z(!1),{link:t}=e,[n,r]=(0,L.useState)(``);return(0,G.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,G.jsxs)(`div`,{className:`flex items-start gap-4 py-5 first:pt-0 last:pb-0`,children:[(0,G.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-full bg-paper-2 text-ink-2`,children:(0,G.jsx)(M,{className:`size-5`})}),(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`font-medium text-[15px]`,children:C(`account.local`)}),(0,G.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:C(`account.localText`)})]})]}),D.account?(0,G.jsxs)(`div`,{className:`flex flex-col gap-4 py-5 last:pb-0`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`font-medium text-[15px]`,children:C(`account.with`)}),(0,G.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[14px] text-ink-2 leading-snug`,children:[(0,G.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,G.jsx)(f,{className:`mt-0.5 size-4 shrink-0 text-amber`}),C(`account.withCredits`)]}),(0,G.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,G.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),C(`account.withCloud`)]})]})]}),(0,G.jsx)(`div`,{children:(0,G.jsx)(S,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:C(`account.signIn`)})})]}):null,D.account?(0,G.jsxs)(`form`,{className:`flex flex-col gap-3 py-5 last:pb-0`,onSubmit:e=>{e.preventDefault(),t.mutate({signup:!0,code:n.trim()||void 0})},children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`font-medium text-[15px]`,children:C(`account.new`)}),(0,G.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:C(`account.newHint`)})]}),(0,G.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,G.jsx)(x,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:C(`account.code`),"aria-label":C(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[14px]`}),(0,G.jsx)(S,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:C(`account.create`)})]}),(0,G.jsx)(Q,{...e})]}):null]})}var $={start:`account.kind.start`,monthly:`account.kind.monthly`,gift:`account.kind.gift`};function ne({account:e}){let t=o(),n=Z(e.signedIn),r=s({mutationFn:()=>a.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),i=new Intl.DateTimeFormat(m,{dateStyle:`medium`});return(0,G.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3 py-5 first:pt-0`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium text-[15px]`,children:e.name||e.email}),e.signedIn?(0,G.jsx)(b,{tone:`live`,children:C(`account.linked`)}):null]}),(0,G.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.email})]}),(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,G.jsxs)(S,{variant:`secondary`,onClick:()=>A(e.url),children:[C(`setup.openAccount`),` `,(0,G.jsx)(p,{className:`size-4`})]}),(0,G.jsxs)(S,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,G.jsx)(w,{className:`size-4`}),` `,C(`nav.logout`)]})]})]}),e.signedIn?null:(0,G.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,G.jsx)(`p`,{className:`text-[14px] text-ink-2`,children:C(`local.accountExpired`)}),(0,G.jsx)(`div`,{children:(0,G.jsx)(S,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:C(`account.signInAgain`)})}),(0,G.jsx)(Q,{...n})]}),e.credits===null?null:(0,G.jsxs)(`div`,{className:`py-5`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsx)(`div`,{className:`text-[13px] text-ink-3`,children:C(`account.credits`)}),(0,G.jsx)(`div`,{className:`font-display font-semibold text-[22px] tabular-nums leading-tight`,children:C(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,G.jsxs)(S,{variant:`secondary`,onClick:()=>A(`${e.url}/billing`),children:[C(`account.topUp`),` `,(0,G.jsx)(p,{className:`size-4`})]})]}),e.expiring.length?(0,G.jsx)(`ul`,{className:`mt-3 flex flex-col gap-1 text-[13px] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,G.jsxs)(`li`,{children:[C(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:i.format(new Date(e.expiresAt))}),$[e.kind]?(0,G.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,C($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,G.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[14px] text-ink-2 leading-snug last:pb-0`,children:[(0,G.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,G.jsx)(`p`,{children:C(`account.cloud`,{host:O(e.cloudUrl)})})]})]})}function re({me:e,fromAccount:t}){let n=o(),[r,i]=(0,L.useState)(e.profile),s=e=>i(t=>({...t,...e})),l=U(r,async e=>{await a.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,G.jsx)(K,{title:C(`account.profile`),hint:C(`account.hint`),save:l,children:(0,G.jsxs)(`div`,{className:`flex flex-col gap-6 sm:flex-row sm:gap-8`,children:[(0,G.jsxs)(`div`,{className:`flex shrink-0 flex-col items-center gap-2 sm:w-32`,children:[(0,G.jsx)(`div`,{className:`flex size-20 items-center justify-center overflow-hidden rounded-full bg-ember-tint font-semibold text-[28px] text-ember-strong ring-1 ring-border-soft`,children:e.user.image?(0,G.jsx)(`img`,{src:e.user.image,alt:``,className:`size-full object-cover`}):c(r.name)||`?`}),(0,G.jsx)(`p`,{className:`text-center text-[12px] text-ink-3 leading-snug`,children:C(`account.initials`)})]}),(0,G.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-5`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(h,{children:C(`account.name`)}),(0,G.jsx)(x,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,G.jsx)(`p`,{className:X,children:C(t?`account.fromAccount`:`account.nameHint`)})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(h,{children:C(`account.about`)}),(0,G.jsx)(ee,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,G.jsx)(`p`,{className:X,children:C(`account.aboutHint`)})]}),(0,G.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(h,{children:C(`account.email`)}),(0,G.jsx)(x,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(h,{children:C(`account.phone`)}),(0,G.jsx)(x,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>s({phone:e.target.value})})]})]})]})]})})}function ie({me:e}){let t=e.mode===`managed`,n=t||!!e.account;return(0,G.jsxs)(`div`,{className:`flex flex-col gap-9`,children:[(0,G.jsx)(K,{title:C(`account.connection`),hint:C(`account.connectionHint`),children:t?(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`truncate font-medium text-[15px]`,children:e.user.name}),(0,G.jsx)(b,{tone:`live`,children:C(`account.linked`)})]}),(0,G.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,G.jsxs)(S,{variant:`secondary`,onClick:()=>A(`${e.manageUrl}/account`),children:[C(`setup.openAccount`),` `,(0,G.jsx)(p,{className:`size-4`})]}):null]}):e.account?(0,G.jsx)(ne,{account:e.account}):(0,G.jsx)(te,{})}),(0,G.jsx)(re,{me:e,fromAccount:n},n?`account`:`own`),(0,G.jsx)(K,{title:C(`account.look`),hint:C(`account.lookHint`),children:(0,G.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pb-4`,children:[(0,G.jsx)(`span`,{className:`font-medium text-[14px]`,children:C(`nav.language`)}),(0,G.jsx)(k,{tone:`surface`})]}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pt-4`,children:[(0,G.jsx)(`span`,{className:`font-medium text-[14px]`,children:C(`nav.theme`)}),(0,G.jsx)(E,{})]})]})})]})}export{q as a,W as c,V as d,H as f,Y as i,B as l,Q as n,J as o,z as p,Z as r,K as s,ie as t,U as u};