@dereekb/openrouter 13.37.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/firebase/index.cjs.default.js +1 -0
  4. package/firebase/index.cjs.js +666 -0
  5. package/firebase/index.cjs.mjs +2 -0
  6. package/firebase/index.d.ts +1 -0
  7. package/firebase/index.esm.js +626 -0
  8. package/firebase/package.json +25 -0
  9. package/firebase/src/index.d.ts +1 -0
  10. package/firebase/src/lib/index.d.ts +4 -0
  11. package/firebase/src/lib/openrouter.api.d.ts +226 -0
  12. package/firebase/src/lib/openrouter.id.d.ts +56 -0
  13. package/firebase/src/lib/openrouter.model.d.ts +609 -0
  14. package/firebase/src/lib/openrouter.query.d.ts +121 -0
  15. package/firebase-server/index.cjs.default.js +1 -0
  16. package/firebase-server/index.cjs.js +4520 -0
  17. package/firebase-server/index.cjs.mjs +2 -0
  18. package/firebase-server/index.d.ts +1 -0
  19. package/firebase-server/index.esm.js +4466 -0
  20. package/firebase-server/package.json +38 -0
  21. package/firebase-server/src/index.d.ts +1 -0
  22. package/firebase-server/src/lib/index.d.ts +10 -0
  23. package/firebase-server/src/lib/openrouter.action.server.d.ts +196 -0
  24. package/firebase-server/src/lib/openrouter.broadcast.d.ts +93 -0
  25. package/firebase-server/src/lib/openrouter.call.inline.d.ts +57 -0
  26. package/firebase-server/src/lib/openrouter.file.attachment.d.ts +97 -0
  27. package/firebase-server/src/lib/openrouter.module.d.ts +65 -0
  28. package/firebase-server/src/lib/openrouter.prompt.service.d.ts +109 -0
  29. package/firebase-server/src/lib/openrouter.runtask.handle.d.ts +56 -0
  30. package/firebase-server/src/lib/openrouter.runtask.service.d.ts +380 -0
  31. package/firebase-server/src/lib/openrouter.runtask.sweep.d.ts +170 -0
  32. package/firebase-server/src/lib/openrouter.state.accessor.d.ts +106 -0
  33. package/firebase-server/src/test/openrouter.fake.d.ts +134 -0
  34. package/index.cjs.default.js +1 -0
  35. package/index.cjs.js +1867 -0
  36. package/index.cjs.mjs +2 -0
  37. package/index.d.ts +1 -0
  38. package/index.esm.js +1771 -0
  39. package/package.json +32 -0
  40. package/src/index.d.ts +1 -0
  41. package/src/lib/index.d.ts +10 -0
  42. package/src/lib/openrouter.call.d.ts +268 -0
  43. package/src/lib/openrouter.config.d.ts +314 -0
  44. package/src/lib/openrouter.embedding.d.ts +87 -0
  45. package/src/lib/openrouter.generation.d.ts +46 -0
  46. package/src/lib/openrouter.input.d.ts +238 -0
  47. package/src/lib/openrouter.prompt.d.ts +79 -0
  48. package/src/lib/openrouter.request.d.ts +91 -0
  49. package/src/lib/openrouter.sdk.d.ts +37 -0
  50. package/src/lib/openrouter.tool.d.ts +99 -0
  51. package/src/lib/openrouter.type.d.ts +125 -0
@@ -0,0 +1,4466 @@
1
+ import { firestoreModelId, firestoreModelKeyParentKey, getDocumentSnapshotDataTuples } from '@dereekb/firebase';
2
+ import { runAsyncTasksForValues, mergeObjects, KeyValueTypleValueFilter, concatArraysUnique, MS_IN_MINUTE, arrayToMap, expiringCachedGetter, filterMaybeArrayValues, filterUniqueValues, mergeArrays, addMilliseconds, filterUndefinedValues, randomNumberFactory, performTasksInParallel } from '@dereekb/util';
3
+ import { validateOpenRouterModelConfig, openRouterPromptRequest, callModelForOpenRouterRequest, openRouterMessagesWithoutFileAttachmentData, openRouterMessagesWithFreshFileAttachments, openRouterInputMessages, openRouterFunctionCallOutputItems } from '@dereekb/openrouter';
4
+ import { updateOpenRouterPromptParamsType, createOpenRouterPromptVersionParamsType, updateOpenRouterPromptVersionParamsType, OpenRouterPromptState, openRouterPromptVersionId, openRouterResolvedPromptForVersion, OpenRouterRunTaskState, openRouterRunTasksRunnableQuery, openRouterRunTasksReclaimableQuery, OPENROUTER_RUN_TASK_MAX_AGE, openRouterRunTasksExpiredQuery, isOpenRouterRunTaskStateTerminal } from '@dereekb/openrouter/firebase';
5
+
6
+ function asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, key, arg) {
7
+ try {
8
+ var info = gen[key](arg);
9
+ var value = info.value;
10
+ } catch (error) {
11
+ reject(error);
12
+ return;
13
+ }
14
+ if (info.done) {
15
+ resolve(value);
16
+ } else {
17
+ Promise.resolve(value).then(_next, _throw);
18
+ }
19
+ }
20
+ function _async_to_generator$8(fn) {
21
+ return function() {
22
+ var self = this, args = arguments;
23
+ return new Promise(function(resolve, reject) {
24
+ var gen = fn.apply(self, args);
25
+ function _next(value) {
26
+ asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, "next", value);
27
+ }
28
+ function _throw(err) {
29
+ asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, "throw", err);
30
+ }
31
+ _next(undefined);
32
+ });
33
+ };
34
+ }
35
+ function _class_call_check$3(instance, Constructor) {
36
+ if (!(instance instanceof Constructor)) {
37
+ throw new TypeError("Cannot call a class as a function");
38
+ }
39
+ }
40
+ function _define_property$3(obj, key, value) {
41
+ if (key in obj) {
42
+ Object.defineProperty(obj, key, {
43
+ value: value,
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true
47
+ });
48
+ } else {
49
+ obj[key] = value;
50
+ }
51
+ return obj;
52
+ }
53
+ function _object_spread$2(target) {
54
+ for(var i = 1; i < arguments.length; i++){
55
+ var source = arguments[i] != null ? arguments[i] : {};
56
+ var ownKeys = Object.keys(source);
57
+ if (typeof Object.getOwnPropertySymbols === "function") {
58
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
59
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
60
+ }));
61
+ }
62
+ ownKeys.forEach(function(key) {
63
+ _define_property$3(target, key, source[key]);
64
+ });
65
+ }
66
+ return target;
67
+ }
68
+ function _ts_generator$8(thisArg, body) {
69
+ var f, y, t, _ = {
70
+ label: 0,
71
+ sent: function() {
72
+ if (t[0] & 1) throw t[1];
73
+ return t[1];
74
+ },
75
+ trys: [],
76
+ ops: []
77
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
78
+ return d(g, "next", {
79
+ value: verb(0)
80
+ }), d(g, "throw", {
81
+ value: verb(1)
82
+ }), d(g, "return", {
83
+ value: verb(2)
84
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
85
+ value: function() {
86
+ return this;
87
+ }
88
+ }), g;
89
+ function verb(n) {
90
+ return function(v) {
91
+ return step([
92
+ n,
93
+ v
94
+ ]);
95
+ };
96
+ }
97
+ function step(op) {
98
+ if (f) throw new TypeError("Generator is already executing.");
99
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
100
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
101
+ if (y = 0, t) op = [
102
+ op[0] & 2,
103
+ t.value
104
+ ];
105
+ switch(op[0]){
106
+ case 0:
107
+ case 1:
108
+ t = op;
109
+ break;
110
+ case 4:
111
+ _.label++;
112
+ return {
113
+ value: op[1],
114
+ done: false
115
+ };
116
+ case 5:
117
+ _.label++;
118
+ y = op[1];
119
+ op = [
120
+ 0
121
+ ];
122
+ continue;
123
+ case 7:
124
+ op = _.ops.pop();
125
+ _.trys.pop();
126
+ continue;
127
+ default:
128
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
129
+ _ = 0;
130
+ continue;
131
+ }
132
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
133
+ _.label = op[1];
134
+ break;
135
+ }
136
+ if (op[0] === 6 && _.label < t[1]) {
137
+ _.label = t[1];
138
+ t = op;
139
+ break;
140
+ }
141
+ if (t && _.label < t[2]) {
142
+ _.label = t[2];
143
+ _.ops.push(op);
144
+ break;
145
+ }
146
+ if (t[2]) _.ops.pop();
147
+ _.trys.pop();
148
+ continue;
149
+ }
150
+ op = body.call(thisArg, _);
151
+ } catch (e) {
152
+ op = [
153
+ 6,
154
+ e
155
+ ];
156
+ y = 0;
157
+ } finally{
158
+ f = t = 0;
159
+ }
160
+ if (op[0] & 5) throw op[1];
161
+ return {
162
+ value: op[0] ? op[1] : void 0,
163
+ done: true
164
+ };
165
+ }
166
+ }
167
+ /**
168
+ * Server actions for managing prompts.
169
+ *
170
+ * The writes exist instead of an Angular UI: they reach the model API, and the existing callModel MCP
171
+ * surface makes them callable without building a screen for it. Reads are absent because the prompt and
172
+ * version model services already make both fetchable by key through model-get, and listing is the
173
+ * model API's standard query operation over {@link openRouterPromptsWithStateQuery}.
174
+ */ var OpenRouterPromptServerActions = function OpenRouterPromptServerActions() {
175
+ _class_call_check$3(this, OpenRouterPromptServerActions);
176
+ };
177
+ /**
178
+ * Creates the {@link OpenRouterPromptServerActions}.
179
+ *
180
+ * @param context - The actions context.
181
+ * @returns The server actions.
182
+ */ function openRouterPromptServerActions(context) {
183
+ return {
184
+ createOpenRouterPrompt: createOpenRouterPromptFactory(context),
185
+ updateOpenRouterPrompt: updateOpenRouterPromptFactory(context),
186
+ createOpenRouterPromptVersion: createOpenRouterPromptVersionFactory(context),
187
+ updateOpenRouterPromptVersion: updateOpenRouterPromptVersionFactory(context),
188
+ seedOpenRouterPrompts: seedOpenRouterPromptsFactory(context)
189
+ };
190
+ }
191
+ /**
192
+ * Creates a new prompt at its caller-supplied key, refusing a key that already exists.
193
+ *
194
+ * Takes its params directly rather than through an arktype-validated action: the only callers are a
195
+ * seed and a test, both of them server-side.
196
+ *
197
+ * @param context - The actions context.
198
+ * @returns The create action.
199
+ */ function createOpenRouterPromptFactory(context) {
200
+ var openRouterPromptCollection = context.openRouterPromptCollection;
201
+ return function(params) {
202
+ return _async_to_generator$8(function() {
203
+ var key, name, description, tags;
204
+ return _ts_generator$8(this, function(_state) {
205
+ key = params.key, name = params.name, description = params.description, tags = params.tags;
206
+ return [
207
+ 2,
208
+ openRouterPromptCollection.firestoreContext.runTransaction(function(transaction) {
209
+ return _async_to_generator$8(function() {
210
+ var document, exists;
211
+ return _ts_generator$8(this, function(_state) {
212
+ switch(_state.label){
213
+ case 0:
214
+ document = openRouterPromptCollection.documentAccessorForTransaction(transaction).loadDocumentForId(key);
215
+ return [
216
+ 4,
217
+ document.accessor.exists()
218
+ ];
219
+ case 1:
220
+ exists = _state.sent();
221
+ if (exists) {
222
+ throw new Error('An OpenRouterPrompt with the key "'.concat(key, '" already exists.'));
223
+ }
224
+ return [
225
+ 4,
226
+ document.accessor.set({
227
+ cat: new Date(),
228
+ n: name,
229
+ d: description,
230
+ s: OpenRouterPromptState.DRAFT,
231
+ lv: 0,
232
+ t: tags
233
+ })
234
+ ];
235
+ case 2:
236
+ _state.sent();
237
+ return [
238
+ 2,
239
+ openRouterPromptCollection.documentAccessor().loadDocumentForId(key)
240
+ ];
241
+ }
242
+ });
243
+ })();
244
+ })
245
+ ];
246
+ });
247
+ })();
248
+ };
249
+ }
250
+ /**
251
+ * Updates a prompt's metadata, lifecycle state, or active version, then drops its cached resolution.
252
+ *
253
+ * @param context - The actions context.
254
+ * @returns The update action.
255
+ */ function updateOpenRouterPromptFactory(context) {
256
+ var firebaseServerActionTransformFunctionFactory = context.firebaseServerActionTransformFunctionFactory, openRouterPromptCollection = context.openRouterPromptCollection, openRouterPromptVersionCollectionFactory = context.openRouterPromptVersionCollectionFactory, openRouterPromptService = context.openRouterPromptService;
257
+ return firebaseServerActionTransformFunctionFactory(updateOpenRouterPromptParamsType, function(params) {
258
+ return _async_to_generator$8(function() {
259
+ var name, description, tags, state, activeVersion;
260
+ return _ts_generator$8(this, function(_state) {
261
+ name = params.name, description = params.description, tags = params.tags, state = params.state, activeVersion = params.activeVersion;
262
+ return [
263
+ 2,
264
+ function(document) {
265
+ return _async_to_generator$8(function() {
266
+ return _ts_generator$8(this, function(_state) {
267
+ switch(_state.label){
268
+ case 0:
269
+ return [
270
+ 4,
271
+ openRouterPromptCollection.firestoreContext.runTransaction(function(transaction) {
272
+ return _async_to_generator$8(function() {
273
+ var inTransaction, prompt, versionDocument, versionExists;
274
+ return _ts_generator$8(this, function(_state) {
275
+ switch(_state.label){
276
+ case 0:
277
+ inTransaction = openRouterPromptCollection.documentAccessorForTransaction(transaction).loadDocument(document.documentRef);
278
+ return [
279
+ 4,
280
+ inTransaction.snapshotData()
281
+ ];
282
+ case 1:
283
+ prompt = _state.sent();
284
+ if (prompt == null) {
285
+ throw new Error('The OpenRouterPrompt "'.concat(document.id, '" does not exist.'));
286
+ }
287
+ if (!(activeVersion != null)) return [
288
+ 3,
289
+ 3
290
+ ];
291
+ // Promoting to a version that was never published would leave every unpinned caller failing to
292
+ // resolve, so the pointer is only allowed to move to a version that exists.
293
+ versionDocument = openRouterPromptVersionCollectionFactory(inTransaction).documentAccessorForTransaction(transaction).loadDocumentForId(openRouterPromptVersionId(activeVersion));
294
+ return [
295
+ 4,
296
+ versionDocument.accessor.exists()
297
+ ];
298
+ case 2:
299
+ versionExists = _state.sent();
300
+ if (!versionExists) {
301
+ throw new Error("Cannot set activeVersion to ".concat(activeVersion, ' on OpenRouterPrompt "').concat(document.id, '": that version does not exist.'));
302
+ }
303
+ _state.label = 3;
304
+ case 3:
305
+ return [
306
+ 4,
307
+ inTransaction.update({
308
+ n: name !== null && name !== void 0 ? name : undefined,
309
+ d: description,
310
+ t: tags,
311
+ s: state !== null && state !== void 0 ? state : undefined,
312
+ av: activeVersion,
313
+ uat: new Date()
314
+ })
315
+ ];
316
+ case 4:
317
+ _state.sent();
318
+ return [
319
+ 2
320
+ ];
321
+ }
322
+ });
323
+ })();
324
+ })
325
+ ];
326
+ case 1:
327
+ _state.sent();
328
+ openRouterPromptService.clearCachedPrompt(document.id);
329
+ return [
330
+ 2,
331
+ document
332
+ ];
333
+ }
334
+ });
335
+ })();
336
+ }
337
+ ];
338
+ });
339
+ })();
340
+ });
341
+ }
342
+ /**
343
+ * Creates a new version, allocating its number inside the transaction, locking the version it succeeds,
344
+ * and optionally promoting it.
345
+ *
346
+ * @param context - The actions context.
347
+ * @returns The create version action.
348
+ */ function createOpenRouterPromptVersionFactory(context) {
349
+ var firebaseServerActionTransformFunctionFactory = context.firebaseServerActionTransformFunctionFactory, openRouterPromptCollection = context.openRouterPromptCollection, openRouterPromptVersionCollectionFactory = context.openRouterPromptVersionCollectionFactory, openRouterPromptService = context.openRouterPromptService;
350
+ return firebaseServerActionTransformFunctionFactory(createOpenRouterPromptVersionParamsType, function(params) {
351
+ return _async_to_generator$8(function() {
352
+ var instructions, messages, config, notes, activate;
353
+ return _ts_generator$8(this, function(_state) {
354
+ instructions = params.instructions, messages = params.messages, config = params.config, notes = params.notes, activate = params.activate;
355
+ return [
356
+ 2,
357
+ function(document) {
358
+ return _async_to_generator$8(function() {
359
+ var modelConfig, validation, result;
360
+ return _ts_generator$8(this, function(_state) {
361
+ switch(_state.label){
362
+ case 0:
363
+ modelConfig = config !== null && config !== void 0 ? config : undefined;
364
+ validation = validateOpenRouterModelConfig(modelConfig !== null && modelConfig !== void 0 ? modelConfig : {});
365
+ if (!validation.valid) {
366
+ throw new Error('Cannot create a version of OpenRouterPrompt "'.concat(document.id, '": ').concat(validation.errors.join(' ')));
367
+ }
368
+ return [
369
+ 4,
370
+ openRouterPromptCollection.firestoreContext.runTransaction(function(transaction) {
371
+ return _async_to_generator$8(function() {
372
+ var inTransaction, prompt, version, versionCollection, versionDocument, previousVersionDocument, previousVersionExists, _tmp, versionData;
373
+ return _ts_generator$8(this, function(_state) {
374
+ switch(_state.label){
375
+ case 0:
376
+ inTransaction = openRouterPromptCollection.documentAccessorForTransaction(transaction).loadDocument(document.documentRef);
377
+ return [
378
+ 4,
379
+ inTransaction.snapshotData()
380
+ ];
381
+ case 1:
382
+ prompt = _state.sent();
383
+ if (prompt == null) {
384
+ throw new Error('The OpenRouterPrompt "'.concat(document.id, '" does not exist.'));
385
+ }
386
+ // Allocated from the prompt document inside the transaction rather than supplied by the caller:
387
+ // two concurrent creates picking the same number would silently overwrite one another.
388
+ version = prompt.lv + 1;
389
+ versionCollection = openRouterPromptVersionCollectionFactory(inTransaction).documentAccessorForTransaction(transaction);
390
+ versionDocument = versionCollection.loadDocumentForId(openRouterPromptVersionId(version));
391
+ // The outgoing version stops being editable the moment it stops being the head — in the same
392
+ // transaction, so there is no window in which two versions are both unlocked. Read first:
393
+ // Firestore forbids a read after a write in a transaction, and a `set` on a version that was
394
+ // deleted out from under us would resurrect it as a document holding nothing but a lock.
395
+ previousVersionDocument = prompt.lv > 0 ? versionCollection.loadDocumentForId(openRouterPromptVersionId(prompt.lv)) : undefined;
396
+ if (!(previousVersionDocument == null)) return [
397
+ 3,
398
+ 2
399
+ ];
400
+ _tmp = false;
401
+ return [
402
+ 3,
403
+ 4
404
+ ];
405
+ case 2:
406
+ return [
407
+ 4,
408
+ previousVersionDocument.accessor.exists()
409
+ ];
410
+ case 3:
411
+ _tmp = _state.sent();
412
+ _state.label = 4;
413
+ case 4:
414
+ previousVersionExists = _tmp;
415
+ versionData = {
416
+ cat: new Date(),
417
+ v: version,
418
+ i: instructions,
419
+ m: messages === null || messages === void 0 ? void 0 : messages.map(function(param) {
420
+ var role = param.role, content = param.content;
421
+ return {
422
+ r: role,
423
+ c: content
424
+ };
425
+ }),
426
+ c: modelConfig,
427
+ nt: notes
428
+ };
429
+ if (!(previousVersionDocument != null && previousVersionExists)) return [
430
+ 3,
431
+ 6
432
+ ];
433
+ return [
434
+ 4,
435
+ previousVersionDocument.update({
436
+ lk: true
437
+ })
438
+ ];
439
+ case 5:
440
+ _state.sent();
441
+ _state.label = 6;
442
+ case 6:
443
+ return [
444
+ 4,
445
+ versionDocument.accessor.set(versionData)
446
+ ];
447
+ case 7:
448
+ _state.sent();
449
+ return [
450
+ 4,
451
+ inTransaction.update(_object_spread$2({
452
+ lv: version,
453
+ uat: new Date()
454
+ }, activate ? {
455
+ av: version,
456
+ s: OpenRouterPromptState.ACTIVE
457
+ } : undefined))
458
+ ];
459
+ case 8:
460
+ _state.sent();
461
+ // The version document's own path, not the prompt's: a create reports what it created.
462
+ return [
463
+ 2,
464
+ {
465
+ modelKeys: [
466
+ versionDocument.documentRef.path
467
+ ],
468
+ version: version,
469
+ activated: activate === true,
470
+ warnings: validation.warnings
471
+ }
472
+ ];
473
+ }
474
+ });
475
+ })();
476
+ })
477
+ ];
478
+ case 1:
479
+ result = _state.sent();
480
+ openRouterPromptService.clearCachedPrompt(document.id);
481
+ return [
482
+ 2,
483
+ result
484
+ ];
485
+ }
486
+ });
487
+ })();
488
+ }
489
+ ];
490
+ });
491
+ })();
492
+ });
493
+ }
494
+ /**
495
+ * Edits the latest version of a prompt in place, refusing one the next version has locked.
496
+ *
497
+ * The lock is re-read inside the transaction rather than trusted from the caller's snapshot: a create
498
+ * racing this edit would otherwise let the write land on a version that had just stopped being the head.
499
+ *
500
+ * @param context - The actions context.
501
+ * @returns The update version action.
502
+ */ function updateOpenRouterPromptVersionFactory(context) {
503
+ var firebaseServerActionTransformFunctionFactory = context.firebaseServerActionTransformFunctionFactory, openRouterPromptCollection = context.openRouterPromptCollection, openRouterPromptVersionCollectionGroup = context.openRouterPromptVersionCollectionGroup, openRouterPromptService = context.openRouterPromptService;
504
+ return firebaseServerActionTransformFunctionFactory(updateOpenRouterPromptVersionParamsType, function(params) {
505
+ return _async_to_generator$8(function() {
506
+ var instructions, messages, config, notes;
507
+ return _ts_generator$8(this, function(_state) {
508
+ instructions = params.instructions, messages = params.messages, config = params.config, notes = params.notes;
509
+ return [
510
+ 2,
511
+ function(document) {
512
+ return _async_to_generator$8(function() {
513
+ var inputConfig, validation;
514
+ return _ts_generator$8(this, function(_state) {
515
+ switch(_state.label){
516
+ case 0:
517
+ inputConfig = config;
518
+ return [
519
+ 4,
520
+ openRouterPromptCollection.firestoreContext.runTransaction(function(transaction) {
521
+ return _async_to_generator$8(function() {
522
+ var _ref, inTransaction, version, result;
523
+ return _ts_generator$8(this, function(_state) {
524
+ switch(_state.label){
525
+ case 0:
526
+ inTransaction = openRouterPromptVersionCollectionGroup.documentAccessorForTransaction(transaction).loadDocument(document.documentRef);
527
+ return [
528
+ 4,
529
+ inTransaction.snapshotData()
530
+ ];
531
+ case 1:
532
+ version = _state.sent();
533
+ if (version == null) {
534
+ throw new Error('The OpenRouterPromptVersion "'.concat(document.key, '" does not exist.'));
535
+ }
536
+ if (version.lk) {
537
+ throw new Error('The OpenRouterPromptVersion "'.concat(document.key, '" is locked, because a newer version exists. Create a new version instead.'));
538
+ }
539
+ // Validated against what the version will SAY once written, not against the patch: an edit that
540
+ // touches only the instructions must not be judged against an empty config and refused for
541
+ // naming no model. An explicitly null config is judged as the empty config it would leave behind,
542
+ // which is exactly the refusal that should happen.
543
+ result = validateOpenRouterModelConfig((_ref = config === undefined ? version.c : inputConfig) !== null && _ref !== void 0 ? _ref : {});
544
+ if (!result.valid) {
545
+ throw new Error('Cannot update OpenRouterPromptVersion "'.concat(document.key, '": ').concat(result.errors.join(' ')));
546
+ }
547
+ // Undefined fields are stripped before the write, so an omitted field is left as it was. `null`
548
+ // is passed through for the fields that can meaningfully carry nothing.
549
+ return [
550
+ 4,
551
+ inTransaction.update({
552
+ i: instructions,
553
+ m: messages == null ? messages : messages.map(function(param) {
554
+ var role = param.role, content = param.content;
555
+ return {
556
+ r: role,
557
+ c: content
558
+ };
559
+ }),
560
+ c: inputConfig,
561
+ nt: notes
562
+ })
563
+ ];
564
+ case 2:
565
+ _state.sent();
566
+ return [
567
+ 2,
568
+ result
569
+ ];
570
+ }
571
+ });
572
+ })();
573
+ })
574
+ ];
575
+ case 1:
576
+ validation = _state.sent();
577
+ // Keyed by the parent prompt, which is the id the cache and the resolver both work in.
578
+ openRouterPromptService.clearCachedPrompt(firestoreModelId(firestoreModelKeyParentKey(document)));
579
+ return [
580
+ 2,
581
+ {
582
+ warnings: validation.warnings
583
+ }
584
+ ];
585
+ }
586
+ });
587
+ })();
588
+ }
589
+ ];
590
+ });
591
+ })();
592
+ });
593
+ }
594
+ /**
595
+ * How many definitions {@link seedOpenRouterPromptsFactory} publishes at a time.
596
+ *
597
+ * Each definition's writes are their own commit against documents no other definition touches, so the
598
+ * bound is not a correctness requirement — it keeps a large registry from opening one connection per
599
+ * prompt against Firestore all at once.
600
+ */ var OPENROUTER_SEED_PROMPTS_MAX_PARALLEL_UPDATES = 25;
601
+ /**
602
+ * Publishes each code definition the prompt service carries at ITS OWN declared version number.
603
+ *
604
+ * The number is a compile-time constant rather than one allocated from `lv`, which is the whole point:
605
+ * an auto-allocating writer cannot converge on a number chosen in code, because its write address moves
606
+ * with its own effect — so a store seeded by {@link createOpenRouterPromptVersionFactory} sits
607
+ * permanently behind the definition and the resolver stands in for it forever. Pinning makes the write
608
+ * address a pure function of the definition, so a re-seed is a no-op rather than a step toward
609
+ * convergence, and a scheduled reseed can keep the store in step with deploys.
610
+ *
611
+ * Publishing is gated on `lv` rather than `av`: `lv` is the allocator and is monotone, while `av` is a
612
+ * pointer an operator can move backwards — gating on it would let a demotion re-trigger a publish on
613
+ * every scheduled tick, forever.
614
+ *
615
+ * Deliberately NOT built on {@link createOpenRouterPromptVersionFactory}: that action is reachable over
616
+ * callModel/MCP, and its in-transaction allocation is a race-safety contract on a public surface rather
617
+ * than an implementation detail. A seed needs no allocator at all, because the number it writes is a
618
+ * compile-time constant — something `CreateOpenRouterPromptVersionParams` cannot assert about an
619
+ * arbitrary caller.
620
+ *
621
+ * No transaction, at any scope. A version document carries a whole prompt's text, so a registry of them
622
+ * can put megabytes through a single commit, and a commit — transaction or write batch alike — is capped
623
+ * around 10MB. The run is instead one read pass over every prompt document, then each definition
624
+ * published independently through its OWN write batch, at most
625
+ * {@link OPENROUTER_SEED_PROMPTS_MAX_PARALLEL_UPDATES} at a time. The batch is what keeps a publish
626
+ * atomic — the version, the lock on the head it replaces, and the pointer move land together or not at
627
+ * all — while holding any one commit to the three documents a single definition touches.
628
+ *
629
+ * What that costs is the transaction's read set: the check that nothing else already holds the number
630
+ * being written is now a read taken shortly before the commit rather than a conflict detected at it.
631
+ * Losing that window means a seed overwrites a version an operator published under the same number in
632
+ * the same instant — narrow enough to trade for a run whose size cannot refuse it.
633
+ *
634
+ * @param context - The actions context.
635
+ * @returns The seed action.
636
+ */ function seedOpenRouterPromptsFactory(context) {
637
+ var openRouterPromptCollection = context.openRouterPromptCollection, openRouterPromptVersionCollectionFactory = context.openRouterPromptVersionCollectionFactory, openRouterPromptService = context.openRouterPromptService;
638
+ return function(params) {
639
+ return _async_to_generator$8(function() {
640
+ var promptKeys, keyFilter, definitions, warnings, promptDocumentAccessor, promptTuples, targets, outcomes, promptsCreated, versionsPublished, upToDate, skipped;
641
+ /**
642
+ * Publishes one definition, starting from the prompt the opening read already produced.
643
+ *
644
+ * @param target - The definition and the prompt document it seeds.
645
+ * @returns What the write did.
646
+ */ function seedTarget(target) {
647
+ return _async_to_generator$8(function() {
648
+ var _ref, definition, promptDocument, prompt, promptKey, version, latestVersion, archived, outcome, versionCollection, versionAccessor, targetVersionId, targetVersionExists, _definition_messages, previousVersionId, previousVersionExists, _tmp, versionData, writeBatch, versionWriteAccessor, promptWriteDocument;
649
+ return _ts_generator$8(this, function(_state) {
650
+ switch(_state.label){
651
+ case 0:
652
+ definition = target.definition, promptDocument = target.promptDocument, prompt = target.prompt;
653
+ promptKey = definition.promptKey, version = definition.version;
654
+ latestVersion = (_ref = prompt === null || prompt === void 0 ? void 0 : prompt.lv) !== null && _ref !== void 0 ? _ref : 0;
655
+ // An ARCHIVED prompt is never resurrected: retirement is a deliberate act, and a scheduled
656
+ // reseed silently undoing it is the same class of bug as reverting an operator's rename. Decided
657
+ // from the prompt alone, so an archived definition costs no further read.
658
+ archived = (prompt === null || prompt === void 0 ? void 0 : prompt.s) === OpenRouterPromptState.ARCHIVED;
659
+ if (!archived) return [
660
+ 3,
661
+ 1
662
+ ];
663
+ outcome = 'skipped';
664
+ return [
665
+ 3,
666
+ 15
667
+ ];
668
+ case 1:
669
+ versionCollection = openRouterPromptVersionCollectionFactory(promptDocument);
670
+ versionAccessor = versionCollection.documentAccessor();
671
+ targetVersionId = openRouterPromptVersionId(version);
672
+ return [
673
+ 4,
674
+ versionAccessor.loadDocumentForId(targetVersionId).accessor.exists()
675
+ ];
676
+ case 2:
677
+ targetVersionExists = _state.sent();
678
+ if (!(version > latestVersion && !targetVersionExists)) return [
679
+ 3,
680
+ 14
681
+ ];
682
+ // The outgoing head's address comes from the prompt's own `lv`, and `version > latestVersion`
683
+ // above is what guarantees it is not the document about to be written. Existence-checked
684
+ // because a batched `update` on a missing document fails the whole commit, and a `set` on a
685
+ // deleted version would resurrect it holding nothing but a lock.
686
+ previousVersionId = latestVersion > 0 ? openRouterPromptVersionId(latestVersion) : undefined;
687
+ if (!(previousVersionId == null)) return [
688
+ 3,
689
+ 3
690
+ ];
691
+ _tmp = false;
692
+ return [
693
+ 3,
694
+ 5
695
+ ];
696
+ case 3:
697
+ return [
698
+ 4,
699
+ versionAccessor.loadDocumentForId(previousVersionId).accessor.exists()
700
+ ];
701
+ case 4:
702
+ _tmp = _state.sent();
703
+ _state.label = 5;
704
+ case 5:
705
+ previousVersionExists = _tmp;
706
+ versionData = {
707
+ cat: new Date(),
708
+ v: version,
709
+ i: definition.instructions,
710
+ m: (_definition_messages = definition.messages) === null || _definition_messages === void 0 ? void 0 : _definition_messages.map(function(param) {
711
+ var role = param.role, content = param.content;
712
+ return {
713
+ r: role,
714
+ c: content
715
+ };
716
+ }),
717
+ c: definition.config,
718
+ nt: "Seeded from the code definition declaring version ".concat(version, ".")
719
+ };
720
+ // One batch for this definition and nothing else. Atomic, so a prompt never ends up pointing
721
+ // at a version the run failed to write, and bounded, so the commit carries one prompt's text
722
+ // rather than the registry's.
723
+ writeBatch = openRouterPromptCollection.firestoreContext.batch();
724
+ versionWriteAccessor = versionCollection.documentAccessorForWriteBatch(writeBatch);
725
+ promptWriteDocument = openRouterPromptCollection.documentAccessorForWriteBatch(writeBatch).loadDocumentForId(promptKey);
726
+ if (!(previousVersionId != null && previousVersionExists)) return [
727
+ 3,
728
+ 7
729
+ ];
730
+ return [
731
+ 4,
732
+ versionWriteAccessor.loadDocumentForId(previousVersionId).update({
733
+ lk: true
734
+ })
735
+ ];
736
+ case 6:
737
+ _state.sent();
738
+ _state.label = 7;
739
+ case 7:
740
+ return [
741
+ 4,
742
+ versionWriteAccessor.loadDocumentForId(targetVersionId).accessor.set(versionData)
743
+ ];
744
+ case 8:
745
+ _state.sent();
746
+ if (!(prompt == null)) return [
747
+ 3,
748
+ 10
749
+ ];
750
+ return [
751
+ 4,
752
+ promptWriteDocument.accessor.set({
753
+ cat: new Date(),
754
+ n: definition.name,
755
+ d: definition.description,
756
+ s: OpenRouterPromptState.ACTIVE,
757
+ lv: version,
758
+ av: version
759
+ })
760
+ ];
761
+ case 9:
762
+ _state.sent();
763
+ return [
764
+ 3,
765
+ 12
766
+ ];
767
+ case 10:
768
+ // `n`/`d`/`t` are deliberately untouched: they are operator-editable through
769
+ // updateOpenRouterPrompt, and a scheduled reseed reverting a rename is a silent regression.
770
+ return [
771
+ 4,
772
+ promptWriteDocument.update({
773
+ lv: version,
774
+ av: version,
775
+ s: OpenRouterPromptState.ACTIVE,
776
+ uat: new Date()
777
+ })
778
+ ];
779
+ case 11:
780
+ _state.sent();
781
+ _state.label = 12;
782
+ case 12:
783
+ return [
784
+ 4,
785
+ writeBatch.commit()
786
+ ];
787
+ case 13:
788
+ _state.sent();
789
+ // Only the prompts that actually changed, and only once the commit landed. Missing this
790
+ // leaves a scheduled reseed invisible for the whole OPENROUTER_PROMPT_CACHE_DURATION window.
791
+ openRouterPromptService.clearCachedPrompt(promptKey);
792
+ outcome = prompt == null ? 'created' : 'published';
793
+ return [
794
+ 3,
795
+ 15
796
+ ];
797
+ case 14:
798
+ // The only way to land on `upToDate` is a prompt whose `lv` already covers the declared
799
+ // number AND whose document at that number is present — anything else is drift the seed
800
+ // refuses to paper over by overwriting a number someone else wrote.
801
+ outcome = version > latestVersion || !targetVersionExists ? 'skipped' : 'upToDate';
802
+ _state.label = 15;
803
+ case 15:
804
+ return [
805
+ 2,
806
+ outcome
807
+ ];
808
+ }
809
+ });
810
+ })();
811
+ }
812
+ return _ts_generator$8(this, function(_state) {
813
+ switch(_state.label){
814
+ case 0:
815
+ promptKeys = params.promptKeys;
816
+ keyFilter = promptKeys == null ? undefined : new Set(promptKeys);
817
+ return [
818
+ 4,
819
+ openRouterPromptService.loadPromptDefinitions()
820
+ ];
821
+ case 1:
822
+ definitions = _state.sent().filter(function(x) {
823
+ return keyFilter == null || keyFilter.has(x.promptKey);
824
+ });
825
+ warnings = [];
826
+ // Every definition is validated before anything is written: half-seeding a registry because entry
827
+ // three is broken leaves a state no rerun explains.
828
+ definitions.forEach(function(definition) {
829
+ var promptKey = definition.promptKey, version = definition.version, config = definition.config;
830
+ if (!Number.isInteger(version) || version < 1) {
831
+ throw new Error('Cannot seed OpenRouterPrompt "'.concat(promptKey, '": the definition declares version ').concat(version, ", which is not an integer >= 1."));
832
+ }
833
+ var validation = validateOpenRouterModelConfig(config);
834
+ if (!validation.valid) {
835
+ throw new Error('Cannot seed OpenRouterPrompt "'.concat(promptKey, '": ').concat(validation.errors.join(' ')));
836
+ }
837
+ validation.warnings.forEach(function(warning) {
838
+ return warnings.push("".concat(promptKey, ": ").concat(warning));
839
+ });
840
+ });
841
+ // Every prompt document up front, in one pass, before a single write: the addresses are the keys the
842
+ // definitions declare, so they all resolve together, and reading them here is what lets the write
843
+ // phase decide each definition without a transaction to re-read them in.
844
+ promptDocumentAccessor = openRouterPromptCollection.documentAccessor();
845
+ return [
846
+ 4,
847
+ getDocumentSnapshotDataTuples(definitions.map(function(x) {
848
+ return promptDocumentAccessor.loadDocumentForId(x.promptKey);
849
+ }))
850
+ ];
851
+ case 2:
852
+ promptTuples = _state.sent();
853
+ targets = definitions.map(function(definition, i) {
854
+ return {
855
+ definition: definition,
856
+ promptDocument: promptTuples[i][0],
857
+ prompt: promptTuples[i][1]
858
+ };
859
+ });
860
+ return [
861
+ 4,
862
+ runAsyncTasksForValues(targets, seedTarget, {
863
+ maxParallelTasks: OPENROUTER_SEED_PROMPTS_MAX_PARALLEL_UPDATES
864
+ })
865
+ ];
866
+ case 3:
867
+ outcomes = _state.sent();
868
+ promptsCreated = 0;
869
+ versionsPublished = 0;
870
+ upToDate = 0;
871
+ skipped = 0;
872
+ outcomes.forEach(function(outcome) {
873
+ switch(outcome){
874
+ case 'created':
875
+ promptsCreated += 1;
876
+ versionsPublished += 1;
877
+ break;
878
+ case 'published':
879
+ versionsPublished += 1;
880
+ break;
881
+ case 'upToDate':
882
+ upToDate += 1;
883
+ break;
884
+ case 'skipped':
885
+ skipped += 1;
886
+ break;
887
+ }
888
+ });
889
+ return [
890
+ 2,
891
+ {
892
+ considered: definitions.length,
893
+ promptsCreated: promptsCreated,
894
+ versionsPublished: versionsPublished,
895
+ upToDate: upToDate,
896
+ skipped: skipped,
897
+ warnings: warnings
898
+ }
899
+ ];
900
+ }
901
+ });
902
+ })();
903
+ };
904
+ }
905
+
906
+ function asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, key, arg) {
907
+ try {
908
+ var info = gen[key](arg);
909
+ var value = info.value;
910
+ } catch (error) {
911
+ reject(error);
912
+ return;
913
+ }
914
+ if (info.done) {
915
+ resolve(value);
916
+ } else {
917
+ Promise.resolve(value).then(_next, _throw);
918
+ }
919
+ }
920
+ function _async_to_generator$7(fn) {
921
+ return function() {
922
+ var self = this, args = arguments;
923
+ return new Promise(function(resolve, reject) {
924
+ var gen = fn.apply(self, args);
925
+ function _next(value) {
926
+ asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "next", value);
927
+ }
928
+ function _throw(err) {
929
+ asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "throw", err);
930
+ }
931
+ _next(undefined);
932
+ });
933
+ };
934
+ }
935
+ function _ts_generator$7(thisArg, body) {
936
+ var f, y, t, _ = {
937
+ label: 0,
938
+ sent: function() {
939
+ if (t[0] & 1) throw t[1];
940
+ return t[1];
941
+ },
942
+ trys: [],
943
+ ops: []
944
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
945
+ return d(g, "next", {
946
+ value: verb(0)
947
+ }), d(g, "throw", {
948
+ value: verb(1)
949
+ }), d(g, "return", {
950
+ value: verb(2)
951
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
952
+ value: function() {
953
+ return this;
954
+ }
955
+ }), g;
956
+ function verb(n) {
957
+ return function(v) {
958
+ return step([
959
+ n,
960
+ v
961
+ ]);
962
+ };
963
+ }
964
+ function step(op) {
965
+ if (f) throw new TypeError("Generator is already executing.");
966
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
967
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
968
+ if (y = 0, t) op = [
969
+ op[0] & 2,
970
+ t.value
971
+ ];
972
+ switch(op[0]){
973
+ case 0:
974
+ case 1:
975
+ t = op;
976
+ break;
977
+ case 4:
978
+ _.label++;
979
+ return {
980
+ value: op[1],
981
+ done: false
982
+ };
983
+ case 5:
984
+ _.label++;
985
+ y = op[1];
986
+ op = [
987
+ 0
988
+ ];
989
+ continue;
990
+ case 7:
991
+ op = _.ops.pop();
992
+ _.trys.pop();
993
+ continue;
994
+ default:
995
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
996
+ _ = 0;
997
+ continue;
998
+ }
999
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1000
+ _.label = op[1];
1001
+ break;
1002
+ }
1003
+ if (op[0] === 6 && _.label < t[1]) {
1004
+ _.label = t[1];
1005
+ t = op;
1006
+ break;
1007
+ }
1008
+ if (t && _.label < t[2]) {
1009
+ _.label = t[2];
1010
+ _.ops.push(op);
1011
+ break;
1012
+ }
1013
+ if (t[2]) _.ops.pop();
1014
+ _.trys.pop();
1015
+ continue;
1016
+ }
1017
+ op = body.call(thisArg, _);
1018
+ } catch (e) {
1019
+ op = [
1020
+ 6,
1021
+ e
1022
+ ];
1023
+ y = 0;
1024
+ } finally{
1025
+ f = t = 0;
1026
+ }
1027
+ if (op[0] & 5) throw op[1];
1028
+ return {
1029
+ value: op[0] ? op[1] : void 0,
1030
+ done: true
1031
+ };
1032
+ }
1033
+ }
1034
+ /**
1035
+ * The attribute key OpenRouter surfaces a `trace: { runTaskKey }` property under.
1036
+ *
1037
+ * OpenRouter's docs: "custom metadata from the `trace` field is included as span attributes in the OTLP
1038
+ * JSON payload". The exact prefix is not contractual, so several candidates are checked.
1039
+ */ var OPENROUTER_BROADCAST_RUN_TASK_KEY_ATTRIBUTES = [
1040
+ 'runTaskKey',
1041
+ 'trace.runTaskKey',
1042
+ 'openrouter.trace.runTaskKey',
1043
+ 'gen_ai.trace.runTaskKey'
1044
+ ];
1045
+ /**
1046
+ * Reads the run task key out of a span's attribute map.
1047
+ *
1048
+ * @param attributes - The flattened span attributes.
1049
+ * @returns The run task key, when the span carries one.
1050
+ */ function openRouterRunTaskKeyFromBroadcastAttributes(attributes) {
1051
+ var result;
1052
+ if (attributes != null) {
1053
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1054
+ try {
1055
+ for(var _iterator = OPENROUTER_BROADCAST_RUN_TASK_KEY_ATTRIBUTES[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1056
+ var key = _step.value;
1057
+ var value = attributes.get(key);
1058
+ if (value != null) {
1059
+ result = String(value);
1060
+ break;
1061
+ }
1062
+ }
1063
+ } catch (err) {
1064
+ _didIteratorError = true;
1065
+ _iteratorError = err;
1066
+ } finally{
1067
+ try {
1068
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1069
+ _iterator.return();
1070
+ }
1071
+ } finally{
1072
+ if (_didIteratorError) {
1073
+ throw _iteratorError;
1074
+ }
1075
+ }
1076
+ }
1077
+ }
1078
+ return result;
1079
+ }
1080
+ /**
1081
+ * Reconciles generation id, usage, and cost onto a run task from a broadcast span.
1082
+ *
1083
+ * This exists for the one thing the runner cannot always know: cost is finalised server-side, so the
1084
+ * value the runner wrote from the response can be provisional.
1085
+ *
1086
+ * TELEMETRY ONLY — it never changes `s`, and a span it cannot match is dropped silently. Broadcast is
1087
+ * enabled account-wide rather than per request, delivery is asynchronous and best-effort, and a dropped
1088
+ * trace must not be able to strand a task. Putting control flow here would make a missing trace look
1089
+ * exactly like a stuck run.
1090
+ *
1091
+ * @param params - The collections, run task key, and generation info.
1092
+ * @returns Whether anything was written.
1093
+ */ function reconcileOpenRouterRunTaskFromBroadcast(params) {
1094
+ return _async_to_generator$7(function() {
1095
+ var collections, key, generation, reconciled, document, task, generationIds, usage;
1096
+ return _ts_generator$7(this, function(_state) {
1097
+ switch(_state.label){
1098
+ case 0:
1099
+ collections = params.collections, key = params.key, generation = params.generation;
1100
+ reconciled = false;
1101
+ if (!key) return [
1102
+ 3,
1103
+ 3
1104
+ ];
1105
+ document = collections.openRouterRunTaskCollection.documentAccessor().loadDocumentForId(key);
1106
+ return [
1107
+ 4,
1108
+ document.snapshotData()
1109
+ ];
1110
+ case 1:
1111
+ task = _state.sent();
1112
+ if (!(task != null)) return [
1113
+ 3,
1114
+ 3
1115
+ ];
1116
+ generationIds = generation.generationId == null ? task.gi : concatArraysUnique(task.gi, [
1117
+ generation.generationId
1118
+ ]);
1119
+ usage = mergeOpenRouterRunUsage(task.u, generation);
1120
+ return [
1121
+ 4,
1122
+ document.update({
1123
+ gi: generationIds,
1124
+ u: usage
1125
+ })
1126
+ ];
1127
+ case 2:
1128
+ _state.sent();
1129
+ reconciled = true;
1130
+ _state.label = 3;
1131
+ case 3:
1132
+ return [
1133
+ 2,
1134
+ {
1135
+ reconciled: reconciled
1136
+ }
1137
+ ];
1138
+ }
1139
+ });
1140
+ })();
1141
+ }
1142
+ /**
1143
+ * Merges broadcast-reported usage into the usage already stored on a task.
1144
+ *
1145
+ * The broadcast value wins where it is present — it is the later, authoritative measurement — and the
1146
+ * stored value is kept where the span is silent, so an incomplete span cannot erase what the runner knew.
1147
+ *
1148
+ * The filter MUST be `NULL`, not `mergeObjects`' default of `UNDEFINED`. Every field here is a `Maybe`, so a
1149
+ * span reporting `cost: null` means "did not measure" — and under the default filter that `null` would win
1150
+ * and erase the cost the runner actually recorded.
1151
+ *
1152
+ * `reasoningTokens` / `cachedTokens` / `isByok` are absent from the literal because a broadcast span carries
1153
+ * none of them; they ride along from `existing` untouched.
1154
+ *
1155
+ * @param existing - Usage already stored.
1156
+ * @param generation - The span's generation info.
1157
+ * @returns The merged usage.
1158
+ *
1159
+ * @__NO_SIDE_EFFECTS__
1160
+ */ function mergeOpenRouterRunUsage(existing, generation) {
1161
+ var inputTokens = generation.promptTokens, outputTokens = generation.completionTokens, totalTokens = generation.totalTokens, cost = generation.cost;
1162
+ return mergeObjects([
1163
+ existing,
1164
+ {
1165
+ inputTokens: inputTokens,
1166
+ outputTokens: outputTokens,
1167
+ totalTokens: totalTokens,
1168
+ cost: cost
1169
+ }
1170
+ ], KeyValueTypleValueFilter.NULL);
1171
+ }
1172
+
1173
+ function asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, key, arg) {
1174
+ try {
1175
+ var info = gen[key](arg);
1176
+ var value = info.value;
1177
+ } catch (error) {
1178
+ reject(error);
1179
+ return;
1180
+ }
1181
+ if (info.done) {
1182
+ resolve(value);
1183
+ } else {
1184
+ Promise.resolve(value).then(_next, _throw);
1185
+ }
1186
+ }
1187
+ function _async_to_generator$6(fn) {
1188
+ return function() {
1189
+ var self = this, args = arguments;
1190
+ return new Promise(function(resolve, reject) {
1191
+ var gen = fn.apply(self, args);
1192
+ function _next(value) {
1193
+ asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "next", value);
1194
+ }
1195
+ function _throw(err) {
1196
+ asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "throw", err);
1197
+ }
1198
+ _next(undefined);
1199
+ });
1200
+ };
1201
+ }
1202
+ function _ts_generator$6(thisArg, body) {
1203
+ var f, y, t, _ = {
1204
+ label: 0,
1205
+ sent: function() {
1206
+ if (t[0] & 1) throw t[1];
1207
+ return t[1];
1208
+ },
1209
+ trys: [],
1210
+ ops: []
1211
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
1212
+ return d(g, "next", {
1213
+ value: verb(0)
1214
+ }), d(g, "throw", {
1215
+ value: verb(1)
1216
+ }), d(g, "return", {
1217
+ value: verb(2)
1218
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
1219
+ value: function() {
1220
+ return this;
1221
+ }
1222
+ }), g;
1223
+ function verb(n) {
1224
+ return function(v) {
1225
+ return step([
1226
+ n,
1227
+ v
1228
+ ]);
1229
+ };
1230
+ }
1231
+ function step(op) {
1232
+ if (f) throw new TypeError("Generator is already executing.");
1233
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
1234
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1235
+ if (y = 0, t) op = [
1236
+ op[0] & 2,
1237
+ t.value
1238
+ ];
1239
+ switch(op[0]){
1240
+ case 0:
1241
+ case 1:
1242
+ t = op;
1243
+ break;
1244
+ case 4:
1245
+ _.label++;
1246
+ return {
1247
+ value: op[1],
1248
+ done: false
1249
+ };
1250
+ case 5:
1251
+ _.label++;
1252
+ y = op[1];
1253
+ op = [
1254
+ 0
1255
+ ];
1256
+ continue;
1257
+ case 7:
1258
+ op = _.ops.pop();
1259
+ _.trys.pop();
1260
+ continue;
1261
+ default:
1262
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1263
+ _ = 0;
1264
+ continue;
1265
+ }
1266
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1267
+ _.label = op[1];
1268
+ break;
1269
+ }
1270
+ if (op[0] === 6 && _.label < t[1]) {
1271
+ _.label = t[1];
1272
+ t = op;
1273
+ break;
1274
+ }
1275
+ if (t && _.label < t[2]) {
1276
+ _.label = t[2];
1277
+ _.ops.push(op);
1278
+ break;
1279
+ }
1280
+ if (t[2]) _.ops.pop();
1281
+ _.trys.pop();
1282
+ continue;
1283
+ }
1284
+ op = body.call(thisArg, _);
1285
+ } catch (e) {
1286
+ op = [
1287
+ 6,
1288
+ e
1289
+ ];
1290
+ y = 0;
1291
+ } finally{
1292
+ f = t = 0;
1293
+ }
1294
+ if (op[0] & 5) throw op[1];
1295
+ return {
1296
+ value: op[0] ? op[1] : void 0,
1297
+ done: true
1298
+ };
1299
+ }
1300
+ }
1301
+ /**
1302
+ * Runs a prompt INLINE and returns the result, with no run task document.
1303
+ *
1304
+ * Use this wherever a call reliably finishes in a few seconds. The queue exists for calls that do not,
1305
+ * and paying for a document, a lease, and a sweep interval on a two-second call buys nothing.
1306
+ *
1307
+ * @param params - The client, prompt service, prompt, and input.
1308
+ * @returns The normalized call result.
1309
+ */ function callModelForPrompt(params) {
1310
+ return _async_to_generator$6(function() {
1311
+ var client, promptService, promptKey, version, input, configOverrides, files, tools, trace, prompt, request;
1312
+ return _ts_generator$6(this, function(_state) {
1313
+ switch(_state.label){
1314
+ case 0:
1315
+ client = params.client, promptService = params.promptService, promptKey = params.promptKey, version = params.version, input = params.input, configOverrides = params.configOverrides, files = params.files, tools = params.tools, trace = params.trace;
1316
+ return [
1317
+ 4,
1318
+ promptService.resolvePrompt({
1319
+ promptKey: promptKey,
1320
+ version: version
1321
+ })
1322
+ ];
1323
+ case 1:
1324
+ prompt = _state.sent();
1325
+ request = openRouterPromptRequest({
1326
+ prompt: prompt,
1327
+ input: input,
1328
+ overrides: configOverrides,
1329
+ files: files,
1330
+ trace: trace
1331
+ });
1332
+ return [
1333
+ 2,
1334
+ callModelForOpenRouterRequest({
1335
+ client: client,
1336
+ request: request,
1337
+ tools: tools !== null && tools !== void 0 ? tools : undefined
1338
+ })
1339
+ ];
1340
+ }
1341
+ });
1342
+ })();
1343
+ }
1344
+
1345
+ function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
1346
+ try {
1347
+ var info = gen[key](arg);
1348
+ var value = info.value;
1349
+ } catch (error) {
1350
+ reject(error);
1351
+ return;
1352
+ }
1353
+ if (info.done) {
1354
+ resolve(value);
1355
+ } else {
1356
+ Promise.resolve(value).then(_next, _throw);
1357
+ }
1358
+ }
1359
+ function _async_to_generator$5(fn) {
1360
+ return function() {
1361
+ var self = this, args = arguments;
1362
+ return new Promise(function(resolve, reject) {
1363
+ var gen = fn.apply(self, args);
1364
+ function _next(value) {
1365
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "next", value);
1366
+ }
1367
+ function _throw(err) {
1368
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "throw", err);
1369
+ }
1370
+ _next(undefined);
1371
+ });
1372
+ };
1373
+ }
1374
+ function _ts_generator$5(thisArg, body) {
1375
+ var f, y, t, _ = {
1376
+ label: 0,
1377
+ sent: function() {
1378
+ if (t[0] & 1) throw t[1];
1379
+ return t[1];
1380
+ },
1381
+ trys: [],
1382
+ ops: []
1383
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
1384
+ return d(g, "next", {
1385
+ value: verb(0)
1386
+ }), d(g, "throw", {
1387
+ value: verb(1)
1388
+ }), d(g, "return", {
1389
+ value: verb(2)
1390
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
1391
+ value: function() {
1392
+ return this;
1393
+ }
1394
+ }), g;
1395
+ function verb(n) {
1396
+ return function(v) {
1397
+ return step([
1398
+ n,
1399
+ v
1400
+ ]);
1401
+ };
1402
+ }
1403
+ function step(op) {
1404
+ if (f) throw new TypeError("Generator is already executing.");
1405
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
1406
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1407
+ if (y = 0, t) op = [
1408
+ op[0] & 2,
1409
+ t.value
1410
+ ];
1411
+ switch(op[0]){
1412
+ case 0:
1413
+ case 1:
1414
+ t = op;
1415
+ break;
1416
+ case 4:
1417
+ _.label++;
1418
+ return {
1419
+ value: op[1],
1420
+ done: false
1421
+ };
1422
+ case 5:
1423
+ _.label++;
1424
+ y = op[1];
1425
+ op = [
1426
+ 0
1427
+ ];
1428
+ continue;
1429
+ case 7:
1430
+ op = _.ops.pop();
1431
+ _.trys.pop();
1432
+ continue;
1433
+ default:
1434
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1435
+ _ = 0;
1436
+ continue;
1437
+ }
1438
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1439
+ _.label = op[1];
1440
+ break;
1441
+ }
1442
+ if (op[0] === 6 && _.label < t[1]) {
1443
+ _.label = t[1];
1444
+ t = op;
1445
+ break;
1446
+ }
1447
+ if (t && _.label < t[2]) {
1448
+ _.label = t[2];
1449
+ _.ops.push(op);
1450
+ break;
1451
+ }
1452
+ if (t[2]) _.ops.pop();
1453
+ _.trys.pop();
1454
+ continue;
1455
+ }
1456
+ op = body.call(thisArg, _);
1457
+ } catch (e) {
1458
+ op = [
1459
+ 6,
1460
+ e
1461
+ ];
1462
+ y = 0;
1463
+ } finally{
1464
+ f = t = 0;
1465
+ }
1466
+ if (op[0] & 5) throw op[1];
1467
+ return {
1468
+ value: op[0] ? op[1] : void 0,
1469
+ done: true
1470
+ };
1471
+ }
1472
+ }
1473
+ /**
1474
+ * Default lifetime of a signed url minted for one attempt.
1475
+ *
1476
+ * Deliberately short. The url only has to survive the single request it is attached to, and every
1477
+ * attempt gets a freshly signed one — so a short TTL costs nothing and narrows the window in which a
1478
+ * third party holds a bearer credential to the object.
1479
+ */ var DEFAULT_OPENROUTER_SIGNED_URL_TTL = MS_IN_MINUTE * 5;
1480
+ /**
1481
+ * Cap on the size of a file carried inline.
1482
+ *
1483
+ * Base64 inflates the payload by roughly a third, and the cost is re-paid on EVERY attempt rather than
1484
+ * amortized the way a url is — so this is a guard against turning a retry loop into a bandwidth bill,
1485
+ * not a correctness limit.
1486
+ */ var DEFAULT_OPENROUTER_MAX_INLINE_FILE_SIZE_BYTES = 256 * 1024;
1487
+ /**
1488
+ * Content type assumed for an inlined object whose metadata reports none.
1489
+ *
1490
+ * Matches {@link openRouterInputFileDataPart}'s own default, so the two cannot disagree.
1491
+ */ var DEFAULT_OPENROUTER_INLINE_FILE_CONTENT_TYPE = 'application/pdf';
1492
+ /**
1493
+ * The mode a config resolves to.
1494
+ *
1495
+ * Order: the explicit override, then the environment service, then `signedUrl`.
1496
+ *
1497
+ * Gated on `isProduction` rather than `isTestingEnv`, because the question is whether OpenRouter can
1498
+ * reach the object, not whether this is a test. Every non-production environment here is a localhost
1499
+ * one — the emulator under `nx serve` as much as a spec run — and `isTestingEnv` is only
1500
+ * `NODE_ENV === 'test'`, so it covered the spec run and left the emulator handing OpenRouter a
1501
+ * `127.0.0.1` url that it rejects outright.
1502
+ *
1503
+ * @param config - The resolver config.
1504
+ * @returns The mode.
1505
+ *
1506
+ * @__NO_SIDE_EFFECTS__
1507
+ */ function openRouterFileAttachmentModeForConfig(config) {
1508
+ var mode = config.mode, envService = config.envService;
1509
+ // `=== false` rather than a negation, so a config with no env service still resolves to `signedUrl`.
1510
+ return mode !== null && mode !== void 0 ? mode : (envService === null || envService === void 0 ? void 0 : envService.isProduction) === false ? 'inlineData' : 'signedUrl';
1511
+ }
1512
+ /**
1513
+ * Creates an {@link OpenRouterFileAttachmentResolver}.
1514
+ *
1515
+ * Called once per attempt, never at enqueue time: both transports produce something that is only valid
1516
+ * for the request it is attached to.
1517
+ *
1518
+ * @param config - The storage context, environment service, and transport settings.
1519
+ * @returns The resolver.
1520
+ */ function openRouterFileAttachmentResolver(config) {
1521
+ var storageContext = config.storageContext, signedUrlTtl = config.signedUrlTtl, maxInlineFileSizeBytes = config.maxInlineFileSizeBytes;
1522
+ var mode = openRouterFileAttachmentModeForConfig(config);
1523
+ var urlTtl = signedUrlTtl !== null && signedUrlTtl !== void 0 ? signedUrlTtl : DEFAULT_OPENROUTER_SIGNED_URL_TTL;
1524
+ var maxInlineBytes = maxInlineFileSizeBytes !== null && maxInlineFileSizeBytes !== void 0 ? maxInlineFileSizeBytes : DEFAULT_OPENROUTER_MAX_INLINE_FILE_SIZE_BYTES;
1525
+ return function resolveAttachments(files) {
1526
+ return _async_to_generator$5(function() {
1527
+ var result, defaultBucketId;
1528
+ return _ts_generator$5(this, function(_state) {
1529
+ switch(_state.label){
1530
+ case 0:
1531
+ result = [];
1532
+ if (!(files != null && files.length > 0)) return [
1533
+ 3,
1534
+ 2
1535
+ ];
1536
+ if (storageContext == null) {
1537
+ throw new Error('An OpenRouterRunTask carries files but no storageContext was configured to attach them with.');
1538
+ }
1539
+ defaultBucketId = storageContext.defaultBucket();
1540
+ return [
1541
+ 4,
1542
+ Promise.all(files.map(function(file) {
1543
+ return _async_to_generator$5(function() {
1544
+ var _file_bucket, path, accessorFile, attached, _metadata_contentType, bytes, metadata, contentType, _tmp;
1545
+ return _ts_generator$5(this, function(_state) {
1546
+ switch(_state.label){
1547
+ case 0:
1548
+ path = {
1549
+ bucketId: (_file_bucket = file.bucket) !== null && _file_bucket !== void 0 ? _file_bucket : defaultBucketId,
1550
+ pathString: file.storagePath
1551
+ };
1552
+ accessorFile = storageContext.file(path);
1553
+ if (!(mode === 'inlineData')) return [
1554
+ 3,
1555
+ 3
1556
+ ];
1557
+ if (accessorFile.getBytes == null) {
1558
+ throw new Error('The configured FirebaseStorageContext cannot read file bytes, which inline file attachment requires.');
1559
+ }
1560
+ return [
1561
+ 4,
1562
+ accessorFile.getBytes(maxInlineBytes)
1563
+ ];
1564
+ case 1:
1565
+ bytes = _state.sent();
1566
+ return [
1567
+ 4,
1568
+ accessorFile.getMetadata()
1569
+ ];
1570
+ case 2:
1571
+ metadata = _state.sent();
1572
+ contentType = (_metadata_contentType = metadata.contentType) !== null && _metadata_contentType !== void 0 ? _metadata_contentType : DEFAULT_OPENROUTER_INLINE_FILE_CONTENT_TYPE;
1573
+ attached = {
1574
+ file: file,
1575
+ fileData: "data:".concat(contentType, ";base64,").concat(Buffer.from(bytes).toString('base64'))
1576
+ };
1577
+ return [
1578
+ 3,
1579
+ 5
1580
+ ];
1581
+ case 3:
1582
+ if (accessorFile.getSignedUrl == null) {
1583
+ throw new Error('The configured FirebaseStorageContext cannot mint signed urls.');
1584
+ }
1585
+ _tmp = {
1586
+ file: file
1587
+ };
1588
+ return [
1589
+ 4,
1590
+ accessorFile.getSignedUrl({
1591
+ action: 'read',
1592
+ expiresIn: urlTtl
1593
+ })
1594
+ ];
1595
+ case 4:
1596
+ attached = (_tmp.fileUrl = _state.sent(), _tmp);
1597
+ _state.label = 5;
1598
+ case 5:
1599
+ return [
1600
+ 2,
1601
+ attached
1602
+ ];
1603
+ }
1604
+ });
1605
+ })();
1606
+ }))
1607
+ ];
1608
+ case 1:
1609
+ result = _state.sent();
1610
+ _state.label = 2;
1611
+ case 2:
1612
+ return [
1613
+ 2,
1614
+ result
1615
+ ];
1616
+ }
1617
+ });
1618
+ })();
1619
+ };
1620
+ }
1621
+
1622
+ function _array_like_to_array$1(arr, len) {
1623
+ if (len == null || len > arr.length) len = arr.length;
1624
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1625
+ return arr2;
1626
+ }
1627
+ function _array_without_holes$1(arr) {
1628
+ if (Array.isArray(arr)) return _array_like_to_array$1(arr);
1629
+ }
1630
+ function _class_call_check$2(instance, Constructor) {
1631
+ if (!(instance instanceof Constructor)) {
1632
+ throw new TypeError("Cannot call a class as a function");
1633
+ }
1634
+ }
1635
+ function _iterable_to_array$1(iter) {
1636
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1637
+ }
1638
+ function _non_iterable_spread$1() {
1639
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1640
+ }
1641
+ function _to_consumable_array$1(arr) {
1642
+ return _array_without_holes$1(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread$1();
1643
+ }
1644
+ function _unsupported_iterable_to_array$1(o, minLen) {
1645
+ if (!o) return;
1646
+ if (typeof o === "string") return _array_like_to_array$1(o, minLen);
1647
+ var n = Object.prototype.toString.call(o).slice(8, -1);
1648
+ if (n === "Object" && o.constructor) n = o.constructor.name;
1649
+ if (n === "Map" || n === "Set") return Array.from(n);
1650
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
1651
+ }
1652
+ /**
1653
+ * Builds the module metadata for an app's OpenRouter module.
1654
+ *
1655
+ * @param config - The dependency module and server-actions provider.
1656
+ * @returns The module metadata.
1657
+ */ function appOpenRouterModuleMetadata(config) {
1658
+ var dependencyModule = config.dependencyModule, serverActionsProvider = config.serverActionsProvider, providers = config.providers, exports = config.exports;
1659
+ return {
1660
+ imports: [
1661
+ dependencyModule
1662
+ ],
1663
+ providers: [
1664
+ serverActionsProvider
1665
+ ].concat(_to_consumable_array$1(providers !== null && providers !== void 0 ? providers : [])),
1666
+ exports: [
1667
+ OpenRouterPromptServerActions
1668
+ ].concat(_to_consumable_array$1(exports !== null && exports !== void 0 ? exports : []))
1669
+ };
1670
+ }
1671
+ /**
1672
+ * Base class an app's OpenRouter module extends.
1673
+ */ var AbstractAppOpenRouterModule = function AbstractAppOpenRouterModule() {
1674
+ _class_call_check$2(this, AbstractAppOpenRouterModule);
1675
+ };
1676
+ /**
1677
+ * Injection token for the {@link OpenRouterPromptService}.
1678
+ */ var OPENROUTER_PROMPT_SERVICE_TOKEN = 'OPENROUTER_PROMPT_SERVICE_TOKEN';
1679
+ /**
1680
+ * Injection token for the {@link OpenRouterRunTaskService}.
1681
+ */ var OPENROUTER_RUN_TASK_SERVICE_TOKEN = 'OPENROUTER_RUN_TASK_SERVICE_TOKEN';
1682
+
1683
+ function _assert_this_initialized(self) {
1684
+ if (self === void 0) {
1685
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
1686
+ }
1687
+ return self;
1688
+ }
1689
+ function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
1690
+ try {
1691
+ var info = gen[key](arg);
1692
+ var value = info.value;
1693
+ } catch (error) {
1694
+ reject(error);
1695
+ return;
1696
+ }
1697
+ if (info.done) {
1698
+ resolve(value);
1699
+ } else {
1700
+ Promise.resolve(value).then(_next, _throw);
1701
+ }
1702
+ }
1703
+ function _async_to_generator$4(fn) {
1704
+ return function() {
1705
+ var self = this, args = arguments;
1706
+ return new Promise(function(resolve, reject) {
1707
+ var gen = fn.apply(self, args);
1708
+ function _next(value) {
1709
+ asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "next", value);
1710
+ }
1711
+ function _throw(err) {
1712
+ asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "throw", err);
1713
+ }
1714
+ _next(undefined);
1715
+ });
1716
+ };
1717
+ }
1718
+ function _call_super(_this, derived, args) {
1719
+ derived = _get_prototype_of(derived);
1720
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
1721
+ }
1722
+ function _class_call_check$1(instance, Constructor) {
1723
+ if (!(instance instanceof Constructor)) {
1724
+ throw new TypeError("Cannot call a class as a function");
1725
+ }
1726
+ }
1727
+ function _construct(Parent, args, Class) {
1728
+ if (_is_native_reflect_construct()) {
1729
+ _construct = Reflect.construct;
1730
+ } else {
1731
+ _construct = function construct(Parent, args, Class) {
1732
+ var a = [
1733
+ null
1734
+ ];
1735
+ a.push.apply(a, args);
1736
+ var Constructor = Function.bind.apply(Parent, a);
1737
+ var instance = new Constructor();
1738
+ if (Class) _set_prototype_of(instance, Class.prototype);
1739
+ return instance;
1740
+ };
1741
+ }
1742
+ return _construct.apply(null, arguments);
1743
+ }
1744
+ function _define_property$2(obj, key, value) {
1745
+ if (key in obj) {
1746
+ Object.defineProperty(obj, key, {
1747
+ value: value,
1748
+ enumerable: true,
1749
+ configurable: true,
1750
+ writable: true
1751
+ });
1752
+ } else {
1753
+ obj[key] = value;
1754
+ }
1755
+ return obj;
1756
+ }
1757
+ function _get_prototype_of(o) {
1758
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
1759
+ return o.__proto__ || Object.getPrototypeOf(o);
1760
+ };
1761
+ return _get_prototype_of(o);
1762
+ }
1763
+ function _inherits(subClass, superClass) {
1764
+ if (typeof superClass !== "function" && superClass !== null) {
1765
+ throw new TypeError("Super expression must either be null or a function");
1766
+ }
1767
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
1768
+ constructor: {
1769
+ value: subClass,
1770
+ writable: true,
1771
+ configurable: true
1772
+ }
1773
+ });
1774
+ if (superClass) _set_prototype_of(subClass, superClass);
1775
+ }
1776
+ function _is_native_function(fn) {
1777
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
1778
+ }
1779
+ function _possible_constructor_return(self, call) {
1780
+ if (call && (_type_of$1(call) === "object" || typeof call === "function")) {
1781
+ return call;
1782
+ }
1783
+ return _assert_this_initialized(self);
1784
+ }
1785
+ function _set_prototype_of(o, p) {
1786
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
1787
+ o.__proto__ = p;
1788
+ return o;
1789
+ };
1790
+ return _set_prototype_of(o, p);
1791
+ }
1792
+ function _type_of$1(obj) {
1793
+ "@swc/helpers - typeof";
1794
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
1795
+ }
1796
+ function _wrap_native_super(Class) {
1797
+ var _cache = typeof Map === "function" ? new Map() : undefined;
1798
+ _wrap_native_super = function wrapNativeSuper(Class) {
1799
+ if (Class === null || !_is_native_function(Class)) return Class;
1800
+ if (typeof Class !== "function") {
1801
+ throw new TypeError("Super expression must either be null or a function");
1802
+ }
1803
+ if (typeof _cache !== "undefined") {
1804
+ if (_cache.has(Class)) return _cache.get(Class);
1805
+ _cache.set(Class, Wrapper);
1806
+ }
1807
+ function Wrapper() {
1808
+ return _construct(Class, arguments, _get_prototype_of(this).constructor);
1809
+ }
1810
+ Wrapper.prototype = Object.create(Class.prototype, {
1811
+ constructor: {
1812
+ value: Wrapper,
1813
+ enumerable: false,
1814
+ writable: true,
1815
+ configurable: true
1816
+ }
1817
+ });
1818
+ return _set_prototype_of(Wrapper, Class);
1819
+ };
1820
+ return _wrap_native_super(Class);
1821
+ }
1822
+ function _is_native_reflect_construct() {
1823
+ try {
1824
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
1825
+ } catch (_) {}
1826
+ return (_is_native_reflect_construct = function() {
1827
+ return !!result;
1828
+ })();
1829
+ }
1830
+ function _ts_generator$4(thisArg, body) {
1831
+ var f, y, t, _ = {
1832
+ label: 0,
1833
+ sent: function() {
1834
+ if (t[0] & 1) throw t[1];
1835
+ return t[1];
1836
+ },
1837
+ trys: [],
1838
+ ops: []
1839
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
1840
+ return d(g, "next", {
1841
+ value: verb(0)
1842
+ }), d(g, "throw", {
1843
+ value: verb(1)
1844
+ }), d(g, "return", {
1845
+ value: verb(2)
1846
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
1847
+ value: function() {
1848
+ return this;
1849
+ }
1850
+ }), g;
1851
+ function verb(n) {
1852
+ return function(v) {
1853
+ return step([
1854
+ n,
1855
+ v
1856
+ ]);
1857
+ };
1858
+ }
1859
+ function step(op) {
1860
+ if (f) throw new TypeError("Generator is already executing.");
1861
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
1862
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1863
+ if (y = 0, t) op = [
1864
+ op[0] & 2,
1865
+ t.value
1866
+ ];
1867
+ switch(op[0]){
1868
+ case 0:
1869
+ case 1:
1870
+ t = op;
1871
+ break;
1872
+ case 4:
1873
+ _.label++;
1874
+ return {
1875
+ value: op[1],
1876
+ done: false
1877
+ };
1878
+ case 5:
1879
+ _.label++;
1880
+ y = op[1];
1881
+ op = [
1882
+ 0
1883
+ ];
1884
+ continue;
1885
+ case 7:
1886
+ op = _.ops.pop();
1887
+ _.trys.pop();
1888
+ continue;
1889
+ default:
1890
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1891
+ _ = 0;
1892
+ continue;
1893
+ }
1894
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1895
+ _.label = op[1];
1896
+ break;
1897
+ }
1898
+ if (op[0] === 6 && _.label < t[1]) {
1899
+ _.label = t[1];
1900
+ t = op;
1901
+ break;
1902
+ }
1903
+ if (t && _.label < t[2]) {
1904
+ _.label = t[2];
1905
+ _.ops.push(op);
1906
+ break;
1907
+ }
1908
+ if (t[2]) _.ops.pop();
1909
+ _.trys.pop();
1910
+ continue;
1911
+ }
1912
+ op = body.call(thisArg, _);
1913
+ } catch (e) {
1914
+ op = [
1915
+ 6,
1916
+ e
1917
+ ];
1918
+ y = 0;
1919
+ } finally{
1920
+ f = t = 0;
1921
+ }
1922
+ if (op[0] & 5) throw op[1];
1923
+ return {
1924
+ value: op[0] ? op[1] : void 0,
1925
+ done: true
1926
+ };
1927
+ }
1928
+ }
1929
+ /**
1930
+ * Error thrown when a prompt cannot be resolved.
1931
+ */ var OpenRouterPromptResolutionError = /*#__PURE__*/ function(Error1) {
1932
+ _inherits(OpenRouterPromptResolutionError, Error1);
1933
+ function OpenRouterPromptResolutionError(promptKey, message, version) {
1934
+ _class_call_check$1(this, OpenRouterPromptResolutionError);
1935
+ var _this;
1936
+ _this = _call_super(this, OpenRouterPromptResolutionError, [
1937
+ 'OpenRouter prompt "'.concat(promptKey, '"').concat(version == null ? '' : " version ".concat(version), ": ").concat(message)
1938
+ ]), _define_property$2(_this, "promptKey", void 0), _define_property$2(_this, "version", void 0);
1939
+ _this.promptKey = promptKey;
1940
+ _this.version = version;
1941
+ return _this;
1942
+ }
1943
+ return OpenRouterPromptResolutionError;
1944
+ }(_wrap_native_super(Error));
1945
+ /**
1946
+ * Default time a resolved prompt is cached for.
1947
+ *
1948
+ * What can go stale is which version is active, and what the latest — still editable — version says.
1949
+ * Neither is critical to serve to the second: a run that used the previous text for a few minutes is a
1950
+ * run against a prompt that was live a few minutes ago, not a wrong run. Bounded rather than permanent
1951
+ * is the requirement, so the change lands on its own rather than at the next cold start.
1952
+ */ var OPENROUTER_PROMPT_CACHE_DURATION = MS_IN_MINUTE * 5;
1953
+ /**
1954
+ * Loads prompts and resolves their versions.
1955
+ */ var OpenRouterPromptService = function OpenRouterPromptService() {
1956
+ _class_call_check$1(this, OpenRouterPromptService);
1957
+ };
1958
+ /**
1959
+ * Creates an {@link OpenRouterPromptService}.
1960
+ *
1961
+ * @param config - The collections and cache configuration.
1962
+ * @returns The service.
1963
+ */ function openRouterPromptService(config) {
1964
+ var collections = config.collections, definitions = config.definitions, cacheDuration = config.cacheDuration, rejectInvalidConfig = config.rejectInvalidConfig;
1965
+ var openRouterPromptCollection = collections.openRouterPromptCollection, openRouterPromptVersionCollectionFactory = collections.openRouterPromptVersionCollectionFactory;
1966
+ var duration = cacheDuration !== null && cacheDuration !== void 0 ? cacheDuration : OPENROUTER_PROMPT_CACHE_DURATION;
1967
+ var definitionsByKey = arrayToMap(definitions !== null && definitions !== void 0 ? definitions : [], function(definition) {
1968
+ return definition.promptKey;
1969
+ });
1970
+ var cache = new Map();
1971
+ function loadPromptDefinitions() {
1972
+ return _async_to_generator$4(function() {
1973
+ return _ts_generator$4(this, function(_state) {
1974
+ // A fresh array each call rather than one built at construction: the returned type is mutable, and
1975
+ // handing every caller the same array would let a seeder's own filtering reach the registry
1976
+ // resolution reads.
1977
+ return [
1978
+ 2,
1979
+ Array.from(definitionsByKey.values())
1980
+ ];
1981
+ });
1982
+ })();
1983
+ }
1984
+ function loadPromptDocument(promptKey) {
1985
+ return openRouterPromptCollection.documentAccessor().loadDocumentForId(promptKey);
1986
+ }
1987
+ function loadPrompt(promptKey) {
1988
+ return _async_to_generator$4(function() {
1989
+ return _ts_generator$4(this, function(_state) {
1990
+ return [
1991
+ 2,
1992
+ loadPromptDocument(promptKey).snapshotData()
1993
+ ];
1994
+ });
1995
+ })();
1996
+ }
1997
+ /**
1998
+ * Reads one published version.
1999
+ *
2000
+ * @param promptDocument - The parent prompt document.
2001
+ * @param promptKey - The prompt's key, recorded on the resolution.
2002
+ * @param version - The version to read.
2003
+ * @returns The resolved version, or undefined when that version was never published.
2004
+ */ function readStoredVersion(promptDocument, promptKey, version) {
2005
+ return _async_to_generator$4(function() {
2006
+ var versionDocument, versionData;
2007
+ return _ts_generator$4(this, function(_state) {
2008
+ switch(_state.label){
2009
+ case 0:
2010
+ versionDocument = openRouterPromptVersionCollectionFactory(promptDocument).documentAccessor().loadDocumentForId(openRouterPromptVersionId(version));
2011
+ return [
2012
+ 4,
2013
+ versionDocument.snapshotData()
2014
+ ];
2015
+ case 1:
2016
+ versionData = _state.sent();
2017
+ return [
2018
+ 2,
2019
+ versionData == null ? undefined : openRouterResolvedPromptForVersion(promptKey, versionData)
2020
+ ];
2021
+ }
2022
+ });
2023
+ })();
2024
+ }
2025
+ function resolveVersion(promptKey, inputVersion) {
2026
+ return _async_to_generator$4(function() {
2027
+ var definition, promptDocument, prompt, storedActiveVersion, resolved, _tmp, validation;
2028
+ return _ts_generator$4(this, function(_state) {
2029
+ switch(_state.label){
2030
+ case 0:
2031
+ definition = definitionsByKey.get(promptKey);
2032
+ promptDocument = loadPromptDocument(promptKey);
2033
+ return [
2034
+ 4,
2035
+ promptDocument.snapshotData()
2036
+ ];
2037
+ case 1:
2038
+ prompt = _state.sent();
2039
+ // The version the store would serve an unpinned caller. A prompt that is missing, not ACTIVE, or has
2040
+ // never had a version promoted cannot serve one — which is precisely when a code definition stands in.
2041
+ // A pinned caller is still allowed to read a draft/archived prompt: that is how a version is tested
2042
+ // before promotion, and how a historical run is replayed after retirement.
2043
+ storedActiveVersion = (prompt === null || prompt === void 0 ? void 0 : prompt.s) === OpenRouterPromptState.ACTIVE ? prompt.av : undefined;
2044
+ if (!(inputVersion != null)) return [
2045
+ 3,
2046
+ 5
2047
+ ];
2048
+ if (!(prompt == null)) return [
2049
+ 3,
2050
+ 2
2051
+ ];
2052
+ _tmp = undefined;
2053
+ return [
2054
+ 3,
2055
+ 4
2056
+ ];
2057
+ case 2:
2058
+ return [
2059
+ 4,
2060
+ readStoredVersion(promptDocument, promptKey, inputVersion)
2061
+ ];
2062
+ case 3:
2063
+ _tmp = _state.sent();
2064
+ _state.label = 4;
2065
+ case 4:
2066
+ // Pinned. The store wins whenever it actually holds that version, so a version published under the
2067
+ // same number after a run was queued is picked up on the run's next attempt. The definition covers
2068
+ // the rest, which is what lets a run enqueued against a definition still dispatch.
2069
+ resolved = _tmp;
2070
+ if (resolved == null && (definition === null || definition === void 0 ? void 0 : definition.version) === inputVersion) {
2071
+ resolved = definition;
2072
+ }
2073
+ return [
2074
+ 3,
2075
+ 8
2076
+ ];
2077
+ case 5:
2078
+ if (!(definition != null && (storedActiveVersion == null || definition.version > storedActiveVersion))) return [
2079
+ 3,
2080
+ 6
2081
+ ];
2082
+ // Unpinned, and code is either standing in for the store or ahead of it.
2083
+ resolved = definition;
2084
+ return [
2085
+ 3,
2086
+ 8
2087
+ ];
2088
+ case 6:
2089
+ if (!(storedActiveVersion != null)) return [
2090
+ 3,
2091
+ 8
2092
+ ];
2093
+ return [
2094
+ 4,
2095
+ readStoredVersion(promptDocument, promptKey, storedActiveVersion)
2096
+ ];
2097
+ case 7:
2098
+ resolved = _state.sent();
2099
+ _state.label = 8;
2100
+ case 8:
2101
+ if (resolved == null) {
2102
+ // Reported against what was actually missing, since "no prompt", "nothing promoted", and "that one
2103
+ // version is gone" need different fixes.
2104
+ if (prompt == null) {
2105
+ throw new OpenRouterPromptResolutionError(promptKey, 'does not exist.', inputVersion);
2106
+ } else if (inputVersion != null) {
2107
+ throw new OpenRouterPromptResolutionError(promptKey, 'version does not exist.', inputVersion);
2108
+ } else if (prompt.s === OpenRouterPromptState.ACTIVE) {
2109
+ throw new OpenRouterPromptResolutionError(promptKey, 'has no activeVersion, and no version was pinned.');
2110
+ } else {
2111
+ throw new OpenRouterPromptResolutionError(promptKey, "is not ACTIVE (state ".concat(prompt.s, "), and no version was pinned."));
2112
+ }
2113
+ }
2114
+ if (rejectInvalidConfig) {
2115
+ validation = validateOpenRouterModelConfig(resolved.config);
2116
+ if (!validation.valid) {
2117
+ throw new OpenRouterPromptResolutionError(promptKey, "has an invalid config: ".concat(validation.errors.join(' ')), resolved.version);
2118
+ }
2119
+ }
2120
+ return [
2121
+ 2,
2122
+ resolved
2123
+ ];
2124
+ }
2125
+ });
2126
+ })();
2127
+ }
2128
+ function cacheKey(promptKey, version) {
2129
+ return "".concat(promptKey, ":").concat(version !== null && version !== void 0 ? version : '_');
2130
+ }
2131
+ function resolvePrompt(params) {
2132
+ return _async_to_generator$4(function() {
2133
+ var promptKey, version, key, getter, load, result, e;
2134
+ return _ts_generator$4(this, function(_state) {
2135
+ switch(_state.label){
2136
+ case 0:
2137
+ promptKey = params.promptKey, version = params.version;
2138
+ key = cacheKey(promptKey, version);
2139
+ getter = cache.get(key);
2140
+ if (getter == null) {
2141
+ load = function load() {
2142
+ return resolveVersion(promptKey, version);
2143
+ };
2144
+ // Everything expires, pinned resolutions included. A version is only immutable once it LOCKS, which
2145
+ // happens when the next version is created — until then the head version is editable in place, and
2146
+ // a permanently cached pin of it would serve the pre-edit text forever on every instance except the
2147
+ // one that handled the edit. Telling the two apart would cost a read of the lock, which is the same
2148
+ // read the expiry already pays for.
2149
+ getter = expiringCachedGetter({
2150
+ getter: load,
2151
+ ttl: duration
2152
+ });
2153
+ cache.set(key, getter);
2154
+ }
2155
+ _state.label = 1;
2156
+ case 1:
2157
+ _state.trys.push([
2158
+ 1,
2159
+ 3,
2160
+ ,
2161
+ 4
2162
+ ]);
2163
+ return [
2164
+ 4,
2165
+ getter()
2166
+ ];
2167
+ case 2:
2168
+ result = _state.sent();
2169
+ return [
2170
+ 3,
2171
+ 4
2172
+ ];
2173
+ case 3:
2174
+ e = _state.sent();
2175
+ // Never cache a rejected promise: a prompt created moments after a failed lookup would keep
2176
+ // failing for the whole cache window.
2177
+ cache.delete(key);
2178
+ throw e;
2179
+ case 4:
2180
+ return [
2181
+ 2,
2182
+ result
2183
+ ];
2184
+ }
2185
+ });
2186
+ })();
2187
+ }
2188
+ function clearCachedPrompt(promptKey) {
2189
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2190
+ try {
2191
+ // Every version of the prompt goes, pinned entries included: a publish or promote can change what any
2192
+ // of them resolve to. Deleting the current entry mid-iteration is well-defined for a Map iterator, so
2193
+ // no snapshot copy is needed.
2194
+ for(var _iterator = cache.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2195
+ var key = _step.value;
2196
+ if (key.startsWith("".concat(promptKey, ":"))) {
2197
+ cache.delete(key);
2198
+ }
2199
+ }
2200
+ } catch (err) {
2201
+ _didIteratorError = true;
2202
+ _iteratorError = err;
2203
+ } finally{
2204
+ try {
2205
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2206
+ _iterator.return();
2207
+ }
2208
+ } finally{
2209
+ if (_didIteratorError) {
2210
+ throw _iteratorError;
2211
+ }
2212
+ }
2213
+ }
2214
+ }
2215
+ return {
2216
+ loadPromptDefinitions: loadPromptDefinitions,
2217
+ loadPrompt: loadPrompt,
2218
+ resolvePrompt: resolvePrompt,
2219
+ clearCachedPrompt: clearCachedPrompt
2220
+ };
2221
+ }
2222
+
2223
+ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
2224
+ try {
2225
+ var info = gen[key](arg);
2226
+ var value = info.value;
2227
+ } catch (error) {
2228
+ reject(error);
2229
+ return;
2230
+ }
2231
+ if (info.done) {
2232
+ resolve(value);
2233
+ } else {
2234
+ Promise.resolve(value).then(_next, _throw);
2235
+ }
2236
+ }
2237
+ function _async_to_generator$3(fn) {
2238
+ return function() {
2239
+ var self = this, args = arguments;
2240
+ return new Promise(function(resolve, reject) {
2241
+ var gen = fn.apply(self, args);
2242
+ function _next(value) {
2243
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
2244
+ }
2245
+ function _throw(err) {
2246
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
2247
+ }
2248
+ _next(undefined);
2249
+ });
2250
+ };
2251
+ }
2252
+ function _ts_generator$3(thisArg, body) {
2253
+ var f, y, t, _ = {
2254
+ label: 0,
2255
+ sent: function() {
2256
+ if (t[0] & 1) throw t[1];
2257
+ return t[1];
2258
+ },
2259
+ trys: [],
2260
+ ops: []
2261
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
2262
+ return d(g, "next", {
2263
+ value: verb(0)
2264
+ }), d(g, "throw", {
2265
+ value: verb(1)
2266
+ }), d(g, "return", {
2267
+ value: verb(2)
2268
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
2269
+ value: function() {
2270
+ return this;
2271
+ }
2272
+ }), g;
2273
+ function verb(n) {
2274
+ return function(v) {
2275
+ return step([
2276
+ n,
2277
+ v
2278
+ ]);
2279
+ };
2280
+ }
2281
+ function step(op) {
2282
+ if (f) throw new TypeError("Generator is already executing.");
2283
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
2284
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
2285
+ if (y = 0, t) op = [
2286
+ op[0] & 2,
2287
+ t.value
2288
+ ];
2289
+ switch(op[0]){
2290
+ case 0:
2291
+ case 1:
2292
+ t = op;
2293
+ break;
2294
+ case 4:
2295
+ _.label++;
2296
+ return {
2297
+ value: op[1],
2298
+ done: false
2299
+ };
2300
+ case 5:
2301
+ _.label++;
2302
+ y = op[1];
2303
+ op = [
2304
+ 0
2305
+ ];
2306
+ continue;
2307
+ case 7:
2308
+ op = _.ops.pop();
2309
+ _.trys.pop();
2310
+ continue;
2311
+ default:
2312
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
2313
+ _ = 0;
2314
+ continue;
2315
+ }
2316
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
2317
+ _.label = op[1];
2318
+ break;
2319
+ }
2320
+ if (op[0] === 6 && _.label < t[1]) {
2321
+ _.label = t[1];
2322
+ t = op;
2323
+ break;
2324
+ }
2325
+ if (t && _.label < t[2]) {
2326
+ _.label = t[2];
2327
+ _.ops.push(op);
2328
+ break;
2329
+ }
2330
+ if (t[2]) _.ops.pop();
2331
+ _.trys.pop();
2332
+ continue;
2333
+ }
2334
+ op = body.call(thisArg, _);
2335
+ } catch (e) {
2336
+ op = [
2337
+ 6,
2338
+ e
2339
+ ];
2340
+ y = 0;
2341
+ } finally{
2342
+ f = t = 0;
2343
+ }
2344
+ if (op[0] & 5) throw op[1];
2345
+ return {
2346
+ value: op[0] ? op[1] : void 0,
2347
+ done: true
2348
+ };
2349
+ }
2350
+ }
2351
+ /**
2352
+ * Classifies a run task into an outcome.
2353
+ *
2354
+ * `AWAITING_ASYNC_TOOLS` reports as `queued`: from the caller's side it is indistinguishable from
2355
+ * waiting, because it is waiting — just on a tool result rather than on a sweep.
2356
+ *
2357
+ * @param task - The run task, or null when it does not exist.
2358
+ * @returns The outcome.
2359
+ *
2360
+ * @__NO_SIDE_EFFECTS__
2361
+ */ function openRouterRunTaskOutcome(task) {
2362
+ var result;
2363
+ if (task == null) {
2364
+ result = 'missing';
2365
+ } else {
2366
+ switch(task.s){
2367
+ case OpenRouterRunTaskState.COMPLETE:
2368
+ result = 'complete';
2369
+ break;
2370
+ case OpenRouterRunTaskState.FAILED:
2371
+ result = 'failure';
2372
+ break;
2373
+ case OpenRouterRunTaskState.QUEUED:
2374
+ case OpenRouterRunTaskState.RUNNING:
2375
+ case OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS:
2376
+ default:
2377
+ result = 'queued';
2378
+ break;
2379
+ }
2380
+ }
2381
+ return result;
2382
+ }
2383
+ /**
2384
+ * Creates a reusable dispatcher for a fixed set of handlers.
2385
+ *
2386
+ * @param handlers - The per-outcome handlers.
2387
+ * @returns A function that dispatches a run task.
2388
+ *
2389
+ * @__NO_SIDE_EFFECTS__
2390
+ */ function handleOpenRouterRunTaskResultFactory(handlers) {
2391
+ return function(task) {
2392
+ return _async_to_generator$3(function() {
2393
+ var outcome, result;
2394
+ return _ts_generator$3(this, function(_state) {
2395
+ switch(_state.label){
2396
+ case 0:
2397
+ outcome = openRouterRunTaskOutcome(task);
2398
+ switch(outcome){
2399
+ case 'complete':
2400
+ return [
2401
+ 3,
2402
+ 1
2403
+ ];
2404
+ case 'queued':
2405
+ return [
2406
+ 3,
2407
+ 3
2408
+ ];
2409
+ case 'failure':
2410
+ return [
2411
+ 3,
2412
+ 5
2413
+ ];
2414
+ case 'missing':
2415
+ return [
2416
+ 3,
2417
+ 7
2418
+ ];
2419
+ }
2420
+ return [
2421
+ 3,
2422
+ 7
2423
+ ];
2424
+ case 1:
2425
+ return [
2426
+ 4,
2427
+ handlers.onComplete(task)
2428
+ ];
2429
+ case 2:
2430
+ result = _state.sent();
2431
+ return [
2432
+ 3,
2433
+ 9
2434
+ ];
2435
+ case 3:
2436
+ return [
2437
+ 4,
2438
+ handlers.onQueued(task)
2439
+ ];
2440
+ case 4:
2441
+ result = _state.sent();
2442
+ return [
2443
+ 3,
2444
+ 9
2445
+ ];
2446
+ case 5:
2447
+ return [
2448
+ 4,
2449
+ handlers.onFailure(task)
2450
+ ];
2451
+ case 6:
2452
+ result = _state.sent();
2453
+ return [
2454
+ 3,
2455
+ 9
2456
+ ];
2457
+ case 7:
2458
+ return [
2459
+ 4,
2460
+ handlers.onMissing()
2461
+ ];
2462
+ case 8:
2463
+ result = _state.sent();
2464
+ return [
2465
+ 3,
2466
+ 9
2467
+ ];
2468
+ case 9:
2469
+ return [
2470
+ 2,
2471
+ result
2472
+ ];
2473
+ }
2474
+ });
2475
+ })();
2476
+ };
2477
+ }
2478
+
2479
+ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
2480
+ try {
2481
+ var info = gen[key](arg);
2482
+ var value = info.value;
2483
+ } catch (error) {
2484
+ reject(error);
2485
+ return;
2486
+ }
2487
+ if (info.done) {
2488
+ resolve(value);
2489
+ } else {
2490
+ Promise.resolve(value).then(_next, _throw);
2491
+ }
2492
+ }
2493
+ function _async_to_generator$2(fn) {
2494
+ return function() {
2495
+ var self = this, args = arguments;
2496
+ return new Promise(function(resolve, reject) {
2497
+ var gen = fn.apply(self, args);
2498
+ function _next(value) {
2499
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
2500
+ }
2501
+ function _throw(err) {
2502
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
2503
+ }
2504
+ _next(undefined);
2505
+ });
2506
+ };
2507
+ }
2508
+ function _define_property$1(obj, key, value) {
2509
+ if (key in obj) {
2510
+ Object.defineProperty(obj, key, {
2511
+ value: value,
2512
+ enumerable: true,
2513
+ configurable: true,
2514
+ writable: true
2515
+ });
2516
+ } else {
2517
+ obj[key] = value;
2518
+ }
2519
+ return obj;
2520
+ }
2521
+ function _object_spread$1(target) {
2522
+ for(var i = 1; i < arguments.length; i++){
2523
+ var source = arguments[i] != null ? arguments[i] : {};
2524
+ var ownKeys = Object.keys(source);
2525
+ if (typeof Object.getOwnPropertySymbols === "function") {
2526
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
2527
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
2528
+ }));
2529
+ }
2530
+ ownKeys.forEach(function(key) {
2531
+ _define_property$1(target, key, source[key]);
2532
+ });
2533
+ }
2534
+ return target;
2535
+ }
2536
+ function ownKeys$1(object, enumerableOnly) {
2537
+ var keys = Object.keys(object);
2538
+ if (Object.getOwnPropertySymbols) {
2539
+ var symbols = Object.getOwnPropertySymbols(object);
2540
+ keys.push.apply(keys, symbols);
2541
+ }
2542
+ return keys;
2543
+ }
2544
+ function _object_spread_props$1(target, source) {
2545
+ source = source != null ? source : {};
2546
+ if (Object.getOwnPropertyDescriptors) {
2547
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
2548
+ } else {
2549
+ ownKeys$1(Object(source)).forEach(function(key) {
2550
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
2551
+ });
2552
+ }
2553
+ return target;
2554
+ }
2555
+ function _ts_generator$2(thisArg, body) {
2556
+ var f, y, t, _ = {
2557
+ label: 0,
2558
+ sent: function() {
2559
+ if (t[0] & 1) throw t[1];
2560
+ return t[1];
2561
+ },
2562
+ trys: [],
2563
+ ops: []
2564
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
2565
+ return d(g, "next", {
2566
+ value: verb(0)
2567
+ }), d(g, "throw", {
2568
+ value: verb(1)
2569
+ }), d(g, "return", {
2570
+ value: verb(2)
2571
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
2572
+ value: function() {
2573
+ return this;
2574
+ }
2575
+ }), g;
2576
+ function verb(n) {
2577
+ return function(v) {
2578
+ return step([
2579
+ n,
2580
+ v
2581
+ ]);
2582
+ };
2583
+ }
2584
+ function step(op) {
2585
+ if (f) throw new TypeError("Generator is already executing.");
2586
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
2587
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
2588
+ if (y = 0, t) op = [
2589
+ op[0] & 2,
2590
+ t.value
2591
+ ];
2592
+ switch(op[0]){
2593
+ case 0:
2594
+ case 1:
2595
+ t = op;
2596
+ break;
2597
+ case 4:
2598
+ _.label++;
2599
+ return {
2600
+ value: op[1],
2601
+ done: false
2602
+ };
2603
+ case 5:
2604
+ _.label++;
2605
+ y = op[1];
2606
+ op = [
2607
+ 0
2608
+ ];
2609
+ continue;
2610
+ case 7:
2611
+ op = _.ops.pop();
2612
+ _.trys.pop();
2613
+ continue;
2614
+ default:
2615
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
2616
+ _ = 0;
2617
+ continue;
2618
+ }
2619
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
2620
+ _.label = op[1];
2621
+ break;
2622
+ }
2623
+ if (op[0] === 6 && _.label < t[1]) {
2624
+ _.label = t[1];
2625
+ t = op;
2626
+ break;
2627
+ }
2628
+ if (t && _.label < t[2]) {
2629
+ _.label = t[2];
2630
+ _.ops.push(op);
2631
+ break;
2632
+ }
2633
+ if (t[2]) _.ops.pop();
2634
+ _.trys.pop();
2635
+ continue;
2636
+ }
2637
+ op = body.call(thisArg, _);
2638
+ } catch (e) {
2639
+ op = [
2640
+ 6,
2641
+ e
2642
+ ];
2643
+ y = 0;
2644
+ } finally{
2645
+ f = t = 0;
2646
+ }
2647
+ if (op[0] & 5) throw op[1];
2648
+ return {
2649
+ value: op[0] ? op[1] : void 0,
2650
+ done: true
2651
+ };
2652
+ }
2653
+ }
2654
+ /**
2655
+ * Maps a run task state to the SDK's conversation status.
2656
+ *
2657
+ * @param state - The run task state.
2658
+ * @returns The conversation status.
2659
+ *
2660
+ * @__NO_SIDE_EFFECTS__
2661
+ */ function conversationStatusForOpenRouterRunTaskState(state) {
2662
+ var result;
2663
+ switch(state){
2664
+ case OpenRouterRunTaskState.COMPLETE:
2665
+ result = 'complete';
2666
+ break;
2667
+ case OpenRouterRunTaskState.FAILED:
2668
+ result = 'interrupted';
2669
+ break;
2670
+ case OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS:
2671
+ // The SDK's vocabulary for "paused holding tool calls we did not execute ourselves".
2672
+ result = 'awaiting_approval';
2673
+ break;
2674
+ case OpenRouterRunTaskState.RUNNING:
2675
+ result = 'in_progress';
2676
+ break;
2677
+ case OpenRouterRunTaskState.QUEUED:
2678
+ default:
2679
+ result = 'in_progress';
2680
+ break;
2681
+ }
2682
+ return result;
2683
+ }
2684
+ /**
2685
+ * Maps a conversation status back to the run task state to persist.
2686
+ *
2687
+ * @param status - The conversation status.
2688
+ * @param hasPendingToolCalls - Whether the state carries tool calls this process cannot resolve.
2689
+ * @returns The run task state.
2690
+ *
2691
+ * @__NO_SIDE_EFFECTS__
2692
+ */ function openRouterRunTaskStateForConversationStatus(status, hasPendingToolCalls) {
2693
+ var result;
2694
+ if (hasPendingToolCalls) {
2695
+ // Pending calls win over the reported status: whatever the SDK called it, the run cannot proceed
2696
+ // until something outside this process supplies those results.
2697
+ result = OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS;
2698
+ } else {
2699
+ switch(status){
2700
+ case 'complete':
2701
+ result = OpenRouterRunTaskState.COMPLETE;
2702
+ break;
2703
+ case 'awaiting_approval':
2704
+ result = OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS;
2705
+ break;
2706
+ case 'interrupted':
2707
+ case 'in_progress':
2708
+ default:
2709
+ result = OpenRouterRunTaskState.RUNNING;
2710
+ break;
2711
+ }
2712
+ }
2713
+ return result;
2714
+ }
2715
+ /**
2716
+ * Builds a {@link ConversationState} from a run task.
2717
+ *
2718
+ * `updatedAt` is derived rather than stored: the run task's existing timestamps already order the
2719
+ * lifecycle (`fat` > `lat` > `sat` > `qat`), and the SDK uses the value informationally.
2720
+ *
2721
+ * @param key - The run task key, which is the conversation id.
2722
+ * @param task - The run task.
2723
+ * @returns The conversation state.
2724
+ *
2725
+ * @__NO_SIDE_EFFECTS__
2726
+ */ function conversationStateForOpenRouterRunTask(key, task) {
2727
+ var _ref, _ref1, _task_fat, _task_msg, _task_ptc, _task_utr;
2728
+ var updatedAt = (_ref = (_ref1 = (_task_fat = task.fat) !== null && _task_fat !== void 0 ? _task_fat : task.lat) !== null && _ref1 !== void 0 ? _ref1 : task.sat) !== null && _ref !== void 0 ? _ref : task.qat;
2729
+ return {
2730
+ id: key,
2731
+ messages: (_task_msg = task.msg) !== null && _task_msg !== void 0 ? _task_msg : [],
2732
+ pendingToolCalls: ((_task_ptc = task.ptc) !== null && _task_ptc !== void 0 ? _task_ptc : []).map(function(call) {
2733
+ return {
2734
+ id: call.callId,
2735
+ name: call.name,
2736
+ arguments: call.arguments
2737
+ };
2738
+ }),
2739
+ unsentToolResults: ((_task_utr = task.utr) !== null && _task_utr !== void 0 ? _task_utr : []).map(function(result) {
2740
+ var _result_error;
2741
+ return {
2742
+ callId: result.callId,
2743
+ name: result.name,
2744
+ output: result.output,
2745
+ error: (_result_error = result.error) !== null && _result_error !== void 0 ? _result_error : undefined
2746
+ };
2747
+ }),
2748
+ status: conversationStatusForOpenRouterRunTaskState(task.s),
2749
+ createdAt: task.qat.getTime(),
2750
+ updatedAt: updatedAt.getTime()
2751
+ };
2752
+ }
2753
+ /**
2754
+ * Builds the run task update for a conversation state.
2755
+ *
2756
+ * @param state - The conversation state to persist.
2757
+ * @returns The fields to write.
2758
+ *
2759
+ * @__NO_SIDE_EFFECTS__
2760
+ */ function openRouterRunTaskUpdateForConversationState(state) {
2761
+ var _state_pendingToolCalls, _state_messages, _state_unsentToolResults;
2762
+ var pendingToolCalls = (_state_pendingToolCalls = state.pendingToolCalls) !== null && _state_pendingToolCalls !== void 0 ? _state_pendingToolCalls : [];
2763
+ return {
2764
+ s: openRouterRunTaskStateForConversationStatus(state.status, pendingToolCalls.length > 0),
2765
+ // Attachment payloads are stripped on the way in. They are resolved per attempt — a signed url has
2766
+ // already expired and inline base64 is the whole file — and `msg` is a Firestore field with a 1 MiB
2767
+ // document budget behind it. `load()` re-points the stripped parts, so nothing is lost.
2768
+ msg: openRouterConversationValueForFirestore(openRouterMessagesWithoutFileAttachmentData((_state_messages = state.messages) !== null && _state_messages !== void 0 ? _state_messages : [])),
2769
+ ptc: pendingToolCalls.map(function(call) {
2770
+ var _openRouterConversationValueForFirestore;
2771
+ return {
2772
+ callId: call.id,
2773
+ name: call.name,
2774
+ taskId: call.id,
2775
+ arguments: (_openRouterConversationValueForFirestore = openRouterConversationValueForFirestore(call.arguments)) !== null && _openRouterConversationValueForFirestore !== void 0 ? _openRouterConversationValueForFirestore : null
2776
+ };
2777
+ }),
2778
+ utr: ((_state_unsentToolResults = state.unsentToolResults) !== null && _state_unsentToolResults !== void 0 ? _state_unsentToolResults : []).map(function(result) {
2779
+ var _openRouterConversationValueForFirestore, _result_error;
2780
+ return {
2781
+ callId: result.callId,
2782
+ name: result.name,
2783
+ output: (_openRouterConversationValueForFirestore = openRouterConversationValueForFirestore(result.output)) !== null && _openRouterConversationValueForFirestore !== void 0 ? _openRouterConversationValueForFirestore : null,
2784
+ error: (_result_error = result.error) !== null && _result_error !== void 0 ? _result_error : null
2785
+ };
2786
+ })
2787
+ };
2788
+ }
2789
+ /**
2790
+ * Strips `undefined` out of a value on its way into Firestore, at ANY DEPTH.
2791
+ *
2792
+ * Conversation state is whatever the SDK hands back, arbitrarily nested, and its response items carry
2793
+ * explicit `undefined`s for absent optional fields at every level. Firestore rejects `undefined` outright,
2794
+ * so persisting one unfiltered fails the whole write — and it fails inside the SDK's `saveStateSafely`,
2795
+ * which surfaces as an opaque "Failed to persist conversation state" rather than as the run-task write it
2796
+ * actually is.
2797
+ *
2798
+ * A JSON round-trip rather than `copyValueWithoutUndefinedValues` (which filters just as deeply, and is
2799
+ * what the run task converter's passthrough-JSON fields use): the round-trip additionally flattens
2800
+ * anything that is not wire json — a `Date`, a class instance with a `toJSON` — which is correct here
2801
+ * precisely because this data IS json. It came off the wire, and `load()` hands it straight back to the
2802
+ * SDK expecting the same shapes. The converter's fields, by contrast, must leave a `Date`/`Timestamp`
2803
+ * intact for Firestore.
2804
+ *
2805
+ * @param value - The value to sanitize.
2806
+ * @returns The value with every `undefined` removed.
2807
+ *
2808
+ * @__NO_SIDE_EFFECTS__
2809
+ */ function openRouterConversationValueForFirestore(value) {
2810
+ // NOT `structuredClone`. It PRESERVES `undefined`-valued keys, which is the one thing this function
2811
+ // exists to remove — so `unicorn/prefer-structured-clone`'s autofix would silently break it.
2812
+ // eslint-disable-next-line unicorn/prefer-structured-clone
2813
+ return value === undefined ? value : JSON.parse(JSON.stringify(value));
2814
+ }
2815
+ /**
2816
+ * Creates a {@link StateAccessor} backed by a run task document.
2817
+ *
2818
+ * This is the persistent backend the SDK's docs ask for — its own example is a `Map`, with the note to
2819
+ * "implement `StateAccessor` with a persistent backend". Because OpenRouter allocates no conversation
2820
+ * id (and rejects `previous_response_id` outright), the conversation id is ours: the run task key.
2821
+ *
2822
+ * A single-shot run simply never populates `msg` / `ptc` / `utr`, so nothing is paid for not using it.
2823
+ *
2824
+ * @param document - The run task document to read and write.
2825
+ * @param config - The initial conversation and this attempt's attached files.
2826
+ * @returns The state accessor.
2827
+ */ function firestoreOpenRouterStateAccessor(document, config) {
2828
+ var _ref = config !== null && config !== void 0 ? config : {}, initialMessages = _ref.initialMessages, attachedFiles = _ref.attachedFiles;
2829
+ return {
2830
+ load: function load() {
2831
+ return _async_to_generator$2(function() {
2832
+ var task, result, _task_msg, stored, messages;
2833
+ return _ts_generator$2(this, function(_state) {
2834
+ switch(_state.label){
2835
+ case 0:
2836
+ return [
2837
+ 4,
2838
+ document.snapshotData()
2839
+ ];
2840
+ case 1:
2841
+ task = _state.sent();
2842
+ if (task != null) {
2843
+ stored = (_task_msg = task.msg) !== null && _task_msg !== void 0 ? _task_msg : [];
2844
+ messages = openRouterMessagesWithFreshFileAttachments(stored.length > 0 ? stored : initialMessages !== null && initialMessages !== void 0 ? initialMessages : [], attachedFiles);
2845
+ result = conversationStateForOpenRouterRunTask(document.id, _object_spread_props$1(_object_spread$1({}, task), {
2846
+ msg: messages
2847
+ }));
2848
+ }
2849
+ return [
2850
+ 2,
2851
+ result !== null && result !== void 0 ? result : null
2852
+ ];
2853
+ }
2854
+ });
2855
+ })();
2856
+ },
2857
+ save: function save(state) {
2858
+ return _async_to_generator$2(function() {
2859
+ return _ts_generator$2(this, function(_state) {
2860
+ switch(_state.label){
2861
+ case 0:
2862
+ return [
2863
+ 4,
2864
+ document.update(openRouterRunTaskUpdateForConversationState(state))
2865
+ ];
2866
+ case 1:
2867
+ _state.sent();
2868
+ return [
2869
+ 2
2870
+ ];
2871
+ }
2872
+ });
2873
+ })();
2874
+ }
2875
+ };
2876
+ }
2877
+
2878
+ function _array_like_to_array(arr, len) {
2879
+ if (len == null || len > arr.length) len = arr.length;
2880
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
2881
+ return arr2;
2882
+ }
2883
+ function _array_with_holes(arr) {
2884
+ if (Array.isArray(arr)) return arr;
2885
+ }
2886
+ function _array_without_holes(arr) {
2887
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
2888
+ }
2889
+ function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
2890
+ try {
2891
+ var info = gen[key](arg);
2892
+ var value = info.value;
2893
+ } catch (error) {
2894
+ reject(error);
2895
+ return;
2896
+ }
2897
+ if (info.done) {
2898
+ resolve(value);
2899
+ } else {
2900
+ Promise.resolve(value).then(_next, _throw);
2901
+ }
2902
+ }
2903
+ function _async_to_generator$1(fn) {
2904
+ return function() {
2905
+ var self = this, args = arguments;
2906
+ return new Promise(function(resolve, reject) {
2907
+ var gen = fn.apply(self, args);
2908
+ function _next(value) {
2909
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
2910
+ }
2911
+ function _throw(err) {
2912
+ asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
2913
+ }
2914
+ _next(undefined);
2915
+ });
2916
+ };
2917
+ }
2918
+ function _class_call_check(instance, Constructor) {
2919
+ if (!(instance instanceof Constructor)) {
2920
+ throw new TypeError("Cannot call a class as a function");
2921
+ }
2922
+ }
2923
+ function _define_property(obj, key, value) {
2924
+ if (key in obj) {
2925
+ Object.defineProperty(obj, key, {
2926
+ value: value,
2927
+ enumerable: true,
2928
+ configurable: true,
2929
+ writable: true
2930
+ });
2931
+ } else {
2932
+ obj[key] = value;
2933
+ }
2934
+ return obj;
2935
+ }
2936
+ function _instanceof(left, right) {
2937
+ "@swc/helpers - instanceof";
2938
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
2939
+ return !!right[Symbol.hasInstance](left);
2940
+ } else {
2941
+ return left instanceof right;
2942
+ }
2943
+ }
2944
+ function _iterable_to_array(iter) {
2945
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
2946
+ }
2947
+ function _iterable_to_array_limit(arr, i) {
2948
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
2949
+ if (_i == null) return;
2950
+ var _arr = [];
2951
+ var _n = true;
2952
+ var _d = false;
2953
+ var _s, _e;
2954
+ try {
2955
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
2956
+ _arr.push(_s.value);
2957
+ if (i && _arr.length === i) break;
2958
+ }
2959
+ } catch (err) {
2960
+ _d = true;
2961
+ _e = err;
2962
+ } finally{
2963
+ try {
2964
+ if (!_n && _i["return"] != null) _i["return"]();
2965
+ } finally{
2966
+ if (_d) throw _e;
2967
+ }
2968
+ }
2969
+ return _arr;
2970
+ }
2971
+ function _non_iterable_rest() {
2972
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2973
+ }
2974
+ function _non_iterable_spread() {
2975
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2976
+ }
2977
+ function _object_spread(target) {
2978
+ for(var i = 1; i < arguments.length; i++){
2979
+ var source = arguments[i] != null ? arguments[i] : {};
2980
+ var ownKeys = Object.keys(source);
2981
+ if (typeof Object.getOwnPropertySymbols === "function") {
2982
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
2983
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
2984
+ }));
2985
+ }
2986
+ ownKeys.forEach(function(key) {
2987
+ _define_property(target, key, source[key]);
2988
+ });
2989
+ }
2990
+ return target;
2991
+ }
2992
+ function ownKeys(object, enumerableOnly) {
2993
+ var keys = Object.keys(object);
2994
+ if (Object.getOwnPropertySymbols) {
2995
+ var symbols = Object.getOwnPropertySymbols(object);
2996
+ keys.push.apply(keys, symbols);
2997
+ }
2998
+ return keys;
2999
+ }
3000
+ function _object_spread_props(target, source) {
3001
+ source = source != null ? source : {};
3002
+ if (Object.getOwnPropertyDescriptors) {
3003
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
3004
+ } else {
3005
+ ownKeys(Object(source)).forEach(function(key) {
3006
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
3007
+ });
3008
+ }
3009
+ return target;
3010
+ }
3011
+ function _sliced_to_array(arr, i) {
3012
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
3013
+ }
3014
+ function _to_consumable_array(arr) {
3015
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
3016
+ }
3017
+ function _type_of(obj) {
3018
+ "@swc/helpers - typeof";
3019
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
3020
+ }
3021
+ function _unsupported_iterable_to_array(o, minLen) {
3022
+ if (!o) return;
3023
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
3024
+ var n = Object.prototype.toString.call(o).slice(8, -1);
3025
+ if (n === "Object" && o.constructor) n = o.constructor.name;
3026
+ if (n === "Map" || n === "Set") return Array.from(n);
3027
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
3028
+ }
3029
+ function _ts_generator$1(thisArg, body) {
3030
+ var f, y, t, _ = {
3031
+ label: 0,
3032
+ sent: function() {
3033
+ if (t[0] & 1) throw t[1];
3034
+ return t[1];
3035
+ },
3036
+ trys: [],
3037
+ ops: []
3038
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
3039
+ return d(g, "next", {
3040
+ value: verb(0)
3041
+ }), d(g, "throw", {
3042
+ value: verb(1)
3043
+ }), d(g, "return", {
3044
+ value: verb(2)
3045
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
3046
+ value: function() {
3047
+ return this;
3048
+ }
3049
+ }), g;
3050
+ function verb(n) {
3051
+ return function(v) {
3052
+ return step([
3053
+ n,
3054
+ v
3055
+ ]);
3056
+ };
3057
+ }
3058
+ function step(op) {
3059
+ if (f) throw new TypeError("Generator is already executing.");
3060
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
3061
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
3062
+ if (y = 0, t) op = [
3063
+ op[0] & 2,
3064
+ t.value
3065
+ ];
3066
+ switch(op[0]){
3067
+ case 0:
3068
+ case 1:
3069
+ t = op;
3070
+ break;
3071
+ case 4:
3072
+ _.label++;
3073
+ return {
3074
+ value: op[1],
3075
+ done: false
3076
+ };
3077
+ case 5:
3078
+ _.label++;
3079
+ y = op[1];
3080
+ op = [
3081
+ 0
3082
+ ];
3083
+ continue;
3084
+ case 7:
3085
+ op = _.ops.pop();
3086
+ _.trys.pop();
3087
+ continue;
3088
+ default:
3089
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
3090
+ _ = 0;
3091
+ continue;
3092
+ }
3093
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
3094
+ _.label = op[1];
3095
+ break;
3096
+ }
3097
+ if (op[0] === 6 && _.label < t[1]) {
3098
+ _.label = t[1];
3099
+ t = op;
3100
+ break;
3101
+ }
3102
+ if (t && _.label < t[2]) {
3103
+ _.label = t[2];
3104
+ _.ops.push(op);
3105
+ break;
3106
+ }
3107
+ if (t[2]) _.ops.pop();
3108
+ _.trys.pop();
3109
+ continue;
3110
+ }
3111
+ op = body.call(thisArg, _);
3112
+ } catch (e) {
3113
+ op = [
3114
+ 6,
3115
+ e
3116
+ ];
3117
+ y = 0;
3118
+ } finally{
3119
+ f = t = 0;
3120
+ }
3121
+ if (op[0] & 5) throw op[1];
3122
+ return {
3123
+ value: op[0] ? op[1] : void 0,
3124
+ done: true
3125
+ };
3126
+ }
3127
+ }
3128
+ /**
3129
+ * Default lease duration. A `RUNNING` task whose lease is older than this is reclaimable.
3130
+ *
3131
+ * Comfortably longer than any single inference plus its retries, so a healthy run is never stolen from
3132
+ * itself, and short enough that a crashed sweep's work resumes on the next tick or two.
3133
+ */ var DEFAULT_OPENROUTER_LEASE_DURATION = MS_IN_MINUTE * 10;
3134
+ /**
3135
+ * Default number of attempts before a task is marked FAILED.
3136
+ *
3137
+ * Spent only on a failure {@link isRetryableOpenRouterError} classifies as transient; a deterministic
3138
+ * failure reaches `FAILED` on its first attempt.
3139
+ */ var DEFAULT_OPENROUTER_MAX_ATTEMPTS = 3;
3140
+ /**
3141
+ * Maximum tasks one retention page may delete.
3142
+ *
3143
+ * A page's deletes go out as a single Firestore write batch, and a batch takes at most 500 writes.
3144
+ */ var OPENROUTER_MAX_EXPIRED_RUN_TASK_DELETE_PAGE_SIZE = 500;
3145
+ /**
3146
+ * Manages the app-owned run-task queue: the replacement for OpenAI's `background: true` plus its
3147
+ * server-side job store, neither of which OpenRouter has.
3148
+ */ var OpenRouterRunTaskService = function OpenRouterRunTaskService() {
3149
+ _class_call_check(this, OpenRouterRunTaskService);
3150
+ };
3151
+ /**
3152
+ * Creates an {@link OpenRouterRunTaskService}.
3153
+ *
3154
+ * @param config - The collections, prompt service, client, and execution settings.
3155
+ * @returns The service.
3156
+ */ function openRouterRunTaskService(config) {
3157
+ var collections = config.collections, promptService = config.promptService, client = config.client, storageContext = config.storageContext, envService = config.envService, fileAttachmentMode = config.fileAttachmentMode, maxInlineFileSizeBytes = config.maxInlineFileSizeBytes, tools = config.tools, onTerminalState = config.onTerminalState, signedUrlTtl = config.signedUrlTtl, inputMaxAttempts = config.maxAttempts, inputLeaseDuration = config.leaseDuration;
3158
+ var openRouterRunTaskCollection = collections.openRouterRunTaskCollection;
3159
+ var attachFilesForAttempt = openRouterFileAttachmentResolver({
3160
+ storageContext: storageContext,
3161
+ envService: envService,
3162
+ mode: fileAttachmentMode,
3163
+ signedUrlTtl: signedUrlTtl,
3164
+ maxInlineFileSizeBytes: maxInlineFileSizeBytes
3165
+ });
3166
+ var maxAttempts = inputMaxAttempts !== null && inputMaxAttempts !== void 0 ? inputMaxAttempts : DEFAULT_OPENROUTER_MAX_ATTEMPTS;
3167
+ var defaultLeaseDuration = inputLeaseDuration !== null && inputLeaseDuration !== void 0 ? inputLeaseDuration : DEFAULT_OPENROUTER_LEASE_DURATION;
3168
+ function runTaskDocument(key) {
3169
+ return openRouterRunTaskCollection.documentAccessor().loadDocumentForId(key);
3170
+ }
3171
+ function readRunTask(key) {
3172
+ return _async_to_generator$1(function() {
3173
+ return _ts_generator$1(this, function(_state) {
3174
+ return [
3175
+ 2,
3176
+ runTaskDocument(key).snapshotData()
3177
+ ];
3178
+ });
3179
+ })();
3180
+ }
3181
+ function enqueueRunTask(params) {
3182
+ return _async_to_generator$1(function() {
3183
+ var key, promptKey, version, input, files, configOverrides, continueFrom, restart, document, existing, created, task, resolved, history, _tmp;
3184
+ return _ts_generator$1(this, function(_state) {
3185
+ switch(_state.label){
3186
+ case 0:
3187
+ key = params.key, promptKey = params.promptKey, version = params.version, input = params.input, files = params.files, configOverrides = params.configOverrides, continueFrom = params.continueFrom, restart = params.restart;
3188
+ document = runTaskDocument(key);
3189
+ return [
3190
+ 4,
3191
+ document.snapshotData()
3192
+ ];
3193
+ case 1:
3194
+ existing = _state.sent();
3195
+ if (!(existing != null && !restart)) return [
3196
+ 3,
3197
+ 2
3198
+ ];
3199
+ created = false;
3200
+ task = existing;
3201
+ return [
3202
+ 3,
3203
+ 8
3204
+ ];
3205
+ case 2:
3206
+ return [
3207
+ 4,
3208
+ promptService.resolvePrompt({
3209
+ promptKey: promptKey,
3210
+ version: version
3211
+ })
3212
+ ];
3213
+ case 3:
3214
+ resolved = _state.sent();
3215
+ if (!(continueFrom == null)) return [
3216
+ 3,
3217
+ 4
3218
+ ];
3219
+ _tmp = undefined;
3220
+ return [
3221
+ 3,
3222
+ 6
3223
+ ];
3224
+ case 4:
3225
+ return [
3226
+ 4,
3227
+ historyForRunTask(continueFrom)
3228
+ ];
3229
+ case 5:
3230
+ _tmp = _state.sent();
3231
+ _state.label = 6;
3232
+ case 6:
3233
+ history = _tmp;
3234
+ task = {
3235
+ s: OpenRouterRunTaskState.QUEUED,
3236
+ // Write-once from here on: the retention ceiling and the claim order both read it as the task's age.
3237
+ qat: new Date(),
3238
+ at: 0,
3239
+ pk: promptKey,
3240
+ pv: resolved.version,
3241
+ in: openRouterInputMessages(input),
3242
+ fp: files,
3243
+ co: configOverrides,
3244
+ msg: history
3245
+ };
3246
+ created = true;
3247
+ return [
3248
+ 4,
3249
+ document.accessor.set(task)
3250
+ ];
3251
+ case 7:
3252
+ _state.sent();
3253
+ _state.label = 8;
3254
+ case 8:
3255
+ return [
3256
+ 2,
3257
+ {
3258
+ key: key,
3259
+ document: document,
3260
+ created: created,
3261
+ task: task
3262
+ }
3263
+ ];
3264
+ }
3265
+ });
3266
+ })();
3267
+ }
3268
+ function historyForRunTask(key) {
3269
+ return _async_to_generator$1(function() {
3270
+ var prior, result, _prior_in, messages;
3271
+ return _ts_generator$1(this, function(_state) {
3272
+ switch(_state.label){
3273
+ case 0:
3274
+ return [
3275
+ 4,
3276
+ readRunTask(key)
3277
+ ];
3278
+ case 1:
3279
+ prior = _state.sent();
3280
+ if (prior != null) {
3281
+ // Prefer the recorded conversation history; a single-shot prior run has none, in which case its
3282
+ // input plus its output text is the history.
3283
+ if (prior.msg != null && prior.msg.length > 0) {
3284
+ result = prior.msg;
3285
+ } else {
3286
+ messages = _to_consumable_array((_prior_in = prior.in) !== null && _prior_in !== void 0 ? _prior_in : []);
3287
+ if (prior.o) {
3288
+ messages.push({
3289
+ role: 'assistant',
3290
+ content: prior.o
3291
+ });
3292
+ }
3293
+ result = messages.length > 0 ? messages : undefined;
3294
+ }
3295
+ }
3296
+ return [
3297
+ 2,
3298
+ result
3299
+ ];
3300
+ }
3301
+ });
3302
+ })();
3303
+ }
3304
+ function claimNextRunTasks(params) {
3305
+ return _async_to_generator$1(function() {
3306
+ var pageLimit, leaseOwner, leaseDuration, now, leaseCutoff, _ref, runnable, reclaimable, candidates, claimed;
3307
+ return _ts_generator$1(this, function(_state) {
3308
+ switch(_state.label){
3309
+ case 0:
3310
+ pageLimit = params.limit, leaseOwner = params.leaseOwner, leaseDuration = params.leaseDuration;
3311
+ now = new Date();
3312
+ leaseCutoff = addMilliseconds(now, -(leaseDuration !== null && leaseDuration !== void 0 ? leaseDuration : defaultLeaseDuration));
3313
+ return [
3314
+ 4,
3315
+ Promise.all([
3316
+ openRouterRunTaskCollection.queryDocument(openRouterRunTasksRunnableQuery({
3317
+ limit: pageLimit
3318
+ })).getDocs(),
3319
+ openRouterRunTaskCollection.queryDocument(openRouterRunTasksReclaimableQuery({
3320
+ limit: pageLimit,
3321
+ leaseCutoff: leaseCutoff
3322
+ })).getDocs()
3323
+ ])
3324
+ ];
3325
+ case 1:
3326
+ _ref = _sliced_to_array.apply(void 0, [
3327
+ _state.sent(),
3328
+ 2
3329
+ ]), runnable = _ref[0], reclaimable = _ref[1];
3330
+ // A task can appear in both pages, so the merged list is de-duplicated by id. First occurrence wins,
3331
+ // which keeps the runnable page's queue order ahead of the reclaimable page's lease order.
3332
+ candidates = filterUniqueValues(mergeArrays([
3333
+ runnable,
3334
+ reclaimable
3335
+ ]), function(x) {
3336
+ return x.id;
3337
+ }).slice(0, pageLimit);
3338
+ return [
3339
+ 4,
3340
+ Promise.all(candidates.map(function(document) {
3341
+ return claimRunTask(document, leaseOwner, now, leaseCutoff);
3342
+ }))
3343
+ ];
3344
+ case 2:
3345
+ claimed = _state.sent();
3346
+ return [
3347
+ 2,
3348
+ filterMaybeArrayValues(claimed)
3349
+ ];
3350
+ }
3351
+ });
3352
+ })();
3353
+ }
3354
+ function deleteExpiredRunTasks(params) {
3355
+ return _async_to_generator$1(function() {
3356
+ var inputLimit, before, pageLimit, cutoff, documents, keys, writeBatch, writeBatchAccessor;
3357
+ return _ts_generator$1(this, function(_state) {
3358
+ switch(_state.label){
3359
+ case 0:
3360
+ inputLimit = params.limit, before = params.before;
3361
+ pageLimit = Math.min(inputLimit, OPENROUTER_MAX_EXPIRED_RUN_TASK_DELETE_PAGE_SIZE);
3362
+ cutoff = before !== null && before !== void 0 ? before : addMilliseconds(new Date(), -OPENROUTER_RUN_TASK_MAX_AGE);
3363
+ return [
3364
+ 4,
3365
+ openRouterRunTaskCollection.queryDocument(openRouterRunTasksExpiredQuery({
3366
+ before: cutoff,
3367
+ limit: pageLimit
3368
+ })).getDocs()
3369
+ ];
3370
+ case 1:
3371
+ documents = _state.sent();
3372
+ keys = documents.map(function(x) {
3373
+ return x.id;
3374
+ });
3375
+ if (!(documents.length > 0)) return [
3376
+ 3,
3377
+ 4
3378
+ ];
3379
+ // One write batch per page rather than N loose deletes: a page either goes away or it does not, and
3380
+ // one round trip replaces up to 500.
3381
+ writeBatch = openRouterRunTaskCollection.firestoreContext.batch();
3382
+ writeBatchAccessor = openRouterRunTaskCollection.documentAccessorForWriteBatch(writeBatch);
3383
+ return [
3384
+ 4,
3385
+ Promise.all(documents.map(function(document) {
3386
+ return writeBatchAccessor.loadDocumentFrom(document).accessor.delete();
3387
+ }))
3388
+ ];
3389
+ case 2:
3390
+ _state.sent();
3391
+ return [
3392
+ 4,
3393
+ writeBatch.commit()
3394
+ ];
3395
+ case 3:
3396
+ _state.sent();
3397
+ _state.label = 4;
3398
+ case 4:
3399
+ return [
3400
+ 2,
3401
+ {
3402
+ deleted: keys.length,
3403
+ keys: keys
3404
+ }
3405
+ ];
3406
+ }
3407
+ });
3408
+ })();
3409
+ }
3410
+ function claimRunTask(document, leaseOwner, now, leaseCutoff) {
3411
+ return _async_to_generator$1(function() {
3412
+ return _ts_generator$1(this, function(_state) {
3413
+ return [
3414
+ 2,
3415
+ openRouterRunTaskCollection.firestoreContext.runTransaction(function(transaction) {
3416
+ return _async_to_generator$1(function() {
3417
+ var transactionDocument, task, result;
3418
+ return _ts_generator$1(this, function(_state) {
3419
+ switch(_state.label){
3420
+ case 0:
3421
+ transactionDocument = runTaskDocumentInTransaction(document, transaction);
3422
+ return [
3423
+ 4,
3424
+ transactionDocument.snapshotData()
3425
+ ];
3426
+ case 1:
3427
+ task = _state.sent();
3428
+ if (!(task != null && isOpenRouterRunTaskClaimable(task, leaseCutoff))) return [
3429
+ 3,
3430
+ 3
3431
+ ];
3432
+ return [
3433
+ 4,
3434
+ transactionDocument.update({
3435
+ s: OpenRouterRunTaskState.RUNNING,
3436
+ sat: now,
3437
+ lat: now,
3438
+ lo: leaseOwner,
3439
+ at: task.at + 1
3440
+ })
3441
+ ];
3442
+ case 2:
3443
+ _state.sent();
3444
+ result = document;
3445
+ _state.label = 3;
3446
+ case 3:
3447
+ return [
3448
+ 2,
3449
+ result
3450
+ ];
3451
+ }
3452
+ });
3453
+ })();
3454
+ })
3455
+ ];
3456
+ });
3457
+ })();
3458
+ }
3459
+ function runTaskDocumentInTransaction(document, transaction) {
3460
+ return openRouterRunTaskCollection.documentAccessorForTransaction(transaction).loadDocumentFrom(document);
3461
+ }
3462
+ function executeRunTask(document) {
3463
+ return _async_to_generator$1(function() {
3464
+ var key, task, executionResult, e;
3465
+ return _ts_generator$1(this, function(_state) {
3466
+ switch(_state.label){
3467
+ case 0:
3468
+ key = document.id;
3469
+ return [
3470
+ 4,
3471
+ document.snapshotData()
3472
+ ];
3473
+ case 1:
3474
+ task = _state.sent();
3475
+ if (!(task == null)) return [
3476
+ 3,
3477
+ 2
3478
+ ];
3479
+ executionResult = {
3480
+ key: key,
3481
+ state: OpenRouterRunTaskState.FAILED,
3482
+ error: new Error('The run task no longer exists.')
3483
+ };
3484
+ return [
3485
+ 3,
3486
+ 6
3487
+ ];
3488
+ case 2:
3489
+ _state.trys.push([
3490
+ 2,
3491
+ 4,
3492
+ ,
3493
+ 6
3494
+ ]);
3495
+ return [
3496
+ 4,
3497
+ executeRunTaskData(document, task)
3498
+ ];
3499
+ case 3:
3500
+ executionResult = _state.sent();
3501
+ return [
3502
+ 3,
3503
+ 6
3504
+ ];
3505
+ case 4:
3506
+ e = _state.sent();
3507
+ return [
3508
+ 4,
3509
+ document.accessor.exists()
3510
+ ];
3511
+ case 5:
3512
+ // A task deleted mid-flight by the retention sweep is the expected cause: every write in
3513
+ // executeRunTaskData goes through `document.update()`, which throws NOT_FOUND on a deleted document —
3514
+ // including the write recordFailure() makes while handling the first throw, which is outside any try
3515
+ // and would otherwise reject the whole sweep and discard every result already collected.
3516
+ //
3517
+ // The existence re-read is what keeps this from swallowing real defects: anything thrown while the
3518
+ // document is still there is rethrown untouched.
3519
+ if (_state.sent()) {
3520
+ throw e;
3521
+ }
3522
+ executionResult = {
3523
+ key: key,
3524
+ state: OpenRouterRunTaskState.FAILED,
3525
+ error: e
3526
+ };
3527
+ return [
3528
+ 3,
3529
+ 6
3530
+ ];
3531
+ case 6:
3532
+ if (!(onTerminalState != null && isOpenRouterRunTaskStateTerminal(executionResult.state))) return [
3533
+ 3,
3534
+ 8
3535
+ ];
3536
+ return [
3537
+ 4,
3538
+ onTerminalState(document, executionResult)
3539
+ ];
3540
+ case 7:
3541
+ _state.sent();
3542
+ _state.label = 8;
3543
+ case 8:
3544
+ return [
3545
+ 2,
3546
+ executionResult
3547
+ ];
3548
+ }
3549
+ });
3550
+ })();
3551
+ }
3552
+ function executeRunTaskData(document, task) {
3553
+ return _async_to_generator$1(function() {
3554
+ var key, executionResult, resolved, attachedFiles, hasTools, request, result, afterCall, _tmp, pausedForTools, finishedAt, e, failure;
3555
+ return _ts_generator$1(this, function(_state) {
3556
+ switch(_state.label){
3557
+ case 0:
3558
+ key = document.id;
3559
+ _state.label = 1;
3560
+ case 1:
3561
+ _state.trys.push([
3562
+ 1,
3563
+ 16,
3564
+ ,
3565
+ 18
3566
+ ]);
3567
+ return [
3568
+ 4,
3569
+ promptService.resolvePrompt({
3570
+ promptKey: task.pk,
3571
+ version: task.pv
3572
+ })
3573
+ ];
3574
+ case 2:
3575
+ resolved = _state.sent();
3576
+ return [
3577
+ 4,
3578
+ attachFilesForAttempt(task.fp)
3579
+ ];
3580
+ case 3:
3581
+ attachedFiles = _state.sent();
3582
+ hasTools = tools != null && tools.length > 0;
3583
+ request = openRouterPromptRequest({
3584
+ prompt: resolved,
3585
+ input: task.in,
3586
+ overrides: task.co,
3587
+ files: attachedFiles,
3588
+ fileAnnotations: task.fa,
3589
+ // With tools in play the conversation lives in the state accessor, which appends to it across
3590
+ // turns; passing it here as well would send every prior turn twice.
3591
+ history: hasTools ? undefined : task.msg,
3592
+ trace: {
3593
+ runTaskKey: key
3594
+ }
3595
+ });
3596
+ if (!hasTools) return [
3597
+ 3,
3598
+ 5
3599
+ ];
3600
+ return [
3601
+ 4,
3602
+ appendDeferredToolResultsToConversation(document, task)
3603
+ ];
3604
+ case 4:
3605
+ _state.sent();
3606
+ _state.label = 5;
3607
+ case 5:
3608
+ return [
3609
+ 4,
3610
+ callModelForOpenRouterRequest({
3611
+ client: client,
3612
+ // The whole conversation is supplied through the state accessor, so the request carries no input
3613
+ // of its own — the SDK appends `input` to the loaded state, and the seeded state already is it.
3614
+ request: hasTools ? _object_spread_props(_object_spread({}, request), {
3615
+ input: []
3616
+ }) : request,
3617
+ tools: tools !== null && tools !== void 0 ? tools : undefined,
3618
+ // The state accessor is only wired when tools are in play. For a single-shot run it would write
3619
+ // conversation history nobody reads, and on a doc whose state the runner is about to set anyway.
3620
+ state: hasTools ? firestoreOpenRouterStateAccessor(document, {
3621
+ initialMessages: request.input,
3622
+ attachedFiles: attachedFiles
3623
+ }) : undefined
3624
+ })
3625
+ ];
3626
+ case 6:
3627
+ result = _state.sent();
3628
+ if (!hasTools) return [
3629
+ 3,
3630
+ 8
3631
+ ];
3632
+ return [
3633
+ 4,
3634
+ document.snapshotData()
3635
+ ];
3636
+ case 7:
3637
+ _tmp = _state.sent();
3638
+ return [
3639
+ 3,
3640
+ 9
3641
+ ];
3642
+ case 8:
3643
+ _tmp = task;
3644
+ _state.label = 9;
3645
+ case 9:
3646
+ afterCall = _tmp;
3647
+ pausedForTools = (afterCall === null || afterCall === void 0 ? void 0 : afterCall.s) === OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS;
3648
+ finishedAt = new Date();
3649
+ if (!pausedForTools) return [
3650
+ 3,
3651
+ 11
3652
+ ];
3653
+ return [
3654
+ 4,
3655
+ document.update({
3656
+ lat: null,
3657
+ lo: null
3658
+ })
3659
+ ];
3660
+ case 10:
3661
+ _state.sent();
3662
+ executionResult = {
3663
+ key: key,
3664
+ state: OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS,
3665
+ result: result
3666
+ };
3667
+ return [
3668
+ 3,
3669
+ 15
3670
+ ];
3671
+ case 11:
3672
+ if (!(result.error == null)) return [
3673
+ 3,
3674
+ 13
3675
+ ];
3676
+ return [
3677
+ 4,
3678
+ document.update({
3679
+ s: OpenRouterRunTaskState.COMPLETE,
3680
+ fat: finishedAt,
3681
+ o: result.outputText,
3682
+ j: result.outputJson,
3683
+ // Appended rather than replaced: a retried task produced real generations on its earlier attempts
3684
+ // too, and those are exactly what an audit of a flaky run needs.
3685
+ gi: concatArraysUnique(task.gi, result.generationIds),
3686
+ u: result.usage,
3687
+ e: null,
3688
+ lat: null,
3689
+ lo: null
3690
+ })
3691
+ ];
3692
+ case 12:
3693
+ _state.sent();
3694
+ executionResult = {
3695
+ key: key,
3696
+ state: OpenRouterRunTaskState.COMPLETE,
3697
+ result: result
3698
+ };
3699
+ return [
3700
+ 3,
3701
+ 15
3702
+ ];
3703
+ case 13:
3704
+ return [
3705
+ 4,
3706
+ recordFailure({
3707
+ document: document,
3708
+ task: task,
3709
+ error: result.error,
3710
+ cause: result.error,
3711
+ at: finishedAt,
3712
+ result: result
3713
+ })
3714
+ ];
3715
+ case 14:
3716
+ executionResult = _state.sent();
3717
+ _state.label = 15;
3718
+ case 15:
3719
+ return [
3720
+ 3,
3721
+ 18
3722
+ ];
3723
+ case 16:
3724
+ e = _state.sent();
3725
+ return [
3726
+ 4,
3727
+ recordFailure({
3728
+ document: document,
3729
+ task: task,
3730
+ error: {
3731
+ code: openRouterErrorCode(e),
3732
+ message: openRouterErrorMessage(e)
3733
+ },
3734
+ cause: e,
3735
+ at: new Date()
3736
+ })
3737
+ ];
3738
+ case 17:
3739
+ failure = _state.sent();
3740
+ executionResult = _object_spread_props(_object_spread({}, failure), {
3741
+ error: e
3742
+ });
3743
+ return [
3744
+ 3,
3745
+ 18
3746
+ ];
3747
+ case 18:
3748
+ return [
3749
+ 2,
3750
+ executionResult
3751
+ ];
3752
+ }
3753
+ });
3754
+ })();
3755
+ }
3756
+ /**
3757
+ * Folds resolved deferred-tool results into the persisted conversation, so the resumed call sends the
3758
+ * model the answers it was waiting on.
3759
+ *
3760
+ * Done here rather than through the SDK because `@openrouter/sdk@1.2.x` has no route back in for a
3761
+ * result produced by another process: its only resume path re-runs the tool locally (a manual tool has
3762
+ * no `execute`) or rejects it. Appending the `function_call_output` items to the conversation and
3763
+ * re-sending it is the same thing the SDK would have put on the wire, minus the API it does not have.
3764
+ *
3765
+ * A no-op unless every pending call has a recorded result — a partially-resolved run has nothing new
3766
+ * to say and must stay parked.
3767
+ */ function appendDeferredToolResultsToConversation(document, task) {
3768
+ return _async_to_generator$1(function() {
3769
+ var _task_ptc, _task_utr, pending, unsent, allResolved, _task_msg, outputItems;
3770
+ return _ts_generator$1(this, function(_state) {
3771
+ switch(_state.label){
3772
+ case 0:
3773
+ pending = (_task_ptc = task.ptc) !== null && _task_ptc !== void 0 ? _task_ptc : [];
3774
+ unsent = (_task_utr = task.utr) !== null && _task_utr !== void 0 ? _task_utr : [];
3775
+ // The length guard means "and there is something to send" — an empty `ptc` satisfies the predicate
3776
+ // vacuously, and appending nothing would clear `ptc` / `utr` for no reason.
3777
+ allResolved = pending.length > 0 && !hasUnresolvedOpenRouterPendingToolCalls(pending, unsent);
3778
+ if (!allResolved) return [
3779
+ 3,
3780
+ 2
3781
+ ];
3782
+ outputItems = openRouterFunctionCallOutputItems(unsent);
3783
+ return [
3784
+ 4,
3785
+ document.update({
3786
+ msg: _to_consumable_array((_task_msg = task.msg) !== null && _task_msg !== void 0 ? _task_msg : []).concat(_to_consumable_array(outputItems)),
3787
+ ptc: null,
3788
+ utr: null
3789
+ })
3790
+ ];
3791
+ case 1:
3792
+ _state.sent();
3793
+ _state.label = 2;
3794
+ case 2:
3795
+ return [
3796
+ 2
3797
+ ];
3798
+ }
3799
+ });
3800
+ })();
3801
+ }
3802
+ function recordFailure(params) {
3803
+ return _async_to_generator$1(function() {
3804
+ var document, task, error, cause, at, result, retryable, attemptsExhausted, finished, state;
3805
+ return _ts_generator$1(this, function(_state) {
3806
+ switch(_state.label){
3807
+ case 0:
3808
+ document = params.document, task = params.task, error = params.error, cause = params.cause, at = params.at, result = params.result;
3809
+ // A deterministic failure — a bad key, a 402, a model id that does not exist — cannot succeed on a
3810
+ // second attempt, so it spends none of the budget and goes straight to FAILED.
3811
+ retryable = isRetryableOpenRouterError(cause);
3812
+ // The attempt counter was already incremented by the claim, so `task.at` is the number of attempts made
3813
+ // INCLUDING this one — which is why nothing is added to it here. Adding one would spend the budget a
3814
+ // tick early and mark a task FAILED with a retry still owed to it.
3815
+ attemptsExhausted = task.at >= maxAttempts;
3816
+ finished = !retryable || attemptsExhausted;
3817
+ state = finished ? OpenRouterRunTaskState.FAILED : OpenRouterRunTaskState.QUEUED;
3818
+ return [
3819
+ 4,
3820
+ document.update({
3821
+ s: state,
3822
+ // Releasing the lease is what makes the task claimable again on the next sweep.
3823
+ lat: null,
3824
+ lo: null,
3825
+ fat: finished ? at : null,
3826
+ e: error,
3827
+ gi: result == null ? undefined : concatArraysUnique(task.gi, result.generationIds),
3828
+ u: result === null || result === void 0 ? void 0 : result.usage
3829
+ })
3830
+ ];
3831
+ case 1:
3832
+ _state.sent();
3833
+ return [
3834
+ 2,
3835
+ {
3836
+ key: document.id,
3837
+ state: state,
3838
+ result: result
3839
+ }
3840
+ ];
3841
+ }
3842
+ });
3843
+ })();
3844
+ }
3845
+ function resolveDeferredTool(params) {
3846
+ return _async_to_generator$1(function() {
3847
+ var key, taskId, output, error;
3848
+ return _ts_generator$1(this, function(_state) {
3849
+ key = params.key, taskId = params.taskId, output = params.output, error = params.error;
3850
+ return [
3851
+ 2,
3852
+ openRouterRunTaskCollection.firestoreContext.runTransaction(function(transaction) {
3853
+ return _async_to_generator$1(function() {
3854
+ var document, task, result, _task_ptc, _task_utr, pending, call, alreadySettled, _task_utr1, unsent, ready;
3855
+ return _ts_generator$1(this, function(_state) {
3856
+ switch(_state.label){
3857
+ case 0:
3858
+ document = openRouterRunTaskCollection.documentAccessorForTransaction(transaction).loadDocumentForId(key);
3859
+ return [
3860
+ 4,
3861
+ document.snapshotData()
3862
+ ];
3863
+ case 1:
3864
+ task = _state.sent();
3865
+ result = {
3866
+ resolved: false,
3867
+ ready: false
3868
+ };
3869
+ if (!(task != null)) return [
3870
+ 3,
3871
+ 3
3872
+ ];
3873
+ pending = (_task_ptc = task.ptc) !== null && _task_ptc !== void 0 ? _task_ptc : [];
3874
+ call = pending.find(function(x) {
3875
+ return x.taskId === taskId;
3876
+ });
3877
+ alreadySettled = ((_task_utr = task.utr) !== null && _task_utr !== void 0 ? _task_utr : []).some(function(x) {
3878
+ return x.callId === (call === null || call === void 0 ? void 0 : call.callId);
3879
+ });
3880
+ if (!(call != null && !alreadySettled)) return [
3881
+ 3,
3882
+ 3
3883
+ ];
3884
+ // Preserves today's semantics exactly: an `output` of `null` is a real result and is kept, while an
3885
+ // absent `error` is dropped rather than written as `undefined`, which Firestore rejects outright.
3886
+ unsent = _to_consumable_array((_task_utr1 = task.utr) !== null && _task_utr1 !== void 0 ? _task_utr1 : []).concat([
3887
+ filterUndefinedValues({
3888
+ callId: call.callId,
3889
+ name: call.name,
3890
+ output: output,
3891
+ error: error !== null && error !== void 0 ? error : undefined
3892
+ })
3893
+ ]);
3894
+ ready = !hasUnresolvedOpenRouterPendingToolCalls(pending, unsent);
3895
+ // `qat` is deliberately NOT moved. It is the task's age for retention, so a task cycling through
3896
+ // tool resolutions would otherwise keep pushing its own age forward and never age out — and keeping
3897
+ // the original also orders correctly: a run waiting on a tool since yesterday should be claimed
3898
+ // ahead of one queued a minute ago.
3899
+ return [
3900
+ 4,
3901
+ document.update(_object_spread({
3902
+ utr: unsent
3903
+ }, ready ? {
3904
+ s: OpenRouterRunTaskState.QUEUED
3905
+ } : undefined))
3906
+ ];
3907
+ case 2:
3908
+ _state.sent();
3909
+ result = {
3910
+ resolved: true,
3911
+ ready: ready
3912
+ };
3913
+ _state.label = 3;
3914
+ case 3:
3915
+ return [
3916
+ 2,
3917
+ result
3918
+ ];
3919
+ }
3920
+ });
3921
+ })();
3922
+ })
3923
+ ];
3924
+ });
3925
+ })();
3926
+ }
3927
+ return {
3928
+ enqueueRunTask: enqueueRunTask,
3929
+ readRunTask: readRunTask,
3930
+ runTaskDocument: runTaskDocument,
3931
+ claimNextRunTasks: claimNextRunTasks,
3932
+ executeRunTask: executeRunTask,
3933
+ resolveDeferredTool: resolveDeferredTool,
3934
+ deleteExpiredRunTasks: deleteExpiredRunTasks,
3935
+ attachFilesForAttempt: attachFilesForAttempt
3936
+ };
3937
+ }
3938
+ /**
3939
+ * Whether a task may be claimed by a sweep running at the given lease cutoff.
3940
+ *
3941
+ * A `RUNNING` task is claimable exactly when its lease has gone stale — that is crash recovery, and it
3942
+ * generalises the ad-hoc "unstick anything processing for over an hour" logic it replaces.
3943
+ *
3944
+ * @param task - The task to check.
3945
+ * @param leaseCutoff - Leases taken at or before this date are stale.
3946
+ * @returns True when the task may be claimed.
3947
+ *
3948
+ * @__NO_SIDE_EFFECTS__
3949
+ */ function isOpenRouterRunTaskClaimable(task, leaseCutoff) {
3950
+ var result;
3951
+ switch(task.s){
3952
+ case OpenRouterRunTaskState.QUEUED:
3953
+ result = true;
3954
+ break;
3955
+ case OpenRouterRunTaskState.RUNNING:
3956
+ result = task.lat == null || task.lat.getTime() <= leaseCutoff.getTime();
3957
+ break;
3958
+ case OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS:
3959
+ // Only once every pending call has a recorded result; otherwise there is nothing new to send.
3960
+ //
3961
+ // Vacuously true for an EMPTY `ptc`, deliberately. Such a task gets claimed, no-ops the append, and can
3962
+ // still complete — whereas refusing to claim it would strand it permanently with nothing able to move it.
3963
+ result = !hasUnresolvedOpenRouterPendingToolCalls(task.ptc, task.utr);
3964
+ break;
3965
+ default:
3966
+ result = false;
3967
+ break;
3968
+ }
3969
+ return result;
3970
+ }
3971
+ /**
3972
+ * Whether any pending deferred tool call is still missing its recorded result.
3973
+ *
3974
+ * The one predicate behind "is this run ready to resume": the claim check, the resolution's `ready` flag,
3975
+ * and the conversation append all ask it, and three hand-written copies had already drifted apart.
3976
+ *
3977
+ * @param pending - The pending deferred tool calls.
3978
+ * @param unsent - The recorded-but-unsent tool results.
3979
+ * @returns True when at least one pending call has no recorded result.
3980
+ *
3981
+ * @__NO_SIDE_EFFECTS__
3982
+ */ function hasUnresolvedOpenRouterPendingToolCalls(pending, unsent) {
3983
+ return (pending !== null && pending !== void 0 ? pending : []).some(function(call) {
3984
+ return !(unsent !== null && unsent !== void 0 ? unsent : []).some(function(result) {
3985
+ return result.callId === call.callId;
3986
+ });
3987
+ });
3988
+ }
3989
+ /**
3990
+ * Extracts an error code from a thrown value.
3991
+ *
3992
+ * @param e - The thrown value.
3993
+ * @returns The code, when one is discernible.
3994
+ *
3995
+ * @__NO_SIDE_EFFECTS__
3996
+ */ function openRouterErrorCode(e) {
3997
+ var result;
3998
+ if (e != null && (typeof e === "undefined" ? "undefined" : _type_of(e)) === 'object') {
3999
+ var _e_code;
4000
+ var candidate = (_e_code = e.code) !== null && _e_code !== void 0 ? _e_code : e.name;
4001
+ if (candidate != null) {
4002
+ result = String(candidate);
4003
+ }
4004
+ }
4005
+ return result;
4006
+ }
4007
+ /**
4008
+ * Extracts an error message from a thrown value.
4009
+ *
4010
+ * @param e - The thrown value.
4011
+ * @returns The message.
4012
+ *
4013
+ * @__NO_SIDE_EFFECTS__
4014
+ */ function openRouterErrorMessage(e) {
4015
+ return _instanceof(e, Error) ? e.message : String(e);
4016
+ }
4017
+ /**
4018
+ * HTTP statuses a retry cannot fix.
4019
+ *
4020
+ * 400 is a malformed request (an invalid model id, a JSON schema the provider rejects), 401/403 are a
4021
+ * credential problem, 402 is an empty account, and 404 is a route or resource that does not exist. Each of
4022
+ * them answers identically on every attempt, so spending the budget on them only delays the FAILED that
4023
+ * the owning work is waiting for.
4024
+ */ var OPENROUTER_PERMANENT_ERROR_STATUSES = [
4025
+ 400,
4026
+ 401,
4027
+ 402,
4028
+ 403,
4029
+ 404
4030
+ ];
4031
+ /**
4032
+ * Whether a failure is worth another attempt.
4033
+ *
4034
+ * What this encodes is a whitelist of the KNOWN-PERMANENT, not a whitelist of the retryable: anything
4035
+ * unrecognized defaults to RETRYABLE. An unknown failure is far more likely to be a transient upstream blip
4036
+ * than a permanent one, and the attempt budget bounds the cost of being wrong either way — whereas
4037
+ * defaulting the other way would turn one bad minute at a provider into a definitively failed run.
4038
+ *
4039
+ * So the retryable side needs no list of its own. 408 / 409 / 429 and every 5xx, socket-level failures
4040
+ * (`ECONNRESET`, `ETIMEDOUT`, `ECONNREFUSED`, `EAI_AGAIN`), and the Google-infrastructure transients
4041
+ * (`UNAVAILABLE`, `DEADLINE_EXCEEDED`, `ABORTED`) a Firestore or GCS call raises mid-run all reach the
4042
+ * default and are retried.
4043
+ *
4044
+ * Permanent is two cases. {@link OPENROUTER_PERMANENT_ERROR_STATUSES}, read off `status` / `statusCode` /
4045
+ * `code` — which covers both routes into `recordFailure`: a thrown SDK/HTTP error, and the numeric
4046
+ * `error.code` OpenRouter reports in a response body without throwing at all. And an
4047
+ * {@link OpenRouterPromptResolutionError}, which is deterministic by construction: the prompt either exists
4048
+ * at that version or it never will, so re-resolving it is guaranteed to fail identically.
4049
+ *
4050
+ * @param e - The thrown value, or the error reported on a response.
4051
+ * @returns True when another attempt could plausibly succeed.
4052
+ *
4053
+ * @__NO_SIDE_EFFECTS__
4054
+ */ function isRetryableOpenRouterError(e) {
4055
+ var status = openRouterErrorStatus(e);
4056
+ return !_instanceof(e, OpenRouterPromptResolutionError) && (status == null || !OPENROUTER_PERMANENT_ERROR_STATUSES.includes(status));
4057
+ }
4058
+ /**
4059
+ * Extracts an HTTP status from a thrown value or a reported response error.
4060
+ *
4061
+ * `code` is read as a status too, because OpenRouter reports a NUMERIC code in a response body's `error`
4062
+ * object where an SDK error would carry `status`.
4063
+ *
4064
+ * @param e - The thrown value.
4065
+ * @returns The status, when the value carries a numeric one.
4066
+ *
4067
+ * @__NO_SIDE_EFFECTS__
4068
+ */ function openRouterErrorStatus(e) {
4069
+ var result;
4070
+ if (e != null && (typeof e === "undefined" ? "undefined" : _type_of(e)) === 'object') {
4071
+ var _ref, _e_status;
4072
+ var candidate = (_ref = (_e_status = e.status) !== null && _e_status !== void 0 ? _e_status : e.statusCode) !== null && _ref !== void 0 ? _ref : e.code;
4073
+ if (typeof candidate === 'number') {
4074
+ result = candidate;
4075
+ } else if (typeof candidate === 'string' && /^\d{3}$/.test(candidate)) {
4076
+ // A three-digit string is a status OpenRouter reported as text; anything else is a symbolic code
4077
+ // (`ECONNRESET`, `server_error`) and is left for the default-retryable path.
4078
+ result = Number(candidate);
4079
+ }
4080
+ }
4081
+ return result;
4082
+ }
4083
+ /**
4084
+ * The deferred-tool resolutions recorded on a task, in the form the core package's resolver consumes.
4085
+ *
4086
+ * @param task - The run task.
4087
+ * @returns The resolutions.
4088
+ *
4089
+ * @__NO_SIDE_EFFECTS__
4090
+ */ function openRouterDeferredToolResolutionsForRunTask(task) {
4091
+ var _task_ptc, _task_utr;
4092
+ var pending = (_task_ptc = task.ptc) !== null && _task_ptc !== void 0 ? _task_ptc : [];
4093
+ return filterMaybeArrayValues(((_task_utr = task.utr) !== null && _task_utr !== void 0 ? _task_utr : []).map(function(unsent) {
4094
+ var call = pending.find(function(x) {
4095
+ return x.callId === unsent.callId;
4096
+ });
4097
+ var result;
4098
+ if (call != null) {
4099
+ result = unsent.error == null ? {
4100
+ taskId: call.taskId,
4101
+ output: unsent.output
4102
+ } : {
4103
+ taskId: call.taskId,
4104
+ error: unsent.error
4105
+ };
4106
+ }
4107
+ return result;
4108
+ }));
4109
+ }
4110
+
4111
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
4112
+ try {
4113
+ var info = gen[key](arg);
4114
+ var value = info.value;
4115
+ } catch (error) {
4116
+ reject(error);
4117
+ return;
4118
+ }
4119
+ if (info.done) {
4120
+ resolve(value);
4121
+ } else {
4122
+ Promise.resolve(value).then(_next, _throw);
4123
+ }
4124
+ }
4125
+ function _async_to_generator(fn) {
4126
+ return function() {
4127
+ var self = this, args = arguments;
4128
+ return new Promise(function(resolve, reject) {
4129
+ var gen = fn.apply(self, args);
4130
+ function _next(value) {
4131
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
4132
+ }
4133
+ function _throw(err) {
4134
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
4135
+ }
4136
+ _next(undefined);
4137
+ });
4138
+ };
4139
+ }
4140
+ function _ts_generator(thisArg, body) {
4141
+ var f, y, t, _ = {
4142
+ label: 0,
4143
+ sent: function() {
4144
+ if (t[0] & 1) throw t[1];
4145
+ return t[1];
4146
+ },
4147
+ trys: [],
4148
+ ops: []
4149
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
4150
+ return d(g, "next", {
4151
+ value: verb(0)
4152
+ }), d(g, "throw", {
4153
+ value: verb(1)
4154
+ }), d(g, "return", {
4155
+ value: verb(2)
4156
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
4157
+ value: function() {
4158
+ return this;
4159
+ }
4160
+ }), g;
4161
+ function verb(n) {
4162
+ return function(v) {
4163
+ return step([
4164
+ n,
4165
+ v
4166
+ ]);
4167
+ };
4168
+ }
4169
+ function step(op) {
4170
+ if (f) throw new TypeError("Generator is already executing.");
4171
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
4172
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
4173
+ if (y = 0, t) op = [
4174
+ op[0] & 2,
4175
+ t.value
4176
+ ];
4177
+ switch(op[0]){
4178
+ case 0:
4179
+ case 1:
4180
+ t = op;
4181
+ break;
4182
+ case 4:
4183
+ _.label++;
4184
+ return {
4185
+ value: op[1],
4186
+ done: false
4187
+ };
4188
+ case 5:
4189
+ _.label++;
4190
+ y = op[1];
4191
+ op = [
4192
+ 0
4193
+ ];
4194
+ continue;
4195
+ case 7:
4196
+ op = _.ops.pop();
4197
+ _.trys.pop();
4198
+ continue;
4199
+ default:
4200
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
4201
+ _ = 0;
4202
+ continue;
4203
+ }
4204
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
4205
+ _.label = op[1];
4206
+ break;
4207
+ }
4208
+ if (op[0] === 6 && _.label < t[1]) {
4209
+ _.label = t[1];
4210
+ t = op;
4211
+ break;
4212
+ }
4213
+ if (t && _.label < t[2]) {
4214
+ _.label = t[2];
4215
+ _.ops.push(op);
4216
+ break;
4217
+ }
4218
+ if (t[2]) _.ops.pop();
4219
+ _.trys.pop();
4220
+ continue;
4221
+ }
4222
+ op = body.call(thisArg, _);
4223
+ } catch (e) {
4224
+ op = [
4225
+ 6,
4226
+ e
4227
+ ];
4228
+ y = 0;
4229
+ } finally{
4230
+ f = t = 0;
4231
+ }
4232
+ if (op[0] & 5) throw op[1];
4233
+ return {
4234
+ value: op[0] ? op[1] : void 0,
4235
+ done: true
4236
+ };
4237
+ }
4238
+ }
4239
+ /**
4240
+ * Default number of tasks executed concurrently by one sweep.
4241
+ */ var DEFAULT_OPENROUTER_SWEEP_MAX_PARALLEL_TASKS = 10;
4242
+ /**
4243
+ * Default wall-clock budget for one sweep.
4244
+ */ var DEFAULT_OPENROUTER_SWEEP_MAX_RUN_TIME = MS_IN_MINUTE * 4;
4245
+ /**
4246
+ * Default number of tasks claimed per page.
4247
+ */ var DEFAULT_OPENROUTER_SWEEP_PAGE_SIZE = 20;
4248
+ /**
4249
+ * Default number of expired tasks deleted per retention page.
4250
+ *
4251
+ * Well under the 500-write batch ceiling: retention runs on its own far slower schedule, so there is
4252
+ * nothing to gain from maximising a single page.
4253
+ */ var DEFAULT_OPENROUTER_EXPIRATION_SWEEP_PAGE_SIZE = 200;
4254
+ /**
4255
+ * Default wall-clock budget for one retention sweep.
4256
+ */ var DEFAULT_OPENROUTER_EXPIRATION_SWEEP_MAX_RUN_TIME = MS_IN_MINUTE * 2;
4257
+ var randomSweepId = randomNumberFactory({
4258
+ min: 0,
4259
+ max: 1000000000,
4260
+ round: 'floor'
4261
+ });
4262
+ /**
4263
+ * Drains the run-task queue within a strict time budget.
4264
+ *
4265
+ * Claim a page by lease, run `maxParallelTasks` at a time, write results, repeat — until the queue is
4266
+ * empty or the budget is spent. Mount it on a schedule the app already runs; it does not need one of its
4267
+ * own, and it must not assume it is the only tenant of the one it gets.
4268
+ *
4269
+ * @param params - The service and budget settings.
4270
+ * @returns What the sweep did.
4271
+ */ function openRouterRunTaskSweep(params) {
4272
+ return _async_to_generator(function() {
4273
+ var service, maxParallelTasks, maxRunTimeMs, pageSize, inputLeaseOwner, leaseDuration, maxPages, startedAt, budget, parallelTasks, limitPerPage, leaseOwner, results, pages, stoppedForTimeBudget, elapsed, claimed, durationMs;
4274
+ return _ts_generator(this, function(_state) {
4275
+ switch(_state.label){
4276
+ case 0:
4277
+ service = params.service, maxParallelTasks = params.maxParallelTasks, maxRunTimeMs = params.maxRunTimeMs, pageSize = params.pageSize, inputLeaseOwner = params.leaseOwner, leaseDuration = params.leaseDuration, maxPages = params.maxPages;
4278
+ startedAt = Date.now();
4279
+ budget = maxRunTimeMs !== null && maxRunTimeMs !== void 0 ? maxRunTimeMs : DEFAULT_OPENROUTER_SWEEP_MAX_RUN_TIME;
4280
+ parallelTasks = maxParallelTasks !== null && maxParallelTasks !== void 0 ? maxParallelTasks : DEFAULT_OPENROUTER_SWEEP_MAX_PARALLEL_TASKS;
4281
+ limitPerPage = pageSize !== null && pageSize !== void 0 ? pageSize : DEFAULT_OPENROUTER_SWEEP_PAGE_SIZE;
4282
+ leaseOwner = inputLeaseOwner !== null && inputLeaseOwner !== void 0 ? inputLeaseOwner : "openRouterRunTaskSweep_".concat(startedAt, "_").concat(randomSweepId());
4283
+ results = [];
4284
+ pages = 0;
4285
+ stoppedForTimeBudget = false;
4286
+ elapsed = function elapsed() {
4287
+ return Date.now() - startedAt;
4288
+ };
4289
+ _state.label = 1;
4290
+ case 1:
4291
+ if (elapsed() >= budget) {
4292
+ stoppedForTimeBudget = true;
4293
+ return [
4294
+ 3,
4295
+ 5
4296
+ ];
4297
+ }
4298
+ if (maxPages != null && pages >= maxPages) {
4299
+ return [
4300
+ 3,
4301
+ 5
4302
+ ];
4303
+ }
4304
+ return [
4305
+ 4,
4306
+ service.claimNextRunTasks({
4307
+ limit: limitPerPage,
4308
+ leaseOwner: leaseOwner,
4309
+ leaseDuration: leaseDuration
4310
+ })
4311
+ ];
4312
+ case 2:
4313
+ claimed = _state.sent();
4314
+ if (claimed.length === 0) {
4315
+ return [
4316
+ 3,
4317
+ 5
4318
+ ];
4319
+ }
4320
+ pages += 1;
4321
+ // Every claimed task IS executed, even if the budget expires mid-page: it already holds a lease and
4322
+ // its attempt counter is already spent, so abandoning it would leave a RUNNING document waiting on
4323
+ // lease reclamation for no reason.
4324
+ return [
4325
+ 4,
4326
+ performTasksInParallel(claimed, {
4327
+ maxParallelTasks: parallelTasks,
4328
+ taskFactory: function taskFactory(document) {
4329
+ return _async_to_generator(function() {
4330
+ var result;
4331
+ return _ts_generator(this, function(_state) {
4332
+ switch(_state.label){
4333
+ case 0:
4334
+ return [
4335
+ 4,
4336
+ service.executeRunTask(document)
4337
+ ];
4338
+ case 1:
4339
+ result = _state.sent();
4340
+ results.push(result);
4341
+ return [
4342
+ 2
4343
+ ];
4344
+ }
4345
+ });
4346
+ })();
4347
+ }
4348
+ })
4349
+ ];
4350
+ case 3:
4351
+ _state.sent();
4352
+ _state.label = 4;
4353
+ case 4:
4354
+ return [
4355
+ 3,
4356
+ 1
4357
+ ];
4358
+ case 5:
4359
+ durationMs = elapsed();
4360
+ return [
4361
+ 2,
4362
+ {
4363
+ executed: results.length,
4364
+ completed: results.filter(function(x) {
4365
+ return x.state === OpenRouterRunTaskState.COMPLETE;
4366
+ }).length,
4367
+ failed: results.filter(function(x) {
4368
+ return x.state === OpenRouterRunTaskState.FAILED;
4369
+ }).length,
4370
+ requeued: results.filter(function(x) {
4371
+ return x.state === OpenRouterRunTaskState.QUEUED;
4372
+ }).length,
4373
+ awaitingAsyncTools: results.filter(function(x) {
4374
+ return x.state === OpenRouterRunTaskState.AWAITING_ASYNC_TOOLS;
4375
+ }).length,
4376
+ pages: pages,
4377
+ stoppedForTimeBudget: stoppedForTimeBudget,
4378
+ durationMs: durationMs,
4379
+ results: results
4380
+ }
4381
+ ];
4382
+ }
4383
+ });
4384
+ })();
4385
+ }
4386
+ /**
4387
+ * Deletes every run task past its retention age, within a strict time budget.
4388
+ *
4389
+ * A SEPARATE sweep from {@link openRouterRunTaskSweep}, on a far slower schedule: the drain tick runs every
4390
+ * minute and there is nothing a week-old document gains from being looked at that often.
4391
+ *
4392
+ * @param params - The service and budget settings.
4393
+ * @returns What the sweep deleted.
4394
+ */ function openRouterRunTaskExpirationSweep(params) {
4395
+ return _async_to_generator(function() {
4396
+ var service, before, pageSize, maxRunTimeMs, maxPages, startedAt, budget, limitPerPage, cutoff, deleted, pages, stoppedForTimeBudget, elapsed, page;
4397
+ return _ts_generator(this, function(_state) {
4398
+ switch(_state.label){
4399
+ case 0:
4400
+ service = params.service, before = params.before, pageSize = params.pageSize, maxRunTimeMs = params.maxRunTimeMs, maxPages = params.maxPages;
4401
+ startedAt = Date.now();
4402
+ budget = maxRunTimeMs !== null && maxRunTimeMs !== void 0 ? maxRunTimeMs : DEFAULT_OPENROUTER_EXPIRATION_SWEEP_MAX_RUN_TIME;
4403
+ limitPerPage = pageSize !== null && pageSize !== void 0 ? pageSize : DEFAULT_OPENROUTER_EXPIRATION_SWEEP_PAGE_SIZE;
4404
+ // The cutoff is PINNED once for the whole run rather than re-derived per page. A cutoff advancing with the
4405
+ // clock would let a task that ages mid-sweep join a page not yet reached, making the pass unbounded.
4406
+ cutoff = before !== null && before !== void 0 ? before : new Date(startedAt - OPENROUTER_RUN_TASK_MAX_AGE);
4407
+ deleted = 0;
4408
+ pages = 0;
4409
+ stoppedForTimeBudget = false;
4410
+ elapsed = function elapsed() {
4411
+ return Date.now() - startedAt;
4412
+ };
4413
+ _state.label = 1;
4414
+ case 1:
4415
+ if (elapsed() >= budget) {
4416
+ stoppedForTimeBudget = true;
4417
+ return [
4418
+ 3,
4419
+ 4
4420
+ ];
4421
+ }
4422
+ if (maxPages != null && pages >= maxPages) {
4423
+ return [
4424
+ 3,
4425
+ 4
4426
+ ];
4427
+ }
4428
+ return [
4429
+ 4,
4430
+ service.deleteExpiredRunTasks({
4431
+ limit: limitPerPage,
4432
+ before: cutoff
4433
+ })
4434
+ ];
4435
+ case 2:
4436
+ page = _state.sent();
4437
+ if (page.deleted === 0) {
4438
+ return [
4439
+ 3,
4440
+ 4
4441
+ ];
4442
+ }
4443
+ deleted += page.deleted;
4444
+ pages += 1;
4445
+ _state.label = 3;
4446
+ case 3:
4447
+ return [
4448
+ 3,
4449
+ 1
4450
+ ];
4451
+ case 4:
4452
+ return [
4453
+ 2,
4454
+ {
4455
+ deleted: deleted,
4456
+ pages: pages,
4457
+ stoppedForTimeBudget: stoppedForTimeBudget,
4458
+ durationMs: elapsed()
4459
+ }
4460
+ ];
4461
+ }
4462
+ });
4463
+ })();
4464
+ }
4465
+
4466
+ export { AbstractAppOpenRouterModule, DEFAULT_OPENROUTER_EXPIRATION_SWEEP_MAX_RUN_TIME, DEFAULT_OPENROUTER_EXPIRATION_SWEEP_PAGE_SIZE, DEFAULT_OPENROUTER_INLINE_FILE_CONTENT_TYPE, DEFAULT_OPENROUTER_LEASE_DURATION, DEFAULT_OPENROUTER_MAX_ATTEMPTS, DEFAULT_OPENROUTER_MAX_INLINE_FILE_SIZE_BYTES, DEFAULT_OPENROUTER_SIGNED_URL_TTL, DEFAULT_OPENROUTER_SWEEP_MAX_PARALLEL_TASKS, DEFAULT_OPENROUTER_SWEEP_MAX_RUN_TIME, DEFAULT_OPENROUTER_SWEEP_PAGE_SIZE, OPENROUTER_BROADCAST_RUN_TASK_KEY_ATTRIBUTES, OPENROUTER_MAX_EXPIRED_RUN_TASK_DELETE_PAGE_SIZE, OPENROUTER_PERMANENT_ERROR_STATUSES, OPENROUTER_PROMPT_CACHE_DURATION, OPENROUTER_PROMPT_SERVICE_TOKEN, OPENROUTER_RUN_TASK_SERVICE_TOKEN, OPENROUTER_SEED_PROMPTS_MAX_PARALLEL_UPDATES, OpenRouterPromptResolutionError, OpenRouterPromptServerActions, OpenRouterPromptService, OpenRouterRunTaskService, appOpenRouterModuleMetadata, callModelForPrompt, conversationStateForOpenRouterRunTask, conversationStatusForOpenRouterRunTaskState, createOpenRouterPromptFactory, createOpenRouterPromptVersionFactory, firestoreOpenRouterStateAccessor, handleOpenRouterRunTaskResultFactory, hasUnresolvedOpenRouterPendingToolCalls, isOpenRouterRunTaskClaimable, isRetryableOpenRouterError, mergeOpenRouterRunUsage, openRouterConversationValueForFirestore, openRouterDeferredToolResolutionsForRunTask, openRouterErrorCode, openRouterErrorMessage, openRouterFileAttachmentModeForConfig, openRouterFileAttachmentResolver, openRouterPromptServerActions, openRouterPromptService, openRouterRunTaskExpirationSweep, openRouterRunTaskKeyFromBroadcastAttributes, openRouterRunTaskOutcome, openRouterRunTaskService, openRouterRunTaskStateForConversationStatus, openRouterRunTaskSweep, openRouterRunTaskUpdateForConversationState, reconcileOpenRouterRunTaskFromBroadcast, seedOpenRouterPromptsFactory, updateOpenRouterPromptFactory, updateOpenRouterPromptVersionFactory };