ugly-app 0.1.105 → 0.1.106

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 (29) hide show
  1. package/dist/cli/version.d.ts +1 -1
  2. package/dist/cli/version.js +1 -1
  3. package/dist/server/ai/ImageGenFactory.d.ts +7 -4
  4. package/dist/server/ai/ImageGenFactory.d.ts.map +1 -1
  5. package/dist/server/ai/ImageGenFactory.js +54 -39
  6. package/dist/server/ai/ImageGenFactory.js.map +1 -1
  7. package/dist/server/ai/providers/FAL.d.ts.map +1 -1
  8. package/dist/server/ai/providers/FAL.js +16 -6
  9. package/dist/server/ai/providers/FAL.js.map +1 -1
  10. package/dist/server/ai/providers/GoogleImage.d.ts.map +1 -1
  11. package/dist/server/ai/providers/GoogleImage.js +7 -2
  12. package/dist/server/ai/providers/GoogleImage.js.map +1 -1
  13. package/dist/server/ai/providers/KieImage.d.ts.map +1 -1
  14. package/dist/server/ai/providers/KieImage.js +7 -2
  15. package/dist/server/ai/providers/KieImage.js.map +1 -1
  16. package/dist/server/ai/providers/TogetherImage.d.ts.map +1 -1
  17. package/dist/server/ai/providers/TogetherImage.js +8 -1
  18. package/dist/server/ai/providers/TogetherImage.js.map +1 -1
  19. package/dist/server/ai/providers/Wavespeed.d.ts.map +1 -1
  20. package/dist/server/ai/providers/Wavespeed.js +8 -2
  21. package/dist/server/ai/providers/Wavespeed.js.map +1 -1
  22. package/package.json +1 -1
  23. package/src/cli/version.ts +1 -1
  24. package/src/server/ai/ImageGenFactory.ts +75 -45
  25. package/src/server/ai/providers/FAL.ts +22 -6
  26. package/src/server/ai/providers/GoogleImage.ts +10 -2
  27. package/src/server/ai/providers/KieImage.ts +11 -2
  28. package/src/server/ai/providers/TogetherImage.ts +13 -1
  29. package/src/server/ai/providers/Wavespeed.ts +13 -2
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.1.105";
1
+ export declare const CLI_VERSION = "0.1.106";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.105";
2
+ export const CLI_VERSION = "0.1.106";
3
3
  //# sourceMappingURL=version.js.map
@@ -1,8 +1,11 @@
1
- import type { ImageGenModelProvider } from '../../shared/ImageGen.js';
1
+ import type { ImageGenModel } from '../../shared/ImageGen.js';
2
2
  import type { ImageGenBase } from './ImageGenBase.js';
3
3
  /**
4
- * Create an ImageGen instance for the given provider-specific model.
5
- * Replaces app/server/ai/ImageGen.ts + ImageGenUglyAppAdapter.ts.
4
+ * Create an ImageGen instance for the given clean model name.
5
+ * Automatically selects the best available provider based on priority.
6
+ *
7
+ * @param model - Clean model name (e.g. 'flux_1_dev', 'seedream', 'nano_banana')
8
+ * @param priority - 'cheap' (default) selects cheapest provider; 'fast' selects lowest latency
6
9
  */
7
- export declare function imageGenCreate(model: ImageGenModelProvider): ImageGenBase;
10
+ export declare function imageGenCreate(model: ImageGenModel, priority?: 'fast' | 'cheap'): ImageGenBase;
8
11
  //# sourceMappingURL=ImageGenFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGenFactory.d.ts","sourceRoot":"","sources":["../../../src/server/ai/ImageGenFactory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,mBAAmB,CAAC;AAoE3B;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAyCzE"}
1
+ {"version":3,"file":"ImageGenFactory.d.ts","sourceRoot":"","sources":["../../../src/server/ai/ImageGenFactory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,mBAAmB,CAAC;AA8G3B;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,QAAQ,GAAE,MAAM,GAAG,OAAiB,GACnC,YAAY,CAgBd"}
@@ -1,4 +1,7 @@
1
- // Merged from app/server/ai/ImageGen.ts (factory switch) and ImageGenUglyAppAdapter.ts (size mapping + url conversion).
1
+ // Image generation factory with automatic provider selection.
2
+ // Callers use clean model names (e.g. 'flux_1_dev') and an optional priority.
3
+ // The factory selects the best available provider and passes the model through.
4
+ import { imageGenMultiProviderModels, } from '../../shared/ImageGen.js';
2
5
  import { falImageProvider } from './providers/FAL.js';
3
6
  import { googleImageProvider } from './providers/GoogleImage.js';
4
7
  import { kieImageProvider } from './providers/KieImage.js';
@@ -32,10 +35,37 @@ async function urlToBase64(url) {
32
35
  const buffer = await res.arrayBuffer();
33
36
  return Buffer.from(buffer).toString('base64');
34
37
  }
38
+ const providerMap = {
39
+ together: togetherImageProvider,
40
+ fireworks: togetherImageProvider, // Fireworks FLUX uses Together's API
41
+ fal: falImageProvider,
42
+ google: googleImageProvider,
43
+ kie: kieImageProvider,
44
+ wavespeed: wavespeedImageProvider,
45
+ };
46
+ function selectOffering(model, priority) {
47
+ const offerings = imageGenMultiProviderModels[model];
48
+ if (!offerings || offerings.length === 0) {
49
+ throw new Error(`[ImageGenFactory] No providers configured for model ${model}`);
50
+ }
51
+ const available = offerings.filter((o) => o.available);
52
+ if (available.length === 0) {
53
+ throw new Error(`[ImageGenFactory] No available provider for model ${model}`);
54
+ }
55
+ if (priority === 'fast') {
56
+ const tierOrder = { fast: 0, standard: 1, slow: 2 };
57
+ const sorted = [...available].sort((a, b) => tierOrder[a.latencyTier] - tierOrder[b.latencyTier]);
58
+ return sorted[0];
59
+ }
60
+ // 'cheap': first entry (array is ordered cheapest first)
61
+ return available[0];
62
+ }
35
63
  class ImageGenImpl {
36
64
  provider;
37
- constructor(provider) {
65
+ model;
66
+ constructor(provider, model) {
38
67
  this.provider = provider;
68
+ this.model = model;
39
69
  }
40
70
  async generate(input) {
41
71
  if (input.images?.some(Boolean)) {
@@ -45,7 +75,11 @@ class ImageGenImpl {
45
75
  const prompt = input.negativePrompt
46
76
  ? `${input.prompt} --no ${input.negativePrompt}`
47
77
  : input.prompt;
48
- const imageUrl = await this.provider.generate(prompt, { width, height });
78
+ const imageUrl = await this.provider.generate(prompt, {
79
+ width,
80
+ height,
81
+ model: this.model,
82
+ });
49
83
  const base64 = await urlToBase64(imageUrl);
50
84
  return {
51
85
  type: 'base64',
@@ -57,43 +91,24 @@ class ImageGenImpl {
57
91
  }
58
92
  }
59
93
  /**
60
- * Create an ImageGen instance for the given provider-specific model.
61
- * Replaces app/server/ai/ImageGen.ts + ImageGenUglyAppAdapter.ts.
94
+ * Create an ImageGen instance for the given clean model name.
95
+ * Automatically selects the best available provider based on priority.
96
+ *
97
+ * @param model - Clean model name (e.g. 'flux_1_dev', 'seedream', 'nano_banana')
98
+ * @param priority - 'cheap' (default) selects cheapest provider; 'fast' selects lowest latency
62
99
  */
63
- export function imageGenCreate(model) {
64
- switch (model) {
65
- // FAL models
66
- case 'fal_flux_dev':
67
- case 'fal_flux_pro':
68
- case 'fal_seedream_v4_5':
69
- return new ImageGenImpl(falImageProvider);
70
- // Google models
71
- case 'google_nano':
72
- case 'google_nano_pro':
73
- return new ImageGenImpl(googleImageProvider);
74
- // Together models
75
- case 'together_flux_schnell':
76
- case 'together_flux_dev':
77
- case 'together_flux_pro':
78
- case 'together_flux_kontext_dev':
79
- case 'together_flux_kontext_pro':
80
- case 'together_flux_kontext_max':
81
- return new ImageGenImpl(togetherImageProvider);
82
- // Fireworks models — use Together image provider (same FLUX models)
83
- case 'fireworks_flux_dev':
84
- case 'fireworks_flux_pro':
85
- return new ImageGenImpl(togetherImageProvider);
86
- // Kie.ai models
87
- case 'kie_nano_banana':
88
- case 'kie_nano_banana_pro':
89
- return new ImageGenImpl(kieImageProvider);
90
- // WaveSpeed models
91
- case 'wavespeed_seedream_v4_5':
92
- case 'wavespeed_flux_dev':
93
- case 'wavespeed_flux_schnell':
94
- return new ImageGenImpl(wavespeedImageProvider);
95
- default:
96
- throw new Error(`Model does not exist ${model}`);
100
+ export function imageGenCreate(model, priority = 'cheap') {
101
+ const offering = selectOffering(model, priority);
102
+ const provider = providerMap[offering.provider];
103
+ if (!provider) {
104
+ throw new Error(`[ImageGenFactory] Unknown provider ${offering.provider}`);
97
105
  }
106
+ console.log('[ImageGenFactory] Selected provider', {
107
+ model,
108
+ provider: offering.provider,
109
+ providerModel: offering.providerModel,
110
+ reason: priority === 'fast' ? 'fastest_available' : 'cheapest_available',
111
+ });
112
+ return new ImageGenImpl(provider, model);
98
113
  }
99
114
  //# sourceMappingURL=ImageGenFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGenFactory.js","sourceRoot":"","sources":["../../../src/server/ai/ImageGenFactory.ts"],"names":[],"mappings":"AAAA,wHAAwH;AAWxH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,SAAS,QAAQ,CAAC,IAAkB;IAClC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACvC,KAAK,cAAc;YACjB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACtC,KAAK,eAAe;YAClB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACtC,KAAK,eAAe;YAClB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACtC,KAAK,eAAe;YAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACtC,KAAK,gBAAgB;YACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACtC,KAAK,gBAAgB;YACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACtC;YACE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,YAAY;IACa;IAA7B,YAA6B,QAA0B;QAA1B,aAAQ,GAAR,QAAQ,CAAkB;IAAG,CAAC;IAE3D,KAAK,CAAC,QAAQ,CACZ,KAA0B;QAE1B,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc;YACjC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,cAAc,EAAE;YAChD,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAEjB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE3C,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM;YACN,IAAI,EAAE,YAAY;YAClB,KAAK;YACL,MAAM;SACP,CAAC;IACJ,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAA4B;IACzD,QAAQ,KAAK,EAAE,CAAC;QACd,aAAa;QACb,KAAK,cAAc,CAAC;QACpB,KAAK,cAAc,CAAC;QACpB,KAAK,mBAAmB;YACtB,OAAO,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAE5C,gBAAgB;QAChB,KAAK,aAAa,CAAC;QACnB,KAAK,iBAAiB;YACpB,OAAO,IAAI,YAAY,CAAC,mBAAmB,CAAC,CAAC;QAE/C,kBAAkB;QAClB,KAAK,uBAAuB,CAAC;QAC7B,KAAK,mBAAmB,CAAC;QACzB,KAAK,mBAAmB,CAAC;QACzB,KAAK,2BAA2B,CAAC;QACjC,KAAK,2BAA2B,CAAC;QACjC,KAAK,2BAA2B;YAC9B,OAAO,IAAI,YAAY,CAAC,qBAAqB,CAAC,CAAC;QAEjD,oEAAoE;QACpE,KAAK,oBAAoB,CAAC;QAC1B,KAAK,oBAAoB;YACvB,OAAO,IAAI,YAAY,CAAC,qBAAqB,CAAC,CAAC;QAEjD,gBAAgB;QAChB,KAAK,iBAAiB,CAAC;QACvB,KAAK,qBAAqB;YACxB,OAAO,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAE5C,mBAAmB;QACnB,KAAK,yBAAyB,CAAC;QAC/B,KAAK,oBAAoB,CAAC;QAC1B,KAAK,wBAAwB;YAC3B,OAAO,IAAI,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAElD;YACE,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"ImageGenFactory.js","sourceRoot":"","sources":["../../../src/server/ai/ImageGenFactory.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FAL.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/FAL.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAmCrE,eAAO,MAAM,gBAAgB,EAAE,gBAyB9B,CAAC"}
1
+ {"version":3,"file":"FAL.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/FAL.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA+CrE,eAAO,MAAM,gBAAgB,EAAE,gBA4B9B,CAAC"}
@@ -1,15 +1,24 @@
1
- const BASE_URL = 'https://queue.fal.run/fal-ai/flux-pro/v1.1';
2
- async function poll(apiKey, requestId) {
1
+ const FAL_ENDPOINTS = {
2
+ flux_1_dev: 'fal-ai/flux/dev',
3
+ flux_1_pro: 'fal-ai/flux-pro/v1.1',
4
+ seedream: 'fal-ai/seedream-v4.5',
5
+ };
6
+ const DEFAULT_ENDPOINT = 'fal-ai/flux-pro/v1.1';
7
+ function getBaseUrl(model) {
8
+ const endpoint = (model && FAL_ENDPOINTS[model]) ?? DEFAULT_ENDPOINT;
9
+ return `https://queue.fal.run/${endpoint}`;
10
+ }
11
+ async function poll(apiKey, baseUrl, requestId) {
3
12
  for (let i = 0; i < 60; i++) {
4
13
  await new Promise((r) => setTimeout(r, 2000));
5
- const res = await fetch(`${BASE_URL}/requests/${requestId}/status`, {
14
+ const res = await fetch(`${baseUrl}/requests/${requestId}/status`, {
6
15
  headers: { Authorization: `Key ${apiKey}` },
7
16
  });
8
17
  if (!res.ok)
9
18
  throw new Error(`[FAL] API error ${res.status}: ${await res.text()}`);
10
19
  const data = (await res.json());
11
20
  if (data.status === 'COMPLETED') {
12
- const resultRes = await fetch(`${BASE_URL}/requests/${requestId}`, {
21
+ const resultRes = await fetch(`${baseUrl}/requests/${requestId}`, {
13
22
  headers: { Authorization: `Key ${apiKey}` },
14
23
  });
15
24
  if (!resultRes.ok)
@@ -32,7 +41,8 @@ export const falImageProvider = {
32
41
  const apiKey = process.env.FAL_API_KEY;
33
42
  if (!apiKey)
34
43
  throw new Error('[FAL] FAL_API_KEY is required');
35
- const res = await fetch(BASE_URL, {
44
+ const baseUrl = getBaseUrl(options.model);
45
+ const res = await fetch(baseUrl, {
36
46
  method: 'POST',
37
47
  headers: {
38
48
  'Content-Type': 'application/json',
@@ -49,7 +59,7 @@ export const falImageProvider = {
49
59
  if (!res.ok)
50
60
  throw new Error(`[FAL] API error ${res.status}: ${await res.text()}`);
51
61
  const data = (await res.json());
52
- return poll(apiKey, data.request_id);
62
+ return poll(apiKey, baseUrl, data.request_id);
53
63
  },
54
64
  };
55
65
  //# sourceMappingURL=FAL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FAL.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/FAL.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FAL.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/FAL.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"GoogleImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/GoogleImage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErE,eAAO,MAAM,mBAAmB,EAAE,gBA6BjC,CAAC"}
1
+ {"version":3,"file":"GoogleImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/GoogleImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAOrE,eAAO,MAAM,mBAAmB,EAAE,gBA+BjC,CAAC"}
@@ -1,11 +1,16 @@
1
+ const API_MODELS = {
2
+ nano_banana: 'imagen-3.0-generate-001',
3
+ nano_banana_pro: 'imagen-3.0-generate-001',
4
+ };
1
5
  export const googleImageProvider = {
2
6
  name: 'google',
3
7
  apiKeyEnv: 'GOOGLE_API_KEY',
4
- async generate(prompt, _options = {}) {
8
+ async generate(prompt, options = {}) {
5
9
  const apiKey = process.env.GOOGLE_API_KEY;
6
10
  if (!apiKey)
7
11
  throw new Error('[GoogleImage] GOOGLE_API_KEY is required');
8
- const url = `https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict?key=${apiKey}`;
12
+ const model = (options.model && API_MODELS[options.model]) ?? 'imagen-3.0-generate-001';
13
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:predict?key=${apiKey}`;
9
14
  const res = await fetch(url, {
10
15
  method: 'POST',
11
16
  headers: { 'Content-Type': 'application/json' },
@@ -1 +1 @@
1
- {"version":3,"file":"GoogleImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/GoogleImage.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,gBAAgB;IAC3B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAA4B,EAAE;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAEzE,MAAM,GAAG,GAAG,+FAA+F,MAAM,EAAE,CAAC;QACpH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;gBACvB,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE;aAC/B,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC7D,CAAC;QAEJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,kBAAkB,IAAI,CAAC,UAAU,EAAE,QAAQ;YAC1D,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAE7D,OAAO,QAAQ,UAAU,CAAC,QAAQ,WAAW,UAAU,CAAC,kBAAkB,EAAE,CAAC;IAC/E,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"GoogleImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/GoogleImage.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,GAA2C;IACzD,WAAW,EAAE,yBAAyB;IACtC,eAAe,EAAE,yBAAyB;CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,gBAAgB;IAC3B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAEzE,MAAM,KAAK,GACT,CAAC,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,yBAAyB,CAAC;QAC5E,MAAM,GAAG,GAAG,2DAA2D,KAAK,gBAAgB,MAAM,EAAE,CAAC;QACrG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;gBACvB,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE;aAC/B,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC7D,CAAC;QAEJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,kBAAkB,IAAI,CAAC,UAAU,EAAE,QAAQ;YAC1D,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAE7D,OAAO,QAAQ,UAAU,CAAC,QAAQ,WAAW,UAAU,CAAC,kBAAkB,EAAE,CAAC;IAC/E,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"KieImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/KieImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA2BrE,eAAO,MAAM,gBAAgB,EAAE,gBA0B9B,CAAC"}
1
+ {"version":3,"file":"KieImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/KieImage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgCrE,eAAO,MAAM,gBAAgB,EAAE,gBA6B9B,CAAC"}
@@ -1,4 +1,8 @@
1
- const MODEL = 'kolors';
1
+ const API_MODELS = {
2
+ nano_banana: 'kolors',
3
+ nano_banana_pro: 'kolors',
4
+ };
5
+ const DEFAULT_MODEL = 'kolors';
2
6
  const BASE_URL = 'https://api.kie.ai/api/v1';
3
7
  async function pollKie(apiKey, taskId) {
4
8
  for (let i = 0; i < 60; i++) {
@@ -27,7 +31,8 @@ export const kieImageProvider = {
27
31
  const apiKey = process.env.KIE_API_KEY;
28
32
  if (!apiKey)
29
33
  throw new Error('[KieImage] KIE_API_KEY is required');
30
- const res = await fetch(`${BASE_URL}/${MODEL}/img2img`, {
34
+ const model = (options.model && API_MODELS[options.model]) ?? DEFAULT_MODEL;
35
+ const res = await fetch(`${BASE_URL}/${model}/img2img`, {
31
36
  method: 'POST',
32
37
  headers: {
33
38
  'Content-Type': 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"KieImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/KieImage.ts"],"names":[],"mappings":"AAGA,MAAM,KAAK,GAAG,QAAQ,CAAC;AACvB,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,MAAc;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,8BAA8B,MAAM,EAAE,EAAE;YACzE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;YACxC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACjE,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ;YAChC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAChD,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,aAAa;IACxB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,KAAK,UAAU,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,MAAM,EAAE;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM;gBACN,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;aAC/B,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"KieImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/KieImage.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAA2C;IACzD,WAAW,EAAE,QAAQ;IACrB,eAAe,EAAE,QAAQ;CAC1B,CAAC;AAEF,MAAM,aAAa,GAAG,QAAQ,CAAC;AAC/B,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,MAAc;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,8BAA8B,MAAM,EAAE,EAAE;YACzE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;YACxC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACjE,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ;YAChC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAChD,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,aAAa;IACxB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACnE,MAAM,KAAK,GACT,CAAC,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC;QAEhE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,KAAK,UAAU,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,MAAM,EAAE;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM;gBACN,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;aAC/B,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"TogetherImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/TogetherImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErE,eAAO,MAAM,qBAAqB,EAAE,gBA8BnC,CAAC"}
1
+ {"version":3,"file":"TogetherImage.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/TogetherImage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQrE,eAAO,MAAM,qBAAqB,EAAE,gBAmCnC,CAAC"}
@@ -1,3 +1,8 @@
1
+ const API_MODELS = {
2
+ flux_1_schnell: 'black-forest-labs/FLUX.1-schnell',
3
+ flux_1_dev: 'black-forest-labs/FLUX.1-dev',
4
+ flux_1_pro: 'black-forest-labs/FLUX.1.1-pro',
5
+ };
1
6
  export const togetherImageProvider = {
2
7
  name: 'together',
3
8
  apiKeyEnv: 'TOGETHER_API_KEY',
@@ -5,6 +10,8 @@ export const togetherImageProvider = {
5
10
  const apiKey = process.env.TOGETHER_API_KEY;
6
11
  if (!apiKey)
7
12
  throw new Error('[TogetherImage] TOGETHER_API_KEY is required');
13
+ const model = (options.model && API_MODELS[options.model]) ??
14
+ 'black-forest-labs/FLUX.1-schnell';
8
15
  const res = await fetch('https://api.together.xyz/v1/images/generations', {
9
16
  method: 'POST',
10
17
  headers: {
@@ -12,7 +19,7 @@ export const togetherImageProvider = {
12
19
  'Content-Type': 'application/json',
13
20
  },
14
21
  body: JSON.stringify({
15
- model: 'black-forest-labs/FLUX.1-schnell-Free',
22
+ model,
16
23
  prompt,
17
24
  n: 1,
18
25
  width: options.width ?? 1024,
@@ -1 +1 @@
1
- {"version":3,"file":"TogetherImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/TogetherImage.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,kBAAkB;IAC7B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC5C,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;YACxE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,MAAM,EAAE;gBACnC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,uCAAuC;gBAC9C,MAAM;gBACN,CAAC,EAAE,CAAC;gBACJ,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;aAC/B,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC/D,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"TogetherImage.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/TogetherImage.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAA2C;IACzD,cAAc,EAAE,kCAAkC;IAClD,UAAU,EAAE,8BAA8B;IAC1C,UAAU,EAAE,gCAAgC;CAC7C,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,kBAAkB;IAC7B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC5C,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAElE,MAAM,KAAK,GACT,CAAC,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5C,kCAAkC,CAAC;QAErC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;YACxE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,MAAM,EAAE;gBACnC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK;gBACL,MAAM;gBACN,CAAC,EAAE,CAAC;gBACJ,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;aAC/B,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC/D,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAC9B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Wavespeed.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/Wavespeed.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA0BrE,eAAO,MAAM,sBAAsB,EAAE,gBA+BpC,CAAC"}
1
+ {"version":3,"file":"Wavespeed.d.ts","sourceRoot":"","sources":["../../../../src/server/ai/providers/Wavespeed.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgCrE,eAAO,MAAM,sBAAsB,EAAE,gBAmCpC,CAAC"}
@@ -1,4 +1,9 @@
1
- const MODEL = 'wavespeed-ai/flux-dev';
1
+ const API_MODELS = {
2
+ flux_1_dev: 'wavespeed-ai/flux-dev',
3
+ flux_1_schnell: 'wavespeed-ai/flux-schnell',
4
+ seedream: 'wavespeed-ai/seedream-v4.5',
5
+ };
6
+ const DEFAULT_MODEL = 'wavespeed-ai/flux-dev';
2
7
  const BASE_URL = 'https://api.wavespeed.ai/api/v3';
3
8
  async function poll(apiKey, id) {
4
9
  for (let i = 0; i < 60; i++) {
@@ -27,7 +32,8 @@ export const wavespeedImageProvider = {
27
32
  const apiKey = process.env.WAVESPEED_API_KEY;
28
33
  if (!apiKey)
29
34
  throw new Error('[Wavespeed] WAVESPEED_API_KEY is required');
30
- const res = await fetch(`${BASE_URL}/${MODEL}`, {
35
+ const model = (options.model && API_MODELS[options.model]) ?? DEFAULT_MODEL;
36
+ const res = await fetch(`${BASE_URL}/${model}`, {
31
37
  method: 'POST',
32
38
  headers: {
33
39
  'Content-Type': 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"Wavespeed.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/Wavespeed.ts"],"names":[],"mappings":"AAGA,MAAM,KAAK,GAAG,uBAAuB,CAAC;AACtC,MAAM,QAAQ,GAAG,iCAAiC,CAAC;AAEnD,KAAK,UAAU,IAAI,CAAC,MAAc,EAAE,EAAU;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,gBAAgB,EAAE,SAAS,EAAE;YAC9D,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE7B,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACvD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC/B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,IAAI,EAAE,WAAW;IACjB,SAAS,EAAE,mBAAmB;IAC9B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAA2B,EAAE;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,IAAI,KAAK,EAAE,EAAE;YAC9C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,MAAM,EAAE;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM;gBACN,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE;aAC3D,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,IAAI,KAAK,CACb,4BAA4B,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAC9D,CAAC;QACJ,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE7B,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACvD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"Wavespeed.js","sourceRoot":"","sources":["../../../../src/server/ai/providers/Wavespeed.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-app",
3
- "version": "0.1.105",
3
+ "version": "0.1.106",
4
4
  "type": "module",
5
5
  "main": "./dist/server/index.js",
6
6
  "exports": {
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.105";
2
+ export const CLI_VERSION = "0.1.106";
@@ -1,9 +1,16 @@
1
- // Merged from app/server/ai/ImageGen.ts (factory switch) and ImageGenUglyAppAdapter.ts (size mapping + url conversion).
1
+ // Image generation factory with automatic provider selection.
2
+ // Callers use clean model names (e.g. 'flux_1_dev') and an optional priority.
3
+ // The factory selects the best available provider and passes the model through.
2
4
 
3
5
  import type {
4
- ImageGenModelProvider,
6
+ ImageGenModel,
7
+ ImageGenProviderOffering,
5
8
  ImageGenSize,
6
9
  } from '../../shared/ImageGen.js';
10
+ import {
11
+ imageGenMultiProviderModels,
12
+ type ImageGenLatencyTier,
13
+ } from '../../shared/ImageGen.js';
7
14
  import type {
8
15
  ImageGenBase,
9
16
  ImageGenPromptInput,
@@ -46,8 +53,46 @@ async function urlToBase64(url: string): Promise<string> {
46
53
  return Buffer.from(buffer).toString('base64');
47
54
  }
48
55
 
56
+ const providerMap: Record<string, ImageGenProvider> = {
57
+ together: togetherImageProvider,
58
+ fireworks: togetherImageProvider, // Fireworks FLUX uses Together's API
59
+ fal: falImageProvider,
60
+ google: googleImageProvider,
61
+ kie: kieImageProvider,
62
+ wavespeed: wavespeedImageProvider,
63
+ };
64
+
65
+ function selectOffering(
66
+ model: ImageGenModel,
67
+ priority: 'fast' | 'cheap',
68
+ ): ImageGenProviderOffering {
69
+ const offerings = imageGenMultiProviderModels[model];
70
+ if (!offerings || offerings.length === 0) {
71
+ throw new Error(`[ImageGenFactory] No providers configured for model ${model}`);
72
+ }
73
+
74
+ const available = offerings.filter((o) => o.available);
75
+ if (available.length === 0) {
76
+ throw new Error(`[ImageGenFactory] No available provider for model ${model}`);
77
+ }
78
+
79
+ if (priority === 'fast') {
80
+ const tierOrder: Record<ImageGenLatencyTier, number> = { fast: 0, standard: 1, slow: 2 };
81
+ const sorted = [...available].sort(
82
+ (a, b) => tierOrder[a.latencyTier] - tierOrder[b.latencyTier],
83
+ );
84
+ return sorted[0]!;
85
+ }
86
+
87
+ // 'cheap': first entry (array is ordered cheapest first)
88
+ return available[0]!;
89
+ }
90
+
49
91
  class ImageGenImpl implements ImageGenBase {
50
- constructor(private readonly provider: ImageGenProvider) {}
92
+ constructor(
93
+ private readonly provider: ImageGenProvider,
94
+ private readonly model: ImageGenModel,
95
+ ) {}
51
96
 
52
97
  async generate(
53
98
  input: ImageGenPromptInput,
@@ -63,7 +108,11 @@ class ImageGenImpl implements ImageGenBase {
63
108
  ? `${input.prompt} --no ${input.negativePrompt}`
64
109
  : input.prompt;
65
110
 
66
- const imageUrl = await this.provider.generate(prompt, { width, height });
111
+ const imageUrl = await this.provider.generate(prompt, {
112
+ width,
113
+ height,
114
+ model: this.model,
115
+ });
67
116
  const base64 = await urlToBase64(imageUrl);
68
117
 
69
118
  return {
@@ -77,48 +126,29 @@ class ImageGenImpl implements ImageGenBase {
77
126
  }
78
127
 
79
128
  /**
80
- * Create an ImageGen instance for the given provider-specific model.
81
- * Replaces app/server/ai/ImageGen.ts + ImageGenUglyAppAdapter.ts.
129
+ * Create an ImageGen instance for the given clean model name.
130
+ * Automatically selects the best available provider based on priority.
131
+ *
132
+ * @param model - Clean model name (e.g. 'flux_1_dev', 'seedream', 'nano_banana')
133
+ * @param priority - 'cheap' (default) selects cheapest provider; 'fast' selects lowest latency
82
134
  */
83
- export function imageGenCreate(model: ImageGenModelProvider): ImageGenBase {
84
- switch (model) {
85
- // FAL models
86
- case 'fal_flux_dev':
87
- case 'fal_flux_pro':
88
- case 'fal_seedream_v4_5':
89
- return new ImageGenImpl(falImageProvider);
90
-
91
- // Google models
92
- case 'google_nano':
93
- case 'google_nano_pro':
94
- return new ImageGenImpl(googleImageProvider);
95
-
96
- // Together models
97
- case 'together_flux_schnell':
98
- case 'together_flux_dev':
99
- case 'together_flux_pro':
100
- case 'together_flux_kontext_dev':
101
- case 'together_flux_kontext_pro':
102
- case 'together_flux_kontext_max':
103
- return new ImageGenImpl(togetherImageProvider);
104
-
105
- // Fireworks models — use Together image provider (same FLUX models)
106
- case 'fireworks_flux_dev':
107
- case 'fireworks_flux_pro':
108
- return new ImageGenImpl(togetherImageProvider);
109
-
110
- // Kie.ai models
111
- case 'kie_nano_banana':
112
- case 'kie_nano_banana_pro':
113
- return new ImageGenImpl(kieImageProvider);
114
-
115
- // WaveSpeed models
116
- case 'wavespeed_seedream_v4_5':
117
- case 'wavespeed_flux_dev':
118
- case 'wavespeed_flux_schnell':
119
- return new ImageGenImpl(wavespeedImageProvider);
135
+ export function imageGenCreate(
136
+ model: ImageGenModel,
137
+ priority: 'fast' | 'cheap' = 'cheap',
138
+ ): ImageGenBase {
139
+ const offering = selectOffering(model, priority);
140
+ const provider = providerMap[offering.provider];
120
141
 
121
- default:
122
- throw new Error(`Model does not exist ${model}`);
142
+ if (!provider) {
143
+ throw new Error(`[ImageGenFactory] Unknown provider ${offering.provider}`);
123
144
  }
145
+
146
+ console.log('[ImageGenFactory] Selected provider', {
147
+ model,
148
+ provider: offering.provider,
149
+ providerModel: offering.providerModel,
150
+ reason: priority === 'fast' ? 'fastest_available' : 'cheapest_available',
151
+ });
152
+
153
+ return new ImageGenImpl(provider, model);
124
154
  }
@@ -1,12 +1,25 @@
1
1
  // src/server/ai/providers/FAL.ts
2
+ import type { ImageGenModel } from '../../../shared/ImageGen.js';
2
3
  import type { ImageGenOptions, ImageGenProvider } from '../types.js';
3
4
 
4
- const BASE_URL = 'https://queue.fal.run/fal-ai/flux-pro/v1.1';
5
+ const FAL_ENDPOINTS: Partial<Record<ImageGenModel, string>> = {
6
+ flux_1_dev: 'fal-ai/flux/dev',
7
+ flux_1_pro: 'fal-ai/flux-pro/v1.1',
8
+ seedream: 'fal-ai/seedream-v4.5',
9
+ };
10
+
11
+ const DEFAULT_ENDPOINT = 'fal-ai/flux-pro/v1.1';
12
+
13
+ function getBaseUrl(model?: ImageGenModel): string {
14
+ const endpoint =
15
+ (model && FAL_ENDPOINTS[model]) ?? DEFAULT_ENDPOINT;
16
+ return `https://queue.fal.run/${endpoint}`;
17
+ }
5
18
 
6
- async function poll(apiKey: string, requestId: string): Promise<string> {
19
+ async function poll(apiKey: string, baseUrl: string, requestId: string): Promise<string> {
7
20
  for (let i = 0; i < 60; i++) {
8
21
  await new Promise((r) => setTimeout(r, 2000));
9
- const res = await fetch(`${BASE_URL}/requests/${requestId}/status`, {
22
+ const res = await fetch(`${baseUrl}/requests/${requestId}/status`, {
10
23
  headers: { Authorization: `Key ${apiKey}` },
11
24
  });
12
25
  if (!res.ok)
@@ -15,7 +28,7 @@ async function poll(apiKey: string, requestId: string): Promise<string> {
15
28
  status: 'IN_QUEUE' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
16
29
  };
17
30
  if (data.status === 'COMPLETED') {
18
- const resultRes = await fetch(`${BASE_URL}/requests/${requestId}`, {
31
+ const resultRes = await fetch(`${baseUrl}/requests/${requestId}`, {
19
32
  headers: { Authorization: `Key ${apiKey}` },
20
33
  });
21
34
  if (!resultRes.ok)
@@ -40,7 +53,10 @@ export const falImageProvider: ImageGenProvider = {
40
53
  async generate(prompt, options: ImageGenOptions = {}) {
41
54
  const apiKey = process.env.FAL_API_KEY;
42
55
  if (!apiKey) throw new Error('[FAL] FAL_API_KEY is required');
43
- const res = await fetch(BASE_URL, {
56
+
57
+ const baseUrl = getBaseUrl(options.model);
58
+
59
+ const res = await fetch(baseUrl, {
44
60
  method: 'POST',
45
61
  headers: {
46
62
  'Content-Type': 'application/json',
@@ -57,6 +73,6 @@ export const falImageProvider: ImageGenProvider = {
57
73
  if (!res.ok)
58
74
  throw new Error(`[FAL] API error ${res.status}: ${await res.text()}`);
59
75
  const data = (await res.json()) as { request_id: string };
60
- return poll(apiKey, data.request_id);
76
+ return poll(apiKey, baseUrl, data.request_id);
61
77
  },
62
78
  };
@@ -1,13 +1,21 @@
1
+ import type { ImageGenModel } from '../../../shared/ImageGen.js';
1
2
  import type { ImageGenOptions, ImageGenProvider } from '../types.js';
2
3
 
4
+ const API_MODELS: Partial<Record<ImageGenModel, string>> = {
5
+ nano_banana: 'imagen-3.0-generate-001',
6
+ nano_banana_pro: 'imagen-3.0-generate-001',
7
+ };
8
+
3
9
  export const googleImageProvider: ImageGenProvider = {
4
10
  name: 'google',
5
11
  apiKeyEnv: 'GOOGLE_API_KEY',
6
- async generate(prompt, _options: ImageGenOptions = {}) {
12
+ async generate(prompt, options: ImageGenOptions = {}) {
7
13
  const apiKey = process.env.GOOGLE_API_KEY;
8
14
  if (!apiKey) throw new Error('[GoogleImage] GOOGLE_API_KEY is required');
9
15
 
10
- const url = `https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict?key=${apiKey}`;
16
+ const model =
17
+ (options.model && API_MODELS[options.model]) ?? 'imagen-3.0-generate-001';
18
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:predict?key=${apiKey}`;
11
19
  const res = await fetch(url, {
12
20
  method: 'POST',
13
21
  headers: { 'Content-Type': 'application/json' },
@@ -1,7 +1,13 @@
1
1
  // src/server/ai/providers/KieImage.ts
2
+ import type { ImageGenModel } from '../../../shared/ImageGen.js';
2
3
  import type { ImageGenOptions, ImageGenProvider } from '../types.js';
3
4
 
4
- const MODEL = 'kolors';
5
+ const API_MODELS: Partial<Record<ImageGenModel, string>> = {
6
+ nano_banana: 'kolors',
7
+ nano_banana_pro: 'kolors',
8
+ };
9
+
10
+ const DEFAULT_MODEL = 'kolors';
5
11
  const BASE_URL = 'https://api.kie.ai/api/v1';
6
12
 
7
13
  async function pollKie(apiKey: string, taskId: string): Promise<string> {
@@ -32,7 +38,10 @@ export const kieImageProvider: ImageGenProvider = {
32
38
  async generate(prompt, options: ImageGenOptions = {}) {
33
39
  const apiKey = process.env.KIE_API_KEY;
34
40
  if (!apiKey) throw new Error('[KieImage] KIE_API_KEY is required');
35
- const res = await fetch(`${BASE_URL}/${MODEL}/img2img`, {
41
+ const model =
42
+ (options.model && API_MODELS[options.model]) ?? DEFAULT_MODEL;
43
+
44
+ const res = await fetch(`${BASE_URL}/${model}/img2img`, {
36
45
  method: 'POST',
37
46
  headers: {
38
47
  'Content-Type': 'application/json',
@@ -1,6 +1,13 @@
1
1
  // src/server/ai/providers/TogetherImage.ts
2
+ import type { ImageGenModel } from '../../../shared/ImageGen.js';
2
3
  import type { ImageGenOptions, ImageGenProvider } from '../types.js';
3
4
 
5
+ const API_MODELS: Partial<Record<ImageGenModel, string>> = {
6
+ flux_1_schnell: 'black-forest-labs/FLUX.1-schnell',
7
+ flux_1_dev: 'black-forest-labs/FLUX.1-dev',
8
+ flux_1_pro: 'black-forest-labs/FLUX.1.1-pro',
9
+ };
10
+
4
11
  export const togetherImageProvider: ImageGenProvider = {
5
12
  name: 'together',
6
13
  apiKeyEnv: 'TOGETHER_API_KEY',
@@ -8,6 +15,11 @@ export const togetherImageProvider: ImageGenProvider = {
8
15
  const apiKey = process.env.TOGETHER_API_KEY;
9
16
  if (!apiKey)
10
17
  throw new Error('[TogetherImage] TOGETHER_API_KEY is required');
18
+
19
+ const model =
20
+ (options.model && API_MODELS[options.model]) ??
21
+ 'black-forest-labs/FLUX.1-schnell';
22
+
11
23
  const res = await fetch('https://api.together.xyz/v1/images/generations', {
12
24
  method: 'POST',
13
25
  headers: {
@@ -15,7 +27,7 @@ export const togetherImageProvider: ImageGenProvider = {
15
27
  'Content-Type': 'application/json',
16
28
  },
17
29
  body: JSON.stringify({
18
- model: 'black-forest-labs/FLUX.1-schnell-Free',
30
+ model,
19
31
  prompt,
20
32
  n: 1,
21
33
  width: options.width ?? 1024,
@@ -1,7 +1,14 @@
1
1
  // src/server/ai/providers/Wavespeed.ts
2
+ import type { ImageGenModel } from '../../../shared/ImageGen.js';
2
3
  import type { ImageGenOptions, ImageGenProvider } from '../types.js';
3
4
 
4
- const MODEL = 'wavespeed-ai/flux-dev';
5
+ const API_MODELS: Partial<Record<ImageGenModel, string>> = {
6
+ flux_1_dev: 'wavespeed-ai/flux-dev',
7
+ flux_1_schnell: 'wavespeed-ai/flux-schnell',
8
+ seedream: 'wavespeed-ai/seedream-v4.5',
9
+ };
10
+
11
+ const DEFAULT_MODEL = 'wavespeed-ai/flux-dev';
5
12
  const BASE_URL = 'https://api.wavespeed.ai/api/v3';
6
13
 
7
14
  async function poll(apiKey: string, id: string): Promise<string> {
@@ -31,7 +38,11 @@ export const wavespeedImageProvider: ImageGenProvider = {
31
38
  async generate(prompt, options: ImageGenOptions = {}) {
32
39
  const apiKey = process.env.WAVESPEED_API_KEY;
33
40
  if (!apiKey) throw new Error('[Wavespeed] WAVESPEED_API_KEY is required');
34
- const res = await fetch(`${BASE_URL}/${MODEL}`, {
41
+
42
+ const model =
43
+ (options.model && API_MODELS[options.model]) ?? DEFAULT_MODEL;
44
+
45
+ const res = await fetch(`${BASE_URL}/${model}`, {
35
46
  method: 'POST',
36
47
  headers: {
37
48
  'Content-Type': 'application/json',