@jini-ai/integrations 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +51 -0
- package/dist/composio/bounded-data.d.ts +36 -0
- package/dist/composio/bounded-data.d.ts.map +1 -0
- package/dist/composio/bounded-data.js +181 -0
- package/dist/composio/bounded-data.js.map +1 -0
- package/dist/composio/catalog.d.ts +147 -0
- package/dist/composio/catalog.d.ts.map +1 -0
- package/dist/composio/catalog.js +126 -0
- package/dist/composio/catalog.js.map +1 -0
- package/dist/composio/composio-config.d.ts +42 -0
- package/dist/composio/composio-config.d.ts.map +1 -0
- package/dist/composio/composio-config.js +145 -0
- package/dist/composio/composio-config.js.map +1 -0
- package/dist/composio/composio-descriptions.d.ts +16 -0
- package/dist/composio/composio-descriptions.d.ts.map +1 -0
- package/dist/composio/composio-descriptions.js +766 -0
- package/dist/composio/composio-descriptions.js.map +1 -0
- package/dist/composio/composio.d.ts +364 -0
- package/dist/composio/composio.d.ts.map +1 -0
- package/dist/composio/composio.js +1902 -0
- package/dist/composio/composio.js.map +1 -0
- package/dist/composio/errors.d.ts +15 -0
- package/dist/composio/errors.d.ts.map +1 -0
- package/dist/composio/errors.js +16 -0
- package/dist/composio/errors.js.map +1 -0
- package/dist/composio/file-lock.d.ts +13 -0
- package/dist/composio/file-lock.d.ts.map +1 -0
- package/dist/composio/file-lock.js +92 -0
- package/dist/composio/file-lock.js.map +1 -0
- package/dist/composio/index.d.ts +18 -0
- package/dist/composio/index.d.ts.map +1 -0
- package/dist/composio/index.js +7 -0
- package/dist/composio/index.js.map +1 -0
- package/dist/composio/json-schema.d.ts +93 -0
- package/dist/composio/json-schema.d.ts.map +1 -0
- package/dist/composio/json-schema.js +498 -0
- package/dist/composio/json-schema.js.map +1 -0
- package/dist/composio/output-protection.d.ts +32 -0
- package/dist/composio/output-protection.d.ts.map +1 -0
- package/dist/composio/output-protection.js +105 -0
- package/dist/composio/output-protection.js.map +1 -0
- package/dist/composio/service.d.ts +181 -0
- package/dist/composio/service.d.ts.map +1 -0
- package/dist/composio/service.js +758 -0
- package/dist/composio/service.js.map +1 -0
- package/dist/media-providers/capability-registry.d.ts +28 -0
- package/dist/media-providers/capability-registry.d.ts.map +1 -0
- package/dist/media-providers/capability-registry.js +27 -0
- package/dist/media-providers/capability-registry.js.map +1 -0
- package/dist/media-providers/catalog.d.ts +20 -0
- package/dist/media-providers/catalog.d.ts.map +1 -0
- package/dist/media-providers/catalog.js +20 -0
- package/dist/media-providers/catalog.js.map +1 -0
- package/dist/media-providers/dispatch/context.d.ts +21 -0
- package/dist/media-providers/dispatch/context.d.ts.map +1 -0
- package/dist/media-providers/dispatch/context.js +36 -0
- package/dist/media-providers/dispatch/context.js.map +1 -0
- package/dist/media-providers/dispatch/credentials.d.ts +4 -0
- package/dist/media-providers/dispatch/credentials.d.ts.map +1 -0
- package/dist/media-providers/dispatch/credentials.js +25 -0
- package/dist/media-providers/dispatch/credentials.js.map +1 -0
- package/dist/media-providers/dispatch/engine.d.ts +30 -0
- package/dist/media-providers/dispatch/engine.d.ts.map +1 -0
- package/dist/media-providers/dispatch/engine.js +208 -0
- package/dist/media-providers/dispatch/engine.js.map +1 -0
- package/dist/media-providers/dispatch/index.d.ts +25 -0
- package/dist/media-providers/dispatch/index.d.ts.map +1 -0
- package/dist/media-providers/dispatch/index.js +24 -0
- package/dist/media-providers/dispatch/index.js.map +1 -0
- package/dist/media-providers/dispatch/openai-compatible.d.ts +44 -0
- package/dist/media-providers/dispatch/openai-compatible.d.ts.map +1 -0
- package/dist/media-providers/dispatch/openai-compatible.js +214 -0
- package/dist/media-providers/dispatch/openai-compatible.js.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts +72 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.js +131 -0
- package/dist/media-providers/dispatch/providers/aihubmix-shared.js.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/aihubmix.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/aihubmix.js +205 -0
- package/dist/media-providers/dispatch/providers/aihubmix.js.map +1 -0
- package/dist/media-providers/dispatch/providers/custom-image.d.ts +6 -0
- package/dist/media-providers/dispatch/providers/custom-image.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/custom-image.js +94 -0
- package/dist/media-providers/dispatch/providers/custom-image.js.map +1 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.js +163 -0
- package/dist/media-providers/dispatch/providers/elevenlabs.js.map +1 -0
- package/dist/media-providers/dispatch/providers/fishaudio.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/fishaudio.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/fishaudio.js +83 -0
- package/dist/media-providers/dispatch/providers/fishaudio.js.map +1 -0
- package/dist/media-providers/dispatch/providers/grok.d.ts +15 -0
- package/dist/media-providers/dispatch/providers/grok.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/grok.js +150 -0
- package/dist/media-providers/dispatch/providers/grok.js.map +1 -0
- package/dist/media-providers/dispatch/providers/imagerouter.d.ts +6 -0
- package/dist/media-providers/dispatch/providers/imagerouter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/imagerouter.js +131 -0
- package/dist/media-providers/dispatch/providers/imagerouter.js.map +1 -0
- package/dist/media-providers/dispatch/providers/minimax.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/minimax.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/minimax.js +96 -0
- package/dist/media-providers/dispatch/providers/minimax.js.map +1 -0
- package/dist/media-providers/dispatch/providers/nanobanana.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/nanobanana.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/nanobanana.js +142 -0
- package/dist/media-providers/dispatch/providers/nanobanana.js.map +1 -0
- package/dist/media-providers/dispatch/providers/openai.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/openai.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/openai.js +231 -0
- package/dist/media-providers/dispatch/providers/openai.js.map +1 -0
- package/dist/media-providers/dispatch/providers/openrouter.d.ts +13 -0
- package/dist/media-providers/dispatch/providers/openrouter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/openrouter.js +152 -0
- package/dist/media-providers/dispatch/providers/openrouter.js.map +1 -0
- package/dist/media-providers/dispatch/providers/senseaudio.d.ts +4 -0
- package/dist/media-providers/dispatch/providers/senseaudio.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/senseaudio.js +190 -0
- package/dist/media-providers/dispatch/providers/senseaudio.js.map +1 -0
- package/dist/media-providers/dispatch/providers/volcengine.d.ts +3 -0
- package/dist/media-providers/dispatch/providers/volcengine.d.ts.map +1 -0
- package/dist/media-providers/dispatch/providers/volcengine.js +95 -0
- package/dist/media-providers/dispatch/providers/volcengine.js.map +1 -0
- package/dist/media-providers/dispatch/response-parsers.d.ts +44 -0
- package/dist/media-providers/dispatch/response-parsers.d.ts.map +1 -0
- package/dist/media-providers/dispatch/response-parsers.js +103 -0
- package/dist/media-providers/dispatch/response-parsers.js.map +1 -0
- package/dist/media-providers/dispatch/ssrf-guard.d.ts +51 -0
- package/dist/media-providers/dispatch/ssrf-guard.d.ts.map +1 -0
- package/dist/media-providers/dispatch/ssrf-guard.js +215 -0
- package/dist/media-providers/dispatch/ssrf-guard.js.map +1 -0
- package/dist/media-providers/dispatch/stub.d.ts +5 -0
- package/dist/media-providers/dispatch/stub.d.ts.map +1 -0
- package/dist/media-providers/dispatch/stub.js +98 -0
- package/dist/media-providers/dispatch/stub.js.map +1 -0
- package/dist/media-providers/dispatch/types.d.ts +133 -0
- package/dist/media-providers/dispatch/types.d.ts.map +1 -0
- package/dist/media-providers/dispatch/types.js +2 -0
- package/dist/media-providers/dispatch/types.js.map +1 -0
- package/dist/media-providers/dispatch/vendor-adapter.d.ts +54 -0
- package/dist/media-providers/dispatch/vendor-adapter.d.ts.map +1 -0
- package/dist/media-providers/dispatch/vendor-adapter.js +68 -0
- package/dist/media-providers/dispatch/vendor-adapter.js.map +1 -0
- package/dist/media-providers/dispatch/vendor-registry.d.ts +36 -0
- package/dist/media-providers/dispatch/vendor-registry.d.ts.map +1 -0
- package/dist/media-providers/dispatch/vendor-registry.js +46 -0
- package/dist/media-providers/dispatch/vendor-registry.js.map +1 -0
- package/dist/media-providers/index.d.ts +22 -0
- package/dist/media-providers/index.d.ts.map +1 -0
- package/dist/media-providers/index.js +22 -0
- package/dist/media-providers/index.js.map +1 -0
- package/dist/media-providers/policy.d.ts +49 -0
- package/dist/media-providers/policy.d.ts.map +1 -0
- package/dist/media-providers/policy.js +39 -0
- package/dist/media-providers/policy.js.map +1 -0
- package/dist/media-providers/providers.d.ts +33 -0
- package/dist/media-providers/providers.d.ts.map +1 -0
- package/dist/media-providers/providers.js +200 -0
- package/dist/media-providers/providers.js.map +1 -0
- package/dist/media-providers/seed.d.ts +14 -0
- package/dist/media-providers/seed.d.ts.map +1 -0
- package/dist/media-providers/seed.js +109 -0
- package/dist/media-providers/seed.js.map +1 -0
- package/dist/media-providers/sqlite-task-store.d.ts +29 -0
- package/dist/media-providers/sqlite-task-store.d.ts.map +1 -0
- package/dist/media-providers/sqlite-task-store.js +234 -0
- package/dist/media-providers/sqlite-task-store.js.map +1 -0
- package/dist/media-providers/staging.d.ts +29 -0
- package/dist/media-providers/staging.d.ts.map +1 -0
- package/dist/media-providers/staging.js +141 -0
- package/dist/media-providers/staging.js.map +1 -0
- package/dist/media-providers/task-store.d.ts +94 -0
- package/dist/media-providers/task-store.d.ts.map +1 -0
- package/dist/media-providers/task-store.js +160 -0
- package/dist/media-providers/task-store.js.map +1 -0
- package/dist/media-providers/tokens.d.ts +7 -0
- package/dist/media-providers/tokens.d.ts.map +1 -0
- package/dist/media-providers/tokens.js +13 -0
- package/dist/media-providers/tokens.js.map +1 -0
- package/dist/media-providers/types.d.ts +123 -0
- package/dist/media-providers/types.d.ts.map +1 -0
- package/dist/media-providers/types.js +12 -0
- package/dist/media-providers/types.js.map +1 -0
- package/dist/media-providers/video-request.d.ts +62 -0
- package/dist/media-providers/video-request.d.ts.map +1 -0
- package/dist/media-providers/video-request.js +219 -0
- package/dist/media-providers/video-request.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,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, '<')
|
|
60
|
+
.replace(/>/g, '>');
|
|
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 @@
|
|
|
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
|