@sentry/junior 0.202.0 → 0.204.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-CMyTD4DD.js +17509 -0
- package/dist/agent-hooks-Bbcp9e33.js +4040 -0
- package/dist/agent-runner-DNb1A49M.js +678 -0
- package/dist/api/schema.d.ts +2728 -2639
- package/dist/api/schema.js +4 -169
- package/dist/api.d.ts +23 -17
- package/dist/api.js +3881 -5326
- package/dist/app-B1TOqBI8.d.ts +246 -0
- package/dist/app.d.ts +4 -520
- package/dist/app.js +9522 -11875
- package/dist/auth-pause-state-DosEalIG.js +168 -0
- package/dist/catalog-runtime-BReos-D4.js +7 -0
- package/dist/checkpoint-CNrPyRJN.js +2450 -0
- package/dist/cli/chat.d.ts +20 -0
- package/dist/cli/chat.js +229 -336
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.js +513 -806
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.js +63 -12
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +90 -159
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +43 -64
- package/dist/cli/plugins.d.ts +13 -0
- package/dist/cli/plugins.js +148 -227
- package/dist/cli/run.d.ts +16 -0
- package/dist/cli/run.js +52 -8
- package/dist/cli/snapshot-create.d.ts +4 -0
- package/dist/cli/snapshot-create.js +71 -125
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +232 -335
- package/dist/config-nGCW1OTG.js +941 -0
- package/dist/context-B45_WqVX.js +298 -0
- package/dist/conversation-privacy-B4voFRSm.js +182 -0
- package/dist/conversation-work-C6y3T5Hx.js +51 -0
- package/dist/credential-sync-kXr1hvO1.js +2660 -0
- package/dist/db-BeyXKJOI.d.ts +5 -0
- package/dist/destinations-BeBiJeEM.js +29 -0
- package/dist/execution-stats-DWfSihcH.js +373 -0
- package/dist/executor-DcMSlI5c.js +721 -0
- package/dist/experimental-CIXf7Uye.js +46 -0
- package/dist/history-ClE4toxe.d.ts +32 -0
- package/dist/history-CqTuSAdI.js +441 -0
- package/dist/instrumentation.d.ts +3 -3
- package/dist/instrumentation.js +130 -176
- package/dist/job-queue-Drn_LXlM.js +63 -0
- package/dist/logging-BzAk1S_s.js +1210 -0
- package/dist/model-profile-CZmVoGdX.js +49 -0
- package/dist/nitro.d.ts +31 -36
- package/dist/nitro.js +275 -456
- package/dist/oauth-callback-server-JiftokvA.js +130 -0
- package/dist/oauth-relay-CdCnu80W.js +62 -0
- package/dist/package-discovery-7a9YqLhE.js +455 -0
- package/dist/pending-auth-CWmSdZVg.js +185 -0
- package/dist/plugin-module-BKGOXca2.js +81 -0
- package/dist/plugins-BI9A1vKA.d.ts +95 -0
- package/dist/plugins-egKWjgue.js +99 -0
- package/dist/private-trace-result-BLvBjy_e.js +16 -0
- package/dist/profile-CrT5nXbw.js +861 -0
- package/dist/registry-DH1xUo2N.js +1419 -0
- package/dist/reporting-schema-DosTN__Q.js +105 -0
- package/dist/resolve-CZHnfxaS.js +546 -0
- package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
- package/dist/runner-CZV2sC46.js +392 -0
- package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
- package/dist/schema-Rn8-XEaN.js +1140 -0
- package/dist/sentry-CD3SdJl-.js +26 -0
- package/dist/skills-CIcDQSgM.js +316 -0
- package/dist/spawn-DdkUFRmq.js +29 -0
- package/dist/stats-DTUbAb88.js +2634 -0
- package/dist/store-C5qxF2ac.d.ts +208 -0
- package/dist/task-queue-CJIR4RF7.js +136 -0
- package/dist/task-runner-D-O3A-Cp.js +639 -0
- package/dist/thread-state-CRc9jTJS.js +431 -0
- package/dist/turn-execution-BkinIdJF.js +47 -0
- package/dist/turn-lifecycle-DQV19VTW.js +54 -0
- package/dist/usage-D3EbSO7w.js +296 -0
- package/dist/usage-schema-CKaDkH_j.js +20 -0
- package/dist/validation-C2CR-OX3.js +40 -0
- package/dist/vercel-queue-DIkVcfK4.js +167 -0
- package/dist/vercel.d.ts +6 -6
- package/dist/vercel.js +14 -6
- package/dist/version-CnXZ614E.d.ts +5 -0
- package/dist/version-DxcWdoKa.js +8 -0
- package/dist/version.d.ts +2 -4
- package/dist/version.js +2 -6
- package/dist/web-authorization-RMBxAR_t.js +76 -0
- package/dist/web-input-3EPfpf55.js +494 -0
- package/dist/work-fGofI7Op.js +509 -0
- package/dist/worker-CsOLq-mR.js +625 -0
- package/package.json +9 -9
- package/dist/agent-hooks-UXITLYOK.js +0 -51
- package/dist/catalog-runtime-BG3JLLK2.js +0 -14
- package/dist/chunk-2LYHWMR4.js +0 -46
- package/dist/chunk-2MK3QBGA.js +0 -321
- package/dist/chunk-3PGQSKJV.js +0 -692
- package/dist/chunk-3UI3WFTX.js +0 -519
- package/dist/chunk-3Y47VMHV.js +0 -6
- package/dist/chunk-4UO6FK4G.js +0 -64
- package/dist/chunk-5NOPO64K.js +0 -198
- package/dist/chunk-5PKWYPFT.js +0 -2943
- package/dist/chunk-63NKKFJL.js +0 -1228
- package/dist/chunk-6AYH6252.js +0 -787
- package/dist/chunk-6Y5B5PEX.js +0 -80
- package/dist/chunk-7DHZP5KJ.js +0 -333
- package/dist/chunk-7H2VZTWN.js +0 -103
- package/dist/chunk-7NL7T6VU.js +0 -406
- package/dist/chunk-A76OIMYN.js +0 -102
- package/dist/chunk-AWMS3SPP.js +0 -58
- package/dist/chunk-B3LY5RCL.js +0 -229
- package/dist/chunk-BD2KT3OB.js +0 -36
- package/dist/chunk-BXCX5QKA.js +0 -2086
- package/dist/chunk-C6VVF43U.js +0 -81
- package/dist/chunk-CEMMLV5L.js +0 -98
- package/dist/chunk-CM5HNV2W.js +0 -131
- package/dist/chunk-DA2KGZZI.js +0 -13
- package/dist/chunk-DBVY6HLX.js +0 -64
- package/dist/chunk-DIB4GX3G.js +0 -8
- package/dist/chunk-DKIJ2RP5.js +0 -68
- package/dist/chunk-DL2KLKVH.js +0 -931
- package/dist/chunk-DWPN6SCH.js +0 -172
- package/dist/chunk-ELWOYVOY.js +0 -206
- package/dist/chunk-EWT7H65X.js +0 -506
- package/dist/chunk-FA6POGLH.js +0 -70
- package/dist/chunk-HMREVIO2.js +0 -135
- package/dist/chunk-IIWUT4FO.js +0 -820
- package/dist/chunk-JAL3CH4G.js +0 -27
- package/dist/chunk-JSJQEWBJ.js +0 -3295
- package/dist/chunk-KHKKHDLD.js +0 -387
- package/dist/chunk-LA6R4A7Q.js +0 -706
- package/dist/chunk-LOOU2DUR.js +0 -20428
- package/dist/chunk-M6FHWXE3.js +0 -700
- package/dist/chunk-M76HMB7M.js +0 -1856
- package/dist/chunk-MAGNK5J4.js +0 -1520
- package/dist/chunk-MTM5IFCY.js +0 -1190
- package/dist/chunk-N7TMSOZH.js +0 -235
- package/dist/chunk-NHJU2ZAL.js +0 -56
- package/dist/chunk-NSXKRGRT.js +0 -717
- package/dist/chunk-OWMPFXJA.js +0 -1764
- package/dist/chunk-PDO5BLNM.js +0 -22
- package/dist/chunk-PEQXYSSE.js +0 -45
- package/dist/chunk-PW4P4JYF.js +0 -1135
- package/dist/chunk-QB54UQUS.js +0 -320
- package/dist/chunk-QP3OGJXF.js +0 -105
- package/dist/chunk-RC745GGZ.js +0 -122
- package/dist/chunk-REOIRYPR.js +0 -37
- package/dist/chunk-SCOZRLZ4.js +0 -164
- package/dist/chunk-TXJSXBV5.js +0 -1433
- package/dist/chunk-TXKUKMVO.js +0 -417
- package/dist/chunk-U2GPUYAL.js +0 -3656
- package/dist/chunk-UIE3R5XU.js +0 -17
- package/dist/chunk-UXPG6ZIN.js +0 -84
- package/dist/chunk-VFUK3X5B.js +0 -50
- package/dist/chunk-WQSHDTTI.js +0 -1163
- package/dist/chunk-X6GDDWQH.js +0 -60
- package/dist/chunk-Y2CM7HXH.js +0 -111
- package/dist/chunk-Y7X25LFY.js +0 -15
- package/dist/chunk-YDUR3ZYW.js +0 -10
- package/dist/conversation-work-VIOQ5ZF3.js +0 -54
- package/dist/db-3L2MCVRI.js +0 -26
- package/dist/discovery-DWVDM7UK.js +0 -44
- package/dist/experimental-P5FZM4CU.js +0 -12
- package/dist/oauth-callback-server-YVV6C6T2.js +0 -243
- package/dist/oauth-relay-5XPVRPYB.js +0 -8
- package/dist/plugins-YTYJMMJF.js +0 -14
- package/dist/runner-LQ7RETDP.js +0 -522
- package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
- package/dist/sentry-MB3NL3IR.js +0 -42
- package/dist/skills-XRWYEDCD.js +0 -27
- package/dist/spawn-RC6SJUAI.js +0 -42
- package/dist/task-runner-7DY7ARYH.js +0 -36
- package/dist/validation-7MNQGCJA.js +0 -17
- package/dist/work-COALHUCG.js +0 -51
- package/dist/worker-6MURZIPD.js +0 -24
package/dist/chunk-6AYH6252.js
DELETED
|
@@ -1,787 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CONVERSATION_WORK_CHECK_IN_INTERVAL_MS,
|
|
3
|
-
CONVERSATION_WORK_MAX_RETRIES,
|
|
4
|
-
ackMessages,
|
|
5
|
-
beginConversationResume,
|
|
6
|
-
checkInConversationWork,
|
|
7
|
-
clearConsumedConversationWake,
|
|
8
|
-
completeConversationStop,
|
|
9
|
-
completeConversationWork,
|
|
10
|
-
countPendingConversationMessages,
|
|
11
|
-
deadLetterAttempt,
|
|
12
|
-
drainConversationMailbox,
|
|
13
|
-
ensureConversationWake,
|
|
14
|
-
getConversationWorkState,
|
|
15
|
-
isFinalAttempt,
|
|
16
|
-
isInvalidConversationRecordError,
|
|
17
|
-
recordAttemptFailure,
|
|
18
|
-
recordConversationRetry,
|
|
19
|
-
releaseConversationWork,
|
|
20
|
-
requestAnotherSlice,
|
|
21
|
-
startConversationWork
|
|
22
|
-
} from "./chunk-OWMPFXJA.js";
|
|
23
|
-
import {
|
|
24
|
-
getTurnRequestDeadline
|
|
25
|
-
} from "./chunk-BD2KT3OB.js";
|
|
26
|
-
import {
|
|
27
|
-
ConversationQueueMessageRejectedError
|
|
28
|
-
} from "./chunk-JAL3CH4G.js";
|
|
29
|
-
import {
|
|
30
|
-
getChatConfig,
|
|
31
|
-
isProviderRetryError
|
|
32
|
-
} from "./chunk-63NKKFJL.js";
|
|
33
|
-
import {
|
|
34
|
-
logException,
|
|
35
|
-
logInfo,
|
|
36
|
-
logWarn,
|
|
37
|
-
withLogContext
|
|
38
|
-
} from "./chunk-MAGNK5J4.js";
|
|
39
|
-
|
|
40
|
-
// src/chat/task-execution/worker.ts
|
|
41
|
-
var CONVERSATION_WORK_DEFER_DELAY_MS = 15e3;
|
|
42
|
-
var CONVERSATION_STOP_CHECK_INTERVAL_MS = 500;
|
|
43
|
-
function now(options) {
|
|
44
|
-
return options.nowMs?.() ?? Date.now();
|
|
45
|
-
}
|
|
46
|
-
function selectContiguousTurnBatch(messages) {
|
|
47
|
-
const first = messages[0];
|
|
48
|
-
if (!first) {
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
const nextTurnIndex = messages.findIndex(
|
|
52
|
-
(message) => message.input.authorId !== first.input.authorId || message.source !== first.source
|
|
53
|
-
);
|
|
54
|
-
return messages.slice(
|
|
55
|
-
0,
|
|
56
|
-
nextTurnIndex === -1 ? messages.length : nextTurnIndex
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
function selectAttemptMessages(work) {
|
|
60
|
-
const messages = work.messages;
|
|
61
|
-
const interrupts = messages.filter(
|
|
62
|
-
(message) => message.delivery === "interrupt"
|
|
63
|
-
);
|
|
64
|
-
if (interrupts.length > 0) {
|
|
65
|
-
return selectContiguousTurnBatch(interrupts);
|
|
66
|
-
}
|
|
67
|
-
return work.execution.status === "paused" ? [] : selectContiguousTurnBatch(messages);
|
|
68
|
-
}
|
|
69
|
-
function nudgeIdempotencyKey(reason, conversationId, nowMs) {
|
|
70
|
-
return `${reason}:${conversationId}:${nowMs}`;
|
|
71
|
-
}
|
|
72
|
-
async function requestLostLeaseRecovery(args) {
|
|
73
|
-
const before = await getConversationWorkState({
|
|
74
|
-
conversationId: args.conversationId,
|
|
75
|
-
state: args.options.state
|
|
76
|
-
});
|
|
77
|
-
const retry = await recordConversationRetry({
|
|
78
|
-
conversationId: args.conversationId,
|
|
79
|
-
leaseToken: args.leaseToken,
|
|
80
|
-
conversationStore: args.options.conversationStore,
|
|
81
|
-
nowMs: args.nowMs,
|
|
82
|
-
state: args.options.state
|
|
83
|
-
});
|
|
84
|
-
if (retry === "lost_lease") {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (retry === "stopped") {
|
|
88
|
-
logException(
|
|
89
|
-
new Error("Conversation work stopped after repeated failed attempts"),
|
|
90
|
-
"conversation.work.retry.exhausted",
|
|
91
|
-
{
|
|
92
|
-
"app.run.id": before?.execution.runId ?? "unknown",
|
|
93
|
-
"app.worker.last_progress_at_ms": before?.execution.lastProgressAtMs ?? before?.createdAtMs ?? 0,
|
|
94
|
-
"app.worker.retry_count": (before?.execution.retryCount ?? 0) + 1
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const sliceRequested = await requestAnotherSlice({
|
|
100
|
-
conversationId: args.conversationId,
|
|
101
|
-
destination: args.destination,
|
|
102
|
-
leaseToken: args.leaseToken,
|
|
103
|
-
conversationStore: args.options.conversationStore,
|
|
104
|
-
nowMs: args.nowMs,
|
|
105
|
-
state: args.options.state
|
|
106
|
-
});
|
|
107
|
-
if (!sliceRequested) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const released = await releaseConversationWork({
|
|
111
|
-
conversationId: args.conversationId,
|
|
112
|
-
leaseToken: args.leaseToken,
|
|
113
|
-
conversationStore: args.options.conversationStore,
|
|
114
|
-
nowMs: args.nowMs,
|
|
115
|
-
state: args.options.state
|
|
116
|
-
});
|
|
117
|
-
if (!released) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
await ensureConversationWake({
|
|
121
|
-
conversationId: args.conversationId,
|
|
122
|
-
conversationStore: args.options.conversationStore,
|
|
123
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
124
|
-
"lost_lease",
|
|
125
|
-
args.conversationId,
|
|
126
|
-
args.nowMs
|
|
127
|
-
),
|
|
128
|
-
nowMs: args.nowMs,
|
|
129
|
-
queue: args.options.queue,
|
|
130
|
-
replaceExistingWake: true,
|
|
131
|
-
state: args.options.state
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
async function recordFailedDeliveryAttempt(args) {
|
|
135
|
-
const failure = await recordAttemptFailure({
|
|
136
|
-
conversationId: args.conversationId,
|
|
137
|
-
inboundMessageIds: args.messageIds,
|
|
138
|
-
leaseToken: args.leaseToken,
|
|
139
|
-
conversationStore: args.options.conversationStore,
|
|
140
|
-
nowMs: args.nowMs,
|
|
141
|
-
state: args.options.state
|
|
142
|
-
});
|
|
143
|
-
for (const message of failure.deadLetteredMessages) {
|
|
144
|
-
logWarn("conversation.work.dead_lettered", {
|
|
145
|
-
"app.conversation.source": message.source,
|
|
146
|
-
"app.inbound.attempt_count": message.attemptCount ?? 0,
|
|
147
|
-
"app.inbound.message_id": message.inboundMessageId,
|
|
148
|
-
"app.inbound.pending_count": failure.pendingCount
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
return failure;
|
|
152
|
-
}
|
|
153
|
-
function isTerminalFailure(failure) {
|
|
154
|
-
return failure.status === "recorded" && failure.deadLetteredMessages.length > 0 && failure.pendingCount === 0;
|
|
155
|
-
}
|
|
156
|
-
function logRetryExhausted(args) {
|
|
157
|
-
logException(args.error, "conversation.work.retry.exhausted", {
|
|
158
|
-
"app.run.id": args.work.execution.runId ?? "unknown",
|
|
159
|
-
"app.worker.last_progress_at_ms": args.work.execution.lastProgressAtMs ?? args.work.createdAtMs,
|
|
160
|
-
"app.worker.retry_count": args.retryCount
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
function startLeaseCheckIn(args) {
|
|
164
|
-
const timer = setInterval(() => {
|
|
165
|
-
const nowMs = now(args.options);
|
|
166
|
-
void checkInConversationWork({
|
|
167
|
-
conversationId: args.conversationId,
|
|
168
|
-
leaseToken: args.leaseToken,
|
|
169
|
-
conversationStore: args.options.conversationStore,
|
|
170
|
-
nowMs,
|
|
171
|
-
state: args.options.state
|
|
172
|
-
}).then(
|
|
173
|
-
(checkedIn) => {
|
|
174
|
-
if (!checkedIn) {
|
|
175
|
-
args.onLostLease();
|
|
176
|
-
logWarn("conversation.work.check_in.failed");
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
(error) => {
|
|
180
|
-
logException(error, "conversation.work.check_in.failed");
|
|
181
|
-
}
|
|
182
|
-
);
|
|
183
|
-
}, args.options.checkInIntervalMs ?? CONVERSATION_WORK_CHECK_IN_INTERVAL_MS);
|
|
184
|
-
timer.unref?.();
|
|
185
|
-
return timer;
|
|
186
|
-
}
|
|
187
|
-
function createConversationStopSignal(args) {
|
|
188
|
-
const controller = new AbortController();
|
|
189
|
-
let checking = false;
|
|
190
|
-
let failureCaptured = false;
|
|
191
|
-
let listening = false;
|
|
192
|
-
let timer;
|
|
193
|
-
const requestStop = () => {
|
|
194
|
-
if (!controller.signal.aborted) {
|
|
195
|
-
controller.abort(new Error("Conversation work stopped"));
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
if (args.initialStopRunId === args.runId) {
|
|
199
|
-
requestStop();
|
|
200
|
-
}
|
|
201
|
-
const check = async () => {
|
|
202
|
-
if (checking || controller.signal.aborted) return;
|
|
203
|
-
checking = true;
|
|
204
|
-
try {
|
|
205
|
-
const current = await getConversationWorkState({
|
|
206
|
-
conversationId: args.conversationId,
|
|
207
|
-
state: args.options.state
|
|
208
|
-
});
|
|
209
|
-
if (current?.execution.stop?.runId === args.runId) {
|
|
210
|
-
requestStop();
|
|
211
|
-
}
|
|
212
|
-
} catch (error) {
|
|
213
|
-
if (!failureCaptured) {
|
|
214
|
-
failureCaptured = true;
|
|
215
|
-
logException(error, "conversation.work.stop_check.failed");
|
|
216
|
-
}
|
|
217
|
-
} finally {
|
|
218
|
-
checking = false;
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
return {
|
|
222
|
-
close() {
|
|
223
|
-
if (timer) clearInterval(timer);
|
|
224
|
-
},
|
|
225
|
-
isEnabled() {
|
|
226
|
-
return listening;
|
|
227
|
-
},
|
|
228
|
-
wasObserved() {
|
|
229
|
-
return listening && controller.signal.aborted;
|
|
230
|
-
},
|
|
231
|
-
signal() {
|
|
232
|
-
listening = true;
|
|
233
|
-
if (!timer && !controller.signal.aborted) {
|
|
234
|
-
timer = setInterval(
|
|
235
|
-
() => void check(),
|
|
236
|
-
CONVERSATION_STOP_CHECK_INTERVAL_MS
|
|
237
|
-
);
|
|
238
|
-
timer.unref?.();
|
|
239
|
-
}
|
|
240
|
-
return controller.signal;
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
async function processConversationWork(message, options) {
|
|
245
|
-
return withLogContext(
|
|
246
|
-
{ conversationId: message.conversationId },
|
|
247
|
-
() => processConversationWorkInContext(message, options)
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
async function processConversationWorkInContext(message, options) {
|
|
251
|
-
const conversationId = message.conversationId;
|
|
252
|
-
let initial;
|
|
253
|
-
try {
|
|
254
|
-
initial = await getConversationWorkState({
|
|
255
|
-
conversationId,
|
|
256
|
-
state: options.state
|
|
257
|
-
});
|
|
258
|
-
} catch (error) {
|
|
259
|
-
if (isInvalidConversationRecordError(error)) {
|
|
260
|
-
throw new ConversationQueueMessageRejectedError(
|
|
261
|
-
"invalid_record",
|
|
262
|
-
`Conversation record failed validation for ${conversationId}`,
|
|
263
|
-
{ conversationId }
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
throw error;
|
|
267
|
-
}
|
|
268
|
-
if (!initial || countPendingConversationMessages(initial) === 0 && initial.execution.status === "idle" && !initial.execution.lease) {
|
|
269
|
-
if (initial) {
|
|
270
|
-
await clearConsumedConversationWake({
|
|
271
|
-
conversationId,
|
|
272
|
-
conversationStore: options.conversationStore,
|
|
273
|
-
nowMs: now(options),
|
|
274
|
-
state: options.state
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
return { status: "no_work" };
|
|
278
|
-
}
|
|
279
|
-
let destination = initial.destination;
|
|
280
|
-
if (!destination && options.conversationStore) {
|
|
281
|
-
const stored = await options.conversationStore.get({ conversationId });
|
|
282
|
-
if (stored && !stored.parentConversationId) {
|
|
283
|
-
destination = stored.destination;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
const lease = await startConversationWork({
|
|
287
|
-
conversationId,
|
|
288
|
-
conversationStore: options.conversationStore,
|
|
289
|
-
nowMs: now(options),
|
|
290
|
-
state: options.state
|
|
291
|
-
});
|
|
292
|
-
if (lease.status === "no_work") {
|
|
293
|
-
await clearConsumedConversationWake({
|
|
294
|
-
conversationId,
|
|
295
|
-
conversationStore: options.conversationStore,
|
|
296
|
-
nowMs: now(options),
|
|
297
|
-
state: options.state
|
|
298
|
-
});
|
|
299
|
-
return { status: "no_work" };
|
|
300
|
-
}
|
|
301
|
-
if (lease.status === "active") {
|
|
302
|
-
const nudgeNowMs = now(options);
|
|
303
|
-
await ensureConversationWake({
|
|
304
|
-
conversationId,
|
|
305
|
-
conversationStore: options.conversationStore,
|
|
306
|
-
delayMs: CONVERSATION_WORK_DEFER_DELAY_MS,
|
|
307
|
-
idempotencyKey: nudgeIdempotencyKey("active", conversationId, nudgeNowMs),
|
|
308
|
-
nowMs: nudgeNowMs,
|
|
309
|
-
queue: options.queue,
|
|
310
|
-
replaceExistingWake: true,
|
|
311
|
-
state: options.state
|
|
312
|
-
});
|
|
313
|
-
logInfo("conversation.work.nudge.deferred", {
|
|
314
|
-
"app.lease.expires_at_ms": lease.leaseExpiresAtMs
|
|
315
|
-
});
|
|
316
|
-
return { status: "active" };
|
|
317
|
-
}
|
|
318
|
-
const startedAtMs = now(options);
|
|
319
|
-
const softYieldDeadlineMs = startedAtMs + (options.softYieldAfterMs ?? getChatConfig().conversationWorkSoftYieldAfterMs);
|
|
320
|
-
let attemptMessageIds = [];
|
|
321
|
-
let attemptSelectedMessageIds = /* @__PURE__ */ new Set();
|
|
322
|
-
let attemptStartMessageIds = /* @__PURE__ */ new Set();
|
|
323
|
-
let failedWithoutProgress = false;
|
|
324
|
-
let leaseLost = false;
|
|
325
|
-
const markLeaseLost = () => {
|
|
326
|
-
leaseLost = true;
|
|
327
|
-
};
|
|
328
|
-
const timer = startLeaseCheckIn({
|
|
329
|
-
conversationId,
|
|
330
|
-
leaseToken: lease.leaseToken,
|
|
331
|
-
onLostLease: markLeaseLost,
|
|
332
|
-
options
|
|
333
|
-
});
|
|
334
|
-
logInfo("conversation.work.lease.acquired", {
|
|
335
|
-
"app.lease.expires_at_ms": lease.leaseExpiresAtMs,
|
|
336
|
-
"app.worker.soft_yield_deadline_ms": softYieldDeadlineMs
|
|
337
|
-
});
|
|
338
|
-
const drain = (handle) => drainConversationMailbox({
|
|
339
|
-
conversationId,
|
|
340
|
-
leaseToken: lease.leaseToken,
|
|
341
|
-
conversationStore: options.conversationStore,
|
|
342
|
-
handle: async (messages) => {
|
|
343
|
-
const candidates = messages.filter(
|
|
344
|
-
(message2) => message2.delivery === "interrupt" && (attemptSelectedMessageIds.has(message2.inboundMessageId) || !attemptStartMessageIds.has(message2.inboundMessageId))
|
|
345
|
-
);
|
|
346
|
-
if (candidates.length === 0) {
|
|
347
|
-
return [];
|
|
348
|
-
}
|
|
349
|
-
return await handle(candidates) ?? candidates.map((message2) => message2.inboundMessageId);
|
|
350
|
-
},
|
|
351
|
-
nowMs: now(options),
|
|
352
|
-
state: options.state
|
|
353
|
-
});
|
|
354
|
-
const requestDeadlineAtMs = getTurnRequestDeadline()?.deadlineAtMs;
|
|
355
|
-
const shouldYield = () => (
|
|
356
|
-
// Lease ownership is no longer confirmed, so this worker must stop.
|
|
357
|
-
leaseLost || // The worker soft limit reserves time to persist state and release the lease.
|
|
358
|
-
now(options) >= softYieldDeadlineMs || // Nested work can inherit an older host request deadline. Stop after that
|
|
359
|
-
// absolute deadline, even if this worker acquired its lease later.
|
|
360
|
-
requestDeadlineAtMs !== void 0 && Date.now() >= requestDeadlineAtMs
|
|
361
|
-
);
|
|
362
|
-
const checkIn = async () => {
|
|
363
|
-
const checkedIn = await checkInConversationWork({
|
|
364
|
-
conversationId,
|
|
365
|
-
leaseToken: lease.leaseToken,
|
|
366
|
-
conversationStore: options.conversationStore,
|
|
367
|
-
nowMs: now(options),
|
|
368
|
-
state: options.state
|
|
369
|
-
});
|
|
370
|
-
if (!checkedIn) {
|
|
371
|
-
markLeaseLost();
|
|
372
|
-
}
|
|
373
|
-
return checkedIn;
|
|
374
|
-
};
|
|
375
|
-
const yieldWork = async () => {
|
|
376
|
-
const yieldNowMs = now(options);
|
|
377
|
-
await ensureConversationWake({
|
|
378
|
-
conversationId,
|
|
379
|
-
conversationStore: options.conversationStore,
|
|
380
|
-
idempotencyKey: nudgeIdempotencyKey("yield", conversationId, yieldNowMs),
|
|
381
|
-
nowMs: yieldNowMs,
|
|
382
|
-
queue: options.queue,
|
|
383
|
-
replaceExistingWake: true,
|
|
384
|
-
state: options.state
|
|
385
|
-
});
|
|
386
|
-
const released = await releaseConversationWork({
|
|
387
|
-
conversationId,
|
|
388
|
-
leaseToken: lease.leaseToken,
|
|
389
|
-
conversationStore: options.conversationStore,
|
|
390
|
-
nowMs: yieldNowMs,
|
|
391
|
-
state: options.state
|
|
392
|
-
});
|
|
393
|
-
if (!released) {
|
|
394
|
-
return { status: "lost_lease" };
|
|
395
|
-
}
|
|
396
|
-
logInfo("conversation.work.yielded", {
|
|
397
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs,
|
|
398
|
-
"app.worker.soft_yield_deadline_ms": softYieldDeadlineMs
|
|
399
|
-
});
|
|
400
|
-
return { status: "yielded" };
|
|
401
|
-
};
|
|
402
|
-
try {
|
|
403
|
-
let hasRun = false;
|
|
404
|
-
let resumeIfStopped = false;
|
|
405
|
-
while (true) {
|
|
406
|
-
attemptMessageIds = [];
|
|
407
|
-
const leasedWork = await getConversationWorkState({
|
|
408
|
-
conversationId,
|
|
409
|
-
state: options.state
|
|
410
|
-
});
|
|
411
|
-
if (!leasedWork || leasedWork.lease?.leaseToken !== lease.leaseToken || leaseLost) {
|
|
412
|
-
markLeaseLost();
|
|
413
|
-
await requestLostLeaseRecovery({
|
|
414
|
-
conversationId,
|
|
415
|
-
destination,
|
|
416
|
-
leaseToken: lease.leaseToken,
|
|
417
|
-
nowMs: now(options),
|
|
418
|
-
options
|
|
419
|
-
});
|
|
420
|
-
return { status: "lost_lease" };
|
|
421
|
-
}
|
|
422
|
-
const resumePending = leasedWork.execution.status === "paused";
|
|
423
|
-
const attemptMessages = selectAttemptMessages(leasedWork);
|
|
424
|
-
const runId = leasedWork.execution.runId;
|
|
425
|
-
if (!runId) {
|
|
426
|
-
throw new Error(`Conversation run is missing for ${conversationId}`);
|
|
427
|
-
}
|
|
428
|
-
attemptStartMessageIds = new Set(
|
|
429
|
-
leasedWork.messages.map((message2) => message2.inboundMessageId)
|
|
430
|
-
);
|
|
431
|
-
if (hasRun && shouldYield()) {
|
|
432
|
-
if (resumePending) {
|
|
433
|
-
return await yieldWork();
|
|
434
|
-
}
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
if (resumePending && attemptMessages.length === 0) {
|
|
438
|
-
const resumeStarted = await beginConversationResume({
|
|
439
|
-
conversationId,
|
|
440
|
-
leaseToken: lease.leaseToken,
|
|
441
|
-
conversationStore: options.conversationStore,
|
|
442
|
-
nowMs: now(options),
|
|
443
|
-
state: options.state
|
|
444
|
-
});
|
|
445
|
-
if (!resumeStarted) {
|
|
446
|
-
markLeaseLost();
|
|
447
|
-
await requestLostLeaseRecovery({
|
|
448
|
-
conversationId,
|
|
449
|
-
destination,
|
|
450
|
-
leaseToken: lease.leaseToken,
|
|
451
|
-
nowMs: now(options),
|
|
452
|
-
options
|
|
453
|
-
});
|
|
454
|
-
return { status: "lost_lease" };
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
attemptMessageIds = attemptMessages.map(
|
|
458
|
-
(message2) => message2.inboundMessageId
|
|
459
|
-
);
|
|
460
|
-
attemptSelectedMessageIds = new Set(attemptMessageIds);
|
|
461
|
-
const ack = async () => {
|
|
462
|
-
const acknowledged = await ackMessages({
|
|
463
|
-
conversationId,
|
|
464
|
-
inboundMessageIds: attemptMessageIds,
|
|
465
|
-
leaseToken: lease.leaseToken,
|
|
466
|
-
conversationStore: options.conversationStore,
|
|
467
|
-
nowMs: now(options),
|
|
468
|
-
state: options.state
|
|
469
|
-
});
|
|
470
|
-
if (!acknowledged) {
|
|
471
|
-
markLeaseLost();
|
|
472
|
-
throw new Error(
|
|
473
|
-
`Conversation work lease lost before inbox ack for ${conversationId}`
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
const stop = createConversationStopSignal({
|
|
478
|
-
conversationId,
|
|
479
|
-
initialStopRunId: leasedWork.execution.stop?.runId,
|
|
480
|
-
options,
|
|
481
|
-
runId
|
|
482
|
-
});
|
|
483
|
-
const workerContext = {
|
|
484
|
-
attempt: {
|
|
485
|
-
ack,
|
|
486
|
-
conversationId,
|
|
487
|
-
destination,
|
|
488
|
-
drain,
|
|
489
|
-
isFinalAttempt: attemptMessages.some(
|
|
490
|
-
(message2) => isFinalAttempt(message2)
|
|
491
|
-
),
|
|
492
|
-
messages: attemptMessages
|
|
493
|
-
},
|
|
494
|
-
conversationId,
|
|
495
|
-
destination,
|
|
496
|
-
shouldYield,
|
|
497
|
-
stopSignal: stop.signal,
|
|
498
|
-
checkIn
|
|
499
|
-
};
|
|
500
|
-
let result;
|
|
501
|
-
try {
|
|
502
|
-
result = await options.run(workerContext);
|
|
503
|
-
} finally {
|
|
504
|
-
stop.close();
|
|
505
|
-
}
|
|
506
|
-
resumeIfStopped ||= stop.isEnabled();
|
|
507
|
-
hasRun = true;
|
|
508
|
-
if (result.status === "lost_lease") {
|
|
509
|
-
await requestLostLeaseRecovery({
|
|
510
|
-
conversationId,
|
|
511
|
-
destination,
|
|
512
|
-
leaseToken: lease.leaseToken,
|
|
513
|
-
nowMs: now(options),
|
|
514
|
-
options
|
|
515
|
-
});
|
|
516
|
-
return { status: "lost_lease" };
|
|
517
|
-
}
|
|
518
|
-
if (leaseLost) {
|
|
519
|
-
await requestLostLeaseRecovery({
|
|
520
|
-
conversationId,
|
|
521
|
-
destination,
|
|
522
|
-
leaseToken: lease.leaseToken,
|
|
523
|
-
nowMs: now(options),
|
|
524
|
-
options
|
|
525
|
-
});
|
|
526
|
-
return { status: "lost_lease" };
|
|
527
|
-
}
|
|
528
|
-
if (result.status === "completed" && stop.wasObserved()) {
|
|
529
|
-
const stopped = await completeConversationStop({
|
|
530
|
-
conversationId,
|
|
531
|
-
conversationStore: options.conversationStore,
|
|
532
|
-
leaseToken: lease.leaseToken,
|
|
533
|
-
nowMs: now(options),
|
|
534
|
-
runId,
|
|
535
|
-
state: options.state
|
|
536
|
-
});
|
|
537
|
-
if (stopped.status === "lost_lease") {
|
|
538
|
-
markLeaseLost();
|
|
539
|
-
await requestLostLeaseRecovery({
|
|
540
|
-
conversationId,
|
|
541
|
-
destination,
|
|
542
|
-
leaseToken: lease.leaseToken,
|
|
543
|
-
nowMs: now(options),
|
|
544
|
-
options
|
|
545
|
-
});
|
|
546
|
-
return { status: "lost_lease" };
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (result.status === "yielded") {
|
|
550
|
-
const sliceRequested = await requestAnotherSlice({
|
|
551
|
-
conversationId,
|
|
552
|
-
destination,
|
|
553
|
-
leaseToken: lease.leaseToken,
|
|
554
|
-
conversationStore: options.conversationStore,
|
|
555
|
-
nowMs: now(options),
|
|
556
|
-
state: options.state
|
|
557
|
-
});
|
|
558
|
-
if (!sliceRequested) {
|
|
559
|
-
return { status: "lost_lease" };
|
|
560
|
-
}
|
|
561
|
-
return await yieldWork();
|
|
562
|
-
}
|
|
563
|
-
if (result.status === "deferred") {
|
|
564
|
-
const deferredNowMs = now(options);
|
|
565
|
-
const released = await releaseConversationWork({
|
|
566
|
-
conversationId,
|
|
567
|
-
leaseToken: lease.leaseToken,
|
|
568
|
-
conversationStore: options.conversationStore,
|
|
569
|
-
nowMs: deferredNowMs,
|
|
570
|
-
state: options.state
|
|
571
|
-
});
|
|
572
|
-
if (!released) {
|
|
573
|
-
return { status: "lost_lease" };
|
|
574
|
-
}
|
|
575
|
-
const wake = await ensureConversationWake({
|
|
576
|
-
conversationId,
|
|
577
|
-
conversationStore: options.conversationStore,
|
|
578
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
579
|
-
"deferred",
|
|
580
|
-
conversationId,
|
|
581
|
-
deferredNowMs
|
|
582
|
-
),
|
|
583
|
-
nowMs: deferredNowMs,
|
|
584
|
-
queue: options.queue,
|
|
585
|
-
state: options.state
|
|
586
|
-
});
|
|
587
|
-
return wake.status === "enqueued" ? { status: "pending_requeued" } : { status: "completed" };
|
|
588
|
-
}
|
|
589
|
-
if (attemptMessageIds.length > 0) {
|
|
590
|
-
const failure = await recordFailedDeliveryAttempt({
|
|
591
|
-
conversationId,
|
|
592
|
-
leaseToken: lease.leaseToken,
|
|
593
|
-
nowMs: now(options),
|
|
594
|
-
messageIds: attemptMessageIds,
|
|
595
|
-
options
|
|
596
|
-
});
|
|
597
|
-
if (isTerminalFailure(failure)) {
|
|
598
|
-
if (failure.retryCount >= CONVERSATION_WORK_MAX_RETRIES) {
|
|
599
|
-
logRetryExhausted({
|
|
600
|
-
error: new Error(
|
|
601
|
-
"Conversation work stopped after repeated failed attempts"
|
|
602
|
-
),
|
|
603
|
-
retryCount: failure.retryCount,
|
|
604
|
-
work: leasedWork
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
await deadLetterAttempt({
|
|
608
|
-
conversationId,
|
|
609
|
-
leaseToken: lease.leaseToken,
|
|
610
|
-
conversationStore: options.conversationStore,
|
|
611
|
-
nowMs: now(options),
|
|
612
|
-
state: options.state
|
|
613
|
-
});
|
|
614
|
-
return { status: "failed" };
|
|
615
|
-
}
|
|
616
|
-
if (failure.status === "lost_lease") {
|
|
617
|
-
return { status: "lost_lease" };
|
|
618
|
-
}
|
|
619
|
-
if (failure.status === "recorded") {
|
|
620
|
-
failedWithoutProgress = true;
|
|
621
|
-
break;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
if (result.status === "paused") {
|
|
625
|
-
break;
|
|
626
|
-
}
|
|
627
|
-
const next = await getConversationWorkState({
|
|
628
|
-
conversationId,
|
|
629
|
-
state: options.state
|
|
630
|
-
});
|
|
631
|
-
if (!next || next.lease?.leaseToken !== lease.leaseToken) {
|
|
632
|
-
return { status: "lost_lease" };
|
|
633
|
-
}
|
|
634
|
-
if (next.execution.status !== "paused" && countPendingConversationMessages(next) === 0) {
|
|
635
|
-
break;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
const completion = await completeConversationWork({
|
|
639
|
-
conversationId,
|
|
640
|
-
leaseToken: lease.leaseToken,
|
|
641
|
-
madeProgress: !failedWithoutProgress,
|
|
642
|
-
// A stop that raced an external pause must reach the paused Turn.
|
|
643
|
-
resumeIfStopped,
|
|
644
|
-
conversationStore: options.conversationStore,
|
|
645
|
-
nowMs: now(options),
|
|
646
|
-
state: options.state
|
|
647
|
-
});
|
|
648
|
-
if (completion === "lost_lease") {
|
|
649
|
-
return { status: "lost_lease" };
|
|
650
|
-
}
|
|
651
|
-
if (completion === "pending") {
|
|
652
|
-
const nudgeNowMs = now(options);
|
|
653
|
-
const wake = await ensureConversationWake({
|
|
654
|
-
conversationId,
|
|
655
|
-
conversationStore: options.conversationStore,
|
|
656
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
657
|
-
"pending",
|
|
658
|
-
conversationId,
|
|
659
|
-
nudgeNowMs
|
|
660
|
-
),
|
|
661
|
-
nowMs: nudgeNowMs,
|
|
662
|
-
queue: options.queue,
|
|
663
|
-
state: options.state
|
|
664
|
-
});
|
|
665
|
-
return wake.status === "enqueued" ? { status: "pending_requeued" } : { status: "completed" };
|
|
666
|
-
}
|
|
667
|
-
logInfo("conversation.work.completed", {
|
|
668
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs
|
|
669
|
-
});
|
|
670
|
-
return { status: "completed" };
|
|
671
|
-
} catch (error) {
|
|
672
|
-
const errorNowMs = now(options);
|
|
673
|
-
let recoveryRecorded = false;
|
|
674
|
-
try {
|
|
675
|
-
const failure = attemptMessageIds.length > 0 ? await recordFailedDeliveryAttempt({
|
|
676
|
-
conversationId,
|
|
677
|
-
leaseToken: lease.leaseToken,
|
|
678
|
-
nowMs: errorNowMs,
|
|
679
|
-
messageIds: attemptMessageIds,
|
|
680
|
-
options
|
|
681
|
-
}) : void 0;
|
|
682
|
-
if (failure && isTerminalFailure(failure)) {
|
|
683
|
-
if (failure.retryCount >= CONVERSATION_WORK_MAX_RETRIES) {
|
|
684
|
-
logRetryExhausted({
|
|
685
|
-
error,
|
|
686
|
-
retryCount: failure.retryCount,
|
|
687
|
-
work: initial
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
await deadLetterAttempt({
|
|
691
|
-
conversationId,
|
|
692
|
-
leaseToken: lease.leaseToken,
|
|
693
|
-
conversationStore: options.conversationStore,
|
|
694
|
-
nowMs: errorNowMs,
|
|
695
|
-
state: options.state
|
|
696
|
-
});
|
|
697
|
-
} else if (failure?.status === "recorded") {
|
|
698
|
-
await releaseConversationWork({
|
|
699
|
-
conversationId,
|
|
700
|
-
leaseToken: lease.leaseToken,
|
|
701
|
-
conversationStore: options.conversationStore,
|
|
702
|
-
nowMs: errorNowMs,
|
|
703
|
-
state: options.state
|
|
704
|
-
});
|
|
705
|
-
await ensureConversationWake({
|
|
706
|
-
conversationId,
|
|
707
|
-
conversationStore: options.conversationStore,
|
|
708
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
709
|
-
"error",
|
|
710
|
-
conversationId,
|
|
711
|
-
errorNowMs
|
|
712
|
-
),
|
|
713
|
-
nowMs: errorNowMs,
|
|
714
|
-
queue: options.queue,
|
|
715
|
-
replaceExistingWake: true,
|
|
716
|
-
state: options.state
|
|
717
|
-
});
|
|
718
|
-
} else {
|
|
719
|
-
const retry = failure ? failure.status : await recordConversationRetry({
|
|
720
|
-
conversationId,
|
|
721
|
-
leaseToken: lease.leaseToken,
|
|
722
|
-
conversationStore: options.conversationStore,
|
|
723
|
-
nowMs: errorNowMs,
|
|
724
|
-
state: options.state
|
|
725
|
-
});
|
|
726
|
-
if (retry === "stopped") {
|
|
727
|
-
logException(error, "conversation.work.retry.exhausted", {
|
|
728
|
-
"app.run.id": initial.execution.runId ?? "unknown",
|
|
729
|
-
"app.worker.last_progress_at_ms": initial.execution.lastProgressAtMs ?? initial.createdAtMs,
|
|
730
|
-
"app.worker.retry_count": failure?.retryCount ?? (initial.execution.retryCount ?? 0) + 1
|
|
731
|
-
});
|
|
732
|
-
recoveryRecorded = true;
|
|
733
|
-
return { status: "failed" };
|
|
734
|
-
}
|
|
735
|
-
const sliceRequested = await requestAnotherSlice({
|
|
736
|
-
conversationId,
|
|
737
|
-
destination,
|
|
738
|
-
leaseToken: lease.leaseToken,
|
|
739
|
-
conversationStore: options.conversationStore,
|
|
740
|
-
nowMs: errorNowMs,
|
|
741
|
-
state: options.state
|
|
742
|
-
});
|
|
743
|
-
if (sliceRequested) {
|
|
744
|
-
await ensureConversationWake({
|
|
745
|
-
conversationId,
|
|
746
|
-
conversationStore: options.conversationStore,
|
|
747
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
748
|
-
"error",
|
|
749
|
-
conversationId,
|
|
750
|
-
errorNowMs
|
|
751
|
-
),
|
|
752
|
-
nowMs: errorNowMs,
|
|
753
|
-
queue: options.queue,
|
|
754
|
-
replaceExistingWake: true,
|
|
755
|
-
state: options.state
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
await releaseConversationWork({
|
|
759
|
-
conversationId,
|
|
760
|
-
leaseToken: lease.leaseToken,
|
|
761
|
-
conversationStore: options.conversationStore,
|
|
762
|
-
nowMs: errorNowMs,
|
|
763
|
-
state: options.state
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
recoveryRecorded = true;
|
|
767
|
-
} catch (recoveryError) {
|
|
768
|
-
logException(recoveryError, "conversation.work.requeue.failed");
|
|
769
|
-
}
|
|
770
|
-
if (!isProviderRetryError(error)) {
|
|
771
|
-
logException(error, "conversation.work.failed", {
|
|
772
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
if (!recoveryRecorded) {
|
|
776
|
-
throw error;
|
|
777
|
-
}
|
|
778
|
-
return { status: "failed" };
|
|
779
|
-
} finally {
|
|
780
|
-
clearInterval(timer);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
export {
|
|
785
|
-
CONVERSATION_WORK_DEFER_DELAY_MS,
|
|
786
|
-
processConversationWork
|
|
787
|
-
};
|