vidspotai-shared 1.0.84 → 1.0.86

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 (54) hide show
  1. package/lib/globals/aiModels/providers/runway.d.ts.map +1 -1
  2. package/lib/globals/aiModels/providers/runway.js +12 -7
  3. package/lib/globals/types.d.ts +10 -0
  4. package/lib/globals/types.d.ts.map +1 -1
  5. package/lib/globals/types.js +11 -0
  6. package/lib/models/agent.model.d.ts +129 -1
  7. package/lib/models/agent.model.d.ts.map +1 -1
  8. package/lib/schemas/agentRunJob.schema.d.ts +21 -0
  9. package/lib/schemas/agentRunJob.schema.d.ts.map +1 -1
  10. package/lib/schemas/agentRunJob.schema.js +35 -3
  11. package/lib/services/agent/executor/core.d.ts.map +1 -1
  12. package/lib/services/agent/executor/core.js +21 -1
  13. package/lib/services/agent/executor/types.d.ts +10 -0
  14. package/lib/services/agent/executor/types.d.ts.map +1 -1
  15. package/lib/services/agent/index.d.ts +3 -0
  16. package/lib/services/agent/index.d.ts.map +1 -1
  17. package/lib/services/agent/index.js +3 -0
  18. package/lib/services/agent/providerFallback/chains.d.ts +2 -0
  19. package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
  20. package/lib/services/agent/providerFallback/chains.js +1 -0
  21. package/lib/services/agent/recovery/degradeLadder.d.ts +74 -0
  22. package/lib/services/agent/recovery/degradeLadder.d.ts.map +1 -0
  23. package/lib/services/agent/recovery/degradeLadder.js +133 -0
  24. package/lib/services/agent/repair/engine.d.ts +38 -0
  25. package/lib/services/agent/repair/engine.d.ts.map +1 -0
  26. package/lib/services/agent/repair/engine.js +175 -0
  27. package/lib/services/agent/repair/index.d.ts +20 -0
  28. package/lib/services/agent/repair/index.d.ts.map +1 -0
  29. package/lib/services/agent/repair/index.js +49 -0
  30. package/lib/services/agent/repair/strategies/llmRepair.strategy.d.ts +6 -0
  31. package/lib/services/agent/repair/strategies/llmRepair.strategy.d.ts.map +1 -0
  32. package/lib/services/agent/repair/strategies/llmRepair.strategy.js +210 -0
  33. package/lib/services/agent/repair/strategies/paramRepair.strategy.d.ts +3 -0
  34. package/lib/services/agent/repair/strategies/paramRepair.strategy.d.ts.map +1 -0
  35. package/lib/services/agent/repair/strategies/paramRepair.strategy.js +151 -0
  36. package/lib/services/agent/repair/types.d.ts +92 -0
  37. package/lib/services/agent/repair/types.d.ts.map +1 -0
  38. package/lib/services/agent/repair/types.js +2 -0
  39. package/lib/services/agent/runPlanning.d.ts +96 -0
  40. package/lib/services/agent/runPlanning.d.ts.map +1 -0
  41. package/lib/services/agent/runPlanning.js +233 -0
  42. package/lib/services/aiGen/providers/runway/types.d.ts +14 -0
  43. package/lib/services/aiGen/providers/runway/types.d.ts.map +1 -1
  44. package/lib/services/aiGen/providers/runway/types.js +22 -1
  45. package/lib/services/firestore.service.d.ts +7 -1
  46. package/lib/services/firestore.service.d.ts.map +1 -1
  47. package/lib/services/firestore.service.js +8 -0
  48. package/package.json +1 -1
  49. package/lib/services/agent/executor.d.ts +0 -141
  50. package/lib/services/agent/executor.d.ts.map +0 -1
  51. package/lib/services/agent/executor.js +0 -561
  52. package/lib/services/agent/llmCallerGateway.d.ts +0 -61
  53. package/lib/services/agent/llmCallerGateway.d.ts.map +0 -1
  54. package/lib/services/agent/llmCallerGateway.js +0 -368
@@ -1,368 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GatewayLlmCaller = void 0;
4
- const zod_1 = require("zod");
5
- /**
6
- * Marks a transient error that should trigger HTTP retry (and, when exhausted,
7
- * model fallback). Non-transient errors (4xx other than 408/429, schema
8
- * validation, malformed JSON) are NOT wrapped and propagate immediately.
9
- */
10
- class TransientLlmError extends Error {
11
- constructor(message, cause) {
12
- super(message);
13
- this.cause = cause;
14
- this.name = "TransientLlmError";
15
- }
16
- }
17
- const TRANSIENT_HTTP_STATUSES = new Set([408, 425, 429, 500, 502, 503, 504]);
18
- function isTransientNetworkError(err) {
19
- if (!err || typeof err !== "object")
20
- return false;
21
- const e = err;
22
- const code = e.code ?? e.cause?.code;
23
- if (code && /^(ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|EPIPE|UND_ERR_.*)$/.test(code)) {
24
- return true;
25
- }
26
- // Our own per-request timeout (ctrl.abort() in postOnce / structuredStream)
27
- // surfaces as AbortError "This operation was aborted". Treat as transient so
28
- // the retry loop (and then the fallback model) gets a chance — otherwise a
29
- // single slow Gemini Flash vision call sinks the entire critic stage with
30
- // no recovery.
31
- if (e.name === "AbortError")
32
- return true;
33
- const msg = String(e.message ?? "");
34
- return /fetch failed|socket hang up|other side closed|network|timeout|operation was aborted/i.test(msg);
35
- }
36
- class GatewayLlmCaller {
37
- constructor(cfg) {
38
- this.cfg = cfg;
39
- this.fetchImpl = cfg.fetchImpl ?? fetch;
40
- this.timeoutMs = cfg.timeoutMs ?? 60000;
41
- this.maxRetries = cfg.maxRetries ?? 3;
42
- this.retryBaseMs = cfg.retryBaseMs ?? 250;
43
- }
44
- async chat(req) {
45
- const attempted = [];
46
- const run = async (model) => {
47
- attempted.push(model);
48
- const messages = await Promise.all(req.messages.map((m) => this.encodeMessage(m)));
49
- const raw = await this.postWithRetry({
50
- model: this.modelId(model),
51
- messages,
52
- temperature: req.temperature,
53
- max_tokens: req.maxTokens,
54
- stop: req.stop,
55
- });
56
- const text = raw.choices?.[0]?.message?.content ?? "";
57
- return {
58
- text: typeof text === "string" ? text : JSON.stringify(text),
59
- usage: this.usage(raw),
60
- requestId: raw.id,
61
- };
62
- };
63
- try {
64
- const out = await run(req.model);
65
- return { ...out, attemptedModels: attempted, usedFallback: false };
66
- }
67
- catch (err) {
68
- if (req.fallbackModel && err instanceof TransientLlmError) {
69
- const out = await run(req.fallbackModel);
70
- return { ...out, attemptedModels: attempted, usedFallback: true };
71
- }
72
- throw err;
73
- }
74
- }
75
- async structured(req) {
76
- const attempted = [];
77
- const jsonSchema = zod_1.z.toJSONSchema(req.schema, { target: "draft-7" });
78
- const run = async (model) => {
79
- attempted.push(model);
80
- const messages = await Promise.all(req.messages.map((m) => this.encodeMessage(m)));
81
- const raw = await this.postWithRetry({
82
- model: this.modelId(model),
83
- messages,
84
- temperature: req.temperature,
85
- max_tokens: req.maxTokens,
86
- response_format: {
87
- type: "json_schema",
88
- json_schema: {
89
- name: req.schemaName,
90
- schema: jsonSchema,
91
- strict: true,
92
- },
93
- },
94
- });
95
- const txt = raw.choices?.[0]?.message?.content ?? "";
96
- if (!txt || typeof txt !== "string") {
97
- // Empty body from the model is not retryable across providers —
98
- // surface immediately; planner-level retry can re-prompt.
99
- throw new Error(`GatewayLlmCaller.structured: empty response for schema ${req.schemaName}`);
100
- }
101
- let parsed;
102
- try {
103
- parsed = JSON.parse(txt);
104
- }
105
- catch {
106
- throw new Error(`GatewayLlmCaller.structured: model returned non-JSON for schema ${req.schemaName}: ${txt.slice(0, 200)}`);
107
- }
108
- const result = req.schema.safeParse(parsed);
109
- if (!result.success) {
110
- throw new Error(`GatewayLlmCaller.structured: schema validation failed for ${req.schemaName}: ${result.error.message}`);
111
- }
112
- return {
113
- data: result.data,
114
- usage: this.usage(raw),
115
- requestId: raw.id,
116
- };
117
- };
118
- try {
119
- const out = await run(req.model);
120
- return { ...out, attemptedModels: attempted, usedFallback: false };
121
- }
122
- catch (err) {
123
- if (req.fallbackModel && err instanceof TransientLlmError) {
124
- const out = await run(req.fallbackModel);
125
- return { ...out, attemptedModels: attempted, usedFallback: true };
126
- }
127
- throw err;
128
- }
129
- }
130
- structuredStream(req) {
131
- // Streaming: fall back is NOT applied mid-stream (would confuse UI
132
- // chunks). Transport retry IS applied on the initial connect; once
133
- // bytes start flowing, a mid-stream drop propagates as an error and
134
- // the caller (planner) handles it via its own retry loop.
135
- let resolveResult;
136
- let rejectResult;
137
- const result = new Promise((resolve, reject) => {
138
- resolveResult = resolve;
139
- rejectResult = reject;
140
- });
141
- const self = this;
142
- const tokens = {
143
- [Symbol.asyncIterator]() {
144
- return self.createStreamingIterator(req, resolveResult, rejectResult);
145
- },
146
- };
147
- return { tokens, result };
148
- }
149
- async *createStreamingIterator(req, resolveResult, rejectResult) {
150
- const jsonSchema = zod_1.z.toJSONSchema(req.schema, { target: "draft-7" });
151
- const messages = await Promise.all(req.messages.map((m) => this.encodeMessage(m)));
152
- const ctrl = new AbortController();
153
- const t = setTimeout(() => ctrl.abort(), this.timeoutMs);
154
- let accumulated = "";
155
- let requestId;
156
- let usage;
157
- try {
158
- // Connect attempt with retry on transient connect failures (pre-stream).
159
- const res = await this.withRetry(() => this.fetchImpl(`${this.cfg.baseUrl.replace(/\/$/, "")}/chat/completions`, {
160
- method: "POST",
161
- headers: {
162
- "content-type": "application/json",
163
- authorization: `Bearer ${this.cfg.apiKey}`,
164
- },
165
- body: JSON.stringify({
166
- model: this.modelId(req.model),
167
- messages,
168
- temperature: req.temperature,
169
- max_tokens: req.maxTokens,
170
- stream: true,
171
- response_format: {
172
- type: "json_schema",
173
- json_schema: {
174
- name: req.schemaName,
175
- schema: jsonSchema,
176
- strict: true,
177
- },
178
- },
179
- }),
180
- signal: ctrl.signal,
181
- }).then((r) => {
182
- if (!r.ok && TRANSIENT_HTTP_STATUSES.has(r.status)) {
183
- throw new TransientLlmError(`GatewayLlmCaller.structuredStream: ${r.status} ${r.statusText}`);
184
- }
185
- return r;
186
- }));
187
- if (!res.ok || !res.body) {
188
- const text = await res.text().catch(() => "");
189
- const err = new Error(`GatewayLlmCaller.structuredStream: ${res.status} ${res.statusText} — ${text.slice(0, 500)}`);
190
- rejectResult(err);
191
- throw err;
192
- }
193
- const reader = res.body.getReader();
194
- const decoder = new TextDecoder();
195
- let buf = "";
196
- while (true) {
197
- const { value, done } = await reader.read();
198
- if (done)
199
- break;
200
- buf += decoder.decode(value, { stream: true });
201
- let nl;
202
- while ((nl = buf.indexOf("\n")) !== -1) {
203
- const line = buf.slice(0, nl).trim();
204
- buf = buf.slice(nl + 1);
205
- if (!line || !line.startsWith("data:"))
206
- continue;
207
- const payload = line.slice(5).trim();
208
- if (payload === "[DONE]")
209
- break;
210
- try {
211
- const obj = JSON.parse(payload);
212
- if (obj.id)
213
- requestId = obj.id;
214
- if (obj.usage) {
215
- usage = {
216
- promptTokens: obj.usage.prompt_tokens,
217
- completionTokens: obj.usage.completion_tokens,
218
- };
219
- }
220
- const delta = obj.choices?.[0]?.delta?.content ?? "";
221
- if (delta) {
222
- accumulated += delta;
223
- yield delta;
224
- }
225
- }
226
- catch {
227
- // skip malformed line
228
- }
229
- }
230
- }
231
- // Post-stream failures (bad JSON / schema mismatch) reject the RESULT
232
- // promise but must NOT throw out of this generator. The tokens already
233
- // streamed fine; throwing here would propagate into the caller's
234
- // `for await (...stream.tokens)` loop and abort it before the caller can
235
- // reach `await stream.result` — which is exactly where the planner's
236
- // non-streaming retry fallback lives (Planner.planStream). Returning
237
- // cleanly lets the token loop complete, then the rejected result drives
238
- // the retry. See plan.controller.ts:planProjectStream.
239
- let parsed;
240
- try {
241
- parsed = JSON.parse(accumulated);
242
- }
243
- catch {
244
- const err = new Error(`GatewayLlmCaller.structuredStream: model returned non-JSON for ${req.schemaName}: ${accumulated.slice(0, 200)}`);
245
- rejectResult(err);
246
- return;
247
- }
248
- const validated = req.schema.safeParse(parsed);
249
- if (!validated.success) {
250
- const err = new Error(`GatewayLlmCaller.structuredStream: schema validation failed for ${req.schemaName}: ${validated.error.message}`);
251
- rejectResult(err);
252
- return;
253
- }
254
- resolveResult({
255
- data: validated.data,
256
- usage,
257
- requestId,
258
- attemptedModels: [req.model],
259
- usedFallback: false,
260
- });
261
- }
262
- catch (e) {
263
- rejectResult(e);
264
- throw e;
265
- }
266
- finally {
267
- clearTimeout(t);
268
- }
269
- }
270
- modelId(m) {
271
- return `${m.provider}/${m.modelId}`;
272
- }
273
- async encodeMessage(m) {
274
- if (!m.imageUrls?.length) {
275
- return { role: m.role, content: m.content };
276
- }
277
- // Fetch + base64-encode each URL into a data URI. The gateway's Anthropic
278
- // translator rejects raw https URLs ("URL sources are not supported"); data
279
- // URIs round-trip through every provider's OpenAI-compat shim correctly.
280
- const dataUris = await Promise.all(m.imageUrls.map((u) => this.toDataUri(u)));
281
- return {
282
- role: m.role,
283
- content: [
284
- { type: "text", text: m.content },
285
- ...dataUris.map((url) => ({ type: "image_url", image_url: { url } })),
286
- ],
287
- };
288
- }
289
- async toDataUri(url) {
290
- if (url.startsWith("data:"))
291
- return url;
292
- const res = await this.fetchImpl(url);
293
- if (!res.ok) {
294
- throw new Error(`GatewayLlmCaller.toDataUri: ${res.status} ${res.statusText} fetching ${url}`);
295
- }
296
- const contentType = res.headers.get("content-type")?.split(";")[0]?.trim() || "image/jpeg";
297
- const buf = Buffer.from(await res.arrayBuffer());
298
- return `data:${contentType};base64,${buf.toString("base64")}`;
299
- }
300
- usage(raw) {
301
- if (!raw.usage)
302
- return undefined;
303
- return {
304
- promptTokens: raw.usage.prompt_tokens,
305
- completionTokens: raw.usage.completion_tokens,
306
- };
307
- }
308
- /**
309
- * POST /chat/completions with transient-error retry (F1).
310
- * Throws TransientLlmError after exhausting retries on transient failures —
311
- * caller catches it to trigger model fallback (F2). Non-transient errors
312
- * (4xx other than 408/425/429, malformed responses) propagate as plain Error.
313
- */
314
- async postWithRetry(body) {
315
- return this.withRetry(() => this.postOnce(body));
316
- }
317
- async withRetry(fn) {
318
- let lastErr;
319
- for (let attempt = 0; attempt < this.maxRetries; attempt++) {
320
- try {
321
- return await fn();
322
- }
323
- catch (err) {
324
- lastErr = err;
325
- const transient = err instanceof TransientLlmError || isTransientNetworkError(err);
326
- if (!transient || attempt === this.maxRetries - 1) {
327
- if (transient) {
328
- // Wrap so the fallback-model path can catch it explicitly.
329
- throw err instanceof TransientLlmError
330
- ? err
331
- : new TransientLlmError(`transient LLM error after ${attempt + 1} attempts: ${String(err?.message ?? err)}`, err);
332
- }
333
- throw err;
334
- }
335
- await new Promise((r) => setTimeout(r, this.retryBaseMs * Math.pow(4, attempt)));
336
- }
337
- }
338
- throw lastErr;
339
- }
340
- async postOnce(body) {
341
- const ctrl = new AbortController();
342
- const t = setTimeout(() => ctrl.abort(), this.timeoutMs);
343
- try {
344
- const res = await this.fetchImpl(`${this.cfg.baseUrl.replace(/\/$/, "")}/chat/completions`, {
345
- method: "POST",
346
- headers: {
347
- "content-type": "application/json",
348
- authorization: `Bearer ${this.cfg.apiKey}`,
349
- },
350
- body: JSON.stringify(body),
351
- signal: ctrl.signal,
352
- });
353
- if (!res.ok) {
354
- const text = await res.text().catch(() => "");
355
- const msg = `GatewayLlmCaller: ${res.status} ${res.statusText} — ${text.slice(0, 500)}`;
356
- if (TRANSIENT_HTTP_STATUSES.has(res.status)) {
357
- throw new TransientLlmError(msg);
358
- }
359
- throw new Error(msg);
360
- }
361
- return (await res.json());
362
- }
363
- finally {
364
- clearTimeout(t);
365
- }
366
- }
367
- }
368
- exports.GatewayLlmCaller = GatewayLlmCaller;