@microfox/ai-worker 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +22 -0
- package/dist/chainMapDefaults.d.mts +21 -0
- package/dist/chainMapDefaults.d.ts +21 -0
- package/dist/chainMapDefaults.js +59 -0
- package/dist/chainMapDefaults.js.map +1 -0
- package/dist/chainMapDefaults.mjs +10 -0
- package/dist/chainMapDefaults.mjs.map +1 -0
- package/dist/chunk-BCRJIFKB.mjs +9 -0
- package/dist/chunk-BCRJIFKB.mjs.map +1 -0
- package/dist/{chunk-72XGFZCE.mjs → chunk-CILTGUUQ.mjs} +14 -3
- package/dist/chunk-CILTGUUQ.mjs.map +1 -0
- package/dist/{chunk-7LQNS2SG.mjs → chunk-QHX55IML.mjs} +442 -56
- package/dist/chunk-QHX55IML.mjs.map +1 -0
- package/dist/chunk-SQB5FQCZ.mjs +21 -0
- package/dist/chunk-SQB5FQCZ.mjs.map +1 -0
- package/dist/{chunk-AOXGONGI.mjs → chunk-T7DRPKR6.mjs} +7 -5
- package/dist/chunk-T7DRPKR6.mjs.map +1 -0
- package/dist/chunk-XCKWV2WZ.mjs +34 -0
- package/dist/chunk-XCKWV2WZ.mjs.map +1 -0
- package/dist/chunk-ZW4PNCDH.mjs +17 -0
- package/dist/chunk-ZW4PNCDH.mjs.map +1 -0
- package/dist/client.d.mts +148 -2
- package/dist/client.d.ts +148 -2
- package/dist/client.js +13 -2
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/handler.d.mts +121 -23
- package/dist/handler.d.ts +121 -23
- package/dist/handler.js +450 -58
- package/dist/handler.js.map +1 -1
- package/dist/handler.mjs +5 -2
- package/dist/hitlConfig.d.mts +46 -0
- package/dist/hitlConfig.d.ts +46 -0
- package/dist/hitlConfig.js +33 -0
- package/dist/hitlConfig.js.map +1 -0
- package/dist/hitlConfig.mjs +8 -0
- package/dist/hitlConfig.mjs.map +1 -0
- package/dist/index.d.mts +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +575 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +78 -20
- package/dist/index.mjs.map +1 -1
- package/dist/queue-B5n6YVQV.d.ts +306 -0
- package/dist/queue-DaR2UuZi.d.mts +306 -0
- package/dist/queue.d.mts +3 -0
- package/dist/queue.d.ts +3 -0
- package/dist/queue.js +47 -0
- package/dist/queue.js.map +1 -0
- package/dist/queue.mjs +12 -0
- package/dist/queue.mjs.map +1 -0
- package/dist/queueInputEnvelope.d.mts +31 -0
- package/dist/queueInputEnvelope.d.ts +31 -0
- package/dist/queueInputEnvelope.js +42 -0
- package/dist/queueInputEnvelope.js.map +1 -0
- package/dist/queueInputEnvelope.mjs +10 -0
- package/dist/queueInputEnvelope.mjs.map +1 -0
- package/dist/queueJobStore.d.mts +3 -2
- package/dist/queueJobStore.d.ts +3 -2
- package/dist/queueJobStore.js +6 -4
- package/dist/queueJobStore.js.map +1 -1
- package/dist/queueJobStore.mjs +1 -1
- package/package.json +7 -2
- package/dist/chunk-72XGFZCE.mjs.map +0 -1
- package/dist/chunk-7LQNS2SG.mjs.map +0 -1
- package/dist/chunk-AOXGONGI.mjs.map +0 -1
- package/dist/client-BqSJQ9mZ.d.mts +0 -183
- package/dist/client-BqSJQ9mZ.d.ts +0 -183
package/dist/handler.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var handler_exports = {};
|
|
22
22
|
__export(handler_exports, {
|
|
23
23
|
SQS_MAX_DELAY_SECONDS: () => SQS_MAX_DELAY_SECONDS,
|
|
24
|
+
TokenBudgetExceededError: () => TokenBudgetExceededError,
|
|
24
25
|
createLambdaHandler: () => createLambdaHandler,
|
|
25
26
|
createWorkerLogger: () => createWorkerLogger,
|
|
26
27
|
wrapHandlerForQueue: () => wrapHandlerForQueue
|
|
@@ -68,7 +69,7 @@ async function getJobById(jobId) {
|
|
|
68
69
|
return null;
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
function createMongoJobStore(workerId, jobId, input, metadata) {
|
|
72
|
+
function createMongoJobStore(workerId, jobId, input, metadata, userId) {
|
|
72
73
|
return {
|
|
73
74
|
update: async (update) => {
|
|
74
75
|
try {
|
|
@@ -107,6 +108,7 @@ function createMongoJobStore(workerId, jobId, input, metadata) {
|
|
|
107
108
|
output: update.output,
|
|
108
109
|
error: update.error,
|
|
109
110
|
metadata: metadataUpdate,
|
|
111
|
+
...userId ? { userId } : {},
|
|
110
112
|
createdAt: now,
|
|
111
113
|
updatedAt: now,
|
|
112
114
|
completedAt: set.completedAt
|
|
@@ -172,7 +174,7 @@ function createMongoJobStore(workerId, jobId, input, metadata) {
|
|
|
172
174
|
}
|
|
173
175
|
};
|
|
174
176
|
}
|
|
175
|
-
async function upsertJob(jobId, workerId, input, metadata) {
|
|
177
|
+
async function upsertJob(jobId, workerId, input, metadata, userId) {
|
|
176
178
|
const coll = await getCollection();
|
|
177
179
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
178
180
|
await coll.updateOne(
|
|
@@ -185,6 +187,7 @@ async function upsertJob(jobId, workerId, input, metadata) {
|
|
|
185
187
|
status: "queued",
|
|
186
188
|
input: input ?? {},
|
|
187
189
|
metadata: metadata ?? {},
|
|
190
|
+
...userId ? { userId } : {},
|
|
188
191
|
createdAt: now,
|
|
189
192
|
updatedAt: now
|
|
190
193
|
}
|
|
@@ -263,13 +266,14 @@ async function loadJob(jobId) {
|
|
|
263
266
|
error: parseJson(data.error),
|
|
264
267
|
metadata: parseJson(data.metadata) ?? {},
|
|
265
268
|
internalJobs,
|
|
269
|
+
...data.userId ? { userId: data.userId } : {},
|
|
266
270
|
createdAt: data.createdAt,
|
|
267
271
|
updatedAt: data.updatedAt,
|
|
268
272
|
completedAt: data.completedAt
|
|
269
273
|
};
|
|
270
274
|
return record;
|
|
271
275
|
}
|
|
272
|
-
function createRedisJobStore(workerId, jobId, input, metadata) {
|
|
276
|
+
function createRedisJobStore(workerId, jobId, input, metadata, userId) {
|
|
273
277
|
return {
|
|
274
278
|
update: async (update) => {
|
|
275
279
|
const redis = getRedis();
|
|
@@ -327,28 +331,20 @@ function createRedisJobStore(workerId, jobId, input, metadata) {
|
|
|
327
331
|
}
|
|
328
332
|
};
|
|
329
333
|
}
|
|
330
|
-
async function upsertRedisJob(jobId, workerId, input, metadata) {
|
|
334
|
+
async function upsertRedisJob(jobId, workerId, input, metadata, userId) {
|
|
331
335
|
const redis = getRedis();
|
|
332
336
|
const key = jobKey(jobId);
|
|
333
337
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
334
|
-
const doc = {
|
|
335
|
-
jobId,
|
|
336
|
-
workerId,
|
|
337
|
-
status: "queued",
|
|
338
|
-
input,
|
|
339
|
-
metadata,
|
|
340
|
-
createdAt: now,
|
|
341
|
-
updatedAt: now
|
|
342
|
-
};
|
|
343
338
|
const toSet = {
|
|
344
339
|
jobId,
|
|
345
340
|
workerId,
|
|
346
|
-
status:
|
|
347
|
-
input: JSON.stringify(
|
|
348
|
-
metadata: JSON.stringify(
|
|
341
|
+
status: "queued",
|
|
342
|
+
input: JSON.stringify(input ?? {}),
|
|
343
|
+
metadata: JSON.stringify(metadata ?? {}),
|
|
349
344
|
createdAt: now,
|
|
350
345
|
updatedAt: now
|
|
351
346
|
};
|
|
347
|
+
if (userId) toSet.userId = userId;
|
|
352
348
|
await redis.hset(key, toSet);
|
|
353
349
|
if (jobTtlSeconds > 0) {
|
|
354
350
|
await redis.expire(key, jobTtlSeconds);
|
|
@@ -440,6 +436,7 @@ async function loadQueueJobRedis(queueJobId) {
|
|
|
440
436
|
status: String(d.status ?? "running"),
|
|
441
437
|
steps: stepsFromHash(d.steps),
|
|
442
438
|
metadata: metadataFromHash(d.metadata),
|
|
439
|
+
...d.userId ? { userId: String(d.userId) } : {},
|
|
443
440
|
createdAt: String(d.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
444
441
|
updatedAt: String(d.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
445
442
|
completedAt: d.completedAt != null ? String(d.completedAt) : void 0
|
|
@@ -459,9 +456,8 @@ async function saveQueueJobRedis(record) {
|
|
|
459
456
|
createdAt: record.createdAt || now,
|
|
460
457
|
updatedAt: record.updatedAt || now
|
|
461
458
|
};
|
|
462
|
-
if (record.completedAt)
|
|
463
|
-
|
|
464
|
-
}
|
|
459
|
+
if (record.completedAt) toSet.completedAt = record.completedAt;
|
|
460
|
+
if (record.userId) toSet.userId = record.userId;
|
|
465
461
|
await redis.hset(key, toSet);
|
|
466
462
|
if (queueJobTtlSeconds > 0) {
|
|
467
463
|
await redis.expire(key, queueJobTtlSeconds);
|
|
@@ -478,7 +474,7 @@ function preferRedis() {
|
|
|
478
474
|
return getStoreType() !== "mongodb" && Boolean((redisUrl2 || "").trim() && (redisToken2 || "").trim());
|
|
479
475
|
}
|
|
480
476
|
async function upsertInitialQueueJob(options) {
|
|
481
|
-
const { queueJobId, queueId, firstWorkerId, firstWorkerJobId, metadata } = options;
|
|
477
|
+
const { queueJobId, queueId, firstWorkerId, firstWorkerJobId, metadata, userId } = options;
|
|
482
478
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
483
479
|
if (preferMongo()) {
|
|
484
480
|
const coll = await getMongoQueueCollection();
|
|
@@ -515,6 +511,7 @@ async function upsertInitialQueueJob(options) {
|
|
|
515
511
|
}
|
|
516
512
|
],
|
|
517
513
|
metadata: metadata ?? {},
|
|
514
|
+
...userId ? { userId } : {},
|
|
518
515
|
createdAt: now,
|
|
519
516
|
updatedAt: now
|
|
520
517
|
};
|
|
@@ -553,6 +550,7 @@ async function upsertInitialQueueJob(options) {
|
|
|
553
550
|
}
|
|
554
551
|
],
|
|
555
552
|
metadata: metadata ?? {},
|
|
553
|
+
...userId ? { userId } : {},
|
|
556
554
|
createdAt: now,
|
|
557
555
|
updatedAt: now
|
|
558
556
|
};
|
|
@@ -665,6 +663,150 @@ async function appendQueueJobStepInStore(options) {
|
|
|
665
663
|
}
|
|
666
664
|
}
|
|
667
665
|
|
|
666
|
+
// src/queue.ts
|
|
667
|
+
var QUEUE_ORCHESTRATION_KEYS = [
|
|
668
|
+
"__workerQueue",
|
|
669
|
+
"__hitlInput",
|
|
670
|
+
"__hitlDecision",
|
|
671
|
+
"__hitlPending",
|
|
672
|
+
"hitl"
|
|
673
|
+
];
|
|
674
|
+
|
|
675
|
+
// src/retryConfig.ts
|
|
676
|
+
var BUILT_IN_PATTERNS = {
|
|
677
|
+
"rate-limit": {
|
|
678
|
+
match: (err) => /rate.?limit|too.?many.?requests/i.test(err.message) || err.status === 429 || err.code === 429 || err.name === "RateLimitError",
|
|
679
|
+
delayMs: (attempt) => attempt * 1e4,
|
|
680
|
+
// 10s, 20s, 30s…
|
|
681
|
+
injectContext: false
|
|
682
|
+
},
|
|
683
|
+
"json-parse": {
|
|
684
|
+
match: (err) => err.name === "SyntaxError" || err.name === "ZodError" || /json|parse|unexpected.?token|invalid.?format/i.test(err.message),
|
|
685
|
+
delayMs: (_attempt) => 0,
|
|
686
|
+
// Immediate — model self-corrects from ctx
|
|
687
|
+
injectContext: true
|
|
688
|
+
},
|
|
689
|
+
overloaded: {
|
|
690
|
+
match: (err) => /overloaded|model.?is.?busy/i.test(err.message) || err.status === 529 || err.code === 529,
|
|
691
|
+
delayMs: (attempt) => attempt * 15e3,
|
|
692
|
+
// 15s, 30s…
|
|
693
|
+
injectContext: false
|
|
694
|
+
},
|
|
695
|
+
"server-error": {
|
|
696
|
+
match: (err) => /internal.?server.?error|service.?unavailable|bad.?gateway/i.test(err.message) || typeof err.status === "number" && err.status >= 500 && err.status < 600,
|
|
697
|
+
delayMs: (attempt) => attempt * 5e3,
|
|
698
|
+
// 5s, 10s…
|
|
699
|
+
injectContext: false
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
function matchesRetryPattern(err, patterns, attempt) {
|
|
703
|
+
for (const pattern of patterns) {
|
|
704
|
+
if (typeof pattern === "string") {
|
|
705
|
+
const impl = BUILT_IN_PATTERNS[pattern];
|
|
706
|
+
if (impl.match(err)) {
|
|
707
|
+
return { matched: true, delayMs: impl.delayMs(attempt), injectContext: impl.injectContext };
|
|
708
|
+
}
|
|
709
|
+
} else {
|
|
710
|
+
let matched = false;
|
|
711
|
+
if (pattern.match instanceof RegExp) {
|
|
712
|
+
matched = pattern.match.test(err.message);
|
|
713
|
+
} else {
|
|
714
|
+
try {
|
|
715
|
+
matched = pattern.match(err);
|
|
716
|
+
} catch {
|
|
717
|
+
matched = false;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (matched) {
|
|
721
|
+
const delayMs = typeof pattern.delayMs === "function" ? pattern.delayMs(attempt) : pattern.delayMs ?? 0;
|
|
722
|
+
return { matched: true, delayMs, injectContext: pattern.injectContext ?? false };
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return { matched: false, delayMs: 0, injectContext: false };
|
|
727
|
+
}
|
|
728
|
+
async function executeWithRetry(fn, config, onRetry) {
|
|
729
|
+
const maxAttempts = config.maxAttempts ?? 3;
|
|
730
|
+
let lastError;
|
|
731
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
732
|
+
const retryCtx = attempt > 1 && lastError ? {
|
|
733
|
+
attempt,
|
|
734
|
+
maxAttempts,
|
|
735
|
+
lastError: {
|
|
736
|
+
message: lastError.message,
|
|
737
|
+
name: lastError.name,
|
|
738
|
+
stack: lastError.stack,
|
|
739
|
+
code: lastError.code ?? lastError.status
|
|
740
|
+
}
|
|
741
|
+
} : void 0;
|
|
742
|
+
try {
|
|
743
|
+
return await fn(retryCtx);
|
|
744
|
+
} catch (err) {
|
|
745
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
746
|
+
if (err?.name === "TokenBudgetExceededError") throw err;
|
|
747
|
+
if (attempt >= maxAttempts) throw err;
|
|
748
|
+
const retryAttemptNumber = attempt;
|
|
749
|
+
const { matched, delayMs } = matchesRetryPattern(lastError, config.on, retryAttemptNumber);
|
|
750
|
+
if (!matched) throw err;
|
|
751
|
+
const nextCtx = {
|
|
752
|
+
attempt: attempt + 1,
|
|
753
|
+
maxAttempts,
|
|
754
|
+
lastError: {
|
|
755
|
+
message: lastError.message,
|
|
756
|
+
name: lastError.name,
|
|
757
|
+
stack: lastError.stack,
|
|
758
|
+
code: lastError.code ?? lastError.status
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
onRetry?.(nextCtx, delayMs);
|
|
762
|
+
if (delayMs > 0) {
|
|
763
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
throw lastError ?? new Error("executeWithRetry: unknown error");
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// src/tokenBudget.ts
|
|
771
|
+
var TokenBudgetExceededError = class extends Error {
|
|
772
|
+
constructor(used, budget) {
|
|
773
|
+
super(`Token budget exceeded: used ${used} tokens (budget: ${budget})`);
|
|
774
|
+
this.name = "TokenBudgetExceededError";
|
|
775
|
+
this.used = used;
|
|
776
|
+
this.budget = budget;
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
function createTokenTracker(budget) {
|
|
780
|
+
let inputTokens = 0;
|
|
781
|
+
let outputTokens = 0;
|
|
782
|
+
function checkBudget() {
|
|
783
|
+
if (budget !== null) {
|
|
784
|
+
const total = inputTokens + outputTokens;
|
|
785
|
+
if (total > budget) {
|
|
786
|
+
throw new TokenBudgetExceededError(total, budget);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return {
|
|
791
|
+
report(usage) {
|
|
792
|
+
inputTokens += usage.inputTokens;
|
|
793
|
+
outputTokens += usage.outputTokens;
|
|
794
|
+
checkBudget();
|
|
795
|
+
},
|
|
796
|
+
getState() {
|
|
797
|
+
return { inputTokens, outputTokens, budget };
|
|
798
|
+
},
|
|
799
|
+
getBudgetInfo() {
|
|
800
|
+
const used = inputTokens + outputTokens;
|
|
801
|
+
return {
|
|
802
|
+
used,
|
|
803
|
+
budget,
|
|
804
|
+
remaining: budget !== null ? Math.max(0, budget - used) : null
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
668
810
|
// src/handler.ts
|
|
669
811
|
var SQS_MAX_DELAY_SECONDS = 900;
|
|
670
812
|
function createWorkerLogger(jobId, workerId) {
|
|
@@ -687,6 +829,67 @@ function createWorkerLogger(jobId, workerId) {
|
|
|
687
829
|
};
|
|
688
830
|
}
|
|
689
831
|
var WORKER_QUEUE_KEY = "__workerQueue";
|
|
832
|
+
async function loadPreviousOutputsBeforeStep(queueRuntime, queueJobId, beforeStepIndex) {
|
|
833
|
+
if (!queueJobId || typeof queueRuntime.getQueueJob !== "function") {
|
|
834
|
+
return [];
|
|
835
|
+
}
|
|
836
|
+
try {
|
|
837
|
+
const job = await queueRuntime.getQueueJob(queueJobId);
|
|
838
|
+
if (!job?.steps) return [];
|
|
839
|
+
return job.steps.slice(0, beforeStepIndex).map((s, i) => ({ stepIndex: i, workerId: s.workerId, output: s.output }));
|
|
840
|
+
} catch (e) {
|
|
841
|
+
if (process.env.AI_WORKER_QUEUES_DEBUG === "1") {
|
|
842
|
+
console.warn("[Worker] getQueueJob failed (resume mapping):", e?.message ?? e);
|
|
843
|
+
}
|
|
844
|
+
return [];
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
async function maybeApplyHitlResumeMapper(params, queueRuntime) {
|
|
848
|
+
const inputObj = params.input;
|
|
849
|
+
if (!inputObj || typeof inputObj !== "object") return;
|
|
850
|
+
if (!("__hitlInput" in inputObj)) return;
|
|
851
|
+
const wq = inputObj[WORKER_QUEUE_KEY];
|
|
852
|
+
if (!wq?.id || typeof wq.stepIndex !== "number") return;
|
|
853
|
+
const queueId = wq.id;
|
|
854
|
+
const stepIndex = wq.stepIndex;
|
|
855
|
+
const initialInput = wq.initialInput;
|
|
856
|
+
const queueJobId = wq.queueJobId;
|
|
857
|
+
const previousOutputs = await loadPreviousOutputsBeforeStep(queueRuntime, queueJobId, stepIndex);
|
|
858
|
+
const pendingInput = { ...inputObj };
|
|
859
|
+
for (const key of QUEUE_ORCHESTRATION_KEYS) {
|
|
860
|
+
delete pendingInput[key];
|
|
861
|
+
}
|
|
862
|
+
delete pendingInput[WORKER_QUEUE_KEY];
|
|
863
|
+
const reviewerInput = inputObj.__hitlInput;
|
|
864
|
+
const decision = inputObj.__hitlDecision;
|
|
865
|
+
let merged;
|
|
866
|
+
if (typeof queueRuntime.invokeResume === "function") {
|
|
867
|
+
merged = await queueRuntime.invokeResume(queueId, stepIndex, {
|
|
868
|
+
initialInput,
|
|
869
|
+
previousOutputs,
|
|
870
|
+
reviewerInput,
|
|
871
|
+
pendingInput
|
|
872
|
+
});
|
|
873
|
+
} else {
|
|
874
|
+
merged = {
|
|
875
|
+
...pendingInput,
|
|
876
|
+
...reviewerInput !== null && typeof reviewerInput === "object" ? reviewerInput : {}
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
const mergedObj = merged !== null && typeof merged === "object" ? merged : { value: merged };
|
|
880
|
+
params.input = {
|
|
881
|
+
...mergedObj,
|
|
882
|
+
[WORKER_QUEUE_KEY]: wq,
|
|
883
|
+
...decision !== void 0 ? { __hitlDecision: decision } : {}
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
function getWorkerQueueContext(input, metadata) {
|
|
887
|
+
const fromInput = input !== null && typeof input === "object" && WORKER_QUEUE_KEY in input ? input[WORKER_QUEUE_KEY] : void 0;
|
|
888
|
+
const fromMeta = metadata !== void 0 && typeof metadata === "object" && WORKER_QUEUE_KEY in metadata ? metadata[WORKER_QUEUE_KEY] : void 0;
|
|
889
|
+
const q = fromInput ?? fromMeta;
|
|
890
|
+
if (q === null || typeof q !== "object") return void 0;
|
|
891
|
+
return q;
|
|
892
|
+
}
|
|
690
893
|
async function notifyQueueJobStep(queueJobId, action, params) {
|
|
691
894
|
try {
|
|
692
895
|
if (action === "append") {
|
|
@@ -706,7 +909,7 @@ async function notifyQueueJobStep(queueJobId, action, params) {
|
|
|
706
909
|
return;
|
|
707
910
|
}
|
|
708
911
|
if (params.stepIndex === void 0) return;
|
|
709
|
-
const status = action === "start" ? "running" : action === "complete" ? "completed" : action === "fail" ? "failed" : void 0;
|
|
912
|
+
const status = action === "start" ? "running" : action === "awaiting_approval" ? "awaiting_approval" : action === "complete" ? "completed" : action === "fail" ? "failed" : void 0;
|
|
710
913
|
if (!status) return;
|
|
711
914
|
await updateQueueJobStepInStore({
|
|
712
915
|
queueJobId,
|
|
@@ -726,6 +929,13 @@ async function notifyQueueJobStep(queueJobId, action, params) {
|
|
|
726
929
|
status
|
|
727
930
|
});
|
|
728
931
|
} catch (err) {
|
|
932
|
+
if (action === "append") {
|
|
933
|
+
console.error("[Worker] Queue append failed (rethrowing):", {
|
|
934
|
+
queueJobId,
|
|
935
|
+
error: err?.message ?? String(err)
|
|
936
|
+
});
|
|
937
|
+
throw err;
|
|
938
|
+
}
|
|
729
939
|
console.warn("[Worker] Queue job update error:", {
|
|
730
940
|
queueJobId,
|
|
731
941
|
action,
|
|
@@ -735,26 +945,152 @@ async function notifyQueueJobStep(queueJobId, action, params) {
|
|
|
735
945
|
}
|
|
736
946
|
function wrapHandlerForQueue(handler, queueRuntime) {
|
|
737
947
|
return async (params) => {
|
|
738
|
-
|
|
739
|
-
const
|
|
740
|
-
|
|
948
|
+
await maybeApplyHitlResumeMapper(params, queueRuntime);
|
|
949
|
+
const inputObj = params.input !== null && typeof params.input === "object" ? params.input : {};
|
|
950
|
+
const queueContextRaw = inputObj[WORKER_QUEUE_KEY];
|
|
951
|
+
const queueCtxForRetry = queueContextRaw && typeof queueContextRaw === "object" ? queueContextRaw : void 0;
|
|
952
|
+
const stepRetryConfig = queueCtxForRetry?.id && typeof queueCtxForRetry.stepIndex === "number" && typeof queueRuntime.getStepAt === "function" ? queueRuntime.getStepAt(queueCtxForRetry.id, queueCtxForRetry.stepIndex)?.retry : void 0;
|
|
953
|
+
const domainInput = { ...inputObj };
|
|
954
|
+
for (const key of QUEUE_ORCHESTRATION_KEYS) {
|
|
955
|
+
delete domainInput[key];
|
|
956
|
+
}
|
|
957
|
+
delete domainInput[WORKER_QUEUE_KEY];
|
|
958
|
+
params.input = domainInput;
|
|
959
|
+
let output;
|
|
960
|
+
if (stepRetryConfig && stepRetryConfig.on.length > 0) {
|
|
961
|
+
output = await executeWithRetry(
|
|
962
|
+
async (retryCtx) => {
|
|
963
|
+
params.ctx.retryContext = retryCtx;
|
|
964
|
+
return handler(params);
|
|
965
|
+
},
|
|
966
|
+
stepRetryConfig,
|
|
967
|
+
(retryCtx, delayMs) => {
|
|
968
|
+
const logger = params.ctx.logger;
|
|
969
|
+
if (logger?.warn) {
|
|
970
|
+
logger.warn(
|
|
971
|
+
`[queue-retry] Retrying step (attempt ${retryCtx.attempt}/${retryCtx.maxAttempts}): ${retryCtx.lastError.message}`,
|
|
972
|
+
{ delayMs }
|
|
973
|
+
);
|
|
974
|
+
} else {
|
|
975
|
+
console.warn("[queue-retry] Step retry", { attempt: retryCtx.attempt, error: retryCtx.lastError.message, delayMs });
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
);
|
|
979
|
+
} else {
|
|
980
|
+
output = await handler(params);
|
|
981
|
+
}
|
|
982
|
+
if (!queueContextRaw || typeof queueContextRaw !== "object") {
|
|
983
|
+
return output;
|
|
984
|
+
}
|
|
985
|
+
const queueContext = queueContextRaw;
|
|
986
|
+
if (!queueContext.id) {
|
|
741
987
|
return output;
|
|
742
988
|
}
|
|
743
989
|
const { id: queueId, stepIndex, initialInput, queueJobId } = queueContext;
|
|
744
|
-
const
|
|
745
|
-
const
|
|
990
|
+
const arrayStepIndex = queueContext.arrayStepIndex ?? stepIndex;
|
|
991
|
+
const jobId = params.ctx.jobId;
|
|
992
|
+
const workerId = params.ctx.workerId ?? "";
|
|
746
993
|
const next = queueRuntime.getNextStep(queueId, stepIndex);
|
|
747
994
|
const childJobId = next ? `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}` : void 0;
|
|
995
|
+
const iterationCount = queueContext.iterationCount ?? 0;
|
|
996
|
+
if (typeof queueRuntime.invokeLoop === "function") {
|
|
997
|
+
const currentStep = typeof queueRuntime.getStepAt === "function" ? queueRuntime.getStepAt(queueId, stepIndex) : void 0;
|
|
998
|
+
const maxIterations = currentStep?.loop?.maxIterations ?? 50;
|
|
999
|
+
if (iterationCount < maxIterations - 1) {
|
|
1000
|
+
let previousOutputsForLoop = [];
|
|
1001
|
+
let stepsLengthBeforeAppend = arrayStepIndex + 1;
|
|
1002
|
+
if (queueJobId && typeof queueRuntime.getQueueJob === "function") {
|
|
1003
|
+
try {
|
|
1004
|
+
const job = await queueRuntime.getQueueJob(queueJobId);
|
|
1005
|
+
if (job?.steps) {
|
|
1006
|
+
previousOutputsForLoop = job.steps.slice(0, stepIndex).map((s, i) => ({ stepIndex: i, workerId: s.workerId, output: s.output }));
|
|
1007
|
+
stepsLengthBeforeAppend = job.steps.length;
|
|
1008
|
+
}
|
|
1009
|
+
} catch {
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
previousOutputsForLoop = previousOutputsForLoop.concat([{ stepIndex, workerId, output }]);
|
|
1013
|
+
const shouldLoop = await queueRuntime.invokeLoop(queueId, stepIndex, {
|
|
1014
|
+
output,
|
|
1015
|
+
stepIndex,
|
|
1016
|
+
iterationCount,
|
|
1017
|
+
initialInput,
|
|
1018
|
+
previousOutputs: previousOutputsForLoop
|
|
1019
|
+
});
|
|
1020
|
+
if (shouldLoop) {
|
|
1021
|
+
const loopJobId = `job-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
1022
|
+
let loopInput = output;
|
|
1023
|
+
if (typeof queueRuntime.invokeChain === "function") {
|
|
1024
|
+
loopInput = await queueRuntime.invokeChain(queueId, stepIndex, {
|
|
1025
|
+
initialInput,
|
|
1026
|
+
previousOutputs: previousOutputsForLoop
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
const loopInputWithQueue = {
|
|
1030
|
+
...loopInput !== null && typeof loopInput === "object" ? loopInput : { value: loopInput },
|
|
1031
|
+
[WORKER_QUEUE_KEY]: {
|
|
1032
|
+
id: queueId,
|
|
1033
|
+
stepIndex,
|
|
1034
|
+
// definition index stays fixed
|
|
1035
|
+
arrayStepIndex: stepsLengthBeforeAppend,
|
|
1036
|
+
// actual index for next iteration
|
|
1037
|
+
initialInput,
|
|
1038
|
+
queueJobId,
|
|
1039
|
+
iterationCount: iterationCount + 1
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
if (queueJobId) {
|
|
1043
|
+
await notifyQueueJobStep(queueJobId, "append", { workerJobId: loopJobId, workerId });
|
|
1044
|
+
}
|
|
1045
|
+
if (queueJobId && typeof arrayStepIndex === "number") {
|
|
1046
|
+
await notifyQueueJobStep(queueJobId, "complete", {
|
|
1047
|
+
queueId,
|
|
1048
|
+
stepIndex: arrayStepIndex,
|
|
1049
|
+
workerJobId: jobId,
|
|
1050
|
+
workerId,
|
|
1051
|
+
output
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
if (currentStep?.requiresApproval && queueJobId) {
|
|
1055
|
+
const hitlUiSpec = currentStep.hitl && typeof currentStep.hitl === "object" && "ui" in currentStep.hitl ? currentStep.hitl.ui : void 0;
|
|
1056
|
+
const pendingInput = {
|
|
1057
|
+
...loopInputWithQueue,
|
|
1058
|
+
...hitlUiSpec !== void 0 ? { hitl: { uiSpec: hitlUiSpec } } : {},
|
|
1059
|
+
__hitlPending: {
|
|
1060
|
+
queueId,
|
|
1061
|
+
queueJobId,
|
|
1062
|
+
stepIndex,
|
|
1063
|
+
workerId,
|
|
1064
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
await notifyQueueJobStep(queueJobId, "awaiting_approval", {
|
|
1068
|
+
queueId,
|
|
1069
|
+
stepIndex: stepsLengthBeforeAppend,
|
|
1070
|
+
workerJobId: loopJobId,
|
|
1071
|
+
workerId,
|
|
1072
|
+
input: pendingInput
|
|
1073
|
+
});
|
|
1074
|
+
return output;
|
|
1075
|
+
}
|
|
1076
|
+
await params.ctx.dispatchWorker(workerId, loopInputWithQueue, {
|
|
1077
|
+
await: false,
|
|
1078
|
+
jobId: loopJobId
|
|
1079
|
+
});
|
|
1080
|
+
return output;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
748
1084
|
if (next && queueJobId) {
|
|
749
1085
|
await notifyQueueJobStep(queueJobId, "append", {
|
|
750
1086
|
workerJobId: childJobId,
|
|
751
1087
|
workerId: next.workerId
|
|
752
1088
|
});
|
|
753
1089
|
}
|
|
754
|
-
if (queueJobId && typeof
|
|
1090
|
+
if (queueJobId && typeof arrayStepIndex === "number") {
|
|
755
1091
|
await notifyQueueJobStep(queueJobId, "complete", {
|
|
756
1092
|
queueId,
|
|
757
|
-
stepIndex,
|
|
1093
|
+
stepIndex: arrayStepIndex,
|
|
758
1094
|
workerJobId: jobId,
|
|
759
1095
|
workerId,
|
|
760
1096
|
output
|
|
@@ -764,7 +1100,7 @@ function wrapHandlerForQueue(handler, queueRuntime) {
|
|
|
764
1100
|
return output;
|
|
765
1101
|
}
|
|
766
1102
|
let nextInput = output;
|
|
767
|
-
if (
|
|
1103
|
+
if (typeof queueRuntime.invokeChain === "function") {
|
|
768
1104
|
let previousOutputs = [];
|
|
769
1105
|
if (queueJobId && typeof queueRuntime.getQueueJob === "function") {
|
|
770
1106
|
try {
|
|
@@ -772,7 +1108,7 @@ function wrapHandlerForQueue(handler, queueRuntime) {
|
|
|
772
1108
|
if (job?.steps) {
|
|
773
1109
|
const fromStore = job.steps.slice(0, stepIndex).map((s, i) => ({ stepIndex: i, workerId: s.workerId, output: s.output }));
|
|
774
1110
|
previousOutputs = fromStore.concat([
|
|
775
|
-
{ stepIndex, workerId: params.ctx
|
|
1111
|
+
{ stepIndex, workerId: params.ctx.workerId ?? "", output }
|
|
776
1112
|
]);
|
|
777
1113
|
}
|
|
778
1114
|
} catch (e) {
|
|
@@ -781,12 +1117,10 @@ function wrapHandlerForQueue(handler, queueRuntime) {
|
|
|
781
1117
|
}
|
|
782
1118
|
}
|
|
783
1119
|
}
|
|
784
|
-
nextInput = await queueRuntime.
|
|
785
|
-
queueId,
|
|
786
|
-
stepIndex + 1,
|
|
1120
|
+
nextInput = await queueRuntime.invokeChain(queueId, stepIndex + 1, {
|
|
787
1121
|
initialInput,
|
|
788
1122
|
previousOutputs
|
|
789
|
-
);
|
|
1123
|
+
});
|
|
790
1124
|
}
|
|
791
1125
|
const nextInputWithQueue = {
|
|
792
1126
|
...nextInput !== null && typeof nextInput === "object" ? nextInput : { value: nextInput },
|
|
@@ -806,6 +1140,37 @@ function wrapHandlerForQueue(handler, queueRuntime) {
|
|
|
806
1140
|
delaySeconds: next.delaySeconds
|
|
807
1141
|
});
|
|
808
1142
|
}
|
|
1143
|
+
if (next.requiresApproval && queueJobId && typeof stepIndex === "number") {
|
|
1144
|
+
const hitlUiSpec = next.hitl && typeof next.hitl === "object" && "ui" in next.hitl ? next.hitl.ui : void 0;
|
|
1145
|
+
const pendingInput = {
|
|
1146
|
+
...nextInputWithQueue,
|
|
1147
|
+
...hitlUiSpec !== void 0 ? { hitl: { uiSpec: hitlUiSpec } } : {},
|
|
1148
|
+
__hitlPending: {
|
|
1149
|
+
queueId,
|
|
1150
|
+
queueJobId,
|
|
1151
|
+
stepIndex: stepIndex + 1,
|
|
1152
|
+
workerId: next.workerId,
|
|
1153
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
await notifyQueueJobStep(queueJobId, "awaiting_approval", {
|
|
1157
|
+
queueId,
|
|
1158
|
+
stepIndex: stepIndex + 1,
|
|
1159
|
+
workerJobId: childJobId,
|
|
1160
|
+
workerId: next.workerId,
|
|
1161
|
+
input: pendingInput
|
|
1162
|
+
});
|
|
1163
|
+
if (debug) {
|
|
1164
|
+
console.log("[Worker] Queue chain paused for HITL approval:", {
|
|
1165
|
+
queueId,
|
|
1166
|
+
queueJobId,
|
|
1167
|
+
nextStep: stepIndex + 1,
|
|
1168
|
+
nextWorkerId: next.workerId,
|
|
1169
|
+
pendingWorkerJobId: childJobId
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
return output;
|
|
1173
|
+
}
|
|
809
1174
|
await params.ctx.dispatchWorker(next.workerId, nextInputWithQueue, {
|
|
810
1175
|
await: false,
|
|
811
1176
|
delaySeconds: next.delaySeconds,
|
|
@@ -829,6 +1194,7 @@ function createDispatchWorker(parentJobId, parentWorkerId, parentContext, jobSto
|
|
|
829
1194
|
const metadata = options?.metadata ?? {};
|
|
830
1195
|
const serializedContext = {};
|
|
831
1196
|
if (parentContext.requestId) serializedContext.requestId = parentContext.requestId;
|
|
1197
|
+
if (parentContext.userId) serializedContext.userId = parentContext.userId;
|
|
832
1198
|
const messageBody = {
|
|
833
1199
|
workerId: calleeWorkerId,
|
|
834
1200
|
jobId: childJobId,
|
|
@@ -918,13 +1284,14 @@ async function sendWebhook(webhookUrl, payload) {
|
|
|
918
1284
|
});
|
|
919
1285
|
}
|
|
920
1286
|
}
|
|
921
|
-
function createLambdaHandler(handler, outputSchema) {
|
|
1287
|
+
function createLambdaHandler(handler, outputSchema, options) {
|
|
922
1288
|
return async (event, lambdaContext) => {
|
|
923
1289
|
const promises = event.Records.map(async (record) => {
|
|
924
1290
|
let messageBody = null;
|
|
925
1291
|
try {
|
|
926
1292
|
messageBody = JSON.parse(record.body);
|
|
927
|
-
const { workerId, jobId, input, context, webhookUrl, metadata = {} } = messageBody;
|
|
1293
|
+
const { workerId, jobId, input, context, webhookUrl, metadata = {}, userId: messageUserId, maxTokens } = messageBody;
|
|
1294
|
+
const userId = context.userId ?? messageUserId;
|
|
928
1295
|
const raw = (process.env.WORKER_DATABASE_TYPE || "upstash-redis").toLowerCase();
|
|
929
1296
|
const jobStoreType = raw === "mongodb" ? "mongodb" : "upstash-redis";
|
|
930
1297
|
if (jobStoreType === "upstash-redis" && isRedisJobStoreConfigured()) {
|
|
@@ -950,33 +1317,45 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
950
1317
|
}
|
|
951
1318
|
let jobStore;
|
|
952
1319
|
if (jobStoreType === "upstash-redis" && isRedisJobStoreConfigured()) {
|
|
953
|
-
await upsertRedisJob(jobId, workerId, input, metadata);
|
|
954
|
-
jobStore = createRedisJobStore(workerId, jobId, input, metadata);
|
|
1320
|
+
await upsertRedisJob(jobId, workerId, input, metadata, userId);
|
|
1321
|
+
jobStore = createRedisJobStore(workerId, jobId, input, metadata, userId);
|
|
955
1322
|
} else if (jobStoreType === "mongodb" || isMongoJobStoreConfigured()) {
|
|
956
|
-
await upsertJob(jobId, workerId, input, metadata);
|
|
957
|
-
jobStore = createMongoJobStore(workerId, jobId, input, metadata);
|
|
1323
|
+
await upsertJob(jobId, workerId, input, metadata, userId);
|
|
1324
|
+
jobStore = createMongoJobStore(workerId, jobId, input, metadata, userId);
|
|
1325
|
+
}
|
|
1326
|
+
if (userId) {
|
|
1327
|
+
console.log(`[WORKER_USER:${userId}]`, { jobId, workerId, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
958
1328
|
}
|
|
959
1329
|
const baseContext = {
|
|
960
1330
|
jobId,
|
|
961
1331
|
workerId,
|
|
962
1332
|
requestId: context.requestId || lambdaContext.awsRequestId,
|
|
1333
|
+
...userId ? { userId } : {},
|
|
963
1334
|
...context
|
|
964
1335
|
};
|
|
1336
|
+
const tokenTracker = createTokenTracker(maxTokens ?? null);
|
|
1337
|
+
const logger = createWorkerLogger(jobId, workerId);
|
|
965
1338
|
const handlerContext = {
|
|
966
1339
|
...baseContext,
|
|
967
1340
|
...jobStore ? { jobStore } : {},
|
|
968
|
-
logger
|
|
969
|
-
dispatchWorker: createDispatchWorker(
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
jobStore
|
|
974
|
-
|
|
1341
|
+
logger,
|
|
1342
|
+
dispatchWorker: createDispatchWorker(jobId, workerId, baseContext, jobStore),
|
|
1343
|
+
reportTokenUsage: async (usage) => {
|
|
1344
|
+
tokenTracker.report(usage);
|
|
1345
|
+
const state = tokenTracker.getState();
|
|
1346
|
+
if (jobStore) {
|
|
1347
|
+
await jobStore.update({ metadata: { tokenUsage: state } }).catch((e) => {
|
|
1348
|
+
logger.warn("Failed to persist tokenUsage to job store", { error: e?.message });
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
getTokenBudget: () => tokenTracker.getBudgetInfo(),
|
|
1353
|
+
retryContext: void 0
|
|
975
1354
|
};
|
|
976
1355
|
if (jobStore) {
|
|
977
1356
|
try {
|
|
978
1357
|
await jobStore.update({ status: "running" });
|
|
979
|
-
const queueCtxForLog = input
|
|
1358
|
+
const queueCtxForLog = getWorkerQueueContext(input, metadata);
|
|
980
1359
|
console.log("[Worker] Job status updated to running:", {
|
|
981
1360
|
jobId,
|
|
982
1361
|
workerId,
|
|
@@ -991,7 +1370,7 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
991
1370
|
});
|
|
992
1371
|
}
|
|
993
1372
|
}
|
|
994
|
-
const queueCtx = input
|
|
1373
|
+
const queueCtx = getWorkerQueueContext(input, metadata);
|
|
995
1374
|
if (queueCtx?.queueJobId && typeof queueCtx.stepIndex === "number") {
|
|
996
1375
|
if (queueCtx.stepIndex === 0) {
|
|
997
1376
|
try {
|
|
@@ -1000,7 +1379,8 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
1000
1379
|
queueId: queueCtx.id,
|
|
1001
1380
|
firstWorkerId: workerId,
|
|
1002
1381
|
firstWorkerJobId: jobId,
|
|
1003
|
-
metadata
|
|
1382
|
+
metadata,
|
|
1383
|
+
userId
|
|
1004
1384
|
});
|
|
1005
1385
|
} catch (e) {
|
|
1006
1386
|
console.warn("[Worker] Failed to upsert initial queue job:", {
|
|
@@ -1012,7 +1392,9 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
1012
1392
|
}
|
|
1013
1393
|
await notifyQueueJobStep(queueCtx.queueJobId, "start", {
|
|
1014
1394
|
queueId: queueCtx.id,
|
|
1015
|
-
|
|
1395
|
+
// Use arrayStepIndex when set — it tracks the actual steps[] position for
|
|
1396
|
+
// looping steps where the definition index stays fixed across iterations.
|
|
1397
|
+
stepIndex: queueCtx.arrayStepIndex ?? queueCtx.stepIndex,
|
|
1016
1398
|
workerJobId: jobId,
|
|
1017
1399
|
workerId,
|
|
1018
1400
|
input
|
|
@@ -1020,12 +1402,21 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
1020
1402
|
}
|
|
1021
1403
|
let output;
|
|
1022
1404
|
try {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1405
|
+
const workerRetryConfig = options?.retry;
|
|
1406
|
+
const executeHandler = async (retryCtx) => {
|
|
1407
|
+
handlerContext.retryContext = retryCtx;
|
|
1408
|
+
const result = await handler({ input, ctx: handlerContext });
|
|
1409
|
+
return outputSchema ? outputSchema.parse(result) : result;
|
|
1410
|
+
};
|
|
1411
|
+
if (workerRetryConfig && workerRetryConfig.on.length > 0) {
|
|
1412
|
+
output = await executeWithRetry(executeHandler, workerRetryConfig, (retryCtx, delayMs) => {
|
|
1413
|
+
logger.warn(
|
|
1414
|
+
`[worker-retry] Retrying handler (attempt ${retryCtx.attempt}/${retryCtx.maxAttempts}): ${retryCtx.lastError.message}`,
|
|
1415
|
+
{ delayMs }
|
|
1416
|
+
);
|
|
1417
|
+
});
|
|
1418
|
+
} else {
|
|
1419
|
+
output = await executeHandler(void 0);
|
|
1029
1420
|
}
|
|
1030
1421
|
} catch (error) {
|
|
1031
1422
|
const errorPayload = {
|
|
@@ -1057,7 +1448,7 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
1057
1448
|
});
|
|
1058
1449
|
}
|
|
1059
1450
|
}
|
|
1060
|
-
const queueCtxFail = input
|
|
1451
|
+
const queueCtxFail = getWorkerQueueContext(input, metadata);
|
|
1061
1452
|
if (queueCtxFail?.queueJobId && typeof queueCtxFail.stepIndex === "number") {
|
|
1062
1453
|
await notifyQueueJobStep(queueCtxFail.queueJobId, "fail", {
|
|
1063
1454
|
queueId: queueCtxFail.id,
|
|
@@ -1121,6 +1512,7 @@ function createLambdaHandler(handler, outputSchema) {
|
|
|
1121
1512
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1122
1513
|
0 && (module.exports = {
|
|
1123
1514
|
SQS_MAX_DELAY_SECONDS,
|
|
1515
|
+
TokenBudgetExceededError,
|
|
1124
1516
|
createLambdaHandler,
|
|
1125
1517
|
createWorkerLogger,
|
|
1126
1518
|
wrapHandlerForQueue
|