@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,98 @@
1
+ /**
2
+ * Deterministic placeholder-bytes renderer used when
3
+ * `MediaDispatchEngineOptions.allowStubFallback` is `true` and no real
4
+ * renderer is wired up for a (provider, surface) pair — a labelled SVG/PNG,
5
+ * silent WAV/MP3, or a minimal MP4 container, so a pipeline can be
6
+ * exercised end-to-end before every vendor integration lands. Ported
7
+ * near-verbatim from Open Design's `apps/daemon/src/media/index.ts`
8
+ * `renderStub`/`svgPlaceholder`/`aspectToBox`/`silentWav` — see
9
+ * `source-map.md`.
10
+ */
11
+ import { truncate } from './openai-compatible.js';
12
+ export async function renderStub(ctx, providerId, integrated) {
13
+ const note = !integrated ? `stub-${ctx.surface} · provider '${providerId}' integration pending` : `stub-${ctx.surface} · model=${ctx.model}`;
14
+ if (ctx.surface === 'image') {
15
+ const png = Buffer.from([
16
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00,
17
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, 0x89, 0x00, 0x00, 0x00,
18
+ 0x0d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d,
19
+ 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
20
+ ]);
21
+ return {
22
+ bytes: png,
23
+ providerNote: `${note} · aspect=${ctx.aspect} · prompt=${truncate(ctx.prompt, 60)}`,
24
+ suggestedExt: '.png',
25
+ };
26
+ }
27
+ if (ctx.surface === 'video') {
28
+ const ftyp = Buffer.from([
29
+ 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x00, 0x69, 0x73,
30
+ 0x6f, 0x6d, 0x69, 0x73, 0x6f, 0x32,
31
+ ]);
32
+ const mdat = Buffer.from([0x00, 0x00, 0x00, 0x08, 0x6d, 0x64, 0x61, 0x74]);
33
+ return {
34
+ bytes: Buffer.concat([ftyp, mdat]),
35
+ providerNote: `${note} · aspect=${ctx.aspect} · length=${ctx.length ?? '?'}s · prompt=${truncate(ctx.prompt, 60)}`,
36
+ suggestedExt: '.mp4',
37
+ };
38
+ }
39
+ // Audio
40
+ if (ctx.speechFormat === 'wav') {
41
+ return {
42
+ bytes: silentWav(0.5),
43
+ providerNote: `${note} · kind=${ctx.audioKind} · duration=${ctx.duration ?? '?'}s`,
44
+ suggestedExt: '.wav',
45
+ };
46
+ }
47
+ const mp3 = Buffer.from([0xff, 0xfb, 0x90, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
48
+ return {
49
+ bytes: mp3,
50
+ providerNote: `${note} · kind=${ctx.audioKind} · voice=${ctx.voice || '-'} · duration=${ctx.duration ?? '?'}s`,
51
+ suggestedExt: '.mp3',
52
+ };
53
+ }
54
+ /** Renders a labelled placeholder SVG for the image surface (an explicit opt-in alternative to the PNG placeholder). */
55
+ export function svgPlaceholder(ctx) {
56
+ const [w, h] = aspectToBox(ctx.aspect, 800);
57
+ const safe = (s) => String(s || '')
58
+ .replace(/&/g, '&')
59
+ .replace(/</g, '&lt;')
60
+ .replace(/>/g, '&gt;');
61
+ return [
62
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} ${h}" width="${w}" height="${h}">`,
63
+ `<rect width="${w}" height="${h}" fill="#0f1424"/>`,
64
+ `<text x="50%" y="50%" fill="#7da4ff" font-family="ui-sans-serif" font-size="20" text-anchor="middle">${safe(ctx.model)} — ${safe(ctx.prompt).slice(0, 60)}</text>`,
65
+ '</svg>',
66
+ ].join('');
67
+ }
68
+ function aspectToBox(aspect, base) {
69
+ const [a, b] = String(aspect || '1:1')
70
+ .split(':')
71
+ .map(Number);
72
+ if (!a || !b)
73
+ return [base, base];
74
+ if (a >= b)
75
+ return [base, Math.round((base * b) / a)];
76
+ return [Math.round((base * a) / b), base];
77
+ }
78
+ function silentWav(seconds) {
79
+ const sampleRate = 8000;
80
+ const numSamples = Math.max(1, Math.round(sampleRate * seconds));
81
+ const dataSize = numSamples * 2;
82
+ const buf = Buffer.alloc(44 + dataSize);
83
+ buf.write('RIFF', 0, 'ascii');
84
+ buf.writeUInt32LE(36 + dataSize, 4);
85
+ buf.write('WAVE', 8, 'ascii');
86
+ buf.write('fmt ', 12, 'ascii');
87
+ buf.writeUInt32LE(16, 16);
88
+ buf.writeUInt16LE(1, 20);
89
+ buf.writeUInt16LE(1, 22);
90
+ buf.writeUInt32LE(sampleRate, 24);
91
+ buf.writeUInt32LE(sampleRate * 2, 28);
92
+ buf.writeUInt16LE(2, 32);
93
+ buf.writeUInt16LE(16, 34);
94
+ buf.write('data', 36, 'ascii');
95
+ buf.writeUInt32LE(dataSize, 40);
96
+ return buf;
97
+ }
98
+ //# sourceMappingURL=stub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub.js","sourceRoot":"","sources":["../../../src/media-providers/dispatch/stub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * The media dispatch engine's public types. Generalized from Open Design's
3
+ * `apps/daemon/src/media/index.ts` `generateMedia` — the real multi-vendor
4
+ * REST dispatch engine, not the substrate (`policy.ts`/`staging.ts`/
5
+ * `task-store.ts`/`video-request.ts`/`capability-registry.ts`) already
6
+ * ported. See `source-map.md` for the full port record: what's ported in
7
+ * this pass vs explicitly deferred.
8
+ *
9
+ * Boundary redesign vs the origin (not a verbatim lift — see source-map.md):
10
+ * the origin resolves an OD `projectId` into a filesystem path and writes
11
+ * generated bytes there directly (`ensureProject`/`sanitizeName`/
12
+ * `mkdir`/write). Jini's kernel has no `Project` concept at all (locked
13
+ * architecture §2.1), so this engine returns bytes to the caller instead —
14
+ * a host pairs this with its own `AttachmentStaging`/`MediaTaskStore`
15
+ * wiring to decide where generated bytes land. Reference-image resolution
16
+ * is the same story: the origin reads a project-relative path itself
17
+ * (`resolveProjectImage`); here the caller resolves any reference image to
18
+ * a data URL before calling, exactly matching the convention `video-
19
+ * request.ts`'s `VideoBuildInput.imageRef` already established for this
20
+ * package — "this package performs no I/O" is a standing invariant across
21
+ * `@jini-ai/integrations/media-providers`, not a new one introduced here.
22
+ */
23
+ import type { AudioKind, MediaSurface } from '../types.js';
24
+ /** Per-provider credentials a host resolves however it wants (env vars, a secrets manager, a config file, ...). This engine never reads `process.env` itself — see `resolveProviderCredentialsFromEnv` in `credentials.ts` for an opt-in reference resolver a host may use to build this map. */
25
+ export interface ProviderCredentials {
26
+ readonly apiKey?: string;
27
+ readonly baseUrl?: string;
28
+ readonly model?: string;
29
+ }
30
+ /** Subset of `RequestInit` a caller may want to control (e.g. a custom `undici.Agent` for connection pooling/timeouts). */
31
+ export type MediaGenerationRequestInit = Pick<RequestInit, 'dispatcher'>;
32
+ /** A reference image already resolved to a base64 data URL — this package performs no filesystem I/O (see `types.ts`'s `VideoBuildInput.imageRef` for the same convention). */
33
+ export interface MediaImageReference {
34
+ readonly dataUrl: string;
35
+ }
36
+ export type MediaSpeechFormat = 'mp3' | 'wav' | 'flac' | 'aac' | 'opus';
37
+ export interface MediaGenerationRequest {
38
+ readonly surface: MediaSurface;
39
+ /** Catalog id (e.g. `dall-e-3`, `gpt-4o-mini-tts`) — must be registered in `@jini-ai/integrations/media-providers`'s catalogue for the given surface/audioKind. */
40
+ readonly model: string;
41
+ readonly prompt?: string;
42
+ readonly aspect?: string;
43
+ readonly length?: number;
44
+ readonly duration?: number;
45
+ readonly voice?: string;
46
+ readonly audioKind?: AudioKind;
47
+ readonly language?: string;
48
+ readonly loop?: boolean;
49
+ /**
50
+ * ElevenLabs SFX's "how closely should generation follow the prompt"
51
+ * dial (0-1). Currently unconsumed by any ported renderer — no
52
+ * SFX-capable vendor is wired up in this pass yet — but the field and
53
+ * its validation are real and directly tested via `buildRenderContext`
54
+ * (see `context.ts`), not speculative dead plumbing.
55
+ */
56
+ readonly promptInfluence?: number;
57
+ /** Primary reference image for i2v / image-edit flows. */
58
+ readonly imageRef?: MediaImageReference;
59
+ /**
60
+ * Additional reference images for multi-image i2v / style-reference
61
+ * flows. Currently unconsumed by any ported renderer — no multi-image
62
+ * vendor (e.g. AIHubMix video) is wired up in this pass yet — but, like
63
+ * `promptInfluence`, is directly tested via `buildRenderContext`.
64
+ */
65
+ readonly imageRefs?: readonly MediaImageReference[];
66
+ /**
67
+ * What the provider's request body should carry as `model` (or what gets
68
+ * templated into an Azure-style deployment URL). Defaults to `model`.
69
+ * Capability branches (DALL-E sizing, gpt-image quality, ...) always key
70
+ * off the catalog `model` field, never this one — set this only when a
71
+ * host has its own model-aliasing layer and wants the wire request to
72
+ * carry a different name than the catalog id.
73
+ */
74
+ readonly wireModel?: string;
75
+ /** Desired audio container/codec for speech synthesis. Defaults to `'mp3'`. */
76
+ readonly speechFormat?: MediaSpeechFormat;
77
+ readonly requestInit?: MediaGenerationRequestInit;
78
+ readonly onProgress?: (message: string) => void;
79
+ }
80
+ export interface MediaGenerationResult {
81
+ readonly bytes: Buffer;
82
+ readonly providerNote: string;
83
+ readonly suggestedExt?: string;
84
+ readonly providerId: string;
85
+ /** `true` when no real renderer was wired up for this (provider, surface) pair and deterministic placeholder bytes were returned instead — see `MediaDispatchEngineOptions.allowStubFallback`. */
86
+ readonly usedStubFallback: boolean;
87
+ /** Non-fatal notices (e.g. a requested `length`/`duration` was clamped to the nearest allowed value). */
88
+ readonly warnings: readonly string[];
89
+ }
90
+ export interface MediaDispatchEngineOptions {
91
+ /** Per-provider credentials, keyed by provider id (see `providers.ts`'s `MEDIA_PROVIDERS` for valid ids). */
92
+ readonly credentials?: Readonly<Record<string, ProviderCredentials>>;
93
+ /**
94
+ * When a (provider, surface) pair has no real renderer wired up, return
95
+ * deterministic placeholder bytes instead of throwing. Defaults to
96
+ * `false` (fail closed) — matching the origin's own explicitly-gated
97
+ * stub-fallback design (`OD_MEDIA_ALLOW_STUBS`): generated media is
98
+ * costly and a placeholder must never look like a successful real
99
+ * generation by accident, so a host must opt in explicitly rather than
100
+ * getting silent placeholders by default.
101
+ */
102
+ readonly allowStubFallback?: boolean;
103
+ }
104
+ export interface MediaDispatchEngine {
105
+ generate(request: MediaGenerationRequest): Promise<MediaGenerationResult>;
106
+ }
107
+ /** Internal: the pure shape rendered by `render*` provider functions, before the engine attaches `providerId`/`usedStubFallback`/`warnings`. */
108
+ export interface RenderResult {
109
+ readonly bytes: Buffer;
110
+ readonly providerNote: string;
111
+ readonly suggestedExt?: string;
112
+ }
113
+ /** Internal: per-generation context threaded into every `render*` provider function. */
114
+ export interface RenderContext {
115
+ readonly surface: MediaSurface;
116
+ readonly model: string;
117
+ readonly wireModel: string;
118
+ readonly prompt: string;
119
+ readonly aspect: string | undefined;
120
+ readonly length: number | undefined;
121
+ readonly duration: number | undefined;
122
+ readonly voice: string;
123
+ readonly audioKind: AudioKind | undefined;
124
+ readonly language: string;
125
+ readonly loop: boolean;
126
+ readonly promptInfluence: number | undefined;
127
+ readonly imageRef: MediaImageReference | null;
128
+ readonly imageRefs: readonly MediaImageReference[];
129
+ readonly requestInit: MediaGenerationRequestInit;
130
+ readonly speechFormat: MediaSpeechFormat;
131
+ readonly onProgress?: ((message: string) => void) | undefined;
132
+ }
133
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/media-providers/dispatch/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/media-providers/dispatch/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import type { ProviderCredentials, RenderContext, RenderResult } from './types.js';
2
+ /**
3
+ * One vendor HTTP request, plus any values `buildRequest` computed that
4
+ * `parseResponse` also needs (e.g. a resolved `wireModel`/`voiceId` for
5
+ * building `providerNote`). Kept out of `RenderContext` because these are
6
+ * per-adapter derived values, not universal fields every vendor shares.
7
+ */
8
+ export interface VendorRequest<Meta = undefined> {
9
+ readonly url: string;
10
+ readonly init: RequestInit;
11
+ readonly meta: Meta;
12
+ }
13
+ export type VendorRequestBuilder<Meta = undefined> = (ctx: RenderContext, credentials: ProviderCredentials) => VendorRequest<Meta>;
14
+ /**
15
+ * Turns a `fetch` `Response` into a `RenderResult`, or throws a
16
+ * vendor-tagged `Error` — the "response-parsing + error-mapping" half of a
17
+ * vendor adapter. Receives `ctx`/`request` too since some vendors need a
18
+ * second request (an SSRF-guarded asset download, a Gemini-native
19
+ * redirect) to finish parsing — see this module's doc comment.
20
+ */
21
+ export type VendorResponseParser<Meta = undefined> = (resp: Response, ctx: RenderContext, request: VendorRequest<Meta>) => Promise<RenderResult>;
22
+ /** Validates `credentials` before any network call, throwing a vendor-tagged `Error` when they're unusable (e.g. no API key configured). */
23
+ export type VendorCredentialGuard = (credentials: ProviderCredentials) => void;
24
+ /**
25
+ * A fully-configured vendor: the "auth-scheme" (`requireCredential`),
26
+ * "request-shape" (`buildRequest`), and "response-parsing + error-mapping"
27
+ * (`parseResponse`) a new vendor registers instead of writing a bespoke
28
+ * `render*` function.
29
+ */
30
+ export interface VendorAdapter<Meta = undefined> {
31
+ readonly requireCredential?: VendorCredentialGuard;
32
+ readonly buildRequest: VendorRequestBuilder<Meta>;
33
+ readonly parseResponse: VendorResponseParser<Meta>;
34
+ }
35
+ /**
36
+ * The generic dispatch core: `requireCredential` -> `buildRequest` -> one
37
+ * `fetch` -> `parseResponse`. Every migrated vendor's `render*` export is
38
+ * now a one-line call to this (see `providers/minimax.ts`,
39
+ * `providers/senseaudio.ts`, `providers/fishaudio.ts`, `providers/openai.ts`
40
+ * for real examples). `parseResponse` runs even on a non-2xx response —
41
+ * unlike `fetch` itself, an HTTP error status is not a rejected `Promise`,
42
+ * so mapping a bad status into a thrown `Error` is each adapter's own job,
43
+ * exactly like every hand-written `render*` function already did.
44
+ */
45
+ export declare function dispatchVendorRequest<Meta = undefined>(adapter: VendorAdapter<Meta>, ctx: RenderContext, credentials: ProviderCredentials): Promise<RenderResult>;
46
+ /**
47
+ * Reference `requireCredential` guard: throws `message` when
48
+ * `credentials.apiKey` is unset. Covers every ported vendor's own
49
+ * "no credential" check — each currently hand-writes the identical
50
+ * `if (!credentials.apiKey) throw new Error(...)` line with only the
51
+ * message text differing.
52
+ */
53
+ export declare function requireApiKey(message: string): VendorCredentialGuard;
54
+ //# sourceMappingURL=vendor-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-adapter.d.ts","sourceRoot":"","sources":["../../../src/media-providers/dispatch/vendor-adapter.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,IAAI,GAAG,SAAS;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,oBAAoB,CAAC,IAAI,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;AAEnI;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,CAAC,IAAI,GAAG,SAAS,IAAI,CACnD,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KACzB,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,4IAA4I;AAC5I,MAAM,MAAM,qBAAqB,GAAG,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,IAAI,GAAG,SAAS;IAC7C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;IACnD,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,GAAG,SAAS,EAC1D,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,EAC5B,GAAG,EAAE,aAAa,EAClB,WAAW,EAAE,mBAAmB,GAC/B,OAAO,CAAC,YAAY,CAAC,CAavB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAMpE"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The generic vendor-adapter dispatch core — the mechanism every registered
3
+ * media vendor's HTTP round trip runs through: validate credentials, build a
4
+ * request, perform exactly one `fetch`, then hand the response to a
5
+ * vendor-supplied parser. This is the piece `source-map.md`'s 2026-07-21
6
+ * dispatch-engine entry flagged as missing ("the actual multi-provider REST
7
+ * dispatch engine and durable task adapter" — each vendor was "essentially
8
+ * its own hand-written function, not a generalized system that can register
9
+ * a new vendor via configuration"): a vendor is now a `VendorAdapter` —
10
+ * (auth-scheme, request-shape, response-parsing/error-mapping)
11
+ * *configuration* passed to `dispatchVendorRequest` via
12
+ * `VendorAdapterRegistry` (see `vendor-registry.ts`) — not a bespoke async
13
+ * function that reimplements fetch/error-handling/byte-extraction inline
14
+ * every time.
15
+ *
16
+ * `parseResponse` is intentionally still a full function, not a further
17
+ * declarative shape — several real vendors need a *second* network call
18
+ * inside their "response parsing" step (SenseAudio's SSRF-guarded asset
19
+ * download, AIHubMix's Gemini-native redirect), which a purely declarative
20
+ * parser DSL can't express without becoming its own bespoke escape hatch
21
+ * anyway. The genericity this module buys is in the *harness* (uniform
22
+ * credential-check -> build -> fetch -> parse flow, pluggable via the
23
+ * registry), not in eliminating vendor-specific wire logic that doesn't
24
+ * actually repeat across vendors. Where response-parsing genuinely IS
25
+ * identical across vendors (MiniMax's and SenseAudio's TTS envelope), see
26
+ * `response-parsers.ts`'s `createHexEnvelopeAudioParser` for the shared,
27
+ * reusable piece.
28
+ */
29
+ import { FETCH_TIMEOUT_MS, fetchWithTimeout } from '@jini-ai/platform';
30
+ /**
31
+ * The generic dispatch core: `requireCredential` -> `buildRequest` -> one
32
+ * `fetch` -> `parseResponse`. Every migrated vendor's `render*` export is
33
+ * now a one-line call to this (see `providers/minimax.ts`,
34
+ * `providers/senseaudio.ts`, `providers/fishaudio.ts`, `providers/openai.ts`
35
+ * for real examples). `parseResponse` runs even on a non-2xx response —
36
+ * unlike `fetch` itself, an HTTP error status is not a rejected `Promise`,
37
+ * so mapping a bad status into a thrown `Error` is each adapter's own job,
38
+ * exactly like every hand-written `render*` function already did.
39
+ */
40
+ export async function dispatchVendorRequest(adapter, ctx, credentials) {
41
+ adapter.requireCredential?.(credentials);
42
+ const request = adapter.buildRequest(ctx, credentials);
43
+ // Backstop, not an override: as of 2026-08-16 only 2 of 13 registered vendors
44
+ // (providers/openai.ts, providers/openrouter.ts) set their own `request.init.signal`; the other
45
+ // 11 set none at all (Finding 2 of the 2026-08-16 failure-mode audit — a stalled vendor endpoint
46
+ // hung this call forever, nothing to alert on). `fetchWithTimeout` combines any signal a vendor
47
+ // DOES already set with this one via `AbortSignal.any`, so a more specific per-vendor timeout
48
+ // still applies unchanged; `GENERATE` (10min) matches what those two vendors already picked
49
+ // deliberately for the same reason — media generation genuinely finishes on that order, not in
50
+ // seconds, so anything shorter would abort a legitimately still-generating request.
51
+ const resp = await fetchWithTimeout(request.url, request.init, { timeoutMs: FETCH_TIMEOUT_MS.GENERATE });
52
+ return adapter.parseResponse(resp, ctx, request);
53
+ }
54
+ /**
55
+ * Reference `requireCredential` guard: throws `message` when
56
+ * `credentials.apiKey` is unset. Covers every ported vendor's own
57
+ * "no credential" check — each currently hand-writes the identical
58
+ * `if (!credentials.apiKey) throw new Error(...)` line with only the
59
+ * message text differing.
60
+ */
61
+ export function requireApiKey(message) {
62
+ return (credentials) => {
63
+ if (!credentials.apiKey) {
64
+ throw new Error(message);
65
+ }
66
+ };
67
+ }
68
+ //# sourceMappingURL=vendor-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-adapter.js","sourceRoot":"","sources":["../../../src/media-providers/dispatch/vendor-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA6CvE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA4B,EAC5B,GAAkB,EAClB,WAAgC;IAEhC,OAAO,CAAC,iBAAiB,EAAE,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvD,8EAA8E;IAC9E,gGAAgG;IAChG,iGAAiG;IACjG,gGAAgG;IAChG,8FAA8F;IAC9F,4FAA4F;IAC5F,+FAA+F;IAC/F,oFAAoF;IACpF,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzG,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,CAAC,WAAW,EAAE,EAAE;QACrB,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `VendorAdapterRegistry` — the registration surface a vendor module calls
3
+ * at import time instead of `engine.ts`'s `ROUTES` table pointing directly
4
+ * at a hand-written render function. A migrated vendor registers its
5
+ * `VendorAdapter` here, keyed by `(providerId, routeKey)` — the same
6
+ * `routeKey` shape `engine.ts`'s internal `routeKeyFor` already produces
7
+ * (`'image'`, `'video'`, `'audio:speech'`, ...). `engine.ts` consults this
8
+ * registry first when resolving a renderer, falling back to the static
9
+ * `ROUTES` table for vendors not yet migrated onto the generic engine — see
10
+ * `source-map.md`'s 2026-07-21 dispatch-engine-generalization section for
11
+ * exactly which vendors are registered here today, and why the rest
12
+ * legitimately aren't (yet).
13
+ */
14
+ import type { VendorAdapter } from './vendor-adapter.js';
15
+ export declare class VendorAdapterRegistry {
16
+ private readonly table;
17
+ /** Registers `adapter` for `(providerId, routeKey)`. Throws if that pair is already registered — a vendor module should register each of its (provider, surface) pairs exactly once, at module load. */
18
+ register<Meta>(providerId: string, routeKey: string, adapter: VendorAdapter<Meta>): void;
19
+ /** Looks up the adapter registered for `(providerId, routeKey)`, or `undefined` if none is registered. */
20
+ get(providerId: string, routeKey: string): VendorAdapter<never> | undefined;
21
+ /** Whether an adapter is registered for `(providerId, routeKey)`. */
22
+ has(providerId: string, routeKey: string): boolean;
23
+ /** Every `(providerId, routeKey)` pair currently registered — used by tests (and any diagnostics a host wants) to enumerate exactly which vendors run through the generic engine. */
24
+ list(): ReadonlyArray<readonly [providerId: string, routeKey: string]>;
25
+ }
26
+ /** Creates a fresh, empty registry — mainly useful for tests that want isolation from the shared `mediaVendorRegistry` singleton. */
27
+ export declare function createVendorAdapterRegistry(): VendorAdapterRegistry;
28
+ /**
29
+ * The shared registry every migrated vendor module registers into at import
30
+ * time, and `engine.ts` consults for dispatch. A host embedding
31
+ * `@jini-ai/integrations/media-providers` that wants a clean, isolated registry (e.g. to register its
32
+ * own vendor adapters without touching this module's set) can still call
33
+ * `createVendorAdapterRegistry()` directly instead of using this singleton.
34
+ */
35
+ export declare const mediaVendorRegistry: VendorAdapterRegistry;
36
+ //# sourceMappingURL=vendor-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-registry.d.ts","sourceRoot":"","sources":["../../../src/media-providers/dispatch/vendor-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwD;IAE9E,wMAAwM;IACxM,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI;IAYxF,0GAA0G;IAC1G,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS;IAI3E,qEAAqE;IACrE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIlD,qLAAqL;IACrL,IAAI,IAAI,aAAa,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;CASvE;AAED,qIAAqI;AACrI,wBAAgB,2BAA2B,IAAI,qBAAqB,CAEnE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,qBAAqD,CAAC"}
@@ -0,0 +1,46 @@
1
+ export class VendorAdapterRegistry {
2
+ table = new Map();
3
+ /** Registers `adapter` for `(providerId, routeKey)`. Throws if that pair is already registered — a vendor module should register each of its (provider, surface) pairs exactly once, at module load. */
4
+ register(providerId, routeKey, adapter) {
5
+ let bySurface = this.table.get(providerId);
6
+ if (!bySurface) {
7
+ bySurface = new Map();
8
+ this.table.set(providerId, bySurface);
9
+ }
10
+ if (bySurface.has(routeKey)) {
11
+ throw new Error(`a vendor adapter is already registered for "${providerId}" / "${routeKey}"`);
12
+ }
13
+ bySurface.set(routeKey, adapter);
14
+ }
15
+ /** Looks up the adapter registered for `(providerId, routeKey)`, or `undefined` if none is registered. */
16
+ get(providerId, routeKey) {
17
+ return this.table.get(providerId)?.get(routeKey);
18
+ }
19
+ /** Whether an adapter is registered for `(providerId, routeKey)`. */
20
+ has(providerId, routeKey) {
21
+ return this.table.get(providerId)?.has(routeKey) ?? false;
22
+ }
23
+ /** Every `(providerId, routeKey)` pair currently registered — used by tests (and any diagnostics a host wants) to enumerate exactly which vendors run through the generic engine. */
24
+ list() {
25
+ const out = [];
26
+ for (const [providerId, bySurface] of this.table) {
27
+ for (const routeKey of bySurface.keys()) {
28
+ out.push([providerId, routeKey]);
29
+ }
30
+ }
31
+ return out;
32
+ }
33
+ }
34
+ /** Creates a fresh, empty registry — mainly useful for tests that want isolation from the shared `mediaVendorRegistry` singleton. */
35
+ export function createVendorAdapterRegistry() {
36
+ return new VendorAdapterRegistry();
37
+ }
38
+ /**
39
+ * The shared registry every migrated vendor module registers into at import
40
+ * time, and `engine.ts` consults for dispatch. A host embedding
41
+ * `@jini-ai/integrations/media-providers` that wants a clean, isolated registry (e.g. to register its
42
+ * own vendor adapters without touching this module's set) can still call
43
+ * `createVendorAdapterRegistry()` directly instead of using this singleton.
44
+ */
45
+ export const mediaVendorRegistry = createVendorAdapterRegistry();
46
+ //# sourceMappingURL=vendor-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-registry.js","sourceRoot":"","sources":["../../../src/media-providers/dispatch/vendor-registry.ts"],"names":[],"mappings":"AAeA,MAAM,OAAO,qBAAqB;IACf,KAAK,GAAG,IAAI,GAAG,EAA6C,CAAC;IAE9E,wMAAwM;IACxM,QAAQ,CAAO,UAAkB,EAAE,QAAgB,EAAE,OAA4B;QAC/E,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,+CAA+C,UAAU,QAAQ,QAAQ,GAAG,CAAC,CAAC;QAChG,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,OAA0C,CAAC,CAAC;IACtE,CAAC;IAED,0GAA0G;IAC1G,GAAG,CAAC,UAAkB,EAAE,QAAgB;QACtC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,qEAAqE;IACrE,GAAG,CAAC,UAAkB,EAAE,QAAgB;QACtC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC5D,CAAC;IAED,qLAAqL;IACrL,IAAI;QACF,MAAM,GAAG,GAAqC,EAAE,CAAC;QACjD,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACjD,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;gBACxC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,qIAAqI;AACrI,MAAM,UAAU,2BAA2B;IACzC,OAAO,IAAI,qBAAqB,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA0B,2BAA2B,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `@jini-ai/integrations/media-providers` — multi-provider image/video/audio generation gateway:
3
+ * provider/model types, the real vendor catalogue as reference data, an
4
+ * injection-style capability registry, a pure video-request builder, an
5
+ * async task-tracking port, a host-injected policy port, a generic
6
+ * attachment-staging port, and (as of the dispatch engine) a real
7
+ * multi-vendor REST dispatch engine covering an initial vendor slice — see
8
+ * `source-map.md` for full provenance, exactly which vendors are ported vs
9
+ * deferred, and this package's not-yet-locked status.
10
+ */
11
+ export * from './types.js';
12
+ export * from './providers.js';
13
+ export * from './capability-registry.js';
14
+ export * from './seed.js';
15
+ export * from './video-request.js';
16
+ export * from './task-store.js';
17
+ export * from './policy.js';
18
+ export * from './staging.js';
19
+ export * from './tokens.js';
20
+ export * from './dispatch/index.js';
21
+ export * from './sqlite-task-store.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `@jini-ai/integrations/media-providers` — multi-provider image/video/audio generation gateway:
3
+ * provider/model types, the real vendor catalogue as reference data, an
4
+ * injection-style capability registry, a pure video-request builder, an
5
+ * async task-tracking port, a host-injected policy port, a generic
6
+ * attachment-staging port, and (as of the dispatch engine) a real
7
+ * multi-vendor REST dispatch engine covering an initial vendor slice — see
8
+ * `source-map.md` for full provenance, exactly which vendors are ported vs
9
+ * deferred, and this package's not-yet-locked status.
10
+ */
11
+ export * from './types.js';
12
+ export * from './providers.js';
13
+ export * from './capability-registry.js';
14
+ export * from './seed.js';
15
+ export * from './video-request.js';
16
+ export * from './task-store.js';
17
+ export * from './policy.js';
18
+ export * from './staging.js';
19
+ export * from './tokens.js';
20
+ export * from './dispatch/index.js';
21
+ export * from './sqlite-task-store.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `MediaPolicy` — a host-injected gate on media generation. Generalized from
3
+ * OD's `apps/daemon/src/media/policy.ts`, which is a thin wrapper
4
+ * around `@open-design/contracts`'s `MediaExecutionPolicy`/
5
+ * `mediaExecutionPolicyDenial` (that package is OD-owned and out of scope
6
+ * for this engine package). The underlying evaluation logic itself carries
7
+ * no OD-specific moderation content or thresholds — it is a plain
8
+ * enabled/disabled + surface/model allowlist gate — so it ports as generic
9
+ * data + a pure evaluator, redefined locally rather than imported. A host
10
+ * that needs real content-moderation rules (NSFW classifiers, per-tenant
11
+ * quotas, etc.) implements `MediaPolicy` itself; `createAllowlistMediaPolicy`
12
+ * is the reference implementation proving the port's shape, not a
13
+ * moderation engine.
14
+ */
15
+ import type { MediaSurface } from './types.js';
16
+ export type MediaExecutionMode = 'enabled' | 'disabled';
17
+ export type MediaPolicyDenialCode = 'MEDIA_EXECUTION_DISABLED' | 'MEDIA_SURFACE_DENIED' | 'MEDIA_MODEL_DENIED';
18
+ /** What a caller is asking permission to do. */
19
+ export interface MediaPolicyTarget {
20
+ readonly surface: MediaSurface;
21
+ readonly model?: string;
22
+ }
23
+ export interface MediaPolicyDenial {
24
+ readonly code: MediaPolicyDenialCode;
25
+ readonly message: string;
26
+ }
27
+ /** Declarative shape for `createAllowlistMediaPolicy` — an allowlist gate, not the only possible `MediaPolicy` implementation. */
28
+ export interface MediaExecutionPolicy {
29
+ readonly mode: MediaExecutionMode;
30
+ readonly allowedSurfaces?: readonly MediaSurface[];
31
+ readonly allowedModels?: readonly string[];
32
+ }
33
+ export declare const DEFAULT_MEDIA_EXECUTION_POLICY: MediaExecutionPolicy;
34
+ /**
35
+ * Host-injected policy port. `@jini-ai/integrations/media-providers` never calls this itself — a
36
+ * caller (a pack's app-service, a tool handler) evaluates a target before
37
+ * dispatching generation and honors a non-null denial.
38
+ */
39
+ export interface MediaPolicy {
40
+ evaluate(target: MediaPolicyTarget): MediaPolicyDenial | null;
41
+ }
42
+ /**
43
+ * Reference `MediaPolicy`: an enabled/disabled + surface/model allowlist
44
+ * gate, ported verbatim from the origin's `mediaExecutionPolicyDenial`. A
45
+ * missing/empty `allowedSurfaces`/`allowedModels` means "no restriction on
46
+ * that dimension" (matches the origin's `Array.isArray(...) && length > 0` guard).
47
+ */
48
+ export declare function createAllowlistMediaPolicy(policy?: MediaExecutionPolicy): MediaPolicy;
49
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/media-providers/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAE/G,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,kIAAkI;AAClI,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACnD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAOD,eAAO,MAAM,8BAA8B,EAAE,oBAA2C,CAAC;AAEzF;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,IAAI,CAAC;CAC/D;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,GAAE,oBAAqD,GAAG,WAAW,CAyBrH"}
@@ -0,0 +1,39 @@
1
+ // SEC-RB-010: deny by default. A host must explicitly opt into `mode:
2
+ // 'enabled'` (and, if it cares about restricting models, explicitly supply
3
+ // `allowedModels`) rather than getting an unrestricted default merely by
4
+ // not passing a policy at all — media generation is a real-money, costly
5
+ // capability, not something that should be on by default.
6
+ export const DEFAULT_MEDIA_EXECUTION_POLICY = { mode: 'disabled' };
7
+ /**
8
+ * Reference `MediaPolicy`: an enabled/disabled + surface/model allowlist
9
+ * gate, ported verbatim from the origin's `mediaExecutionPolicyDenial`. A
10
+ * missing/empty `allowedSurfaces`/`allowedModels` means "no restriction on
11
+ * that dimension" (matches the origin's `Array.isArray(...) && length > 0` guard).
12
+ */
13
+ export function createAllowlistMediaPolicy(policy = DEFAULT_MEDIA_EXECUTION_POLICY) {
14
+ return {
15
+ evaluate(target) {
16
+ if (policy.mode === 'disabled') {
17
+ return { code: 'MEDIA_EXECUTION_DISABLED', message: 'media generation is disabled for this run' };
18
+ }
19
+ if (policy.allowedSurfaces && policy.allowedSurfaces.length > 0 && !policy.allowedSurfaces.includes(target.surface)) {
20
+ return { code: 'MEDIA_SURFACE_DENIED', message: `media surface "${target.surface}" is not allowed for this run` };
21
+ }
22
+ // SEC-RB-010: a model allowlist must not be bypassable by omitting the
23
+ // model field. If the host restricted models at all, an unspecified
24
+ // (or blank-after-normalization) model can't be verified against that
25
+ // allowlist and must be denied, not silently waved through.
26
+ const normalizedModel = target.model?.trim();
27
+ if (policy.allowedModels && policy.allowedModels.length > 0) {
28
+ if (!normalizedModel || !policy.allowedModels.includes(normalizedModel)) {
29
+ return {
30
+ code: 'MEDIA_MODEL_DENIED',
31
+ message: `media model ${normalizedModel ? `"${normalizedModel}"` : '(none specified)'} is not allowed for this run`,
32
+ };
33
+ }
34
+ }
35
+ return null;
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=policy.js.map