@jini-ai/integrations 0.1.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/LICENSE +201 -0
- package/README.md +51 -0
- package/dist/composio/bounded-data.d.ts +36 -0
- package/dist/composio/bounded-data.d.ts.map +1 -0
- package/dist/composio/bounded-data.js +181 -0
- package/dist/composio/bounded-data.js.map +1 -0
- package/dist/composio/catalog.d.ts +147 -0
- package/dist/composio/catalog.d.ts.map +1 -0
- package/dist/composio/catalog.js +126 -0
- package/dist/composio/catalog.js.map +1 -0
- package/dist/composio/composio-config.d.ts +42 -0
- package/dist/composio/composio-config.d.ts.map +1 -0
- package/dist/composio/composio-config.js +145 -0
- package/dist/composio/composio-config.js.map +1 -0
- package/dist/composio/composio-descriptions.d.ts +16 -0
- package/dist/composio/composio-descriptions.d.ts.map +1 -0
- package/dist/composio/composio-descriptions.js +766 -0
- package/dist/composio/composio-descriptions.js.map +1 -0
- package/dist/composio/composio.d.ts +364 -0
- package/dist/composio/composio.d.ts.map +1 -0
- package/dist/composio/composio.js +1902 -0
- package/dist/composio/composio.js.map +1 -0
- package/dist/composio/errors.d.ts +15 -0
- package/dist/composio/errors.d.ts.map +1 -0
- package/dist/composio/errors.js +16 -0
- package/dist/composio/errors.js.map +1 -0
- package/dist/composio/file-lock.d.ts +13 -0
- package/dist/composio/file-lock.d.ts.map +1 -0
- package/dist/composio/file-lock.js +92 -0
- package/dist/composio/file-lock.js.map +1 -0
- package/dist/composio/index.d.ts +18 -0
- package/dist/composio/index.d.ts.map +1 -0
- package/dist/composio/index.js +7 -0
- package/dist/composio/index.js.map +1 -0
- package/dist/composio/json-schema.d.ts +93 -0
- package/dist/composio/json-schema.d.ts.map +1 -0
- package/dist/composio/json-schema.js +498 -0
- package/dist/composio/json-schema.js.map +1 -0
- package/dist/composio/output-protection.d.ts +32 -0
- package/dist/composio/output-protection.d.ts.map +1 -0
- package/dist/composio/output-protection.js +105 -0
- package/dist/composio/output-protection.js.map +1 -0
- package/dist/composio/service.d.ts +181 -0
- package/dist/composio/service.d.ts.map +1 -0
- package/dist/composio/service.js +758 -0
- package/dist/composio/service.js.map +1 -0
- package/dist/media-providers/capability-registry.d.ts +28 -0
- package/dist/media-providers/capability-registry.d.ts.map +1 -0
- package/dist/media-providers/capability-registry.js +27 -0
- package/dist/media-providers/capability-registry.js.map +1 -0
- package/dist/media-providers/catalog.d.ts +20 -0
- package/dist/media-providers/catalog.d.ts.map +1 -0
- package/dist/media-providers/catalog.js +20 -0
- package/dist/media-providers/catalog.js.map +1 -0
- package/dist/media-providers/dispatch/context.d.ts +21 -0
- package/dist/media-providers/dispatch/context.d.ts.map +1 -0
- package/dist/media-providers/dispatch/context.js +36 -0
- package/dist/media-providers/dispatch/context.js.map +1 -0
- package/dist/media-providers/dispatch/credentials.d.ts +4 -0
- package/dist/media-providers/dispatch/credentials.d.ts.map +1 -0
- package/dist/media-providers/dispatch/credentials.js +25 -0
- package/dist/media-providers/dispatch/credentials.js.map +1 -0
- package/dist/media-providers/dispatch/engine.d.ts +30 -0
- package/dist/media-providers/dispatch/engine.d.ts.map +1 -0
- package/dist/media-providers/dispatch/engine.js +208 -0
- package/dist/media-providers/dispatch/engine.js.map +1 -0
- package/dist/media-providers/dispatch/index.d.ts +25 -0
- package/dist/media-providers/dispatch/index.d.ts.map +1 -0
- package/dist/media-providers/dispatch/index.js +24 -0
- package/dist/media-providers/dispatch/index.js.map +1 -0
- package/dist/media-providers/dispatch/openai-compatible.d.ts +44 -0
- package/dist/media-providers/dispatch/openai-compatible.d.ts.map +1 -0
- package/dist/media-providers/dispatch/openai-compatible.js +214 -0
- package/dist/media-providers/dispatch/openai-compatible.js.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts +72 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.js +131 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.js.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/aihubmix.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix.js +205 -0
- package/dist/media-providers/dispatch/providers/aihubmix.js.map +1 -0
- package/dist/media-providers/dispatch/providers/custom-image.d.ts +6 -0
- package/dist/media-providers/dispatch/providers/custom-image.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/custom-image.js +94 -0
- package/dist/media-providers/dispatch/providers/custom-image.js.map +1 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.js +163 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.js.map +1 -0
- package/dist/media-providers/dispatch/providers/fishaudio.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/fishaudio.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/fishaudio.js +83 -0
- package/dist/media-providers/dispatch/providers/fishaudio.js.map +1 -0
- package/dist/media-providers/dispatch/providers/grok.d.ts +15 -0
- package/dist/media-providers/dispatch/providers/grok.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/grok.js +150 -0
- package/dist/media-providers/dispatch/providers/grok.js.map +1 -0
- package/dist/media-providers/dispatch/providers/imagerouter.d.ts +6 -0
- package/dist/media-providers/dispatch/providers/imagerouter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/imagerouter.js +131 -0
- package/dist/media-providers/dispatch/providers/imagerouter.js.map +1 -0
- package/dist/media-providers/dispatch/providers/minimax.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/minimax.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/minimax.js +96 -0
- package/dist/media-providers/dispatch/providers/minimax.js.map +1 -0
- package/dist/media-providers/dispatch/providers/nanobanana.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/nanobanana.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/nanobanana.js +142 -0
- package/dist/media-providers/dispatch/providers/nanobanana.js.map +1 -0
- package/dist/media-providers/dispatch/providers/openai.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/openai.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/openai.js +231 -0
- package/dist/media-providers/dispatch/providers/openai.js.map +1 -0
- package/dist/media-providers/dispatch/providers/openrouter.d.ts +13 -0
- package/dist/media-providers/dispatch/providers/openrouter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/openrouter.js +152 -0
- package/dist/media-providers/dispatch/providers/openrouter.js.map +1 -0
- package/dist/media-providers/dispatch/providers/senseaudio.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/senseaudio.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/senseaudio.js +190 -0
- package/dist/media-providers/dispatch/providers/senseaudio.js.map +1 -0
- package/dist/media-providers/dispatch/providers/volcengine.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/volcengine.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/volcengine.js +95 -0
- package/dist/media-providers/dispatch/providers/volcengine.js.map +1 -0
- package/dist/media-providers/dispatch/response-parsers.d.ts +44 -0
- package/dist/media-providers/dispatch/response-parsers.d.ts.map +1 -0
- package/dist/media-providers/dispatch/response-parsers.js +103 -0
- package/dist/media-providers/dispatch/response-parsers.js.map +1 -0
- package/dist/media-providers/dispatch/ssrf-guard.d.ts +51 -0
- package/dist/media-providers/dispatch/ssrf-guard.d.ts.map +1 -0
- package/dist/media-providers/dispatch/ssrf-guard.js +215 -0
- package/dist/media-providers/dispatch/ssrf-guard.js.map +1 -0
- package/dist/media-providers/dispatch/stub.d.ts +5 -0
- package/dist/media-providers/dispatch/stub.d.ts.map +1 -0
- package/dist/media-providers/dispatch/stub.js +98 -0
- package/dist/media-providers/dispatch/stub.js.map +1 -0
- package/dist/media-providers/dispatch/types.d.ts +133 -0
- package/dist/media-providers/dispatch/types.d.ts.map +1 -0
- package/dist/media-providers/dispatch/types.js +2 -0
- package/dist/media-providers/dispatch/types.js.map +1 -0
- package/dist/media-providers/dispatch/vendor-adapter.d.ts +54 -0
- package/dist/media-providers/dispatch/vendor-adapter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/vendor-adapter.js +68 -0
- package/dist/media-providers/dispatch/vendor-adapter.js.map +1 -0
- package/dist/media-providers/dispatch/vendor-registry.d.ts +36 -0
- package/dist/media-providers/dispatch/vendor-registry.d.ts.map +1 -0
- package/dist/media-providers/dispatch/vendor-registry.js +46 -0
- package/dist/media-providers/dispatch/vendor-registry.js.map +1 -0
- package/dist/media-providers/index.d.ts +22 -0
- package/dist/media-providers/index.d.ts.map +1 -0
- package/dist/media-providers/index.js +22 -0
- package/dist/media-providers/index.js.map +1 -0
- package/dist/media-providers/policy.d.ts +49 -0
- package/dist/media-providers/policy.d.ts.map +1 -0
- package/dist/media-providers/policy.js +39 -0
- package/dist/media-providers/policy.js.map +1 -0
- package/dist/media-providers/providers.d.ts +33 -0
- package/dist/media-providers/providers.d.ts.map +1 -0
- package/dist/media-providers/providers.js +200 -0
- package/dist/media-providers/providers.js.map +1 -0
- package/dist/media-providers/seed.d.ts +14 -0
- package/dist/media-providers/seed.d.ts.map +1 -0
- package/dist/media-providers/seed.js +109 -0
- package/dist/media-providers/seed.js.map +1 -0
- package/dist/media-providers/sqlite-task-store.d.ts +29 -0
- package/dist/media-providers/sqlite-task-store.d.ts.map +1 -0
- package/dist/media-providers/sqlite-task-store.js +234 -0
- package/dist/media-providers/sqlite-task-store.js.map +1 -0
- package/dist/media-providers/staging.d.ts +29 -0
- package/dist/media-providers/staging.d.ts.map +1 -0
- package/dist/media-providers/staging.js +141 -0
- package/dist/media-providers/staging.js.map +1 -0
- package/dist/media-providers/task-store.d.ts +94 -0
- package/dist/media-providers/task-store.d.ts.map +1 -0
- package/dist/media-providers/task-store.js +160 -0
- package/dist/media-providers/task-store.js.map +1 -0
- package/dist/media-providers/tokens.d.ts +7 -0
- package/dist/media-providers/tokens.d.ts.map +1 -0
- package/dist/media-providers/tokens.js +13 -0
- package/dist/media-providers/tokens.js.map +1 -0
- package/dist/media-providers/types.d.ts +123 -0
- package/dist/media-providers/types.d.ts.map +1 -0
- package/dist/media-providers/types.js +12 -0
- package/dist/media-providers/types.js.map +1 -0
- package/dist/media-providers/video-request.d.ts +62 -0
- package/dist/media-providers/video-request.d.ts.map +1 -0
- package/dist/media-providers/video-request.js +219 -0
- package/dist/media-providers/video-request.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider: xAI Grok — image generation via an OpenAI-images-compatible
|
|
3
|
+
* `/images/generations` endpoint (`renderGrokImage`), plus text-to-speech
|
|
4
|
+
* via a dedicated `/tts` endpoint (`renderXAITTS`). Ported near-verbatim
|
|
5
|
+
* from Open Design's `apps/daemon/src/media/index.ts` `renderGrokImage`/
|
|
6
|
+
* `renderXAITTS` — see `source-map.md`.
|
|
7
|
+
*
|
|
8
|
+
* Image response shape (`{ data: [{ b64_json | url }] }`) is identical to
|
|
9
|
+
* OpenAI's images API, so `renderGrokImage` routes through
|
|
10
|
+
* `openai-compatible.ts`'s already-ported JSON-parsing/byte-extraction/
|
|
11
|
+
* URL-building helpers rather than re-implementing them. `/tts` is xAI's
|
|
12
|
+
* own dedicated endpoint (not the OpenAI `/audio/speech` shape) — it
|
|
13
|
+
* returns raw audio bytes directly from a plain JSON POST, with no
|
|
14
|
+
* per-request format negotiation the caller can control, so `renderXAITTS`
|
|
15
|
+
* doesn't route through `openai-compatible.ts` at all (only the generic
|
|
16
|
+
* `truncate`/`withRequestInit` helpers are shared).
|
|
17
|
+
*
|
|
18
|
+
* Dropped from the origin's no-credential error messages (both
|
|
19
|
+
* functions): the OD-specific "sign in with your SuperGrok subscription
|
|
20
|
+
* (in OD or via `hermes auth add xai-oauth`)" OAuth guidance — this
|
|
21
|
+
* package has no OAuth chain or local-CLI-login concept; credentials are
|
|
22
|
+
* always host-injected (see `types.ts`'s `ProviderCredentials`), matching
|
|
23
|
+
* every other ported provider's error-message style (e.g. `openai.ts`'s
|
|
24
|
+
* `OPENAI_IMAGE_NO_CREDENTIAL_MESSAGE`).
|
|
25
|
+
*
|
|
26
|
+
* 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
|
|
27
|
+
* (`vendor-adapter.ts`/`vendor-registry.ts`) — two adapters registered on
|
|
28
|
+
* the same `grok` provider id (`image`/`audio:speech`). External behavior
|
|
29
|
+
* is unchanged (verified against `grok.test.ts`, which asserts URL/body/
|
|
30
|
+
* header/error-message/providerNote shape and passes unmodified) — only
|
|
31
|
+
* the internal implementation moved. The image adapter is not routed
|
|
32
|
+
* through `response-parsers.ts`'s factories (reuses
|
|
33
|
+
* `openai-compatible.ts`'s JSON-parsing helpers directly, same as before —
|
|
34
|
+
* see `imagerouter.ts`'s module doc for the identical reasoning); the TTS
|
|
35
|
+
* adapter's response (raw bytes, no envelope) is the same shape
|
|
36
|
+
* `fishaudio.ts`/`openai.ts`'s speech renderer return, so it now shares
|
|
37
|
+
* `response-parsers.ts`'s `createRawBytesParser`.
|
|
38
|
+
*/
|
|
39
|
+
import { buildOpenAIImageUrl, bytesFromOpenAICompatibleData, parseOpenAICompatibleJson, sniffImageExt, withRequestInit } from '../openai-compatible.js';
|
|
40
|
+
import { createRawBytesParser } from '../response-parsers.js';
|
|
41
|
+
import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
|
|
42
|
+
import { mediaVendorRegistry } from '../vendor-registry.js';
|
|
43
|
+
/**
|
|
44
|
+
* xAI's Imagine API accepts a wide list of aspect ratios (1:1, 16:9, 9:16,
|
|
45
|
+
* 4:3, 3:4, 3:2, 2:3, 2:1, 1:2, 19.5:9, 9:19.5, 20:9, 9:20, auto) —
|
|
46
|
+
* `providers.ts`'s `MEDIA_ASPECTS` is a strict subset, so a recognized
|
|
47
|
+
* value passes through and anything else defaults to 16:9. Written as
|
|
48
|
+
* independent `if` returns (rather than the origin's one `||`-chained
|
|
49
|
+
* condition) to match this package's established aspect-mapping style
|
|
50
|
+
* (see `imagerouter.ts`'s `imageRouterSizeFor`) — same input -> output
|
|
51
|
+
* mapping for every case, not a behavior change.
|
|
52
|
+
*/
|
|
53
|
+
export function grokAspectFor(aspect) {
|
|
54
|
+
if (aspect === '1:1')
|
|
55
|
+
return '1:1';
|
|
56
|
+
if (aspect === '16:9')
|
|
57
|
+
return '16:9';
|
|
58
|
+
if (aspect === '9:16')
|
|
59
|
+
return '9:16';
|
|
60
|
+
if (aspect === '4:3')
|
|
61
|
+
return '4:3';
|
|
62
|
+
if (aspect === '3:4')
|
|
63
|
+
return '3:4';
|
|
64
|
+
return '16:9';
|
|
65
|
+
}
|
|
66
|
+
const NO_CREDENTIAL_MESSAGE = 'no xAI credential — configure an API key or set XAI_API_KEY.';
|
|
67
|
+
const grokImageAdapter = {
|
|
68
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
69
|
+
buildRequest(ctx, credentials) {
|
|
70
|
+
const apiKey = credentials.apiKey; // requireCredential already validated this.
|
|
71
|
+
const baseUrl = (credentials.baseUrl || 'https://api.x.ai/v1').replace(/\/$/, '');
|
|
72
|
+
const aspectRatio = grokAspectFor(ctx.aspect);
|
|
73
|
+
const body = {
|
|
74
|
+
model: ctx.wireModel,
|
|
75
|
+
prompt: ctx.prompt || 'A high-quality reference image.',
|
|
76
|
+
n: 1,
|
|
77
|
+
aspect_ratio: aspectRatio,
|
|
78
|
+
response_format: 'b64_json',
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
url: buildOpenAIImageUrl(baseUrl, false),
|
|
82
|
+
init: withRequestInit(ctx, {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers: {
|
|
85
|
+
authorization: `Bearer ${apiKey}`,
|
|
86
|
+
'content-type': 'application/json',
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify(body),
|
|
89
|
+
}),
|
|
90
|
+
meta: { wireModel: ctx.wireModel, aspectRatio },
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
async parseResponse(resp, ctx, request) {
|
|
94
|
+
const data = await parseOpenAICompatibleJson(resp, 'grok image');
|
|
95
|
+
const bytes = await bytesFromOpenAICompatibleData(data, 'grok image', ctx.requestInit);
|
|
96
|
+
return {
|
|
97
|
+
bytes,
|
|
98
|
+
providerNote: `grok/${request.meta.wireModel} · ${request.meta.aspectRatio} · ${bytes.length} bytes`,
|
|
99
|
+
suggestedExt: sniffImageExt(bytes),
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
mediaVendorRegistry.register('grok', 'image', grokImageAdapter);
|
|
104
|
+
export async function renderGrokImage(ctx, credentials) {
|
|
105
|
+
return dispatchVendorRequest(grokImageAdapter, ctx, credentials);
|
|
106
|
+
}
|
|
107
|
+
const XAI_TTS_DEFAULT_VOICE_ID = 'eve';
|
|
108
|
+
const XAI_TTS_DEFAULT_LANGUAGE = 'en';
|
|
109
|
+
/**
|
|
110
|
+
* xAI's `/tts` endpoint takes only `{ text, voice_id, language }` — no
|
|
111
|
+
* per-request output-format field — and always returns mp3/24kHz/128kbps
|
|
112
|
+
* audio bytes directly (not wrapped in JSON), matching the origin exactly.
|
|
113
|
+
* `ctx.speechFormat` (used by `openai.ts`'s `renderOpenAISpeech`/AIHubMix's
|
|
114
|
+
* TTS) has no equivalent here since the wire protocol offers nothing to
|
|
115
|
+
* set it with.
|
|
116
|
+
*/
|
|
117
|
+
const xaiTTSAdapter = {
|
|
118
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
119
|
+
buildRequest(ctx, credentials) {
|
|
120
|
+
const apiKey = credentials.apiKey; // requireCredential already validated this.
|
|
121
|
+
const baseUrl = (credentials.baseUrl || 'https://api.x.ai/v1').replace(/\/$/, '');
|
|
122
|
+
const text = (ctx.prompt && ctx.prompt.trim()) || 'This is a test.';
|
|
123
|
+
const voiceId = (ctx.voice && ctx.voice.trim()) || XAI_TTS_DEFAULT_VOICE_ID;
|
|
124
|
+
const language = ctx.language.trim() || XAI_TTS_DEFAULT_LANGUAGE;
|
|
125
|
+
const body = { text, voice_id: voiceId, language };
|
|
126
|
+
return {
|
|
127
|
+
url: `${baseUrl}/tts`,
|
|
128
|
+
init: withRequestInit(ctx, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
authorization: `Bearer ${apiKey}`,
|
|
132
|
+
'content-type': 'application/json',
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify(body),
|
|
135
|
+
}),
|
|
136
|
+
meta: { wireModel: ctx.wireModel, voiceId, language },
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
parseResponse: createRawBytesParser({
|
|
140
|
+
errorTag: 'xai tts',
|
|
141
|
+
zeroBytesMessage: 'xai tts response had zero bytes',
|
|
142
|
+
note: (bytes, meta) => `xai/${meta.wireModel} · voice=${meta.voiceId} · ${meta.language} · ${bytes.length} bytes`,
|
|
143
|
+
suggestedExt: '.mp3',
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
mediaVendorRegistry.register('grok', 'audio:speech', xaiTTSAdapter);
|
|
147
|
+
export async function renderXAITTS(ctx, credentials) {
|
|
148
|
+
return dispatchVendorRequest(xaiTTSAdapter, ctx, credentials);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=grok.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/grok.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ProviderCredentials, RenderContext, RenderResult } from '../types.js';
|
|
2
|
+
/** ImageRouter's image/video generation `size` string for a given aspect ratio. */
|
|
3
|
+
export declare function imageRouterSizeFor(aspect: string | undefined, surface: 'image' | 'video'): string;
|
|
4
|
+
export declare function renderImageRouterImage(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
|
|
5
|
+
export declare function renderImageRouterVideo(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
|
|
6
|
+
//# sourceMappingURL=imagerouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagerouter.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/imagerouter.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKpF,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAajG;AAqDD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAExH;AAqDD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAExH"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider: ImageRouter — OpenAI-compatible image + video generation
|
|
3
|
+
* routing (`https://api.imagerouter.io/v1/openai`). Ported near-verbatim
|
|
4
|
+
* from Open Design's `apps/daemon/src/media/index.ts`
|
|
5
|
+
* `renderImageRouterImage`/`renderImageRouterVideo` — see `source-map.md`.
|
|
6
|
+
*
|
|
7
|
+
* 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
|
|
8
|
+
* (`vendor-adapter.ts`/`vendor-registry.ts`) — two adapters registered on
|
|
9
|
+
* the same `imagerouter` provider id, one per surface (`image`/`video`).
|
|
10
|
+
* External behavior is unchanged (verified against `imagerouter.test.ts`,
|
|
11
|
+
* which asserts URL/body/error-message/providerNote shape and passes
|
|
12
|
+
* unmodified) — only the internal implementation moved. Neither adapter
|
|
13
|
+
* routes through `response-parsers.ts`'s factories — this vendor's
|
|
14
|
+
* `{ data: [...] }` JSON envelope isn't the "no envelope" raw-bytes shape
|
|
15
|
+
* either factory covers; both keep reusing `openai-compatible.ts`'s
|
|
16
|
+
* `parseOpenAICompatibleJson`/`bytesFromOpenAICompatibleData` helpers
|
|
17
|
+
* directly, same as before this pass.
|
|
18
|
+
*/
|
|
19
|
+
import { buildOpenAIImageUrl, buildOpenAIVideoUrl, bytesFromOpenAICompatibleData, parseOpenAICompatibleJson, sniffImageExt, withRequestInit, } from '../openai-compatible.js';
|
|
20
|
+
import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
|
|
21
|
+
import { mediaVendorRegistry } from '../vendor-registry.js';
|
|
22
|
+
/** ImageRouter's image/video generation `size` string for a given aspect ratio. */
|
|
23
|
+
export function imageRouterSizeFor(aspect, surface) {
|
|
24
|
+
if (surface === 'video') {
|
|
25
|
+
if (aspect === '1:1')
|
|
26
|
+
return '1024x1024';
|
|
27
|
+
if (aspect === '9:16')
|
|
28
|
+
return '576x1024';
|
|
29
|
+
if (aspect === '4:3')
|
|
30
|
+
return '1024x768';
|
|
31
|
+
if (aspect === '3:4')
|
|
32
|
+
return '768x1024';
|
|
33
|
+
return '1024x576';
|
|
34
|
+
}
|
|
35
|
+
if (aspect === '16:9')
|
|
36
|
+
return '1024x576';
|
|
37
|
+
if (aspect === '9:16')
|
|
38
|
+
return '576x1024';
|
|
39
|
+
if (aspect === '4:3')
|
|
40
|
+
return '1024x768';
|
|
41
|
+
if (aspect === '3:4')
|
|
42
|
+
return '768x1024';
|
|
43
|
+
return '1024x1024';
|
|
44
|
+
}
|
|
45
|
+
const NO_CREDENTIAL_MESSAGE = 'no ImageRouter API key — configure it or set IMAGEROUTER_API_KEY';
|
|
46
|
+
const imageRouterImageAdapter = {
|
|
47
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
48
|
+
buildRequest(ctx, credentials) {
|
|
49
|
+
const apiKey = credentials.apiKey; // requireCredential already validated this.
|
|
50
|
+
const baseUrl = (credentials.baseUrl || 'https://api.imagerouter.io/v1/openai').trim();
|
|
51
|
+
const wireModel = (credentials.model || ctx.wireModel).trim();
|
|
52
|
+
const size = imageRouterSizeFor(ctx.aspect, 'image');
|
|
53
|
+
const body = {
|
|
54
|
+
prompt: ctx.prompt || 'A high-quality reference image.',
|
|
55
|
+
model: wireModel,
|
|
56
|
+
quality: 'auto',
|
|
57
|
+
size,
|
|
58
|
+
response_format: 'b64_json',
|
|
59
|
+
output_format: 'png',
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
url: buildOpenAIImageUrl(baseUrl, false),
|
|
63
|
+
init: withRequestInit(ctx, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
authorization: `Bearer ${apiKey}`,
|
|
67
|
+
'content-type': 'application/json',
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify(body),
|
|
70
|
+
}),
|
|
71
|
+
meta: { wireModel, size },
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
async parseResponse(resp, ctx, request) {
|
|
75
|
+
const data = await parseOpenAICompatibleJson(resp, 'imagerouter image');
|
|
76
|
+
const bytes = await bytesFromOpenAICompatibleData(data, 'imagerouter image', ctx.requestInit);
|
|
77
|
+
return {
|
|
78
|
+
bytes,
|
|
79
|
+
providerNote: `imagerouter/${request.meta.wireModel} · ${request.meta.size} · ${bytes.length} bytes`,
|
|
80
|
+
suggestedExt: sniffImageExt(bytes),
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
mediaVendorRegistry.register('imagerouter', 'image', imageRouterImageAdapter);
|
|
85
|
+
export async function renderImageRouterImage(ctx, credentials) {
|
|
86
|
+
return dispatchVendorRequest(imageRouterImageAdapter, ctx, credentials);
|
|
87
|
+
}
|
|
88
|
+
const imageRouterVideoAdapter = {
|
|
89
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
90
|
+
buildRequest(ctx, credentials) {
|
|
91
|
+
const apiKey = credentials.apiKey; // requireCredential already validated this.
|
|
92
|
+
const baseUrl = (credentials.baseUrl || 'https://api.imagerouter.io/v1/openai').trim();
|
|
93
|
+
const wireModel = (credentials.model || ctx.wireModel).trim();
|
|
94
|
+
const seconds = typeof ctx.length === 'number' ? ctx.length : 'auto';
|
|
95
|
+
const size = imageRouterSizeFor(ctx.aspect, 'video');
|
|
96
|
+
const body = {
|
|
97
|
+
prompt: ctx.prompt || 'A short cinematic clip.',
|
|
98
|
+
model: wireModel,
|
|
99
|
+
size,
|
|
100
|
+
seconds,
|
|
101
|
+
response_format: 'b64_json',
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
url: buildOpenAIVideoUrl(baseUrl),
|
|
105
|
+
init: withRequestInit(ctx, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
headers: {
|
|
108
|
+
authorization: `Bearer ${apiKey}`,
|
|
109
|
+
'content-type': 'application/json',
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify(body),
|
|
112
|
+
}),
|
|
113
|
+
meta: { wireModel, size, seconds },
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
async parseResponse(resp, ctx, request) {
|
|
117
|
+
const data = await parseOpenAICompatibleJson(resp, 'imagerouter video');
|
|
118
|
+
const bytes = await bytesFromOpenAICompatibleData(data, 'imagerouter video', ctx.requestInit);
|
|
119
|
+
const { wireModel, size, seconds } = request.meta;
|
|
120
|
+
return {
|
|
121
|
+
bytes,
|
|
122
|
+
providerNote: `imagerouter/${wireModel} · ${size} · ${seconds === 'auto' ? 'auto' : `${seconds}s`} · ${bytes.length} bytes`,
|
|
123
|
+
suggestedExt: '.mp4',
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
mediaVendorRegistry.register('imagerouter', 'video', imageRouterVideoAdapter);
|
|
128
|
+
export async function renderImageRouterVideo(ctx, credentials) {
|
|
129
|
+
return dispatchVendorRequest(imageRouterVideoAdapter, ctx, credentials);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=imagerouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagerouter.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/imagerouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimax.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/minimax.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkEpF,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAElH"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider: MiniMax — Speech-02 family text-to-speech (synchronous,
|
|
3
|
+
* `POST /t2a_v2`). Ported near-verbatim from Open Design's
|
|
4
|
+
* `apps/daemon/src/media/index.ts` `renderMinimaxTTS` — see
|
|
5
|
+
* `source-map.md`.
|
|
6
|
+
*
|
|
7
|
+
* 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
|
|
8
|
+
* (`vendor-adapter.ts`/`vendor-registry.ts`) — `renderMinimaxTTS`'s
|
|
9
|
+
* external behavior (URL, body, headers, every error message,
|
|
10
|
+
* `providerNote` format) is unchanged; only the internal implementation
|
|
11
|
+
* moved from one hand-written async function into a registered
|
|
12
|
+
* `VendorAdapter` dispatched via `dispatchVendorRequest`. Its response
|
|
13
|
+
* envelope (hex-encoded audio inside a `base_resp`-wrapped JSON body) is
|
|
14
|
+
* identical to `senseaudio.ts`'s TTS renderer, so both now share
|
|
15
|
+
* `response-parsers.ts`'s `createHexEnvelopeAudioParser` — the first real,
|
|
16
|
+
* observable de-duplication this engine buys, not just a mechanical
|
|
17
|
+
* reshuffle.
|
|
18
|
+
*
|
|
19
|
+
* Not OpenAI-wire-compatible — MiniMax's request body
|
|
20
|
+
* (`voice_setting`/`audio_setting`) and response shape share nothing with
|
|
21
|
+
* `/audio/speech`, so this does not route through `openai-compatible.ts`'s
|
|
22
|
+
* JSON-parsing helpers — only the genuinely vendor-agnostic
|
|
23
|
+
* `withRequestInit` is reused (matching `nanobanana.ts`'s/`openrouter.ts`'s
|
|
24
|
+
* reasoning for the same call).
|
|
25
|
+
*
|
|
26
|
+
* `renderMinimaxImage` (a *different* surface on the same provider slot,
|
|
27
|
+
* gated behind its own `OD_MINIMAX_IMAGE_BASE_URL` env var read directly
|
|
28
|
+
* from `process.env` in the origin) is intentionally not ported — this
|
|
29
|
+
* package never reads `process.env` itself (see `providers.ts`'s standing
|
|
30
|
+
* invariant) and the task for this pass only covers MiniMax TTS.
|
|
31
|
+
*
|
|
32
|
+
* Dropped from the origin's no-credential error message: the `OD_`-
|
|
33
|
+
* prefixed override env var (`OD_MINIMAX_API_KEY`) — `providers.ts`'s
|
|
34
|
+
* `PROVIDER_CREDENTIAL_ENV_VARS.minimax` already de-branded this to plain
|
|
35
|
+
* `MINIMAX_API_KEY`.
|
|
36
|
+
*/
|
|
37
|
+
import { withRequestInit } from '../openai-compatible.js';
|
|
38
|
+
import { createHexEnvelopeAudioParser } from '../response-parsers.js';
|
|
39
|
+
import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
|
|
40
|
+
import { mediaVendorRegistry } from '../vendor-registry.js';
|
|
41
|
+
const MINIMAX_DEFAULT_BASE_URL = 'https://api.minimaxi.chat/v1';
|
|
42
|
+
const MINIMAX_DEFAULT_VOICE_ID = 'male-qn-qingse';
|
|
43
|
+
const MINIMAX_TTS_MODEL_MAP = {
|
|
44
|
+
'minimax-tts': 'speech-02-turbo',
|
|
45
|
+
};
|
|
46
|
+
const NO_CREDENTIAL_MESSAGE = 'no MiniMax credential — configure an API key or set MINIMAX_API_KEY.';
|
|
47
|
+
const minimaxTTSAdapter = {
|
|
48
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
49
|
+
buildRequest(ctx, credentials) {
|
|
50
|
+
// Safe: `requireCredential` above already validated this is set before
|
|
51
|
+
// `dispatchVendorRequest` ever calls `buildRequest`.
|
|
52
|
+
const apiKey = credentials.apiKey;
|
|
53
|
+
const baseUrl = (credentials.baseUrl || MINIMAX_DEFAULT_BASE_URL).replace(/\/$/, '');
|
|
54
|
+
// Precedence: an explicit caller alias (ctx.wireModel set to something
|
|
55
|
+
// other than the catalog id) wins over the legacy MiniMax rename map,
|
|
56
|
+
// which in turn wins over passing the catalog id through unchanged.
|
|
57
|
+
const wireModel = ctx.wireModel !== ctx.model ? ctx.wireModel : MINIMAX_TTS_MODEL_MAP[ctx.model] || ctx.model;
|
|
58
|
+
const text = (ctx.prompt && ctx.prompt.trim()) || 'This is a test.';
|
|
59
|
+
const voiceId = (ctx.voice && ctx.voice.trim()) || MINIMAX_DEFAULT_VOICE_ID;
|
|
60
|
+
const languageBoost = ctx.language.trim();
|
|
61
|
+
const body = {
|
|
62
|
+
model: wireModel,
|
|
63
|
+
text,
|
|
64
|
+
stream: false,
|
|
65
|
+
...(languageBoost ? { language_boost: languageBoost } : {}),
|
|
66
|
+
voice_setting: {
|
|
67
|
+
voice_id: voiceId,
|
|
68
|
+
speed: 1.0,
|
|
69
|
+
vol: 1.0,
|
|
70
|
+
pitch: 0,
|
|
71
|
+
},
|
|
72
|
+
audio_setting: {
|
|
73
|
+
sample_rate: 32000,
|
|
74
|
+
format: 'mp3',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
url: `${baseUrl}/t2a_v2`,
|
|
79
|
+
init: withRequestInit(ctx, {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers: {
|
|
82
|
+
authorization: `Bearer ${apiKey}`,
|
|
83
|
+
'content-type': 'application/json',
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify(body),
|
|
86
|
+
}),
|
|
87
|
+
meta: { wireModel, voiceId },
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
parseResponse: createHexEnvelopeAudioParser({ errorTag: 'minimax tts', providerId: 'minimax' }),
|
|
91
|
+
};
|
|
92
|
+
mediaVendorRegistry.register('minimax', 'audio:speech', minimaxTTSAdapter);
|
|
93
|
+
export async function renderMinimaxTTS(ctx, credentials) {
|
|
94
|
+
return dispatchVendorRequest(minimaxTTSAdapter, ctx, credentials);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=minimax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimax.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/minimax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nanobanana.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/nanobanana.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA0HpF,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider: Nano Banana (Google Gemini image generation) —
|
|
3
|
+
* `POST /v1beta/models/{model}:generateContent`. Ported near-verbatim from
|
|
4
|
+
* Open Design's `apps/daemon/src/media/index.ts` `renderNanoBananaImage`
|
|
5
|
+
* (plus its `nanoBananaHeaders`/`usesOfficialGoogleApiKeyHeader`/
|
|
6
|
+
* `nanoBananaAspectFor`/`inlineImageBytesFromGenerateContent` helpers) —
|
|
7
|
+
* see `source-map.md`.
|
|
8
|
+
*
|
|
9
|
+
* Not OpenAI-images-wire-compatible — Gemini's `generateContent` request
|
|
10
|
+
* shape (`contents[].parts[].text` + `generationConfig`) and response shape
|
|
11
|
+
* (`candidates[].content.parts[].inlineData.data`) are unrelated to
|
|
12
|
+
* `/images/generations`'s `{ data: [{ b64_json | url }] }` — so this does
|
|
13
|
+
* not route through `openai-compatible.ts`'s OpenAI-images helpers; only
|
|
14
|
+
* its genuinely vendor-agnostic utilities (`truncate`, `sniffImageExt`,
|
|
15
|
+
* `withRequestInit`) are reused.
|
|
16
|
+
*
|
|
17
|
+
* 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
|
|
18
|
+
* (`vendor-adapter.ts`/`vendor-registry.ts`). External behavior is
|
|
19
|
+
* unchanged (verified against `nanobanana.test.ts`, which asserts URL/
|
|
20
|
+
* body/header/error-message/providerNote shape and passes unmodified) —
|
|
21
|
+
* only the internal implementation moved into a registered
|
|
22
|
+
* `VendorAdapter`. Not routed through `response-parsers.ts`'s factories:
|
|
23
|
+
* this Gemini `candidates[].content.parts[].inlineData.data` shape has no
|
|
24
|
+
* other current consumer with byte-for-byte identical error messages (see
|
|
25
|
+
* `aihubmix.ts`'s own Gemini-native branch, which throws differently-
|
|
26
|
+
* tagged errors), so it correctly stays a bespoke `parseResponse`.
|
|
27
|
+
*/
|
|
28
|
+
import { sniffImageExt, truncate, withRequestInit } from '../openai-compatible.js';
|
|
29
|
+
import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
|
|
30
|
+
import { mediaVendorRegistry } from '../vendor-registry.js';
|
|
31
|
+
const NANOBANANA_DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com';
|
|
32
|
+
const NANOBANANA_DEFAULT_MODEL = 'gemini-3.1-flash-image-preview';
|
|
33
|
+
const NANOBANANA_DEFAULT_IMAGE_SIZE = '1K';
|
|
34
|
+
/** Google's official Gemini API wants an `x-goog-api-key` header; any other host (a custom gateway/proxy) gets a standard `Authorization: Bearer` header instead. */
|
|
35
|
+
function usesOfficialGoogleApiKeyHeader(baseUrl) {
|
|
36
|
+
try {
|
|
37
|
+
return new URL(baseUrl).hostname === 'generativelanguage.googleapis.com';
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function nanoBananaHeaders(baseUrl, apiKey) {
|
|
44
|
+
const headers = { 'content-type': 'application/json' };
|
|
45
|
+
if (usesOfficialGoogleApiKeyHeader(baseUrl)) {
|
|
46
|
+
headers['x-goog-api-key'] = apiKey;
|
|
47
|
+
return headers;
|
|
48
|
+
}
|
|
49
|
+
headers.authorization = `Bearer ${apiKey}`;
|
|
50
|
+
return headers;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* `providers.ts`'s `MEDIA_ASPECTS` are all natively supported by Nano
|
|
54
|
+
* Banana's `imageConfig.aspectRatio`; anything else defaults to `'1:1'`.
|
|
55
|
+
* Written as independent `if` returns (rather than the origin's one
|
|
56
|
+
* `||`-chained condition) to match this package's established
|
|
57
|
+
* aspect-mapping style (see `imagerouter.ts`'s `imageRouterSizeFor`) — same
|
|
58
|
+
* input -> output mapping for every case, not a behavior change.
|
|
59
|
+
*/
|
|
60
|
+
function nanoBananaAspectFor(aspect) {
|
|
61
|
+
if (aspect === '1:1')
|
|
62
|
+
return '1:1';
|
|
63
|
+
if (aspect === '16:9')
|
|
64
|
+
return '16:9';
|
|
65
|
+
if (aspect === '9:16')
|
|
66
|
+
return '9:16';
|
|
67
|
+
if (aspect === '4:3')
|
|
68
|
+
return '4:3';
|
|
69
|
+
if (aspect === '3:4')
|
|
70
|
+
return '3:4';
|
|
71
|
+
return '1:1';
|
|
72
|
+
}
|
|
73
|
+
function inlineImageBytesFromGenerateContent(data) {
|
|
74
|
+
const candidates = data?.candidates;
|
|
75
|
+
if (Array.isArray(candidates)) {
|
|
76
|
+
for (const candidate of candidates) {
|
|
77
|
+
const parts = candidate?.content?.parts;
|
|
78
|
+
if (Array.isArray(parts)) {
|
|
79
|
+
for (const part of parts) {
|
|
80
|
+
const inline = part?.inlineData;
|
|
81
|
+
if (typeof inline?.data === 'string' && inline.data) {
|
|
82
|
+
return Buffer.from(inline.data, 'base64');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
throw new Error('nano-banana image response missing candidates[].content.parts[].inlineData.data');
|
|
89
|
+
}
|
|
90
|
+
const NO_CREDENTIAL_MESSAGE = 'no Nano Banana credential — configure an API key or set GOOGLE_API_KEY / GEMINI_API_KEY.';
|
|
91
|
+
const nanoBananaImageAdapter = {
|
|
92
|
+
requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
|
|
93
|
+
buildRequest(ctx, credentials) {
|
|
94
|
+
const apiKey = credentials.apiKey; // requireCredential already validated this.
|
|
95
|
+
const baseUrl = (credentials.baseUrl || NANOBANANA_DEFAULT_BASE_URL).replace(/\/$/, '');
|
|
96
|
+
const wireModel = (credentials.model || ctx.wireModel || NANOBANANA_DEFAULT_MODEL).trim();
|
|
97
|
+
const aspectRatio = nanoBananaAspectFor(ctx.aspect);
|
|
98
|
+
const body = {
|
|
99
|
+
contents: [{ parts: [{ text: ctx.prompt || 'A high-quality reference image.' }] }],
|
|
100
|
+
generationConfig: {
|
|
101
|
+
responseModalities: ['IMAGE'],
|
|
102
|
+
imageConfig: {
|
|
103
|
+
aspectRatio,
|
|
104
|
+
imageSize: NANOBANANA_DEFAULT_IMAGE_SIZE,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
url: `${baseUrl}/v1beta/models/${encodeURIComponent(wireModel)}:generateContent`,
|
|
110
|
+
init: withRequestInit(ctx, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: nanoBananaHeaders(baseUrl, apiKey),
|
|
113
|
+
body: JSON.stringify(body),
|
|
114
|
+
}),
|
|
115
|
+
meta: { wireModel, aspectRatio },
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
async parseResponse(resp, _ctx, request) {
|
|
119
|
+
const text = await resp.text();
|
|
120
|
+
if (!resp.ok) {
|
|
121
|
+
throw new Error(`nano-banana image ${resp.status}: ${truncate(text, 240)}`);
|
|
122
|
+
}
|
|
123
|
+
let data;
|
|
124
|
+
try {
|
|
125
|
+
data = JSON.parse(text);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
throw new Error(`nano-banana image non-JSON response: ${truncate(text, 200)}`);
|
|
129
|
+
}
|
|
130
|
+
const bytes = inlineImageBytesFromGenerateContent(data);
|
|
131
|
+
return {
|
|
132
|
+
bytes,
|
|
133
|
+
providerNote: `nano-banana/${request.meta.wireModel} · ${request.meta.aspectRatio} · ${NANOBANANA_DEFAULT_IMAGE_SIZE} · ${bytes.length} bytes`,
|
|
134
|
+
suggestedExt: sniffImageExt(bytes),
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
mediaVendorRegistry.register('nanobanana', 'image', nanoBananaImageAdapter);
|
|
139
|
+
export async function renderNanoBananaImage(ctx, credentials) {
|
|
140
|
+
return dispatchVendorRequest(nanoBananaImageAdapter, ctx, credentials);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=nanobanana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nanobanana.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/nanobanana.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProviderCredentials, RenderContext, RenderResult } from '../types.js';
|
|
2
|
+
export declare function renderOpenAIImage(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
|
|
3
|
+
export declare function renderOpenAISpeech(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
|
|
4
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/openai.ts"],"names":[],"mappings":"AAyDA,OAAO,KAAK,EAAqB,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyHvG,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnH;AAkFD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEpH"}
|