@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.
Files changed (191) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +51 -0
  3. package/dist/composio/bounded-data.d.ts +36 -0
  4. package/dist/composio/bounded-data.d.ts.map +1 -0
  5. package/dist/composio/bounded-data.js +181 -0
  6. package/dist/composio/bounded-data.js.map +1 -0
  7. package/dist/composio/catalog.d.ts +147 -0
  8. package/dist/composio/catalog.d.ts.map +1 -0
  9. package/dist/composio/catalog.js +126 -0
  10. package/dist/composio/catalog.js.map +1 -0
  11. package/dist/composio/composio-config.d.ts +42 -0
  12. package/dist/composio/composio-config.d.ts.map +1 -0
  13. package/dist/composio/composio-config.js +145 -0
  14. package/dist/composio/composio-config.js.map +1 -0
  15. package/dist/composio/composio-descriptions.d.ts +16 -0
  16. package/dist/composio/composio-descriptions.d.ts.map +1 -0
  17. package/dist/composio/composio-descriptions.js +766 -0
  18. package/dist/composio/composio-descriptions.js.map +1 -0
  19. package/dist/composio/composio.d.ts +364 -0
  20. package/dist/composio/composio.d.ts.map +1 -0
  21. package/dist/composio/composio.js +1902 -0
  22. package/dist/composio/composio.js.map +1 -0
  23. package/dist/composio/errors.d.ts +15 -0
  24. package/dist/composio/errors.d.ts.map +1 -0
  25. package/dist/composio/errors.js +16 -0
  26. package/dist/composio/errors.js.map +1 -0
  27. package/dist/composio/file-lock.d.ts +13 -0
  28. package/dist/composio/file-lock.d.ts.map +1 -0
  29. package/dist/composio/file-lock.js +92 -0
  30. package/dist/composio/file-lock.js.map +1 -0
  31. package/dist/composio/index.d.ts +18 -0
  32. package/dist/composio/index.d.ts.map +1 -0
  33. package/dist/composio/index.js +7 -0
  34. package/dist/composio/index.js.map +1 -0
  35. package/dist/composio/json-schema.d.ts +93 -0
  36. package/dist/composio/json-schema.d.ts.map +1 -0
  37. package/dist/composio/json-schema.js +498 -0
  38. package/dist/composio/json-schema.js.map +1 -0
  39. package/dist/composio/output-protection.d.ts +32 -0
  40. package/dist/composio/output-protection.d.ts.map +1 -0
  41. package/dist/composio/output-protection.js +105 -0
  42. package/dist/composio/output-protection.js.map +1 -0
  43. package/dist/composio/service.d.ts +181 -0
  44. package/dist/composio/service.d.ts.map +1 -0
  45. package/dist/composio/service.js +758 -0
  46. package/dist/composio/service.js.map +1 -0
  47. package/dist/media-providers/capability-registry.d.ts +28 -0
  48. package/dist/media-providers/capability-registry.d.ts.map +1 -0
  49. package/dist/media-providers/capability-registry.js +27 -0
  50. package/dist/media-providers/capability-registry.js.map +1 -0
  51. package/dist/media-providers/catalog.d.ts +20 -0
  52. package/dist/media-providers/catalog.d.ts.map +1 -0
  53. package/dist/media-providers/catalog.js +20 -0
  54. package/dist/media-providers/catalog.js.map +1 -0
  55. package/dist/media-providers/dispatch/context.d.ts +21 -0
  56. package/dist/media-providers/dispatch/context.d.ts.map +1 -0
  57. package/dist/media-providers/dispatch/context.js +36 -0
  58. package/dist/media-providers/dispatch/context.js.map +1 -0
  59. package/dist/media-providers/dispatch/credentials.d.ts +4 -0
  60. package/dist/media-providers/dispatch/credentials.d.ts.map +1 -0
  61. package/dist/media-providers/dispatch/credentials.js +25 -0
  62. package/dist/media-providers/dispatch/credentials.js.map +1 -0
  63. package/dist/media-providers/dispatch/engine.d.ts +30 -0
  64. package/dist/media-providers/dispatch/engine.d.ts.map +1 -0
  65. package/dist/media-providers/dispatch/engine.js +208 -0
  66. package/dist/media-providers/dispatch/engine.js.map +1 -0
  67. package/dist/media-providers/dispatch/index.d.ts +25 -0
  68. package/dist/media-providers/dispatch/index.d.ts.map +1 -0
  69. package/dist/media-providers/dispatch/index.js +24 -0
  70. package/dist/media-providers/dispatch/index.js.map +1 -0
  71. package/dist/media-providers/dispatch/openai-compatible.d.ts +44 -0
  72. package/dist/media-providers/dispatch/openai-compatible.d.ts.map +1 -0
  73. package/dist/media-providers/dispatch/openai-compatible.js +214 -0
  74. package/dist/media-providers/dispatch/openai-compatible.js.map +1 -0
  75. package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts +72 -0
  76. package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts.map +1 -0
  77. package/dist/media-providers/dispatch/providers/aihubmix-shared.js +131 -0
  78. package/dist/media-providers/dispatch/providers/aihubmix-shared.js.map +1 -0
  79. package/dist/media-providers/dispatch/providers/aihubmix.d.ts +4 -0
  80. package/dist/media-providers/dispatch/providers/aihubmix.d.ts.map +1 -0
  81. package/dist/media-providers/dispatch/providers/aihubmix.js +205 -0
  82. package/dist/media-providers/dispatch/providers/aihubmix.js.map +1 -0
  83. package/dist/media-providers/dispatch/providers/custom-image.d.ts +6 -0
  84. package/dist/media-providers/dispatch/providers/custom-image.d.ts.map +1 -0
  85. package/dist/media-providers/dispatch/providers/custom-image.js +94 -0
  86. package/dist/media-providers/dispatch/providers/custom-image.js.map +1 -0
  87. package/dist/media-providers/dispatch/providers/elevenlabs.d.ts +4 -0
  88. package/dist/media-providers/dispatch/providers/elevenlabs.d.ts.map +1 -0
  89. package/dist/media-providers/dispatch/providers/elevenlabs.js +163 -0
  90. package/dist/media-providers/dispatch/providers/elevenlabs.js.map +1 -0
  91. package/dist/media-providers/dispatch/providers/fishaudio.d.ts +3 -0
  92. package/dist/media-providers/dispatch/providers/fishaudio.d.ts.map +1 -0
  93. package/dist/media-providers/dispatch/providers/fishaudio.js +83 -0
  94. package/dist/media-providers/dispatch/providers/fishaudio.js.map +1 -0
  95. package/dist/media-providers/dispatch/providers/grok.d.ts +15 -0
  96. package/dist/media-providers/dispatch/providers/grok.d.ts.map +1 -0
  97. package/dist/media-providers/dispatch/providers/grok.js +150 -0
  98. package/dist/media-providers/dispatch/providers/grok.js.map +1 -0
  99. package/dist/media-providers/dispatch/providers/imagerouter.d.ts +6 -0
  100. package/dist/media-providers/dispatch/providers/imagerouter.d.ts.map +1 -0
  101. package/dist/media-providers/dispatch/providers/imagerouter.js +131 -0
  102. package/dist/media-providers/dispatch/providers/imagerouter.js.map +1 -0
  103. package/dist/media-providers/dispatch/providers/minimax.d.ts +3 -0
  104. package/dist/media-providers/dispatch/providers/minimax.d.ts.map +1 -0
  105. package/dist/media-providers/dispatch/providers/minimax.js +96 -0
  106. package/dist/media-providers/dispatch/providers/minimax.js.map +1 -0
  107. package/dist/media-providers/dispatch/providers/nanobanana.d.ts +3 -0
  108. package/dist/media-providers/dispatch/providers/nanobanana.d.ts.map +1 -0
  109. package/dist/media-providers/dispatch/providers/nanobanana.js +142 -0
  110. package/dist/media-providers/dispatch/providers/nanobanana.js.map +1 -0
  111. package/dist/media-providers/dispatch/providers/openai.d.ts +4 -0
  112. package/dist/media-providers/dispatch/providers/openai.d.ts.map +1 -0
  113. package/dist/media-providers/dispatch/providers/openai.js +231 -0
  114. package/dist/media-providers/dispatch/providers/openai.js.map +1 -0
  115. package/dist/media-providers/dispatch/providers/openrouter.d.ts +13 -0
  116. package/dist/media-providers/dispatch/providers/openrouter.d.ts.map +1 -0
  117. package/dist/media-providers/dispatch/providers/openrouter.js +152 -0
  118. package/dist/media-providers/dispatch/providers/openrouter.js.map +1 -0
  119. package/dist/media-providers/dispatch/providers/senseaudio.d.ts +4 -0
  120. package/dist/media-providers/dispatch/providers/senseaudio.d.ts.map +1 -0
  121. package/dist/media-providers/dispatch/providers/senseaudio.js +190 -0
  122. package/dist/media-providers/dispatch/providers/senseaudio.js.map +1 -0
  123. package/dist/media-providers/dispatch/providers/volcengine.d.ts +3 -0
  124. package/dist/media-providers/dispatch/providers/volcengine.d.ts.map +1 -0
  125. package/dist/media-providers/dispatch/providers/volcengine.js +95 -0
  126. package/dist/media-providers/dispatch/providers/volcengine.js.map +1 -0
  127. package/dist/media-providers/dispatch/response-parsers.d.ts +44 -0
  128. package/dist/media-providers/dispatch/response-parsers.d.ts.map +1 -0
  129. package/dist/media-providers/dispatch/response-parsers.js +103 -0
  130. package/dist/media-providers/dispatch/response-parsers.js.map +1 -0
  131. package/dist/media-providers/dispatch/ssrf-guard.d.ts +51 -0
  132. package/dist/media-providers/dispatch/ssrf-guard.d.ts.map +1 -0
  133. package/dist/media-providers/dispatch/ssrf-guard.js +215 -0
  134. package/dist/media-providers/dispatch/ssrf-guard.js.map +1 -0
  135. package/dist/media-providers/dispatch/stub.d.ts +5 -0
  136. package/dist/media-providers/dispatch/stub.d.ts.map +1 -0
  137. package/dist/media-providers/dispatch/stub.js +98 -0
  138. package/dist/media-providers/dispatch/stub.js.map +1 -0
  139. package/dist/media-providers/dispatch/types.d.ts +133 -0
  140. package/dist/media-providers/dispatch/types.d.ts.map +1 -0
  141. package/dist/media-providers/dispatch/types.js +2 -0
  142. package/dist/media-providers/dispatch/types.js.map +1 -0
  143. package/dist/media-providers/dispatch/vendor-adapter.d.ts +54 -0
  144. package/dist/media-providers/dispatch/vendor-adapter.d.ts.map +1 -0
  145. package/dist/media-providers/dispatch/vendor-adapter.js +68 -0
  146. package/dist/media-providers/dispatch/vendor-adapter.js.map +1 -0
  147. package/dist/media-providers/dispatch/vendor-registry.d.ts +36 -0
  148. package/dist/media-providers/dispatch/vendor-registry.d.ts.map +1 -0
  149. package/dist/media-providers/dispatch/vendor-registry.js +46 -0
  150. package/dist/media-providers/dispatch/vendor-registry.js.map +1 -0
  151. package/dist/media-providers/index.d.ts +22 -0
  152. package/dist/media-providers/index.d.ts.map +1 -0
  153. package/dist/media-providers/index.js +22 -0
  154. package/dist/media-providers/index.js.map +1 -0
  155. package/dist/media-providers/policy.d.ts +49 -0
  156. package/dist/media-providers/policy.d.ts.map +1 -0
  157. package/dist/media-providers/policy.js +39 -0
  158. package/dist/media-providers/policy.js.map +1 -0
  159. package/dist/media-providers/providers.d.ts +33 -0
  160. package/dist/media-providers/providers.d.ts.map +1 -0
  161. package/dist/media-providers/providers.js +200 -0
  162. package/dist/media-providers/providers.js.map +1 -0
  163. package/dist/media-providers/seed.d.ts +14 -0
  164. package/dist/media-providers/seed.d.ts.map +1 -0
  165. package/dist/media-providers/seed.js +109 -0
  166. package/dist/media-providers/seed.js.map +1 -0
  167. package/dist/media-providers/sqlite-task-store.d.ts +29 -0
  168. package/dist/media-providers/sqlite-task-store.d.ts.map +1 -0
  169. package/dist/media-providers/sqlite-task-store.js +234 -0
  170. package/dist/media-providers/sqlite-task-store.js.map +1 -0
  171. package/dist/media-providers/staging.d.ts +29 -0
  172. package/dist/media-providers/staging.d.ts.map +1 -0
  173. package/dist/media-providers/staging.js +141 -0
  174. package/dist/media-providers/staging.js.map +1 -0
  175. package/dist/media-providers/task-store.d.ts +94 -0
  176. package/dist/media-providers/task-store.d.ts.map +1 -0
  177. package/dist/media-providers/task-store.js +160 -0
  178. package/dist/media-providers/task-store.js.map +1 -0
  179. package/dist/media-providers/tokens.d.ts +7 -0
  180. package/dist/media-providers/tokens.d.ts.map +1 -0
  181. package/dist/media-providers/tokens.js +13 -0
  182. package/dist/media-providers/tokens.js.map +1 -0
  183. package/dist/media-providers/types.d.ts +123 -0
  184. package/dist/media-providers/types.d.ts.map +1 -0
  185. package/dist/media-providers/types.js +12 -0
  186. package/dist/media-providers/types.js.map +1 -0
  187. package/dist/media-providers/video-request.d.ts +62 -0
  188. package/dist/media-providers/video-request.d.ts.map +1 -0
  189. package/dist/media-providers/video-request.js +219 -0
  190. package/dist/media-providers/video-request.js.map +1 -0
  191. package/package.json +93 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Provider: OpenAI Images API (gpt-image-2, gpt-image-1.5, dall-e-3, ...)
3
+ * and text-to-speech via `/v1/audio/speech`. Ported near-verbatim from
4
+ * Open Design's `apps/daemon/src/media/index.ts` `renderOpenAIImage`/
5
+ * `renderOpenAISpeech` — see `source-map.md`.
6
+ *
7
+ * 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
8
+ * (`vendor-adapter.ts`/`vendor-registry.ts`). External behavior is
9
+ * unchanged (verified against `openai.test.ts`, which asserts URL/body/
10
+ * header/error-message/providerNote shape and passes unmodified) — only
11
+ * the internal implementation moved into two registered `VendorAdapter`s.
12
+ * `renderOpenAISpeech`'s response (raw bytes, no envelope) is the same
13
+ * shape `fishaudio.ts` returns, so it now shares
14
+ * `response-parsers.ts`'s `createRawBytesParser`. `renderOpenAIImage`
15
+ * keeps a custom `parseResponse`, deliberately NOT routed through
16
+ * `openai-compatible.ts`'s `parseOpenAICompatibleJson`/
17
+ * `bytesFromOpenAICompatibleData` helpers despite the superficially
18
+ * matching `{ data: [...] }` shape: the origin's non-JSON-parse-failure
19
+ * error message is the literal string `"openai non-JSON response: ..."`
20
+ * regardless of whether the request was Azure-routed (unlike its
21
+ * non-OK-status error, which IS azure-tag-aware) — a real, tested
22
+ * asymmetry in the origin (`openai.test.ts` has no azure-tagged non-JSON
23
+ * assertion, and the origin's own catch block never references the azure
24
+ * tag at all). Forcing this through the shared helper (which always tags
25
+ * both messages the same way) would have silently changed that specific
26
+ * corner's message text — exactly the kind of behavior drift this port's
27
+ * "no scope cuts" constraint forbids, so it stays a bespoke parser
28
+ * instead.
29
+ *
30
+ * Supports both the canonical OpenAI endpoint AND Azure-hosted OpenAI
31
+ * deployments behind the same provider slot — Azure is detected from the
32
+ * base URL (`*.azure.com` host or a `/deployments/<name>` path segment).
33
+ * For Azure this additionally:
34
+ * - appends `?api-version=...` (default 2024-02-01, unless the caller
35
+ * already encoded one into the base URL),
36
+ * - sends the `api-key` header in addition to `Authorization` (Azure
37
+ * accepts either; some deployments only honor `api-key`),
38
+ * - drops the `model` field from the body, since the deployment in the
39
+ * path already names the model.
40
+ *
41
+ * Dropped from the origin: the local Codex-CLI-subscription image
42
+ * fallback (`codex-gpt-image-2` etc.) — an OD-specific local-CLI-login
43
+ * integration already excluded from `providers.ts`'s catalogue, not a REST
44
+ * credential shape any other Jini consumer could use.
45
+ */
46
+ import { FETCH_TIMEOUT_MS, fetchWithTimeout } from '@jini-ai/platform';
47
+ import { Agent as UndiciAgent } from 'undici';
48
+ import { buildOpenAIImageUrl, buildOpenAISpeechUrl, detectAzureEndpoint, openaiSizeFor, OPENAI_TTS_VOICES, truncate, withRequestInit, } from '../openai-compatible.js';
49
+ import { createRawBytesParser } from '../response-parsers.js';
50
+ import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
51
+ import { mediaVendorRegistry } from '../vendor-registry.js';
52
+ // Image generation can legitimately take minutes (gpt-image-2 4K renders
53
+ // especially). A generous default headers/body timeout dispatcher is
54
+ // applied so a caller-configured global fetch default doesn't cut a
55
+ // legitimately-slow-but-succeeding generation short; a caller can still
56
+ // override via `requestInit.dispatcher`.
57
+ const OPENAI_IMAGE_HEADERS_TIMEOUT_MS = 10 * 60 * 1000;
58
+ const OPENAI_IMAGE_BODY_TIMEOUT_MS = 10 * 60 * 1000;
59
+ const openAIImageDispatcher = new UndiciAgent({
60
+ headersTimeout: OPENAI_IMAGE_HEADERS_TIMEOUT_MS,
61
+ bodyTimeout: OPENAI_IMAGE_BODY_TIMEOUT_MS,
62
+ });
63
+ const OPENAI_IMAGE_NO_CREDENTIAL_MESSAGE = 'no OpenAI credential — configure an API key or set OPENAI_API_KEY.';
64
+ const OPENAI_SPEECH_NO_CREDENTIAL_MESSAGE = 'no OpenAI credential — configure an API key or set OPENAI_API_KEY';
65
+ const openAIImageAdapter = {
66
+ requireCredential: requireApiKey(OPENAI_IMAGE_NO_CREDENTIAL_MESSAGE),
67
+ buildRequest(ctx, credentials) {
68
+ const apiKey = credentials.apiKey; // requireCredential already validated this.
69
+ const rawBase = credentials.baseUrl || 'https://api.openai.com/v1';
70
+ const azure = detectAzureEndpoint(rawBase);
71
+ const url = buildOpenAIImageUrl(rawBase, azure);
72
+ const body = {
73
+ prompt: ctx.prompt || 'A high-quality reference image.',
74
+ n: 1,
75
+ size: openaiSizeFor(ctx.model, ctx.aspect),
76
+ };
77
+ // For non-Azure calls, include `model` in the body. Azure infers it from
78
+ // the deployment in the path so omitting it keeps payloads compatible
79
+ // across both flavors. The wire-name (post-alias) goes on the body so a
80
+ // host's model-aliasing layer, if any, reaches the API.
81
+ if (!azure) {
82
+ body.model = ctx.wireModel;
83
+ }
84
+ // Capability branches key off the CATALOG id (not the wire alias) so a
85
+ // host that aliased `dall-e-3` to a custom Azure/proxy deployment still
86
+ // gets the DALL-E-specific quality + response_format flags.
87
+ if (ctx.model.startsWith('dall-e-')) {
88
+ body.response_format = 'b64_json';
89
+ body.quality = ctx.model === 'dall-e-3' ? 'hd' : 'standard';
90
+ }
91
+ else {
92
+ // gpt-image-* accepts quality 'high' | 'medium' | 'low'.
93
+ body.quality = 'high';
94
+ }
95
+ const headers = {
96
+ authorization: `Bearer ${apiKey}`,
97
+ 'content-type': 'application/json',
98
+ };
99
+ if (azure) {
100
+ // Azure's canonical auth header. Some deployments accept Bearer too,
101
+ // but api-key is what their docs document, so both are sent. OpenAI
102
+ // ignores unknown headers, so this is harmless on the standard
103
+ // endpoint too.
104
+ headers['api-key'] = apiKey;
105
+ }
106
+ return {
107
+ url,
108
+ init: withRequestInit(ctx, {
109
+ method: 'POST',
110
+ headers,
111
+ body: JSON.stringify(body),
112
+ dispatcher: ctx.requestInit.dispatcher ?? openAIImageDispatcher,
113
+ signal: AbortSignal.timeout(Math.max(OPENAI_IMAGE_HEADERS_TIMEOUT_MS, OPENAI_IMAGE_BODY_TIMEOUT_MS)),
114
+ }),
115
+ meta: { tag: azure ? 'azure-openai' : 'openai', wireModel: ctx.wireModel },
116
+ };
117
+ },
118
+ async parseResponse(resp, ctx, request) {
119
+ const text = await resp.text();
120
+ if (!resp.ok) {
121
+ throw new Error(`${request.meta.tag} ${resp.status}: ${truncate(text, 240)}`);
122
+ }
123
+ let data;
124
+ try {
125
+ data = JSON.parse(text);
126
+ }
127
+ catch {
128
+ // Deliberately not azure-tag-aware — matches the origin exactly, see
129
+ // this module's doc comment for why.
130
+ throw new Error(`openai non-JSON response: ${truncate(text, 200)}`);
131
+ }
132
+ const entry = Array.isArray(data.data) ? data.data[0] : null;
133
+ if (!entry)
134
+ throw new Error('openai response had no data[0]');
135
+ let bytes;
136
+ if (entry.b64_json) {
137
+ bytes = Buffer.from(entry.b64_json, 'base64');
138
+ }
139
+ else if (entry.url) {
140
+ // Downloading already-generated bytes, not waiting on generation — UPLOAD-class (2min), not
141
+ // the 10-minute GENERATE-class timeout the generation call itself uses above.
142
+ const imgResp = await fetchWithTimeout(entry.url, withRequestInit(ctx), { timeoutMs: FETCH_TIMEOUT_MS.UPLOAD });
143
+ if (!imgResp.ok)
144
+ throw new Error(`openai image fetch ${imgResp.status}`);
145
+ const arr = await imgResp.arrayBuffer();
146
+ bytes = Buffer.from(arr);
147
+ }
148
+ else {
149
+ throw new Error('openai response had neither b64_json nor url');
150
+ }
151
+ return {
152
+ bytes,
153
+ providerNote: `${request.meta.tag}/${request.meta.wireModel} · ${ctx.aspect} · ${bytes.length} bytes`,
154
+ suggestedExt: '.png',
155
+ };
156
+ },
157
+ };
158
+ mediaVendorRegistry.register('openai', 'image', openAIImageAdapter);
159
+ export async function renderOpenAIImage(ctx, credentials) {
160
+ return dispatchVendorRequest(openAIImageAdapter, ctx, credentials);
161
+ }
162
+ const openAISpeechAdapter = {
163
+ requireCredential: requireApiKey(OPENAI_SPEECH_NO_CREDENTIAL_MESSAGE),
164
+ buildRequest(ctx, credentials) {
165
+ const apiKey = credentials.apiKey; // requireCredential already validated this.
166
+ const rawBase = credentials.baseUrl || 'https://api.openai.com/v1';
167
+ const azure = detectAzureEndpoint(rawBase);
168
+ const url = buildOpenAISpeechUrl(rawBase, azure);
169
+ const format = ctx.speechFormat;
170
+ const text = (ctx.prompt && ctx.prompt.trim()) || 'This is a test.';
171
+ let voiceId = 'alloy';
172
+ let instructions = '';
173
+ const requestedVoice = (ctx.voice && ctx.voice.trim()) || '';
174
+ if (requestedVoice) {
175
+ if (OPENAI_TTS_VOICES.has(requestedVoice)) {
176
+ voiceId = requestedVoice;
177
+ }
178
+ else {
179
+ // gpt-4o-mini-tts accepts free-form speaking-style instructions. If
180
+ // the caller passed prose rather than a concrete voice id, preserve
181
+ // it here instead of surfacing a provider error.
182
+ instructions = requestedVoice;
183
+ }
184
+ }
185
+ const body = {
186
+ input: text,
187
+ voice: voiceId,
188
+ response_format: format,
189
+ };
190
+ if (!azure) {
191
+ body.model = ctx.wireModel;
192
+ }
193
+ if (instructions && ctx.model === 'gpt-4o-mini-tts') {
194
+ body.instructions = instructions;
195
+ }
196
+ const headers = {
197
+ authorization: `Bearer ${apiKey}`,
198
+ 'content-type': 'application/json',
199
+ };
200
+ if (azure) {
201
+ headers['api-key'] = apiKey;
202
+ }
203
+ return {
204
+ url,
205
+ init: withRequestInit(ctx, {
206
+ method: 'POST',
207
+ headers,
208
+ body: JSON.stringify(body),
209
+ }),
210
+ meta: { tag: azure ? 'azure-openai' : 'openai', wireModel: ctx.wireModel, voiceId, format, instructions },
211
+ };
212
+ },
213
+ parseResponse: createRawBytesParser({
214
+ errorTag: (meta) => `${meta.tag} speech`,
215
+ // Deliberately not azure-tag-aware — matches the origin exactly (see
216
+ // this module's doc comment).
217
+ zeroBytesMessage: 'openai speech returned zero bytes',
218
+ note: (bytes, meta) => {
219
+ const noteBits = [`${meta.tag}/${meta.wireModel}`, meta.voiceId, meta.format, `${bytes.length} bytes`];
220
+ if (meta.instructions)
221
+ noteBits.splice(2, 0, 'styled');
222
+ return noteBits.join(' · ');
223
+ },
224
+ suggestedExt: (_bytes, meta) => (meta.format === 'opus' ? '.ogg' : `.${meta.format}`),
225
+ }),
226
+ };
227
+ mediaVendorRegistry.register('openai', 'audio:speech', openAISpeechAdapter);
228
+ export async function renderOpenAISpeech(ctx, credentials) {
229
+ return dispatchVendorRequest(openAISpeechAdapter, ctx, credentials);
230
+ }
231
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ProviderCredentials, RenderContext, RenderResult } from '../types.js';
2
+ /**
3
+ * OpenRouter normalizes aspect ratios across the providers it fronts;
4
+ * `providers.ts`'s `MEDIA_ASPECTS` are all natively supported, default to
5
+ * 16:9 for anything else. Written as independent `if` returns (rather than
6
+ * the origin's one `||`-chained condition) to match this package's
7
+ * established aspect-mapping style (see `imagerouter.ts`'s
8
+ * `imageRouterSizeFor`) — same input -> output mapping for every case, not
9
+ * a behavior change.
10
+ */
11
+ export declare function openRouterAspectFor(aspect: string | undefined): string;
12
+ export declare function renderOpenRouterImage(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
13
+ //# sourceMappingURL=openrouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/openrouter.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAYpF;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOtE;AAmGD,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Provider: OpenRouter — unified multi-vendor image generation via the
3
+ * Chat Completions API (`POST /chat/completions` with
4
+ * `modalities: ["image"]`), not the dedicated `/images/generations` shape
5
+ * OpenRouter's own *video* generation uses. Ported near-verbatim from Open
6
+ * Design's `apps/daemon/src/media/index.ts` `renderOpenRouterImage` — see
7
+ * `source-map.md`.
8
+ *
9
+ * Not OpenAI-images-wire-compatible (chat-completions request shape;
10
+ * `choices[0].message.images[].image_url.url` response shape), so this
11
+ * does not route through `openai-compatible.ts`'s OpenAI-images helpers —
12
+ * only its vendor-agnostic utilities (`truncate`, `sniffImageExt`,
13
+ * `withRequestInit`) are reused.
14
+ *
15
+ * Dropped from the origin: the `HTTP-Referer: https://opendesign.dev` /
16
+ * `X-Title: Open Design` request headers — these are OpenRouter's optional
17
+ * app-attribution headers (used for their model leaderboard, not required
18
+ * for the request to succeed) and both values are OD product identity, out
19
+ * of scope per AGENTS.md's no-product-identity-strings boundary. This
20
+ * package has no host-identity concept to substitute one with; a host that
21
+ * wants attribution would need its own request-building layer.
22
+ *
23
+ * 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
24
+ * (`vendor-adapter.ts`/`vendor-registry.ts`). External behavior is
25
+ * unchanged (verified against `openrouter.test.ts`, which asserts URL/
26
+ * body/header/error-message/providerNote shape and passes unmodified) —
27
+ * only the internal implementation moved into a registered
28
+ * `VendorAdapter`. Not routed through `response-parsers.ts`'s factories —
29
+ * the three-way image-decode (`data:` URI / http(s) download / bare
30
+ * base64) has no other current consumer, so it correctly stays a bespoke
31
+ * `parseResponse`.
32
+ */
33
+ import { FETCH_TIMEOUT_MS, fetchWithTimeout } from '@jini-ai/platform';
34
+ import { sniffImageExt, truncate, withRequestInit } from '../openai-compatible.js';
35
+ import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
36
+ import { mediaVendorRegistry } from '../vendor-registry.js';
37
+ // Chat-completions image generation can take a while for some routed
38
+ // models; matches the same 10-minute ceiling `openai.ts`'s image dispatcher
39
+ // uses for the same reason (see `OPENAI_IMAGE_HEADERS_TIMEOUT_MS`/
40
+ // `OPENAI_IMAGE_BODY_TIMEOUT_MS` there — this vendor has no separate
41
+ // headers/body distinction, so a single `AbortSignal.timeout` suffices).
42
+ const OPENROUTER_IMAGE_TIMEOUT_MS = 10 * 60 * 1000;
43
+ /**
44
+ * OpenRouter normalizes aspect ratios across the providers it fronts;
45
+ * `providers.ts`'s `MEDIA_ASPECTS` are all natively supported, default to
46
+ * 16:9 for anything else. Written as independent `if` returns (rather than
47
+ * the origin's one `||`-chained condition) to match this package's
48
+ * established aspect-mapping style (see `imagerouter.ts`'s
49
+ * `imageRouterSizeFor`) — same input -> output mapping for every case, not
50
+ * a behavior change.
51
+ */
52
+ export function openRouterAspectFor(aspect) {
53
+ if (aspect === '1:1')
54
+ return '1:1';
55
+ if (aspect === '16:9')
56
+ return '16:9';
57
+ if (aspect === '9:16')
58
+ return '9:16';
59
+ if (aspect === '4:3')
60
+ return '4:3';
61
+ if (aspect === '3:4')
62
+ return '3:4';
63
+ return '16:9';
64
+ }
65
+ const NO_CREDENTIAL_MESSAGE = 'no OpenRouter API key — configure it or set OPENROUTER_API_KEY';
66
+ const openRouterImageAdapter = {
67
+ requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
68
+ buildRequest(ctx, credentials) {
69
+ const apiKey = credentials.apiKey; // requireCredential already validated this.
70
+ const baseUrl = (credentials.baseUrl || 'https://openrouter.ai/api/v1').replace(/\/$/, '');
71
+ // credentials.model (a host's own model-aliasing layer) wins over
72
+ // ctx.wireModel; strip the catalogue's `openrouter/` prefix so the wire
73
+ // model name matches OpenRouter's canonical slug.
74
+ const resolved = (credentials.model || ctx.wireModel).trim();
75
+ const wireModel = resolved.startsWith('openrouter/') ? resolved.slice('openrouter/'.length) : resolved;
76
+ // Multi-modal models (Gemini variants) accept both image and text
77
+ // output; image-only models (Flux, Recraft, Sourceful) only accept
78
+ // ["image"]. A simple heuristic on the slug, matching the origin.
79
+ const modalities = wireModel.includes('gemini') ? ['image', 'text'] : ['image'];
80
+ const aspectRatio = openRouterAspectFor(ctx.aspect);
81
+ const body = {
82
+ model: wireModel,
83
+ messages: [{ role: 'user', content: ctx.prompt || 'A high-quality reference image.' }],
84
+ modalities,
85
+ stream: false,
86
+ image_config: { aspect_ratio: aspectRatio, image_size: '1K' },
87
+ };
88
+ return {
89
+ url: `${baseUrl}/chat/completions`,
90
+ init: withRequestInit(ctx, {
91
+ method: 'POST',
92
+ headers: {
93
+ authorization: `Bearer ${apiKey}`,
94
+ 'content-type': 'application/json',
95
+ },
96
+ body: JSON.stringify(body),
97
+ signal: AbortSignal.timeout(OPENROUTER_IMAGE_TIMEOUT_MS),
98
+ }),
99
+ meta: { wireModel, aspectRatio },
100
+ };
101
+ },
102
+ async parseResponse(resp, ctx, request) {
103
+ const { wireModel, aspectRatio } = request.meta;
104
+ const text = await resp.text();
105
+ if (!resp.ok) {
106
+ throw new Error(`openrouter image ${resp.status}: ${truncate(text, 240)}`);
107
+ }
108
+ let data;
109
+ try {
110
+ data = JSON.parse(text);
111
+ }
112
+ catch {
113
+ throw new Error(`openrouter image non-JSON response: ${truncate(text, 200)}`);
114
+ }
115
+ const images = data?.choices?.[0]?.message?.images;
116
+ if (!Array.isArray(images) || images.length === 0) {
117
+ throw new Error(`openrouter image response contained no images for model ${wireModel}: ${truncate(text, 200)}`);
118
+ }
119
+ const dataUrl = images[0]?.image_url?.url;
120
+ if (typeof dataUrl !== 'string' || !dataUrl) {
121
+ throw new Error(`openrouter image response missing image_url.url: ${truncate(text, 200)}`);
122
+ }
123
+ // Strip a "data:image/...;base64," prefix and decode; fall back to
124
+ // downloading a plain URL, or treating the string as raw base64.
125
+ const b64Match = dataUrl.match(/^data:image\/[^;]+;base64,(.+)$/s);
126
+ let bytes;
127
+ if (b64Match) {
128
+ bytes = Buffer.from(b64Match[1], 'base64');
129
+ }
130
+ else if (dataUrl.startsWith('http')) {
131
+ // Downloading already-generated bytes, not waiting on generation — UPLOAD-class (2min), not
132
+ // the 10-minute GENERATE-class timeout the chat-completions call itself uses above.
133
+ const imgResp = await fetchWithTimeout(dataUrl, withRequestInit(ctx), { timeoutMs: FETCH_TIMEOUT_MS.UPLOAD });
134
+ if (!imgResp.ok)
135
+ throw new Error(`openrouter image download ${imgResp.status}`);
136
+ bytes = Buffer.from(await imgResp.arrayBuffer());
137
+ }
138
+ else {
139
+ bytes = Buffer.from(dataUrl, 'base64');
140
+ }
141
+ return {
142
+ bytes,
143
+ providerNote: `openrouter/${wireModel} · ${aspectRatio} · ${bytes.length} bytes`,
144
+ suggestedExt: sniffImageExt(bytes),
145
+ };
146
+ },
147
+ };
148
+ mediaVendorRegistry.register('openrouter', 'image', openRouterImageAdapter);
149
+ export async function renderOpenRouterImage(ctx, credentials) {
150
+ return dispatchVendorRequest(openRouterImageAdapter, ctx, credentials);
151
+ }
152
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEnF,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qEAAqE;AACrE,4EAA4E;AAC5E,mEAAmE;AACnE,qEAAqE;AACrE,yEAAyE;AACzE,MAAM,2BAA2B,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACrC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACrC,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,qBAAqB,GAAG,gEAAgE,CAAC;AAO/F,MAAM,sBAAsB,GAAuC;IACjE,iBAAiB,EAAE,aAAa,CAAC,qBAAqB,CAAC;IAEvD,YAAY,CAAC,GAAkB,EAAE,WAAgC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAO,CAAC,CAAC,4CAA4C;QAChF,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,8BAA8B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAE3F,kEAAkE;QAClE,wEAAwE;QACxE,kDAAkD;QAClD,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAC,KAAK,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEvG,kEAAkE;QAClE,mEAAmE;QACnE,kEAAkE;QAClE,MAAM,UAAU,GAAsB,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACnG,MAAM,WAAW,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,IAAI,GAA4B;YACpC,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,IAAI,iCAAiC,EAAE,CAAC;YACtF,UAAU;YACV,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE;SAC9D,CAAC;QAEF,OAAO;YACL,GAAG,EAAE,GAAG,OAAO,mBAAmB;YAClC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE;gBACzB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,EAAE;oBACjC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,2BAA2B,CAAC;aACzD,CAAC;YACF,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE;SACjC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAc,EAAE,GAAkB,EAAE,OAA2C;QACjG,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,uCAAuC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,MAAM,GAAI,IAAuE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC;QACvH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,2DAA2D,SAAS,KAAK,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAClH,CAAC;QACD,MAAM,OAAO,GAAI,MAAM,CAAC,CAAC,CAA8C,EAAE,SAAS,EAAE,GAAG,CAAC;QACxF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,oDAAoD,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,mEAAmE;QACnE,iEAAiE;QACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACnE,IAAI,KAAa,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,4FAA4F;YAC5F,oFAAoF;YACpF,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAChF,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;QAED,OAAO;YACL,KAAK;YACL,YAAY,EAAE,cAAc,SAAS,MAAM,WAAW,MAAM,KAAK,CAAC,MAAM,QAAQ;YAChF,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC;SACnC,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,mBAAmB,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAkB,EAAE,WAAgC;IAC9F,OAAO,qBAAqB,CAAC,sBAAsB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ProviderCredentials, RenderContext, RenderResult } from '../types.js';
2
+ export declare function renderSenseAudioTTS(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
3
+ export declare function renderSenseAudioImage(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
4
+ //# sourceMappingURL=senseaudio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"senseaudio.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/senseaudio.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA8DpF,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAErH;AA0GD,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Provider: SenseAudio — `senseaudio-tts-1.5` text-to-speech
3
+ * (`renderSenseAudioTTS`, `POST /v1/t2a_v2`) and text-to-image
4
+ * (`renderSenseAudioImage`, `POST /v1/image/sync`), both synchronous.
5
+ * Ported near-verbatim from Open Design's
6
+ * `apps/daemon/src/media/index.ts` `renderSenseAudioTTS`/
7
+ * `renderSenseAudioImage` — see `source-map.md`.
8
+ *
9
+ * 2026-07-21: migrated onto the generic vendor-adapter dispatch engine
10
+ * (`vendor-adapter.ts`/`vendor-registry.ts`). External behavior (URLs,
11
+ * bodies, headers, every error message, `providerNote` format, the SSRF
12
+ * guard on the image download) is unchanged; only the internal
13
+ * implementation moved into two registered `VendorAdapter`s. TTS's
14
+ * response envelope is identical to `minimax.ts`'s, so both now share
15
+ * `response-parsers.ts`'s `createHexEnvelopeAudioParser`. Image's response
16
+ * (`{ url }`, downloaded through an SSRF-guarded second fetch, with two
17
+ * independent failure-signaling paths — `base_resp` AND a separate
18
+ * `error_message`) has no equivalent elsewhere in this package, so it
19
+ * keeps a custom `parseResponse` — the generic engine's `parseResponse`
20
+ * hook is a full function precisely so a second network call mid-parse
21
+ * (the SSRF-guarded download) stays possible; see `vendor-adapter.ts`'s
22
+ * module doc.
23
+ *
24
+ * Neither endpoint is OpenAI-wire-compatible: TTS mirrors MiniMax's own
25
+ * `voice_setting`/`audio_setting` body shape and `base_resp` response
26
+ * envelope (an HTTP 200 can still be a logical failure), and image returns
27
+ * `{ url }` rather than `{ data: [...] }`, so only the generic
28
+ * `withRequestInit` helper is reused from `openai-compatible.ts` (matching
29
+ * `minimax.ts`'s reasoning).
30
+ *
31
+ * `renderSenseAudioImage`'s `url` is fetched through `ssrf-guard.ts`'s
32
+ * `assertAndFetchExternalAsset` — same as the real origin — because it is
33
+ * attacker-controllable inside an otherwise-successful response (a
34
+ * compromised/misconfigured gateway could point it at internal
35
+ * infrastructure); `assertAndFetchExternalAsset` DNS-resolves the host,
36
+ * rejects loopback/RFC1918/link-local/CGNAT/metadata-service addresses,
37
+ * and pins `redirect: 'error'` so a validated public URL can't 302 into
38
+ * private space either.
39
+ *
40
+ * Dropped from the origin's no-credential error messages (both
41
+ * functions): the `OD_`-prefixed override env var
42
+ * (`OD_SENSEAUDIO_API_KEY`) — `providers.ts`'s
43
+ * `PROVIDER_CREDENTIAL_ENV_VARS.senseaudio` already de-branded this to
44
+ * plain `SENSEAUDIO_API_KEY`.
45
+ */
46
+ import { truncate, withRequestInit } from '../openai-compatible.js';
47
+ import { createHexEnvelopeAudioParser } from '../response-parsers.js';
48
+ import { assertAndFetchExternalAsset } from '../ssrf-guard.js';
49
+ import { dispatchVendorRequest, requireApiKey } from '../vendor-adapter.js';
50
+ import { mediaVendorRegistry } from '../vendor-registry.js';
51
+ const SENSEAUDIO_DEFAULT_BASE_URL = 'https://api.senseaudio.cn';
52
+ const SENSEAUDIO_DEFAULT_VOICE_ID = 'female_0033_b';
53
+ const SENSEAUDIO_IMAGE_PROMPT_LIMIT = 2000;
54
+ const SENSEAUDIO_TTS_MODEL_MAP = {
55
+ 'senseaudio-tts': 'senseaudio-tts-1.5-260319',
56
+ };
57
+ const NO_CREDENTIAL_MESSAGE = 'no SenseAudio credential — configure an API key or set SENSEAUDIO_API_KEY.';
58
+ const senseAudioTTSAdapter = {
59
+ requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
60
+ buildRequest(ctx, credentials) {
61
+ const apiKey = credentials.apiKey; // requireCredential already validated this.
62
+ const baseUrl = (credentials.baseUrl || SENSEAUDIO_DEFAULT_BASE_URL).replace(/\/$/, '');
63
+ const wireModel = SENSEAUDIO_TTS_MODEL_MAP[ctx.model] || ctx.model;
64
+ const text = (ctx.prompt && ctx.prompt.trim()) || 'This is a test.';
65
+ const voiceId = (ctx.voice && ctx.voice.trim()) || SENSEAUDIO_DEFAULT_VOICE_ID;
66
+ const body = {
67
+ model: wireModel,
68
+ text,
69
+ stream: false,
70
+ voice_setting: {
71
+ voice_id: voiceId,
72
+ speed: 1,
73
+ vol: 1,
74
+ pitch: 0,
75
+ },
76
+ audio_setting: {
77
+ format: 'mp3',
78
+ sample_rate: 32000,
79
+ bitrate: 128000,
80
+ channel: 2,
81
+ },
82
+ };
83
+ return {
84
+ url: `${baseUrl}/v1/t2a_v2`,
85
+ init: withRequestInit(ctx, {
86
+ method: 'POST',
87
+ headers: {
88
+ authorization: `Bearer ${apiKey}`,
89
+ 'content-type': 'application/json',
90
+ },
91
+ body: JSON.stringify(body),
92
+ }),
93
+ meta: { wireModel, voiceId },
94
+ };
95
+ },
96
+ parseResponse: createHexEnvelopeAudioParser({ errorTag: 'senseaudio tts', providerId: 'senseaudio' }),
97
+ };
98
+ mediaVendorRegistry.register('senseaudio', 'audio:speech', senseAudioTTSAdapter);
99
+ export async function renderSenseAudioTTS(ctx, credentials) {
100
+ return dispatchVendorRequest(senseAudioTTSAdapter, ctx, credentials);
101
+ }
102
+ /** SenseAudio's image gateway rejects non-standard pixel sizes with a 400; keep this mapping in sync with any other SenseAudio-image call site a future host adds. */
103
+ function senseAudioImageSize(aspect) {
104
+ if (aspect === '16:9')
105
+ return '1280x720';
106
+ if (aspect === '9:16')
107
+ return '720x1280';
108
+ if (aspect === '4:3')
109
+ return '1024x768';
110
+ if (aspect === '3:4')
111
+ return '768x1024';
112
+ return '1024x1024';
113
+ }
114
+ const senseAudioImageAdapter = {
115
+ requireCredential: requireApiKey(NO_CREDENTIAL_MESSAGE),
116
+ buildRequest(ctx, credentials) {
117
+ const apiKey = credentials.apiKey; // requireCredential already validated this.
118
+ const baseUrl = (credentials.baseUrl || SENSEAUDIO_DEFAULT_BASE_URL).replace(/\/$/, '');
119
+ const promptRaw = (ctx.prompt && ctx.prompt.trim()) || 'A high-quality reference image.';
120
+ // SenseAudio rejects prompts over 2000 chars with a 4xx; trim
121
+ // defensively so a verbose caller doesn't dead-end the generation.
122
+ const prompt = promptRaw.length > SENSEAUDIO_IMAGE_PROMPT_LIMIT ? promptRaw.slice(0, SENSEAUDIO_IMAGE_PROMPT_LIMIT) : promptRaw;
123
+ const size = senseAudioImageSize(ctx.aspect);
124
+ const reference = ctx.imageRef?.dataUrl;
125
+ const body = {
126
+ model: ctx.wireModel,
127
+ prompt,
128
+ size,
129
+ };
130
+ if (reference) {
131
+ // The API documents `size` as optional when a reference image is
132
+ // supplied; it is still sent so output dimensions stay deterministic
133
+ // across t2i/i2i calls for the same model.
134
+ body.reference = reference;
135
+ }
136
+ return {
137
+ url: `${baseUrl}/v1/image/sync`,
138
+ init: withRequestInit(ctx, {
139
+ method: 'POST',
140
+ headers: {
141
+ authorization: `Bearer ${apiKey}`,
142
+ 'content-type': 'application/json',
143
+ },
144
+ body: JSON.stringify(body),
145
+ }),
146
+ meta: { size, hasReference: Boolean(reference) },
147
+ };
148
+ },
149
+ async parseResponse(resp, ctx, request) {
150
+ const respText = await resp.text();
151
+ if (!resp.ok) {
152
+ throw new Error(`senseaudio image ${resp.status}: ${truncate(respText, 240)}`);
153
+ }
154
+ let data;
155
+ try {
156
+ data = JSON.parse(respText);
157
+ }
158
+ catch {
159
+ throw new Error(`senseaudio image non-JSON: ${truncate(respText, 200)}`);
160
+ }
161
+ if (data.base_resp && data.base_resp.status_code !== 0) {
162
+ throw new Error(`senseaudio image api error ${data.base_resp.status_code}: ${data.base_resp.status_msg || 'unknown'}`);
163
+ }
164
+ if (typeof data.error_message === 'string' && data.error_message) {
165
+ throw new Error(`senseaudio image api error: ${data.error_message}`);
166
+ }
167
+ const url = typeof data.url === 'string' ? data.url : '';
168
+ if (!url) {
169
+ throw new Error('senseaudio image response missing url');
170
+ }
171
+ const imgResp = await assertAndFetchExternalAsset(url, withRequestInit(ctx));
172
+ if (!imgResp.ok) {
173
+ throw new Error(`senseaudio image fetch ${imgResp.status}`);
174
+ }
175
+ const bytes = Buffer.from(await imgResp.arrayBuffer());
176
+ if (bytes.length === 0) {
177
+ throw new Error('senseaudio image fetch returned zero bytes');
178
+ }
179
+ return {
180
+ bytes,
181
+ providerNote: `senseaudio/${ctx.wireModel} · ${request.meta.size}${request.meta.hasReference ? ' · i2i' : ''} · ${bytes.length} bytes`,
182
+ suggestedExt: '.png',
183
+ };
184
+ },
185
+ };
186
+ mediaVendorRegistry.register('senseaudio', 'image', senseAudioImageAdapter);
187
+ export async function renderSenseAudioImage(ctx, credentials) {
188
+ return dispatchVendorRequest(senseAudioImageAdapter, ctx, credentials);
189
+ }
190
+ //# sourceMappingURL=senseaudio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"senseaudio.js","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/senseaudio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,2BAA2B,GAAG,2BAA2B,CAAC;AAChE,MAAM,2BAA2B,GAAG,eAAe,CAAC;AACpD,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAE3C,MAAM,wBAAwB,GAA2B;IACvD,gBAAgB,EAAE,2BAA2B;CAC9C,CAAC;AAEF,MAAM,qBAAqB,GAAG,4EAA4E,CAAC;AAE3G,MAAM,oBAAoB,GAAwC;IAChE,iBAAiB,EAAE,aAAa,CAAC,qBAAqB,CAAC;IAEvD,YAAY,CAAC,GAAkB,EAAE,WAAgC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAO,CAAC,CAAC,4CAA4C;QAChF,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxF,MAAM,SAAS,GAAG,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;QACnE,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,iBAAiB,CAAC;QACpE,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,2BAA2B,CAAC;QAE/E,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,SAAS;YAChB,IAAI;YACJ,MAAM,EAAE,KAAK;YACb,aAAa,EAAE;gBACb,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC;gBACR,GAAG,EAAE,CAAC;gBACN,KAAK,EAAE,CAAC;aACT;YACD,aAAa,EAAE;gBACb,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,KAAK;gBAClB,OAAO,EAAE,MAAM;gBACf,OAAO,EAAE,CAAC;aACX;SACF,CAAC;QAEF,OAAO;YACL,GAAG,EAAE,GAAG,OAAO,YAAY;YAC3B,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE;gBACzB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,EAAE;oBACjC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC;YACF,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;SAC7B,CAAC;IACJ,CAAC;IAED,aAAa,EAAE,4BAA4B,CAAuB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;CAC5H,CAAC;AAEF,mBAAmB,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,EAAE,oBAAoB,CAAC,CAAC;AAEjF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAkB,EAAE,WAAgC;IAC5F,OAAO,qBAAqB,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AACvE,CAAC;AAED,sKAAsK;AACtK,SAAS,mBAAmB,CAAC,MAA0B;IACrD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC;IACzC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC;IACzC,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,UAAU,CAAC;IACxC,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,UAAU,CAAC;IACxC,OAAO,WAAW,CAAC;AACrB,CAAC;AAkBD,MAAM,sBAAsB,GAAuC;IACjE,iBAAiB,EAAE,aAAa,CAAC,qBAAqB,CAAC;IAEvD,YAAY,CAAC,GAAkB,EAAE,WAAgC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAO,CAAC,CAAC,4CAA4C;QAChF,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxF,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,iCAAiC,CAAC;QACzF,8DAA8D;QAC9D,mEAAmE;QACnE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,6BAA6B,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChI,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;QAExC,MAAM,IAAI,GAA4B;YACpC,KAAK,EAAE,GAAG,CAAC,SAAS;YACpB,MAAM;YACN,IAAI;SACL,CAAC;QACF,IAAI,SAAS,EAAE,CAAC;YACd,iEAAiE;YACjE,qEAAqE;YACrE,2CAA2C;YAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;QAED,OAAO;YACL,GAAG,EAAE,GAAG,OAAO,gBAAgB;YAC/B,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE;gBACzB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,EAAE;oBACjC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC;YACF,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE;SACjD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAc,EAAE,GAAkB,EAAE,OAA2C;QACjG,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,IAA6B,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,SAAS,CAAC,WAAW,KAAK,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC;QACzH,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,2BAA2B,CAAC,GAAG,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACvD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,OAAO;YACL,KAAK;YACL,YAAY,EAAE,cAAc,GAAG,CAAC,SAAS,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,MAAM,QAAQ;YACtI,YAAY,EAAE,MAAM;SACrB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,mBAAmB,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAkB,EAAE,WAAgC;IAC9F,OAAO,qBAAqB,CAAC,sBAAsB,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ProviderCredentials, RenderContext, RenderResult } from '../types.js';
2
+ export declare function renderVolcengineImage(ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
3
+ //# sourceMappingURL=volcengine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volcengine.d.ts","sourceRoot":"","sources":["../../../../src/media-providers/dispatch/providers/volcengine.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAmDpF,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH"}