@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,160 @@
1
+ /**
2
+ * `MediaTaskStore` — the async task-tracking port for request-now,
3
+ * poll-later media generation. Generalized from OD's
4
+ * `apps/daemon/src/media/tasks.ts`, which is a `better-sqlite3`-coupled,
5
+ * synchronous CRUD module keyed on `projectId` (an OD domain noun) with a
6
+ * hardcoded SQL schema. Per extraction-plan.md §2.6 ("ports are async-only
7
+ * from day one") and the pattern already established by
8
+ * `@jini-ai/daemon`'s `EventLog` (see `packages/daemon/src/event-log.ts`), this
9
+ * is a from-scratch storage-agnostic port + in-memory reference
10
+ * implementation — not a lift — reproducing the same lifecycle semantics
11
+ * (queued → running → done|failed|interrupted, boot-time reconciliation of
12
+ * orphaned in-flight tasks, TTL-based terminal-task pruning) without a SQL
13
+ * schema or an OD project reference. A durable adapter (a future
14
+ * `@jini-ai/sqlite` addition) implements the same interface — see
15
+ * `source-map.md`.
16
+ */
17
+ const VALID_STATUSES = new Set([
18
+ 'queued',
19
+ 'running',
20
+ 'done',
21
+ 'failed',
22
+ 'interrupted',
23
+ ]);
24
+ const TERMINAL_STATUSES = new Set(['done', 'failed', 'interrupted']);
25
+ // CR-013: `assertValidStatus` alone only proves enum membership, not that a
26
+ // transition is legal — it allowed e.g. `done` -> `running`. This is the
27
+ // actual lifecycle graph the store's own docs claim
28
+ // (queued -> running -> done|failed|interrupted); same-state is included so
29
+ // a caller can `update()` progress/file without also having to re-derive the
30
+ // current status, but nothing can leave a terminal state once reached.
31
+ const ALLOWED_TRANSITIONS = {
32
+ // `queued` may go straight to a terminal state too (a caller isn't
33
+ // required to make a separate "now running" update before finishing).
34
+ queued: new Set(['queued', 'running', 'done', 'failed', 'interrupted']),
35
+ running: new Set(['running', 'done', 'failed', 'interrupted']),
36
+ done: new Set(['done']),
37
+ failed: new Set(['failed']),
38
+ interrupted: new Set(['interrupted']),
39
+ };
40
+ function cloneTask(task) {
41
+ return {
42
+ ...task,
43
+ progress: [...task.progress],
44
+ file: task.file == null ? null : structuredClone(task.file),
45
+ error: task.error == null ? null : { ...task.error },
46
+ };
47
+ }
48
+ const INTERRUPTED_ERROR = {
49
+ message: 'media task interrupted by daemon restart',
50
+ code: 'DAEMON_RESTART',
51
+ };
52
+ /** Creates the in-memory reference `MediaTaskStore`. No persistence — state is lost on process exit. */
53
+ export function createInMemoryMediaTaskStore() {
54
+ const tasks = new Map();
55
+ return {
56
+ async create(input) {
57
+ if (tasks.has(input.id)) {
58
+ throw new Error(`media task "${input.id}" already exists`);
59
+ }
60
+ const status = input.status ?? 'queued';
61
+ assertValidStatus(status);
62
+ const now = Date.now();
63
+ const startedAt = input.startedAt ?? now;
64
+ const task = {
65
+ id: input.id,
66
+ ownerRef: input.ownerRef,
67
+ status,
68
+ progress: input.progress ? [...input.progress] : [],
69
+ file: input.file == null ? null : structuredClone(input.file),
70
+ error: input.error == null ? null : { ...input.error },
71
+ startedAt,
72
+ endedAt: null,
73
+ createdAt: now,
74
+ updatedAt: now,
75
+ ...(input.surface !== undefined ? { surface: input.surface } : {}),
76
+ ...(input.model !== undefined ? { model: input.model } : {}),
77
+ };
78
+ tasks.set(task.id, task);
79
+ return cloneTask(task);
80
+ },
81
+ async get(id) {
82
+ const task = tasks.get(id);
83
+ return task ? cloneTask(task) : null;
84
+ },
85
+ async update(id, patch) {
86
+ const existing = tasks.get(id);
87
+ if (!existing)
88
+ return null;
89
+ const status = patch.status ?? existing.status;
90
+ assertValidStatus(status);
91
+ // CR-013: enum membership alone doesn't prove the transition is legal
92
+ // (e.g. `done` -> `running`) — check the actual lifecycle graph too.
93
+ if (!ALLOWED_TRANSITIONS[existing.status].has(status)) {
94
+ throw new RangeError(`Invalid media task transition: "${existing.status}" -> "${status}"`);
95
+ }
96
+ const surface = 'surface' in patch ? (patch.surface ?? undefined) : existing.surface;
97
+ const model = 'model' in patch ? (patch.model ?? undefined) : existing.model;
98
+ const next = {
99
+ id: existing.id,
100
+ ownerRef: existing.ownerRef,
101
+ status,
102
+ progress: patch.progress ? [...patch.progress] : existing.progress,
103
+ file: 'file' in patch ? (patch.file == null ? null : structuredClone(patch.file)) : existing.file,
104
+ error: 'error' in patch ? (patch.error == null ? null : { ...patch.error }) : existing.error,
105
+ startedAt: existing.startedAt,
106
+ endedAt: 'endedAt' in patch ? (patch.endedAt ?? null) : existing.endedAt,
107
+ createdAt: existing.createdAt,
108
+ updatedAt: Date.now(),
109
+ ...(surface !== undefined ? { surface } : {}),
110
+ ...(model !== undefined ? { model } : {}),
111
+ };
112
+ tasks.set(id, next);
113
+ return cloneTask(next);
114
+ },
115
+ async listByOwner(ownerRef, options = {}) {
116
+ const includeTerminal = options.includeTerminal === true;
117
+ return [...tasks.values()]
118
+ .filter((t) => t.ownerRef === ownerRef)
119
+ .filter((t) => includeTerminal || !TERMINAL_STATUSES.has(t.status))
120
+ .sort((a, b) => b.startedAt - a.startedAt)
121
+ .map(cloneTask);
122
+ },
123
+ async delete(id) {
124
+ tasks.delete(id);
125
+ },
126
+ async reconcileOnBoot(options) {
127
+ if (!Number.isFinite(options.terminalTtlMs) || options.terminalTtlMs < 0) {
128
+ throw new RangeError(`Invalid terminalTtlMs: ${options.terminalTtlMs} must be a non-negative finite number`);
129
+ }
130
+ const now = options.now ?? Date.now();
131
+ const cutoff = now - options.terminalTtlMs;
132
+ let interrupted = 0;
133
+ let deleted = 0;
134
+ for (const task of [...tasks.values()]) {
135
+ if (task.status === 'queued' || task.status === 'running') {
136
+ tasks.set(task.id, {
137
+ ...task,
138
+ status: 'interrupted',
139
+ error: INTERRUPTED_ERROR,
140
+ endedAt: task.endedAt ?? now,
141
+ updatedAt: now,
142
+ });
143
+ interrupted += 1;
144
+ continue;
145
+ }
146
+ if (TERMINAL_STATUSES.has(task.status) && (task.endedAt ?? task.updatedAt) < cutoff) {
147
+ tasks.delete(task.id);
148
+ deleted += 1;
149
+ }
150
+ }
151
+ return { interrupted, deleted };
152
+ },
153
+ };
154
+ }
155
+ function assertValidStatus(status) {
156
+ if (!VALID_STATUSES.has(status)) {
157
+ throw new RangeError(`Invalid media task status: "${status}"`);
158
+ }
159
+ }
160
+ //# sourceMappingURL=task-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../../src/media-providers/task-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CapabilityRegistry } from './capability-registry.js';
2
+ import type { MediaPolicy } from './policy.js';
3
+ import type { MediaTaskStore } from './task-store.js';
4
+ export declare const CapabilityRegistryToken: import("@jini-ai/core").Token<CapabilityRegistry, string>;
5
+ export declare const MediaTaskStoreToken: import("@jini-ai/core").Token<MediaTaskStore, string>;
6
+ export declare const MediaPolicyToken: import("@jini-ai/core").Token<MediaPolicy, string>;
7
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/media-providers/tokens.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,eAAO,MAAM,uBAAuB,2DAA6D,CAAC;AAClG,eAAO,MAAM,mBAAmB,uDAAgD,CAAC;AACjF,eAAO,MAAM,gBAAgB,oDAA0C,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Typed DI tokens for `@jini-ai/integrations/media-providers`'s ports, following the exact pattern
3
+ * `@jini-ai/core`'s `token()` establishes (see `packages/core/src/token.ts`)
4
+ * and the naming convention `@jini-ai/daemon`'s `src/tokens.ts` already set
5
+ * (bare-interface-name-suffixed-`Token`, not extraction-plan §2.2's
6
+ * illustrative bare-name pseudocode, which would shadow the interface names
7
+ * in this codebase's actual precedent).
8
+ */
9
+ import { token } from '@jini-ai/core';
10
+ export const CapabilityRegistryToken = token('jini.media.capabilityRegistry');
11
+ export const MediaTaskStoreToken = token('jini.media.taskStore');
12
+ export const MediaPolicyToken = token('jini.media.policy');
13
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/media-providers/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAKtC,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAqB,+BAA+B,CAAC,CAAC;AAClG,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAiB,sBAAsB,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAc,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * `@jini-ai/integrations/media-providers` core type system — the provider/model catalogue shape and the
3
+ * pure, transport-free request-building types layered on top of it.
4
+ *
5
+ * Ported from OD's `apps/daemon/src/media/models.ts` (catalogue
6
+ * shape) and `apps/daemon/src/media-adapters/types.ts` (capability +
7
+ * request-builder shape) — see `source-map.md` for the full provenance.
8
+ * Neither origin file carries any OD domain noun; this is a product-neutral
9
+ * multi-vendor media-generation type system, not an OD concept.
10
+ */
11
+ /** The three kinds of media this package's catalogue covers. */
12
+ export type MediaSurface = 'image' | 'video' | 'audio';
13
+ /** Sub-kind of `'audio'` — audio generation splits into three distinct model families. */
14
+ export type AudioKind = 'music' | 'speech' | 'sfx';
15
+ /**
16
+ * A third-party media-generation vendor (e.g. OpenAI, Fal.ai, ElevenLabs).
17
+ * Reference/catalogue data, not a live connection — a host resolves
18
+ * `credentialsRequired`/`defaultBaseUrl` into its own credential storage.
19
+ */
20
+ export interface MediaProvider {
21
+ readonly id: string;
22
+ readonly label: string;
23
+ readonly hint: string;
24
+ /** Whether this package ships a working request-shape for this provider (vs. a planned/future entry). */
25
+ readonly integrated: boolean;
26
+ readonly defaultBaseUrl?: string;
27
+ readonly docsUrl?: string;
28
+ readonly credentialsRequired?: boolean;
29
+ readonly settingsVisible?: boolean;
30
+ readonly supportsCustomModel?: boolean;
31
+ readonly customModelPlaceholder?: string;
32
+ }
33
+ /** A specific generation model offered by a `MediaProvider`. */
34
+ export interface MediaModel {
35
+ readonly id: string;
36
+ readonly label: string;
37
+ readonly hint: string;
38
+ readonly provider: string;
39
+ /** Capability tags, e.g. `t2i`/`i2i`/`inpaint`/`t2v`/`i2v`/`tts`. Open-ended by design — see `source-map.md`. */
40
+ readonly caps: readonly string[];
41
+ readonly default?: boolean;
42
+ }
43
+ /**
44
+ * Request-shape family, keyed off the resolved upstream model name. Each
45
+ * family is a distinct wire shape a real vendor gateway expects — see
46
+ * `video-request.ts` for the branching logic and `source-map.md` for the
47
+ * vendor-verification notes this was ported with.
48
+ */
49
+ export type MediaFamily = 'seedance' | 'wan' | 'veo' | 'generic';
50
+ export type MediaType = 'video' | 'image' | 'audio';
51
+ /** A vendor-specific parameter a caller may pass through, with an optional default. */
52
+ export interface ExtraBodyParamDef {
53
+ readonly name: string;
54
+ readonly type: 'string' | 'number' | 'boolean';
55
+ readonly default?: string | number | boolean;
56
+ readonly description?: string;
57
+ }
58
+ /**
59
+ * Per-model capability description — the data a `CapabilityRegistry` holds.
60
+ * Field names deliberately align with OpenRouter's `GET /api/v1/videos/models`
61
+ * shape so a future remote-fetched catalogue is a data-source swap, not a
62
+ * reshape (see `source-map.md`).
63
+ */
64
+ export interface ModelCapability {
65
+ /** Catalogue id (vendor-aggregator prefixes stripped — see `normalizeModelId`). */
66
+ readonly id: string;
67
+ /** Upstream model name for text-to-X / base generation. */
68
+ readonly apiModel: string;
69
+ /** Upstream model name used when a reference image is present (image-to-X). */
70
+ readonly apiModelI2V?: string;
71
+ readonly mediaType: MediaType;
72
+ readonly caps: readonly string[];
73
+ /** Explicit family override; when omitted the family is derived from the wire model name — see `deriveVideoFamily`. */
74
+ readonly family?: MediaFamily;
75
+ readonly baseUrl?: string;
76
+ readonly supportedDurations?: readonly number[];
77
+ readonly supportedSizes?: readonly string[];
78
+ readonly supportedAspectRatios?: readonly string[];
79
+ readonly supportedResolutions?: readonly string[];
80
+ /** Reference-frame roles the model accepts, e.g. `['first_frame']`. Empty/absent means no image-to-X support. */
81
+ readonly supportedFrameImages?: readonly string[];
82
+ readonly generateAudio?: boolean;
83
+ readonly seed?: boolean;
84
+ readonly allowedPassthroughParameters?: readonly string[];
85
+ readonly extraBodyDefaults?: readonly ExtraBodyParamDef[];
86
+ }
87
+ /**
88
+ * Unified video-generation request input. The caller resolves any reference
89
+ * image to a data URL before calling — this package performs no I/O.
90
+ */
91
+ export interface VideoBuildInput {
92
+ readonly prompt: string;
93
+ readonly durationSeconds?: number;
94
+ readonly aspectRatio?: string;
95
+ readonly size?: string;
96
+ readonly resolution?: string;
97
+ readonly imageRef?: {
98
+ readonly dataUrl: string;
99
+ };
100
+ readonly extraImageRefs?: readonly {
101
+ readonly dataUrl: string;
102
+ }[];
103
+ readonly generateAudio?: boolean;
104
+ readonly seed?: number;
105
+ readonly passthrough?: Readonly<Record<string, unknown>>;
106
+ }
107
+ /** Result of `buildVideoRequest` — transport-free; the caller attaches auth + base URL and performs the fetch. */
108
+ export interface BuiltVideoRequest {
109
+ readonly wireModel: string;
110
+ readonly family: MediaFamily;
111
+ readonly pathSuffix: string;
112
+ readonly contentType: string;
113
+ readonly body: Record<string, unknown>;
114
+ readonly hasReference: boolean;
115
+ }
116
+ /** Best-effort normalized shape of an async-submit / poll response across vendor families. */
117
+ export interface NormalizedVideoResponse {
118
+ readonly id?: string;
119
+ readonly status?: string;
120
+ readonly url?: string;
121
+ readonly error?: string;
122
+ }
123
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/media-providers/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `@jini-ai/integrations/media-providers` core type system — the provider/model catalogue shape and the
3
+ * pure, transport-free request-building types layered on top of it.
4
+ *
5
+ * Ported from OD's `apps/daemon/src/media/models.ts` (catalogue
6
+ * shape) and `apps/daemon/src/media-adapters/types.ts` (capability +
7
+ * request-builder shape) — see `source-map.md` for the full provenance.
8
+ * Neither origin file carries any OD domain noun; this is a product-neutral
9
+ * multi-vendor media-generation type system, not an OD concept.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/media-providers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Video request builder — pure, transport-free. Ported verbatim from Open
3
+ * Design's `apps/daemon/src/media-adapters/video.ts` (layer ②: family
4
+ * branching on top of the `CapabilityRegistry`'s `ModelCapability` data).
5
+ * No fetch, no auth, no OD nouns — the caller resolves any reference image
6
+ * to a data URL beforehand and attaches auth + base URL afterward; this
7
+ * module only shapes the request body per vendor wire family:
8
+ *
9
+ * • `seedance` (ByteDance Ark) — multimodal `content[]` array (text +
10
+ * image_url{url,role:first_frame}); duration/ratio/resolution fields.
11
+ * • `wan` (Alibaba DashScope/wanx-backed) —
12
+ * `{ input:{ prompt, media[] }, parameters:{ resolution, duration, ... } }`.
13
+ * • `veo` (Google Veo via a Gemini predictLongRunning shim) — flat JSON;
14
+ * `seconds` MUST be a number and the only size hint is `size`.
15
+ * • `generic` (Sora and similar) — flat JSON with `seconds` as a string.
16
+ *
17
+ * See `source-map.md` for the vendor-verification notes each snapping
18
+ * function was ported with — they encode real, tested API quirks, not
19
+ * arbitrary defaults.
20
+ */
21
+ import type { BuiltVideoRequest, MediaFamily, ModelCapability, NormalizedVideoResponse, VideoBuildInput } from './types.js';
22
+ /** Resolves the upstream model name: the i2v variant when a reference image is present. */
23
+ export declare function resolveWireModel(cap: ModelCapability, hasReference: boolean): string;
24
+ /** Derives the request family from the resolved upstream model name (or an explicit `cap.family` override). */
25
+ export declare function deriveVideoFamily(wireModel: string, cap?: ModelCapability): MediaFamily;
26
+ /**
27
+ * Snaps a requested duration to the model's allowed set (e.g. Veo 4/6/8, wan
28
+ * 5/10). Falls back to a 3-12 clamp when the model declares no constraint.
29
+ * Ties prefer the shorter value (array order wins on an exact tie distance).
30
+ */
31
+ export declare function snapDuration(cap: ModelCapability, requested: number | undefined): number;
32
+ /**
33
+ * Seedance and wan accept resolution only as a quality token
34
+ * (`480p`/`720p`/`1080p`), never a `WxH` pixel string. Normalizes whichever
35
+ * the caller supplied to the nearest lowercase token by short side
36
+ * (720→720p, 1080→1080p, ...); defaults to `720p` when nothing usable is
37
+ * supplied. (The `wan` family upper-cases the result itself.)
38
+ */
39
+ export declare function snapResolutionToken(resolution: string | undefined, size: string | undefined): string;
40
+ /**
41
+ * Veo (via the verified gateway's Gemini predictLongRunning shim) only
42
+ * accepts a handful of `size` values — anything mapping outside 720p/1080p
43
+ * (e.g. a 1:1 `1024x1024`) 400s. Snaps to the nearest valid Veo size by
44
+ * orientation; defaults to landscape 720p.
45
+ */
46
+ export declare function snapVeoSize(size: string | undefined): string;
47
+ /**
48
+ * Snaps a requested `size` to the model's declared `supportedSizes` by
49
+ * orientation (portrait matches portrait, else landscape). Returns the size
50
+ * unchanged when the model declares no constraint; falls back to the first
51
+ * supported size when the input is missing/unparseable.
52
+ */
53
+ export declare function snapSizeToSupported(size: string | undefined, supported: readonly string[] | undefined): string | undefined;
54
+ /**
55
+ * Builds the upstream video request body for a model. Pure: no fetch, no
56
+ * auth. Caller: `POST \`${baseUrl}${pathSuffix}\`` with auth headers +
57
+ * `JSON.stringify(body)`.
58
+ */
59
+ export declare function buildVideoRequest(cap: ModelCapability, input: VideoBuildInput): BuiltVideoRequest;
60
+ /** Best-effort normalization of an async-submit / poll response across vendor families. */
61
+ export declare function normalizeVideoResponse(raw: unknown): NormalizedVideoResponse;
62
+ //# sourceMappingURL=video-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-request.d.ts","sourceRoot":"","sources":["../../src/media-providers/video-request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE5H,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAEpF;AAED,+GAA+G;AAC/G,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,WAAW,CAOvF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOxF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAWpG;AAID;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM5D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAa1H;AA6BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,iBAAiB,CA0DjG;AAED,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,uBAAuB,CAuB5E"}
@@ -0,0 +1,219 @@
1
+ /** Resolves the upstream model name: the i2v variant when a reference image is present. */
2
+ export function resolveWireModel(cap, hasReference) {
3
+ return hasReference && cap.apiModelI2V ? cap.apiModelI2V : cap.apiModel;
4
+ }
5
+ /** Derives the request family from the resolved upstream model name (or an explicit `cap.family` override). */
6
+ export function deriveVideoFamily(wireModel, cap) {
7
+ if (cap?.family)
8
+ return cap.family;
9
+ const m = wireModel.toLowerCase();
10
+ if (m.startsWith('doubao-seedance-'))
11
+ return 'seedance';
12
+ if (m.startsWith('wan') || m.startsWith('happyhorse'))
13
+ return 'wan';
14
+ if (m.startsWith('veo'))
15
+ return 'veo';
16
+ return 'generic';
17
+ }
18
+ /**
19
+ * Snaps a requested duration to the model's allowed set (e.g. Veo 4/6/8, wan
20
+ * 5/10). Falls back to a 3-12 clamp when the model declares no constraint.
21
+ * Ties prefer the shorter value (array order wins on an exact tie distance).
22
+ */
23
+ export function snapDuration(cap, requested) {
24
+ const req = Number.isFinite(requested) ? requested : 5;
25
+ const allowed = cap.supportedDurations;
26
+ if (!allowed || allowed.length === 0) {
27
+ return Math.min(12, Math.max(3, Math.round(req)));
28
+ }
29
+ return allowed.reduce((best, v) => (Math.abs(v - req) < Math.abs(best - req) ? v : best), allowed[0]);
30
+ }
31
+ /**
32
+ * Seedance and wan accept resolution only as a quality token
33
+ * (`480p`/`720p`/`1080p`), never a `WxH` pixel string. Normalizes whichever
34
+ * the caller supplied to the nearest lowercase token by short side
35
+ * (720→720p, 1080→1080p, ...); defaults to `720p` when nothing usable is
36
+ * supplied. (The `wan` family upper-cases the result itself.)
37
+ */
38
+ export function snapResolutionToken(resolution, size) {
39
+ const token = (resolution || '').trim().toLowerCase();
40
+ if (/^(480|720|1080)p$/.test(token))
41
+ return token;
42
+ const m = /^(\d+)\s*[x×]\s*(\d+)$/i.exec((size || resolution || '').trim());
43
+ if (m) {
44
+ const shortSide = Math.min(parseInt(m[1], 10), parseInt(m[2], 10));
45
+ if (shortSide <= 480)
46
+ return '480p';
47
+ if (shortSide <= 720)
48
+ return '720p';
49
+ return '1080p';
50
+ }
51
+ return '720p';
52
+ }
53
+ const VEO_VALID_SIZES = new Set(['1280x720', '720x1280', '1920x1080', '1080x1920']);
54
+ /**
55
+ * Veo (via the verified gateway's Gemini predictLongRunning shim) only
56
+ * accepts a handful of `size` values — anything mapping outside 720p/1080p
57
+ * (e.g. a 1:1 `1024x1024`) 400s. Snaps to the nearest valid Veo size by
58
+ * orientation; defaults to landscape 720p.
59
+ */
60
+ export function snapVeoSize(size) {
61
+ const s = (size || '').trim().toLowerCase().replace('×', 'x');
62
+ if (VEO_VALID_SIZES.has(s))
63
+ return s;
64
+ const m = /^(\d+)\s*x\s*(\d+)$/.exec(s);
65
+ if (m)
66
+ return parseInt(m[2], 10) > parseInt(m[1], 10) ? '720x1280' : '1280x720';
67
+ return '1280x720';
68
+ }
69
+ /**
70
+ * Snaps a requested `size` to the model's declared `supportedSizes` by
71
+ * orientation (portrait matches portrait, else landscape). Returns the size
72
+ * unchanged when the model declares no constraint; falls back to the first
73
+ * supported size when the input is missing/unparseable.
74
+ */
75
+ export function snapSizeToSupported(size, supported) {
76
+ if (!supported || supported.length === 0)
77
+ return size;
78
+ const norm = (v) => v.trim().toLowerCase().replace('×', 'x');
79
+ const s = norm(size || '');
80
+ const exact = supported.find((v) => norm(v) === s);
81
+ if (exact)
82
+ return exact;
83
+ const dims = /^(\d+)\s*x\s*(\d+)$/.exec(s);
84
+ const portrait = dims ? parseInt(dims[2], 10) > parseInt(dims[1], 10) : false;
85
+ const match = supported.find((v) => {
86
+ const vm = /^(\d+)\s*x\s*(\d+)$/.exec(norm(v));
87
+ return vm ? parseInt(vm[2], 10) > parseInt(vm[1], 10) === portrait : false;
88
+ });
89
+ return match || supported[0];
90
+ }
91
+ /** Applies `extraBodyDefaults`, then overlays caller passthrough filtered by `allowedPassthroughParameters`. */
92
+ function mergeExtraBody(body, cap, passthrough) {
93
+ for (const def of cap.extraBodyDefaults ?? []) {
94
+ if (def.default !== undefined)
95
+ body[def.name] = def.default;
96
+ }
97
+ if (passthrough && cap.allowedPassthroughParameters?.length) {
98
+ const allow = new Set(cap.allowedPassthroughParameters);
99
+ for (const [k, v] of Object.entries(passthrough)) {
100
+ if (allow.has(k) && v !== undefined)
101
+ body[k] = v;
102
+ }
103
+ }
104
+ }
105
+ /** Builds the seedance multimodal content array (text + reference images). */
106
+ function buildSeedanceContent(input) {
107
+ const content = [{ type: 'text', text: input.prompt }];
108
+ if (input.imageRef?.dataUrl) {
109
+ content.push({ type: 'image_url', image_url: { url: input.imageRef.dataUrl }, role: 'first_frame' });
110
+ }
111
+ for (const ref of input.extraImageRefs ?? []) {
112
+ if (ref?.dataUrl) {
113
+ content.push({ type: 'image_url', image_url: { url: ref.dataUrl }, role: 'reference_image' });
114
+ }
115
+ }
116
+ return content;
117
+ }
118
+ /**
119
+ * Builds the upstream video request body for a model. Pure: no fetch, no
120
+ * auth. Caller: `POST \`${baseUrl}${pathSuffix}\`` with auth headers +
121
+ * `JSON.stringify(body)`.
122
+ */
123
+ export function buildVideoRequest(cap, input) {
124
+ const hasReference = Boolean(input.imageRef?.dataUrl);
125
+ const wireModel = resolveWireModel(cap, hasReference);
126
+ const family = deriveVideoFamily(wireModel, cap);
127
+ const seconds = snapDuration(cap, input.durationSeconds);
128
+ let body;
129
+ if (family === 'seedance') {
130
+ body = {
131
+ model: wireModel,
132
+ prompt: input.prompt,
133
+ duration: seconds,
134
+ content: buildSeedanceContent(input),
135
+ resolution: snapResolutionToken(input.resolution, input.size),
136
+ };
137
+ if (input.aspectRatio)
138
+ body.ratio = input.aspectRatio;
139
+ if (typeof input.generateAudio === 'boolean')
140
+ body.generate_audio = input.generateAudio;
141
+ if (typeof input.seed === 'number')
142
+ body.seed = input.seed;
143
+ }
144
+ else if (family === 'wan') {
145
+ const wanInput = { prompt: input.prompt };
146
+ if (hasReference) {
147
+ wanInput.media = [{ type: 'first_frame', url: input.imageRef.dataUrl }];
148
+ }
149
+ const parameters = {
150
+ resolution: snapResolutionToken(input.resolution, input.size).toUpperCase(),
151
+ duration: seconds,
152
+ prompt_extend: true,
153
+ watermark: false,
154
+ };
155
+ if (input.aspectRatio)
156
+ parameters.aspect_ratio = input.aspectRatio;
157
+ if (typeof input.seed === 'number')
158
+ parameters.seed = input.seed;
159
+ body = { model: wireModel, input: wanInput, parameters };
160
+ }
161
+ else if (family === 'veo') {
162
+ body = {
163
+ model: wireModel,
164
+ prompt: input.prompt,
165
+ seconds,
166
+ size: snapVeoSize(input.size),
167
+ };
168
+ if (typeof input.generateAudio === 'boolean')
169
+ body.generate_audio = input.generateAudio;
170
+ if (typeof input.seed === 'number')
171
+ body.seed = input.seed;
172
+ }
173
+ else {
174
+ body = {
175
+ model: wireModel,
176
+ prompt: input.prompt,
177
+ seconds: String(seconds),
178
+ };
179
+ const genericSize = snapSizeToSupported(input.size, cap.supportedSizes);
180
+ if (genericSize)
181
+ body.size = genericSize;
182
+ if (input.resolution)
183
+ body.resolution = input.resolution;
184
+ if (hasReference)
185
+ body.input_reference = input.imageRef.dataUrl;
186
+ if (typeof input.generateAudio === 'boolean')
187
+ body.generate_audio = input.generateAudio;
188
+ if (typeof input.seed === 'number')
189
+ body.seed = input.seed;
190
+ }
191
+ mergeExtraBody(body, cap, input.passthrough);
192
+ return { wireModel, family, pathSuffix: '/videos', contentType: 'application/json', body, hasReference };
193
+ }
194
+ /** Best-effort normalization of an async-submit / poll response across vendor families. */
195
+ export function normalizeVideoResponse(raw) {
196
+ const d = (raw ?? {});
197
+ const data = d.data;
198
+ const dataArray = Array.isArray(d.data) ? d.data : undefined;
199
+ const unsignedUrls = Array.isArray(d.unsigned_urls) ? d.unsigned_urls : undefined;
200
+ const id = d.id ?? d.task_id ?? data?.id ?? data?.task_id;
201
+ const status = d.status ?? data?.status;
202
+ const url = d.video_url ?? d.url ?? d.output_url ?? data?.video_url ?? data?.url ?? dataArray?.[0]?.url ?? unsignedUrls?.[0];
203
+ const errorObj = d.error;
204
+ const error = (typeof errorObj === 'object' && errorObj ? errorObj.message : undefined) ??
205
+ (typeof errorObj === 'string' ? errorObj : undefined) ??
206
+ d.failure_reason ??
207
+ d.message;
208
+ const result = {};
209
+ if (id !== undefined && id !== null)
210
+ result.id = String(id);
211
+ if (status !== undefined && status !== null)
212
+ result.status = String(status);
213
+ if (url !== undefined && url !== null)
214
+ result.url = String(url);
215
+ if (error !== undefined && error !== null)
216
+ result.error = String(error);
217
+ return result;
218
+ }
219
+ //# sourceMappingURL=video-request.js.map