@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-OWMPFXJA.js
DELETED
|
@@ -1,1764 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CONVERSATION_QUEUE_SCHEMA_VERSION
|
|
3
|
-
} from "./chunk-JAL3CH4G.js";
|
|
4
|
-
import {
|
|
5
|
-
JUNIOR_THREAD_STATE_TTL_MS
|
|
6
|
-
} from "./chunk-3Y47VMHV.js";
|
|
7
|
-
import {
|
|
8
|
-
getConversationStore,
|
|
9
|
-
parseDestination,
|
|
10
|
-
sameDestination
|
|
11
|
-
} from "./chunk-M76HMB7M.js";
|
|
12
|
-
import {
|
|
13
|
-
getDefaultRedisStateAdapterFor,
|
|
14
|
-
getStateAdapter
|
|
15
|
-
} from "./chunk-2MK3QBGA.js";
|
|
16
|
-
import {
|
|
17
|
-
getChatConfig
|
|
18
|
-
} from "./chunk-63NKKFJL.js";
|
|
19
|
-
import {
|
|
20
|
-
parseStoredSlackActor
|
|
21
|
-
} from "./chunk-N7TMSOZH.js";
|
|
22
|
-
import {
|
|
23
|
-
isRecord,
|
|
24
|
-
toOptionalNumber,
|
|
25
|
-
toOptionalString
|
|
26
|
-
} from "./chunk-MAGNK5J4.js";
|
|
27
|
-
|
|
28
|
-
// src/chat/task-execution/state.ts
|
|
29
|
-
import { randomUUID } from "crypto";
|
|
30
|
-
import { destinationSchema } from "@sentry/junior-plugin-api";
|
|
31
|
-
import { z } from "zod";
|
|
32
|
-
var CONVERSATION_PREFIX = "junior:conversation:v2";
|
|
33
|
-
var CONVERSATION_SCHEMA_VERSION = 2;
|
|
34
|
-
var CONVERSATION_ACTIVITY_INDEX_MAX_LENGTH = 1e4;
|
|
35
|
-
var CONVERSATION_INDEX_LOCK_TTL_MS = 1e4;
|
|
36
|
-
var CONVERSATION_INDEX_LOCK_WAIT_MS = 2e3;
|
|
37
|
-
var CONVERSATION_INDEX_LOCK_RETRY_MS = 25;
|
|
38
|
-
var CONVERSATION_MUTATION_LOCK_TTL_MS = 1e4;
|
|
39
|
-
var CONVERSATION_MUTATION_WAIT_MS = 1e4;
|
|
40
|
-
var CONVERSATION_MUTATION_RETRY_MS = 25;
|
|
41
|
-
var InvalidConversationRecordError = class extends Error {
|
|
42
|
-
constructor(conversationId) {
|
|
43
|
-
super(`Conversation record is invalid for ${conversationId}`);
|
|
44
|
-
this.name = "InvalidConversationRecordError";
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
function isInvalidConversationRecordError(error) {
|
|
48
|
-
return error instanceof InvalidConversationRecordError;
|
|
49
|
-
}
|
|
50
|
-
var ConversationMutationFencedError = class extends Error {
|
|
51
|
-
constructor(conversationId) {
|
|
52
|
-
super(
|
|
53
|
-
`Conversation mutation lock was lost before write for ${conversationId}`
|
|
54
|
-
);
|
|
55
|
-
this.name = "ConversationMutationFencedError";
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
var CONVERSATION_BY_ACTIVITY_INDEX_KEY = `${CONVERSATION_PREFIX}:by-activity`;
|
|
59
|
-
var CONVERSATION_ACTIVE_INDEX_KEY = `${CONVERSATION_PREFIX}:active`;
|
|
60
|
-
var CONVERSATION_WORK_LEASE_TTL_MS = 9e4;
|
|
61
|
-
var CONVERSATION_WORK_CHECK_IN_INTERVAL_MS = 15e3;
|
|
62
|
-
var CONVERSATION_WORK_STALE_ENQUEUE_MS = 6e4;
|
|
63
|
-
var CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS = 5;
|
|
64
|
-
var CONVERSATION_WORK_MAX_RETRIES = 5;
|
|
65
|
-
var inboundMessageSourceSchema = z.enum([
|
|
66
|
-
"api",
|
|
67
|
-
"internal",
|
|
68
|
-
"local",
|
|
69
|
-
"plugin",
|
|
70
|
-
"resource_event",
|
|
71
|
-
"scheduler",
|
|
72
|
-
"slack",
|
|
73
|
-
"web"
|
|
74
|
-
]);
|
|
75
|
-
var agentInputSchema = z.object({
|
|
76
|
-
attachments: z.array(z.unknown()).optional(),
|
|
77
|
-
authorId: z.string().min(1).optional(),
|
|
78
|
-
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
79
|
-
text: z.string()
|
|
80
|
-
}).strict().refine((input) => input.text.trim() || input.attachments?.length, {
|
|
81
|
-
message: "agent input requires text or attachments"
|
|
82
|
-
});
|
|
83
|
-
var inboundMessageDeliverySchema = z.enum(["defer", "interrupt"]);
|
|
84
|
-
var inboundMessageSchema = z.object({
|
|
85
|
-
attemptCount: z.number().finite().optional(),
|
|
86
|
-
conversationId: z.string().refine((value) => value.trim().length > 0),
|
|
87
|
-
createdAtMs: z.number().finite(),
|
|
88
|
-
delivery: inboundMessageDeliverySchema,
|
|
89
|
-
destination: destinationSchema.optional(),
|
|
90
|
-
inboundMessageId: z.string().refine((value) => value.trim().length > 0),
|
|
91
|
-
injectedAtMs: z.number().finite().optional(),
|
|
92
|
-
input: agentInputSchema,
|
|
93
|
-
receivedAtMs: z.number().finite(),
|
|
94
|
-
source: inboundMessageSourceSchema
|
|
95
|
-
}).strict();
|
|
96
|
-
var storedInboundMessageSchema = inboundMessageSchema.extend({
|
|
97
|
-
publishExternally: z.boolean()
|
|
98
|
-
});
|
|
99
|
-
function conversationKey(conversationId) {
|
|
100
|
-
return `${CONVERSATION_PREFIX}:${conversationId}`;
|
|
101
|
-
}
|
|
102
|
-
function indexLockKey(indexKey) {
|
|
103
|
-
return `${indexKey}:lock`;
|
|
104
|
-
}
|
|
105
|
-
function mutationLockKey(conversationId) {
|
|
106
|
-
return `${CONVERSATION_PREFIX}:mutation:${conversationId}`;
|
|
107
|
-
}
|
|
108
|
-
function now() {
|
|
109
|
-
return Date.now();
|
|
110
|
-
}
|
|
111
|
-
function compareMessages(left, right) {
|
|
112
|
-
return left.createdAtMs - right.createdAtMs || left.receivedAtMs - right.receivedAtMs || left.inboundMessageId.localeCompare(right.inboundMessageId);
|
|
113
|
-
}
|
|
114
|
-
function inputHasAttachments(input) {
|
|
115
|
-
return Array.isArray(input.attachments) && input.attachments.length > 0;
|
|
116
|
-
}
|
|
117
|
-
function upgradedPendingMessage(stored, duplicate) {
|
|
118
|
-
const promotesInterrupt = stored.delivery === "defer" && duplicate.delivery === "interrupt";
|
|
119
|
-
const delivery = promotesInterrupt ? "interrupt" : stored.delivery;
|
|
120
|
-
const input = promotesInterrupt ? {
|
|
121
|
-
...duplicate.input,
|
|
122
|
-
...inputHasAttachments(duplicate.input) || !inputHasAttachments(stored.input) ? void 0 : { attachments: stored.input.attachments }
|
|
123
|
-
} : inputHasAttachments(duplicate.input) && !inputHasAttachments(stored.input) ? duplicate.input : stored.input;
|
|
124
|
-
if (input === stored.input && delivery === stored.delivery) {
|
|
125
|
-
return stored;
|
|
126
|
-
}
|
|
127
|
-
return { ...stored, delivery, input };
|
|
128
|
-
}
|
|
129
|
-
function compareIndexDescending(left, right) {
|
|
130
|
-
return right.score - left.score || right.conversationId.localeCompare(left.conversationId);
|
|
131
|
-
}
|
|
132
|
-
function compareIndexAscending(left, right) {
|
|
133
|
-
return left.score - right.score || left.conversationId.localeCompare(right.conversationId);
|
|
134
|
-
}
|
|
135
|
-
function uniqueStrings(values) {
|
|
136
|
-
return [...new Set(values)];
|
|
137
|
-
}
|
|
138
|
-
function normalizeSource(value) {
|
|
139
|
-
const parsed = inboundMessageSourceSchema.safeParse(value);
|
|
140
|
-
return parsed.success ? parsed.data : void 0;
|
|
141
|
-
}
|
|
142
|
-
function normalizeExecutionStatus(value) {
|
|
143
|
-
if (value === "paused") {
|
|
144
|
-
return value;
|
|
145
|
-
}
|
|
146
|
-
if (value === "failed" || value === "idle" || value === "pending" || value === "running") {
|
|
147
|
-
return value;
|
|
148
|
-
}
|
|
149
|
-
return void 0;
|
|
150
|
-
}
|
|
151
|
-
function normalizeMessage(value) {
|
|
152
|
-
const parsed = storedInboundMessageSchema.safeParse(value);
|
|
153
|
-
if (!parsed.success) {
|
|
154
|
-
return void 0;
|
|
155
|
-
}
|
|
156
|
-
const { publishExternally: _publishExternally, ...message } = parsed.data;
|
|
157
|
-
return message;
|
|
158
|
-
}
|
|
159
|
-
function storeMessage(message, publishExternally) {
|
|
160
|
-
return { ...message, publishExternally };
|
|
161
|
-
}
|
|
162
|
-
function isFinalAttempt(message) {
|
|
163
|
-
return (message.attemptCount ?? 0) >= CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS - 1;
|
|
164
|
-
}
|
|
165
|
-
function normalizeActor(value) {
|
|
166
|
-
return parseStoredSlackActor(value);
|
|
167
|
-
}
|
|
168
|
-
function normalizeLease(value) {
|
|
169
|
-
if (!isRecord(value)) {
|
|
170
|
-
return void 0;
|
|
171
|
-
}
|
|
172
|
-
const token = toOptionalString(value.token);
|
|
173
|
-
const acquiredAtMs = toOptionalNumber(value.acquiredAtMs);
|
|
174
|
-
const lastCheckInAtMs = toOptionalNumber(value.lastCheckInAtMs);
|
|
175
|
-
const expiresAtMs = toOptionalNumber(value.expiresAtMs);
|
|
176
|
-
if (!token || typeof acquiredAtMs !== "number" || typeof lastCheckInAtMs !== "number" || typeof expiresAtMs !== "number") {
|
|
177
|
-
return void 0;
|
|
178
|
-
}
|
|
179
|
-
return {
|
|
180
|
-
token,
|
|
181
|
-
acquiredAtMs,
|
|
182
|
-
lastCheckInAtMs,
|
|
183
|
-
expiresAtMs
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
function normalizeStop(value) {
|
|
187
|
-
if (!isRecord(value)) {
|
|
188
|
-
return void 0;
|
|
189
|
-
}
|
|
190
|
-
const inboundMessageIds = Array.isArray(value.inboundMessageIds) ? uniqueStrings(
|
|
191
|
-
value.inboundMessageIds.filter(
|
|
192
|
-
(id) => typeof id === "string"
|
|
193
|
-
)
|
|
194
|
-
) : [];
|
|
195
|
-
const runId = toOptionalString(value.runId);
|
|
196
|
-
return runId ? { inboundMessageIds, runId } : void 0;
|
|
197
|
-
}
|
|
198
|
-
function normalizeExecution(conversationId, value) {
|
|
199
|
-
if (!isRecord(value)) {
|
|
200
|
-
return void 0;
|
|
201
|
-
}
|
|
202
|
-
const status = normalizeExecutionStatus(value.status);
|
|
203
|
-
if (!status) {
|
|
204
|
-
return void 0;
|
|
205
|
-
}
|
|
206
|
-
const pendingMessages2 = [];
|
|
207
|
-
if (Array.isArray(value.pendingMessages)) {
|
|
208
|
-
for (const rawMessage of value.pendingMessages) {
|
|
209
|
-
const message = normalizeMessage(rawMessage);
|
|
210
|
-
if (!message || message.conversationId !== conversationId) {
|
|
211
|
-
return void 0;
|
|
212
|
-
}
|
|
213
|
-
if (message.injectedAtMs !== void 0) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
pendingMessages2.push(message);
|
|
217
|
-
}
|
|
218
|
-
pendingMessages2.sort(compareMessages);
|
|
219
|
-
}
|
|
220
|
-
const inboundMessageIds = Array.isArray(value.inboundMessageIds) ? uniqueStrings(
|
|
221
|
-
value.inboundMessageIds.map((id) => typeof id === "string" ? id : void 0).filter((id) => Boolean(id))
|
|
222
|
-
) : [];
|
|
223
|
-
const lease = normalizeLease(value.lease);
|
|
224
|
-
const runId = toOptionalString(value.runId);
|
|
225
|
-
const normalizedStop = normalizeStop(value.stop);
|
|
226
|
-
const stop = normalizedStop?.runId === runId ? normalizedStop : void 0;
|
|
227
|
-
const normalizedStatus = status === "idle" && lease ? "running" : status === "idle" && pendingMessages2.length > 0 ? "pending" : status;
|
|
228
|
-
return {
|
|
229
|
-
status: normalizedStatus,
|
|
230
|
-
inboundMessageIds: uniqueStrings([
|
|
231
|
-
...inboundMessageIds,
|
|
232
|
-
...pendingMessages2.map((message) => message.inboundMessageId)
|
|
233
|
-
]),
|
|
234
|
-
pendingCount: pendingMessages2.length,
|
|
235
|
-
pendingMessages: pendingMessages2,
|
|
236
|
-
lease,
|
|
237
|
-
lastCheckpointAtMs: toOptionalNumber(value.lastCheckpointAtMs),
|
|
238
|
-
lastEnqueuedAtMs: toOptionalNumber(value.lastEnqueuedAtMs),
|
|
239
|
-
lastProgressAtMs: toOptionalNumber(value.lastProgressAtMs),
|
|
240
|
-
retryCount: toOptionalNumber(value.retryCount),
|
|
241
|
-
runId,
|
|
242
|
-
stop,
|
|
243
|
-
updatedAtMs: toOptionalNumber(value.updatedAtMs)
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
function normalizeConversation(conversationId, value) {
|
|
247
|
-
if (!isRecord(value) || value.schemaVersion !== CONVERSATION_SCHEMA_VERSION) {
|
|
248
|
-
return void 0;
|
|
249
|
-
}
|
|
250
|
-
const storedConversationId = toOptionalString(value.conversationId);
|
|
251
|
-
const createdAtMs = toOptionalNumber(value.createdAtMs);
|
|
252
|
-
const lastActivityAtMs = toOptionalNumber(value.lastActivityAtMs);
|
|
253
|
-
const updatedAtMs = toOptionalNumber(value.updatedAtMs);
|
|
254
|
-
const execution = normalizeExecution(conversationId, value.execution);
|
|
255
|
-
const destination = value.destination === void 0 ? void 0 : parseDestination(value.destination);
|
|
256
|
-
if (storedConversationId !== conversationId || typeof createdAtMs !== "number" || typeof lastActivityAtMs !== "number" || typeof updatedAtMs !== "number" || !execution || value.destination !== void 0 && !destination) {
|
|
257
|
-
return void 0;
|
|
258
|
-
}
|
|
259
|
-
if (execution.pendingMessages.length > 0 && execution.pendingMessages.some((message) => {
|
|
260
|
-
if (!message.destination) {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
return !destination || !sameDestination(message.destination, destination);
|
|
264
|
-
})) {
|
|
265
|
-
return void 0;
|
|
266
|
-
}
|
|
267
|
-
return {
|
|
268
|
-
schemaVersion: CONVERSATION_SCHEMA_VERSION,
|
|
269
|
-
conversationId,
|
|
270
|
-
createdAtMs,
|
|
271
|
-
lastActivityAtMs,
|
|
272
|
-
updatedAtMs,
|
|
273
|
-
execution,
|
|
274
|
-
...destination ? { destination } : void 0,
|
|
275
|
-
...toOptionalString(value.title) ? { title: toOptionalString(value.title) } : void 0,
|
|
276
|
-
...toOptionalString(value.channelName) ? { channelName: toOptionalString(value.channelName) } : void 0,
|
|
277
|
-
...normalizeActor(value.actor) ? { actor: normalizeActor(value.actor) } : void 0,
|
|
278
|
-
...normalizeSource(value.source) ? { source: normalizeSource(value.source) } : void 0
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
function emptyConversation(args) {
|
|
282
|
-
return {
|
|
283
|
-
schemaVersion: CONVERSATION_SCHEMA_VERSION,
|
|
284
|
-
conversationId: args.conversationId,
|
|
285
|
-
createdAtMs: args.nowMs,
|
|
286
|
-
lastActivityAtMs: args.nowMs,
|
|
287
|
-
updatedAtMs: args.nowMs,
|
|
288
|
-
...args.destination ? { destination: args.destination } : void 0,
|
|
289
|
-
...args.source ? { source: args.source } : void 0,
|
|
290
|
-
execution: {
|
|
291
|
-
status: "idle",
|
|
292
|
-
inboundMessageIds: [],
|
|
293
|
-
pendingCount: 0,
|
|
294
|
-
pendingMessages: [],
|
|
295
|
-
updatedAtMs: args.nowMs
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
function isLeaseActive(lease, nowMs) {
|
|
300
|
-
return Boolean(lease && lease.expiresAtMs > nowMs);
|
|
301
|
-
}
|
|
302
|
-
function pendingMessages(conversation) {
|
|
303
|
-
return [...conversation.execution.pendingMessages].sort(compareMessages);
|
|
304
|
-
}
|
|
305
|
-
function isRunnableStatus(status) {
|
|
306
|
-
return status !== "failed" && status !== "idle";
|
|
307
|
-
}
|
|
308
|
-
function hasRunnableWork(conversation) {
|
|
309
|
-
return isRunnableStatus(conversation.execution.status) || pendingMessages(conversation).length > 0;
|
|
310
|
-
}
|
|
311
|
-
function executionWithPendingMessages(execution, pending) {
|
|
312
|
-
const pendingMessages2 = [...pending].sort(compareMessages);
|
|
313
|
-
const status = execution.status === "idle" && execution.lease ? "running" : execution.status === "idle" && pendingMessages2.length > 0 ? "pending" : execution.status;
|
|
314
|
-
return {
|
|
315
|
-
...execution,
|
|
316
|
-
status,
|
|
317
|
-
inboundMessageIds: uniqueStrings([
|
|
318
|
-
...execution.inboundMessageIds,
|
|
319
|
-
...pendingMessages2.map((message) => message.inboundMessageId)
|
|
320
|
-
]),
|
|
321
|
-
pendingMessages: pendingMessages2,
|
|
322
|
-
pendingCount: pendingMessages2.length
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
function withExecutionUpdate(conversation, execution, nowMs) {
|
|
326
|
-
return {
|
|
327
|
-
...conversation,
|
|
328
|
-
updatedAtMs: nowMs,
|
|
329
|
-
execution: {
|
|
330
|
-
...executionWithPendingMessages(execution, execution.pendingMessages),
|
|
331
|
-
updatedAtMs: nowMs
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
async function getConnectedState(stateAdapter) {
|
|
336
|
-
const state = stateAdapter ?? getStateAdapter();
|
|
337
|
-
await state.connect();
|
|
338
|
-
return state;
|
|
339
|
-
}
|
|
340
|
-
async function sleep(ms) {
|
|
341
|
-
await new Promise((resolve) => {
|
|
342
|
-
const timer = setTimeout(resolve, ms);
|
|
343
|
-
timer.unref?.();
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
async function withIndexLock(state, indexKey, callback) {
|
|
347
|
-
const startedAtMs = now();
|
|
348
|
-
let lock;
|
|
349
|
-
while (true) {
|
|
350
|
-
lock = await state.acquireLock(
|
|
351
|
-
indexLockKey(indexKey),
|
|
352
|
-
CONVERSATION_INDEX_LOCK_TTL_MS
|
|
353
|
-
);
|
|
354
|
-
if (lock) {
|
|
355
|
-
break;
|
|
356
|
-
}
|
|
357
|
-
if (now() - startedAtMs >= CONVERSATION_INDEX_LOCK_WAIT_MS) {
|
|
358
|
-
throw new Error(
|
|
359
|
-
`Could not acquire conversation index lock for ${indexKey}`
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
await sleep(CONVERSATION_INDEX_LOCK_RETRY_MS);
|
|
363
|
-
}
|
|
364
|
-
try {
|
|
365
|
-
return await callback();
|
|
366
|
-
} finally {
|
|
367
|
-
await state.releaseLock(lock);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
function normalizeIndexEntry(value) {
|
|
371
|
-
if (!isRecord(value)) {
|
|
372
|
-
return void 0;
|
|
373
|
-
}
|
|
374
|
-
const conversationId = toOptionalString(value.conversationId);
|
|
375
|
-
const score = toOptionalNumber(value.score);
|
|
376
|
-
if (!conversationId || typeof score !== "number") {
|
|
377
|
-
return void 0;
|
|
378
|
-
}
|
|
379
|
-
return { conversationId, score };
|
|
380
|
-
}
|
|
381
|
-
function uniqueIndexEntries(value) {
|
|
382
|
-
if (!Array.isArray(value)) {
|
|
383
|
-
return [];
|
|
384
|
-
}
|
|
385
|
-
const entries = /* @__PURE__ */ new Map();
|
|
386
|
-
for (const item of value) {
|
|
387
|
-
const entry = normalizeIndexEntry(item);
|
|
388
|
-
if (!entry) {
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
const existing = entries.get(entry.conversationId);
|
|
392
|
-
if (!existing || entry.score > existing.score) {
|
|
393
|
-
entries.set(entry.conversationId, entry);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
return [...entries.values()];
|
|
397
|
-
}
|
|
398
|
-
function retainedIndexEntries(indexKey, entries) {
|
|
399
|
-
if (indexKey === CONVERSATION_BY_ACTIVITY_INDEX_KEY) {
|
|
400
|
-
return entries.sort(compareIndexDescending).slice(0, CONVERSATION_ACTIVITY_INDEX_MAX_LENGTH);
|
|
401
|
-
}
|
|
402
|
-
if (indexKey === CONVERSATION_ACTIVE_INDEX_KEY) {
|
|
403
|
-
return entries.sort(compareIndexAscending);
|
|
404
|
-
}
|
|
405
|
-
throw new Error(`Unknown conversation index ${indexKey}`);
|
|
406
|
-
}
|
|
407
|
-
function redisIndexKey(indexKey) {
|
|
408
|
-
const prefix = getChatConfig().state.keyPrefix;
|
|
409
|
-
return [...prefix ? [prefix] : [], indexKey].join(":");
|
|
410
|
-
}
|
|
411
|
-
function parseRedisIndexEntries(values) {
|
|
412
|
-
if (!Array.isArray(values)) {
|
|
413
|
-
return [];
|
|
414
|
-
}
|
|
415
|
-
const entries = [];
|
|
416
|
-
for (let index = 0; index < values.length; index += 2) {
|
|
417
|
-
const conversationId = toOptionalString(values[index]);
|
|
418
|
-
const score = typeof values[index + 1] === "number" ? values[index + 1] : Number(values[index + 1]);
|
|
419
|
-
if (!conversationId || !Number.isFinite(score)) {
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
entries.push({ conversationId, score });
|
|
423
|
-
}
|
|
424
|
-
return entries;
|
|
425
|
-
}
|
|
426
|
-
function redisConversationIndexStore(client) {
|
|
427
|
-
const upsertBoundedActivityScript = `
|
|
428
|
-
redis.call("ZADD", KEYS[1], ARGV[1], ARGV[2])
|
|
429
|
-
redis.call("PEXPIRE", KEYS[1], ARGV[3])
|
|
430
|
-
local extra = redis.call("ZCARD", KEYS[1]) - tonumber(ARGV[4])
|
|
431
|
-
if extra > 0 then
|
|
432
|
-
redis.call("ZREMRANGEBYRANK", KEYS[1], 0, extra - 1)
|
|
433
|
-
end
|
|
434
|
-
return 1
|
|
435
|
-
`;
|
|
436
|
-
return {
|
|
437
|
-
async list(args) {
|
|
438
|
-
const key = redisIndexKey(args.indexKey);
|
|
439
|
-
const limit = args.limit;
|
|
440
|
-
const offset = Math.max(0, args.offset ?? 0);
|
|
441
|
-
if (limit === 0) {
|
|
442
|
-
return [];
|
|
443
|
-
}
|
|
444
|
-
const values = args.scoreMax !== void 0 ? await client.sendCommand([
|
|
445
|
-
"ZRANGEBYSCORE",
|
|
446
|
-
key,
|
|
447
|
-
"-inf",
|
|
448
|
-
String(args.scoreMax),
|
|
449
|
-
"WITHSCORES",
|
|
450
|
-
...limit !== void 0 || offset > 0 ? ["LIMIT", String(offset), String(limit ?? 1e9)] : []
|
|
451
|
-
]) : await client.sendCommand([
|
|
452
|
-
args.order === "asc" ? "ZRANGE" : "ZREVRANGE",
|
|
453
|
-
key,
|
|
454
|
-
String(offset),
|
|
455
|
-
String(
|
|
456
|
-
limit === void 0 ? -1 : offset + Math.max(0, limit - 1)
|
|
457
|
-
),
|
|
458
|
-
"WITHSCORES"
|
|
459
|
-
]);
|
|
460
|
-
return parseRedisIndexEntries(values);
|
|
461
|
-
},
|
|
462
|
-
async remove(args) {
|
|
463
|
-
await client.sendCommand([
|
|
464
|
-
"ZREM",
|
|
465
|
-
redisIndexKey(args.indexKey),
|
|
466
|
-
args.conversationId
|
|
467
|
-
]);
|
|
468
|
-
},
|
|
469
|
-
async upsert(args) {
|
|
470
|
-
const key = redisIndexKey(args.indexKey);
|
|
471
|
-
if (args.indexKey === CONVERSATION_BY_ACTIVITY_INDEX_KEY) {
|
|
472
|
-
await client.sendCommand([
|
|
473
|
-
"EVAL",
|
|
474
|
-
upsertBoundedActivityScript,
|
|
475
|
-
"1",
|
|
476
|
-
key,
|
|
477
|
-
String(args.score),
|
|
478
|
-
args.conversationId,
|
|
479
|
-
String(JUNIOR_THREAD_STATE_TTL_MS),
|
|
480
|
-
String(CONVERSATION_ACTIVITY_INDEX_MAX_LENGTH)
|
|
481
|
-
]);
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
if (args.indexKey === CONVERSATION_ACTIVE_INDEX_KEY) {
|
|
485
|
-
await client.sendCommand([
|
|
486
|
-
"ZADD",
|
|
487
|
-
key,
|
|
488
|
-
String(args.score),
|
|
489
|
-
args.conversationId
|
|
490
|
-
]);
|
|
491
|
-
await client.sendCommand([
|
|
492
|
-
"PEXPIRE",
|
|
493
|
-
key,
|
|
494
|
-
String(JUNIOR_THREAD_STATE_TTL_MS)
|
|
495
|
-
]);
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
throw new Error(`Unknown conversation index ${args.indexKey}`);
|
|
499
|
-
}
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
function emulatedConversationIndexStore(state) {
|
|
503
|
-
const readIndex = async (indexKey) => uniqueIndexEntries(await state.get(indexKey));
|
|
504
|
-
const writeIndex = async (indexKey, entries) => {
|
|
505
|
-
await state.set(indexKey, entries, JUNIOR_THREAD_STATE_TTL_MS);
|
|
506
|
-
};
|
|
507
|
-
return {
|
|
508
|
-
async list(args) {
|
|
509
|
-
const entries = (await readIndex(args.indexKey)).filter(
|
|
510
|
-
(entry) => args.scoreMax === void 0 ? true : entry.score <= args.scoreMax
|
|
511
|
-
).sort(
|
|
512
|
-
args.order === "asc" ? compareIndexAscending : compareIndexDescending
|
|
513
|
-
);
|
|
514
|
-
const offset = Math.max(0, args.offset ?? 0);
|
|
515
|
-
return entries.slice(
|
|
516
|
-
offset,
|
|
517
|
-
args.limit === void 0 ? entries.length : offset + args.limit
|
|
518
|
-
);
|
|
519
|
-
},
|
|
520
|
-
async remove(args) {
|
|
521
|
-
await withIndexLock(state, args.indexKey, async () => {
|
|
522
|
-
const entries = await readIndex(args.indexKey);
|
|
523
|
-
const next = entries.filter(
|
|
524
|
-
(entry) => entry.conversationId !== args.conversationId
|
|
525
|
-
);
|
|
526
|
-
if (next.length === entries.length) {
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
await writeIndex(args.indexKey, next);
|
|
530
|
-
});
|
|
531
|
-
},
|
|
532
|
-
async upsert(args) {
|
|
533
|
-
await withIndexLock(state, args.indexKey, async () => {
|
|
534
|
-
const entries = await readIndex(args.indexKey);
|
|
535
|
-
const withoutCurrent = entries.filter(
|
|
536
|
-
(entry) => entry.conversationId !== args.conversationId
|
|
537
|
-
);
|
|
538
|
-
const next = retainedIndexEntries(args.indexKey, [
|
|
539
|
-
...withoutCurrent,
|
|
540
|
-
{ conversationId: args.conversationId, score: args.score }
|
|
541
|
-
]);
|
|
542
|
-
await writeIndex(args.indexKey, next);
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
}
|
|
547
|
-
async function getConversationIndexStore(state) {
|
|
548
|
-
const redisStateAdapter = await getDefaultRedisStateAdapterFor(state);
|
|
549
|
-
if (redisStateAdapter) {
|
|
550
|
-
return redisConversationIndexStore(redisStateAdapter.getClient());
|
|
551
|
-
}
|
|
552
|
-
return emulatedConversationIndexStore(state);
|
|
553
|
-
}
|
|
554
|
-
async function upsertIndexEntry(args) {
|
|
555
|
-
const index = await getConversationIndexStore(args.state);
|
|
556
|
-
await index.upsert({
|
|
557
|
-
conversationId: args.conversationId,
|
|
558
|
-
indexKey: args.indexKey,
|
|
559
|
-
score: args.score
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
async function removeIndexEntry(args) {
|
|
563
|
-
const index = await getConversationIndexStore(args.state);
|
|
564
|
-
await index.remove({
|
|
565
|
-
conversationId: args.conversationId,
|
|
566
|
-
indexKey: args.indexKey
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
async function acquireMutationLock(state, conversationId) {
|
|
570
|
-
const startedAtMs = now();
|
|
571
|
-
while (true) {
|
|
572
|
-
const lock = await state.acquireLock(
|
|
573
|
-
mutationLockKey(conversationId),
|
|
574
|
-
CONVERSATION_MUTATION_LOCK_TTL_MS
|
|
575
|
-
);
|
|
576
|
-
if (lock) {
|
|
577
|
-
return lock;
|
|
578
|
-
}
|
|
579
|
-
if (now() - startedAtMs >= CONVERSATION_MUTATION_WAIT_MS) {
|
|
580
|
-
throw new Error(
|
|
581
|
-
`Could not acquire conversation mutation lock for ${conversationId}`
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
await sleep(CONVERSATION_MUTATION_RETRY_MS);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
async function withConversationMutation(args, callback) {
|
|
588
|
-
const state = await getConnectedState(args.state);
|
|
589
|
-
const lock = await acquireMutationLock(state, args.conversationId);
|
|
590
|
-
try {
|
|
591
|
-
return await callback(state, lock);
|
|
592
|
-
} finally {
|
|
593
|
-
await state.releaseLock(lock);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
async function readConversation(state, conversationId) {
|
|
597
|
-
const raw = await state.get(conversationKey(conversationId));
|
|
598
|
-
if (raw == null) {
|
|
599
|
-
return void 0;
|
|
600
|
-
}
|
|
601
|
-
const conversation = normalizeConversation(conversationId, raw);
|
|
602
|
-
if (!conversation) {
|
|
603
|
-
throw new InvalidConversationRecordError(conversationId);
|
|
604
|
-
}
|
|
605
|
-
return conversation;
|
|
606
|
-
}
|
|
607
|
-
async function writeConversation(state, lock, conversation) {
|
|
608
|
-
const execution = executionWithPendingMessages(
|
|
609
|
-
conversation.execution,
|
|
610
|
-
conversation.execution.pendingMessages
|
|
611
|
-
);
|
|
612
|
-
const next = {
|
|
613
|
-
...conversation,
|
|
614
|
-
execution
|
|
615
|
-
};
|
|
616
|
-
const fenced = await state.extendLock(
|
|
617
|
-
lock,
|
|
618
|
-
CONVERSATION_MUTATION_LOCK_TTL_MS
|
|
619
|
-
);
|
|
620
|
-
if (!fenced) {
|
|
621
|
-
throw new ConversationMutationFencedError(next.conversationId);
|
|
622
|
-
}
|
|
623
|
-
const hasSlackDestination = next.destination?.platform === "slack";
|
|
624
|
-
const stored = {
|
|
625
|
-
...next,
|
|
626
|
-
execution: {
|
|
627
|
-
...next.execution,
|
|
628
|
-
pendingMessages: next.execution.pendingMessages.map(
|
|
629
|
-
(message) => storeMessage(
|
|
630
|
-
message,
|
|
631
|
-
hasSlackDestination && (message.source === "slack" || message.source === "resource_event" || message.source === "plugin" || message.source === "scheduler")
|
|
632
|
-
)
|
|
633
|
-
)
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
await state.set(
|
|
637
|
-
conversationKey(next.conversationId),
|
|
638
|
-
stored,
|
|
639
|
-
JUNIOR_THREAD_STATE_TTL_MS
|
|
640
|
-
);
|
|
641
|
-
await upsertIndexEntry({
|
|
642
|
-
state,
|
|
643
|
-
indexKey: CONVERSATION_BY_ACTIVITY_INDEX_KEY,
|
|
644
|
-
conversationId: next.conversationId,
|
|
645
|
-
score: next.lastActivityAtMs
|
|
646
|
-
});
|
|
647
|
-
if (!hasRunnableWork(next)) {
|
|
648
|
-
await removeIndexEntry({
|
|
649
|
-
state,
|
|
650
|
-
indexKey: CONVERSATION_ACTIVE_INDEX_KEY,
|
|
651
|
-
conversationId: next.conversationId
|
|
652
|
-
});
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
await upsertIndexEntry({
|
|
656
|
-
state,
|
|
657
|
-
indexKey: CONVERSATION_ACTIVE_INDEX_KEY,
|
|
658
|
-
conversationId: next.conversationId,
|
|
659
|
-
score: next.execution.updatedAtMs ?? next.updatedAtMs
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
function assertSameOptionalConversationDestination(args) {
|
|
663
|
-
if (!args.next || !args.current) {
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
if (sameDestination(args.current, args.next)) {
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
throw new Error(
|
|
670
|
-
`Conversation destination changed for ${args.conversationId}`
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
function conversationWorkState(conversation) {
|
|
674
|
-
const lease = conversation.execution.lease;
|
|
675
|
-
return {
|
|
676
|
-
...conversation,
|
|
677
|
-
lastEnqueuedAtMs: conversation.execution.lastEnqueuedAtMs,
|
|
678
|
-
...lease ? {
|
|
679
|
-
lease: {
|
|
680
|
-
acquiredAtMs: lease.acquiredAtMs,
|
|
681
|
-
lastCheckInAtMs: lease.lastCheckInAtMs,
|
|
682
|
-
leaseExpiresAtMs: lease.expiresAtMs,
|
|
683
|
-
leaseToken: lease.token
|
|
684
|
-
}
|
|
685
|
-
} : void 0,
|
|
686
|
-
messages: pendingMessages(conversation),
|
|
687
|
-
needsRun: hasRunnableWork(conversation)
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
async function getConversation(args) {
|
|
691
|
-
const state = await getConnectedState(args.state);
|
|
692
|
-
return await readConversation(state, args.conversationId);
|
|
693
|
-
}
|
|
694
|
-
async function getConversationWorkState(args) {
|
|
695
|
-
const conversation = await getConversation(args);
|
|
696
|
-
return conversation ? conversationWorkState(conversation) : void 0;
|
|
697
|
-
}
|
|
698
|
-
function hasRunnableConversationWork(conversation) {
|
|
699
|
-
return hasRunnableWork(conversation);
|
|
700
|
-
}
|
|
701
|
-
async function appendInboundMessageWithAdmission(args) {
|
|
702
|
-
const nowMs = args.nowMs ?? now();
|
|
703
|
-
return await withConversationMutation(
|
|
704
|
-
{ conversationId: args.message.conversationId, state: args.state },
|
|
705
|
-
async (state, lock) => {
|
|
706
|
-
const existing = await readConversation(
|
|
707
|
-
state,
|
|
708
|
-
args.message.conversationId
|
|
709
|
-
);
|
|
710
|
-
const current = existing ?? emptyConversation({
|
|
711
|
-
conversationId: args.message.conversationId,
|
|
712
|
-
destination: args.message.destination,
|
|
713
|
-
nowMs,
|
|
714
|
-
source: args.message.source
|
|
715
|
-
});
|
|
716
|
-
if (existing) {
|
|
717
|
-
assertSameOptionalConversationDestination({
|
|
718
|
-
conversationId: args.message.conversationId,
|
|
719
|
-
current: current.destination,
|
|
720
|
-
next: args.message.destination
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
const existingPending = current.execution.pendingMessages.some(
|
|
724
|
-
(message) => message.inboundMessageId === args.message.inboundMessageId
|
|
725
|
-
);
|
|
726
|
-
const existingMessage = current.execution.inboundMessageIds.includes(
|
|
727
|
-
args.message.inboundMessageId
|
|
728
|
-
);
|
|
729
|
-
if (existingMessage) {
|
|
730
|
-
if (!existingPending) {
|
|
731
|
-
return { status: "duplicate" };
|
|
732
|
-
}
|
|
733
|
-
const nextStatus = current.execution.status === "idle" ? "pending" : current.execution.status;
|
|
734
|
-
await writeConversation(
|
|
735
|
-
state,
|
|
736
|
-
lock,
|
|
737
|
-
withExecutionUpdate(
|
|
738
|
-
current,
|
|
739
|
-
{
|
|
740
|
-
...current.execution,
|
|
741
|
-
status: nextStatus,
|
|
742
|
-
pendingMessages: current.execution.pendingMessages.map(
|
|
743
|
-
(message) => message.inboundMessageId === args.message.inboundMessageId ? upgradedPendingMessage(message, args.message) : message
|
|
744
|
-
)
|
|
745
|
-
},
|
|
746
|
-
nowMs
|
|
747
|
-
)
|
|
748
|
-
);
|
|
749
|
-
return { status: "duplicate" };
|
|
750
|
-
}
|
|
751
|
-
if (args.exclusive && hasRunnableWork(current)) {
|
|
752
|
-
return { status: "active" };
|
|
753
|
-
}
|
|
754
|
-
let status;
|
|
755
|
-
if (current.execution.lease) {
|
|
756
|
-
status = current.execution.status === "running" ? "running" : "paused";
|
|
757
|
-
} else if (current.execution.status === "paused" && args.message.delivery === "defer") {
|
|
758
|
-
status = "paused";
|
|
759
|
-
} else {
|
|
760
|
-
status = "pending";
|
|
761
|
-
}
|
|
762
|
-
const next = {
|
|
763
|
-
...current,
|
|
764
|
-
destination: current.destination ?? args.message.destination,
|
|
765
|
-
source: current.source ?? args.message.source,
|
|
766
|
-
lastActivityAtMs: nowMs
|
|
767
|
-
};
|
|
768
|
-
await writeConversation(
|
|
769
|
-
state,
|
|
770
|
-
lock,
|
|
771
|
-
withExecutionUpdate(
|
|
772
|
-
next,
|
|
773
|
-
{
|
|
774
|
-
...current.execution,
|
|
775
|
-
status,
|
|
776
|
-
inboundMessageIds: [
|
|
777
|
-
...current.execution.inboundMessageIds,
|
|
778
|
-
args.message.inboundMessageId
|
|
779
|
-
],
|
|
780
|
-
pendingMessages: [
|
|
781
|
-
...current.execution.pendingMessages,
|
|
782
|
-
args.message
|
|
783
|
-
].sort(compareMessages)
|
|
784
|
-
},
|
|
785
|
-
nowMs
|
|
786
|
-
)
|
|
787
|
-
);
|
|
788
|
-
return { status: "appended" };
|
|
789
|
-
}
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
async function appendInboundMessage(args) {
|
|
793
|
-
const result = await appendInboundMessageWithAdmission({
|
|
794
|
-
...args,
|
|
795
|
-
exclusive: false
|
|
796
|
-
});
|
|
797
|
-
if (result.status === "active") {
|
|
798
|
-
throw new Error("Non-exclusive mailbox append returned active");
|
|
799
|
-
}
|
|
800
|
-
return result;
|
|
801
|
-
}
|
|
802
|
-
async function appendExclusiveInboundMessage(args) {
|
|
803
|
-
return await appendInboundMessageWithAdmission({
|
|
804
|
-
...args,
|
|
805
|
-
exclusive: true
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
async function requestConversationWork(args) {
|
|
809
|
-
const nowMs = args.nowMs ?? now();
|
|
810
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
811
|
-
const existing = await readConversation(state, args.conversationId);
|
|
812
|
-
if (existing) {
|
|
813
|
-
assertSameOptionalConversationDestination({
|
|
814
|
-
conversationId: args.conversationId,
|
|
815
|
-
current: existing.destination,
|
|
816
|
-
next: args.destination
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
const current = existing ?? emptyConversation({
|
|
820
|
-
conversationId: args.conversationId,
|
|
821
|
-
destination: args.destination,
|
|
822
|
-
nowMs
|
|
823
|
-
});
|
|
824
|
-
const status = current.execution.lease ? "paused" : "pending";
|
|
825
|
-
await writeConversation(
|
|
826
|
-
state,
|
|
827
|
-
lock,
|
|
828
|
-
withExecutionUpdate(
|
|
829
|
-
{
|
|
830
|
-
...current,
|
|
831
|
-
destination: current.destination ?? args.destination
|
|
832
|
-
},
|
|
833
|
-
{
|
|
834
|
-
...current.execution,
|
|
835
|
-
status
|
|
836
|
-
},
|
|
837
|
-
nowMs
|
|
838
|
-
)
|
|
839
|
-
);
|
|
840
|
-
return { status: existing === void 0 ? "created" : "updated" };
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
async function markConversationWorkEnqueued(args) {
|
|
844
|
-
const nowMs = args.nowMs ?? now();
|
|
845
|
-
await withConversationMutation(args, async (state, lock) => {
|
|
846
|
-
const current = await readConversation(state, args.conversationId);
|
|
847
|
-
if (!current) {
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
await writeConversation(
|
|
851
|
-
state,
|
|
852
|
-
lock,
|
|
853
|
-
withExecutionUpdate(
|
|
854
|
-
current,
|
|
855
|
-
{
|
|
856
|
-
...current.execution,
|
|
857
|
-
lastEnqueuedAtMs: nowMs
|
|
858
|
-
},
|
|
859
|
-
nowMs
|
|
860
|
-
)
|
|
861
|
-
);
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
async function clearConsumedConversationWake(args) {
|
|
865
|
-
const nowMs = args.nowMs ?? now();
|
|
866
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
867
|
-
const current = await readConversation(state, args.conversationId);
|
|
868
|
-
if (!current || hasRunnableWork(current) || current.execution.lastEnqueuedAtMs === void 0) {
|
|
869
|
-
return false;
|
|
870
|
-
}
|
|
871
|
-
await writeConversation(
|
|
872
|
-
state,
|
|
873
|
-
lock,
|
|
874
|
-
withExecutionUpdate(
|
|
875
|
-
current,
|
|
876
|
-
{
|
|
877
|
-
...current.execution,
|
|
878
|
-
lastEnqueuedAtMs: void 0
|
|
879
|
-
},
|
|
880
|
-
nowMs
|
|
881
|
-
)
|
|
882
|
-
);
|
|
883
|
-
return true;
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
async function startConversationWork(args) {
|
|
887
|
-
const nowMs = args.nowMs ?? now();
|
|
888
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
889
|
-
const current = await readConversation(state, args.conversationId);
|
|
890
|
-
if (!current) {
|
|
891
|
-
return { status: "no_work" };
|
|
892
|
-
}
|
|
893
|
-
if (isLeaseActive(current.execution.lease, nowMs)) {
|
|
894
|
-
return {
|
|
895
|
-
status: "active",
|
|
896
|
-
leaseExpiresAtMs: current.execution.lease.expiresAtMs
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
if (!hasRunnableWork(current)) {
|
|
900
|
-
return { status: "no_work" };
|
|
901
|
-
}
|
|
902
|
-
const lease = {
|
|
903
|
-
token: randomUUID(),
|
|
904
|
-
acquiredAtMs: nowMs,
|
|
905
|
-
lastCheckInAtMs: nowMs,
|
|
906
|
-
expiresAtMs: nowMs + CONVERSATION_WORK_LEASE_TTL_MS
|
|
907
|
-
};
|
|
908
|
-
const startsNewRun = current.execution.runId === void 0;
|
|
909
|
-
await writeConversation(
|
|
910
|
-
state,
|
|
911
|
-
lock,
|
|
912
|
-
withExecutionUpdate(
|
|
913
|
-
current,
|
|
914
|
-
{
|
|
915
|
-
...current.execution,
|
|
916
|
-
lease,
|
|
917
|
-
status: current.execution.status === "paused" ? "paused" : "running",
|
|
918
|
-
runId: current.execution.runId ?? randomUUID(),
|
|
919
|
-
lastEnqueuedAtMs: void 0,
|
|
920
|
-
retryCount: startsNewRun ? 0 : current.execution.retryCount
|
|
921
|
-
},
|
|
922
|
-
nowMs
|
|
923
|
-
)
|
|
924
|
-
);
|
|
925
|
-
return {
|
|
926
|
-
status: "acquired",
|
|
927
|
-
leaseToken: lease.token,
|
|
928
|
-
leaseExpiresAtMs: lease.expiresAtMs
|
|
929
|
-
};
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
async function checkInConversationWork(args) {
|
|
933
|
-
const nowMs = args.nowMs ?? now();
|
|
934
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
935
|
-
const current = await readConversation(state, args.conversationId);
|
|
936
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
937
|
-
return false;
|
|
938
|
-
}
|
|
939
|
-
await writeConversation(
|
|
940
|
-
state,
|
|
941
|
-
lock,
|
|
942
|
-
withExecutionUpdate(
|
|
943
|
-
current,
|
|
944
|
-
{
|
|
945
|
-
...current.execution,
|
|
946
|
-
lease: {
|
|
947
|
-
...current.execution.lease,
|
|
948
|
-
lastCheckInAtMs: nowMs,
|
|
949
|
-
expiresAtMs: nowMs + CONVERSATION_WORK_LEASE_TTL_MS
|
|
950
|
-
}
|
|
951
|
-
},
|
|
952
|
-
nowMs
|
|
953
|
-
)
|
|
954
|
-
);
|
|
955
|
-
return true;
|
|
956
|
-
});
|
|
957
|
-
}
|
|
958
|
-
async function drainConversationMailbox(args) {
|
|
959
|
-
const nowMs = args.nowMs ?? now();
|
|
960
|
-
const pending = await withConversationMutation(args, async (state) => {
|
|
961
|
-
const current = await readConversation(state, args.conversationId);
|
|
962
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
963
|
-
throw new Error(
|
|
964
|
-
`Conversation lease is not held for ${args.conversationId}`
|
|
965
|
-
);
|
|
966
|
-
}
|
|
967
|
-
return pendingMessages(current);
|
|
968
|
-
});
|
|
969
|
-
if (pending.length === 0) {
|
|
970
|
-
return { changed: false, messages: [] };
|
|
971
|
-
}
|
|
972
|
-
const result = await args.handle(pending);
|
|
973
|
-
const pendingIds = new Set(
|
|
974
|
-
pending.map((message) => message.inboundMessageId)
|
|
975
|
-
);
|
|
976
|
-
const acknowledgedIds = new Set(
|
|
977
|
-
result ?? pending.map((message) => message.inboundMessageId)
|
|
978
|
-
);
|
|
979
|
-
for (const inboundMessageId of acknowledgedIds) {
|
|
980
|
-
if (!pendingIds.has(inboundMessageId)) {
|
|
981
|
-
throw new Error(
|
|
982
|
-
`Conversation mailbox drain result is not pending for ${args.conversationId}`
|
|
983
|
-
);
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
if (acknowledgedIds.size === 0) {
|
|
987
|
-
return { changed: false, messages: [] };
|
|
988
|
-
}
|
|
989
|
-
await withConversationMutation(args, async (state, lock) => {
|
|
990
|
-
const current = await readConversation(state, args.conversationId);
|
|
991
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
992
|
-
throw new Error(
|
|
993
|
-
`Conversation lease is not held for ${args.conversationId}`
|
|
994
|
-
);
|
|
995
|
-
}
|
|
996
|
-
const pendingMessages2 = current.execution.pendingMessages.filter(
|
|
997
|
-
(message) => !acknowledgedIds.has(message.inboundMessageId)
|
|
998
|
-
);
|
|
999
|
-
await writeConversation(
|
|
1000
|
-
state,
|
|
1001
|
-
lock,
|
|
1002
|
-
withExecutionUpdate(
|
|
1003
|
-
current,
|
|
1004
|
-
{
|
|
1005
|
-
...current.execution,
|
|
1006
|
-
status: current.execution.status === "pending" && pendingMessages2.length === 0 ? "running" : current.execution.status,
|
|
1007
|
-
lastProgressAtMs: nowMs,
|
|
1008
|
-
retryCount: 0,
|
|
1009
|
-
pendingMessages: pendingMessages2
|
|
1010
|
-
},
|
|
1011
|
-
nowMs
|
|
1012
|
-
)
|
|
1013
|
-
);
|
|
1014
|
-
});
|
|
1015
|
-
return {
|
|
1016
|
-
changed: true,
|
|
1017
|
-
messages: pending.filter(
|
|
1018
|
-
(message) => acknowledgedIds.has(message.inboundMessageId)
|
|
1019
|
-
)
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
async function ackMessages(args) {
|
|
1023
|
-
const nowMs = args.nowMs ?? now();
|
|
1024
|
-
const inboundMessageIds = new Set(args.inboundMessageIds);
|
|
1025
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1026
|
-
const current = await readConversation(state, args.conversationId);
|
|
1027
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1028
|
-
return false;
|
|
1029
|
-
}
|
|
1030
|
-
if (inboundMessageIds.size === 0) {
|
|
1031
|
-
return true;
|
|
1032
|
-
}
|
|
1033
|
-
const pendingMessages2 = current.execution.pendingMessages.filter(
|
|
1034
|
-
(message) => !inboundMessageIds.has(message.inboundMessageId)
|
|
1035
|
-
);
|
|
1036
|
-
if (pendingMessages2.length === current.execution.pendingMessages.length) {
|
|
1037
|
-
return true;
|
|
1038
|
-
}
|
|
1039
|
-
await writeConversation(
|
|
1040
|
-
state,
|
|
1041
|
-
lock,
|
|
1042
|
-
withExecutionUpdate(
|
|
1043
|
-
current,
|
|
1044
|
-
{
|
|
1045
|
-
...current.execution,
|
|
1046
|
-
lastProgressAtMs: nowMs,
|
|
1047
|
-
retryCount: 0,
|
|
1048
|
-
pendingMessages: pendingMessages2
|
|
1049
|
-
},
|
|
1050
|
-
nowMs
|
|
1051
|
-
)
|
|
1052
|
-
);
|
|
1053
|
-
return true;
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
function isHumanFacingMessage(message) {
|
|
1057
|
-
return message.source === "web" || message.source === "slack";
|
|
1058
|
-
}
|
|
1059
|
-
async function stopConversationWork(args) {
|
|
1060
|
-
const nowMs = args.nowMs ?? now();
|
|
1061
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1062
|
-
const current = await readConversation(state, args.conversationId);
|
|
1063
|
-
if (!current || !hasRunnableWork(current)) {
|
|
1064
|
-
return { status: "no_work" };
|
|
1065
|
-
}
|
|
1066
|
-
const runId = current.execution.runId ?? randomUUID();
|
|
1067
|
-
const inboundMessageIds = current.execution.pendingMessages.filter(isHumanFacingMessage).map((message) => message.inboundMessageId);
|
|
1068
|
-
await writeConversation(
|
|
1069
|
-
state,
|
|
1070
|
-
lock,
|
|
1071
|
-
withExecutionUpdate(
|
|
1072
|
-
current,
|
|
1073
|
-
{
|
|
1074
|
-
...current.execution,
|
|
1075
|
-
runId,
|
|
1076
|
-
stop: { inboundMessageIds, runId }
|
|
1077
|
-
},
|
|
1078
|
-
nowMs
|
|
1079
|
-
)
|
|
1080
|
-
);
|
|
1081
|
-
return { runId, status: "requested" };
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
async function completeConversationStop(args) {
|
|
1085
|
-
const nowMs = args.nowMs ?? now();
|
|
1086
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1087
|
-
const current = await readConversation(state, args.conversationId);
|
|
1088
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1089
|
-
return { status: "lost_lease", removedInboundMessageIds: [] };
|
|
1090
|
-
}
|
|
1091
|
-
const stop = current.execution.stop;
|
|
1092
|
-
if (!stop || stop.runId !== args.runId) {
|
|
1093
|
-
return { status: "none", removedInboundMessageIds: [] };
|
|
1094
|
-
}
|
|
1095
|
-
const stoppedInboundMessageIds = new Set(stop.inboundMessageIds);
|
|
1096
|
-
const removedInboundMessageIds = [];
|
|
1097
|
-
const pendingMessages2 = current.execution.pendingMessages.filter(
|
|
1098
|
-
(message) => {
|
|
1099
|
-
const shouldStop = stoppedInboundMessageIds.has(
|
|
1100
|
-
message.inboundMessageId
|
|
1101
|
-
);
|
|
1102
|
-
if (shouldStop) {
|
|
1103
|
-
removedInboundMessageIds.push(message.inboundMessageId);
|
|
1104
|
-
}
|
|
1105
|
-
return !shouldStop;
|
|
1106
|
-
}
|
|
1107
|
-
);
|
|
1108
|
-
await writeConversation(
|
|
1109
|
-
state,
|
|
1110
|
-
lock,
|
|
1111
|
-
withExecutionUpdate(
|
|
1112
|
-
current,
|
|
1113
|
-
{
|
|
1114
|
-
...current.execution,
|
|
1115
|
-
lastEnqueuedAtMs: pendingMessages2.length === 0 ? void 0 : current.execution.lastEnqueuedAtMs,
|
|
1116
|
-
pendingMessages: pendingMessages2,
|
|
1117
|
-
stop: void 0
|
|
1118
|
-
},
|
|
1119
|
-
nowMs
|
|
1120
|
-
)
|
|
1121
|
-
);
|
|
1122
|
-
return { status: "cleared", removedInboundMessageIds };
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
async function cancelHumanFacingPendingMessages(args) {
|
|
1126
|
-
const nowMs = args.nowMs ?? now();
|
|
1127
|
-
const requestedIds = args.inboundMessageIds === void 0 ? void 0 : new Set(args.inboundMessageIds);
|
|
1128
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1129
|
-
const current = await readConversation(state, args.conversationId);
|
|
1130
|
-
if (!current) {
|
|
1131
|
-
return { cancelledInboundMessageIds: [] };
|
|
1132
|
-
}
|
|
1133
|
-
const cancelledInboundMessageIds = [];
|
|
1134
|
-
const pendingMessages2 = [];
|
|
1135
|
-
for (const message of current.execution.pendingMessages) {
|
|
1136
|
-
const isRequested = requestedIds === void 0 || requestedIds.has(message.inboundMessageId);
|
|
1137
|
-
const isInSnapshot = args.receivedBeforeMs === void 0 || message.receivedAtMs <= args.receivedBeforeMs;
|
|
1138
|
-
if (isHumanFacingMessage(message) && isRequested && isInSnapshot) {
|
|
1139
|
-
cancelledInboundMessageIds.push(message.inboundMessageId);
|
|
1140
|
-
continue;
|
|
1141
|
-
}
|
|
1142
|
-
pendingMessages2.push(message);
|
|
1143
|
-
}
|
|
1144
|
-
if (cancelledInboundMessageIds.length === 0) {
|
|
1145
|
-
return { cancelledInboundMessageIds };
|
|
1146
|
-
}
|
|
1147
|
-
const becomesIdle = current.execution.status === "pending" && pendingMessages2.length === 0;
|
|
1148
|
-
await writeConversation(
|
|
1149
|
-
state,
|
|
1150
|
-
lock,
|
|
1151
|
-
withExecutionUpdate(
|
|
1152
|
-
current,
|
|
1153
|
-
{
|
|
1154
|
-
...current.execution,
|
|
1155
|
-
lastEnqueuedAtMs: pendingMessages2.length === 0 ? void 0 : current.execution.lastEnqueuedAtMs,
|
|
1156
|
-
pendingMessages: pendingMessages2,
|
|
1157
|
-
retryCount: becomesIdle ? 0 : current.execution.retryCount,
|
|
1158
|
-
runId: becomesIdle ? void 0 : current.execution.runId,
|
|
1159
|
-
status: becomesIdle ? "idle" : current.execution.status,
|
|
1160
|
-
stop: becomesIdle ? void 0 : current.execution.stop
|
|
1161
|
-
},
|
|
1162
|
-
nowMs
|
|
1163
|
-
)
|
|
1164
|
-
);
|
|
1165
|
-
return { cancelledInboundMessageIds };
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
async function requestAnotherSlice(args) {
|
|
1169
|
-
const nowMs = args.nowMs ?? now();
|
|
1170
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1171
|
-
const current = await readConversation(state, args.conversationId);
|
|
1172
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1173
|
-
return false;
|
|
1174
|
-
}
|
|
1175
|
-
assertSameOptionalConversationDestination({
|
|
1176
|
-
conversationId: args.conversationId,
|
|
1177
|
-
current: current.destination,
|
|
1178
|
-
next: args.destination
|
|
1179
|
-
});
|
|
1180
|
-
await writeConversation(
|
|
1181
|
-
state,
|
|
1182
|
-
lock,
|
|
1183
|
-
withExecutionUpdate(
|
|
1184
|
-
current,
|
|
1185
|
-
{
|
|
1186
|
-
...current.execution,
|
|
1187
|
-
status: "paused"
|
|
1188
|
-
},
|
|
1189
|
-
nowMs
|
|
1190
|
-
)
|
|
1191
|
-
);
|
|
1192
|
-
return true;
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
|
-
async function beginConversationResume(args) {
|
|
1196
|
-
const nowMs = args.nowMs ?? now();
|
|
1197
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1198
|
-
const current = await readConversation(state, args.conversationId);
|
|
1199
|
-
if (!current || current.execution.lease?.token !== args.leaseToken || current.execution.status !== "paused") {
|
|
1200
|
-
return false;
|
|
1201
|
-
}
|
|
1202
|
-
await writeConversation(
|
|
1203
|
-
state,
|
|
1204
|
-
lock,
|
|
1205
|
-
withExecutionUpdate(
|
|
1206
|
-
current,
|
|
1207
|
-
{
|
|
1208
|
-
...current.execution,
|
|
1209
|
-
status: "running"
|
|
1210
|
-
},
|
|
1211
|
-
nowMs
|
|
1212
|
-
)
|
|
1213
|
-
);
|
|
1214
|
-
return true;
|
|
1215
|
-
});
|
|
1216
|
-
}
|
|
1217
|
-
async function releaseConversationWork(args) {
|
|
1218
|
-
const nowMs = args.nowMs ?? now();
|
|
1219
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1220
|
-
const current = await readConversation(state, args.conversationId);
|
|
1221
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1222
|
-
return false;
|
|
1223
|
-
}
|
|
1224
|
-
await writeConversation(
|
|
1225
|
-
state,
|
|
1226
|
-
lock,
|
|
1227
|
-
withExecutionUpdate(
|
|
1228
|
-
current,
|
|
1229
|
-
{
|
|
1230
|
-
...current.execution,
|
|
1231
|
-
lease: void 0,
|
|
1232
|
-
status: current.execution.status === "running" ? "pending" : current.execution.status
|
|
1233
|
-
},
|
|
1234
|
-
nowMs
|
|
1235
|
-
)
|
|
1236
|
-
);
|
|
1237
|
-
return true;
|
|
1238
|
-
});
|
|
1239
|
-
}
|
|
1240
|
-
async function recordConversationRetry(args) {
|
|
1241
|
-
const nowMs = args.nowMs ?? now();
|
|
1242
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1243
|
-
const current = await readConversation(state, args.conversationId);
|
|
1244
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1245
|
-
return "lost_lease";
|
|
1246
|
-
}
|
|
1247
|
-
const count = (current.execution.retryCount ?? 0) + 1;
|
|
1248
|
-
const stopped = count >= CONVERSATION_WORK_MAX_RETRIES;
|
|
1249
|
-
await writeConversation(
|
|
1250
|
-
state,
|
|
1251
|
-
lock,
|
|
1252
|
-
withExecutionUpdate(
|
|
1253
|
-
current,
|
|
1254
|
-
{
|
|
1255
|
-
...current.execution,
|
|
1256
|
-
lastEnqueuedAtMs: void 0,
|
|
1257
|
-
lease: stopped ? void 0 : current.execution.lease,
|
|
1258
|
-
retryCount: count,
|
|
1259
|
-
pendingMessages: stopped ? [] : current.execution.pendingMessages,
|
|
1260
|
-
runId: stopped ? void 0 : current.execution.runId,
|
|
1261
|
-
status: stopped ? "failed" : "paused",
|
|
1262
|
-
stop: stopped ? void 0 : current.execution.stop
|
|
1263
|
-
},
|
|
1264
|
-
nowMs
|
|
1265
|
-
)
|
|
1266
|
-
);
|
|
1267
|
-
return stopped ? "stopped" : "recorded";
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1270
|
-
async function completeConversationWork(args) {
|
|
1271
|
-
const nowMs = args.nowMs ?? now();
|
|
1272
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1273
|
-
const current = await readConversation(state, args.conversationId);
|
|
1274
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1275
|
-
return "lost_lease";
|
|
1276
|
-
}
|
|
1277
|
-
const hasPending = pendingMessages(current).length > 0;
|
|
1278
|
-
const needsRun = current.execution.status === "paused" || args.resumeIfStopped === true && current.execution.stop !== void 0;
|
|
1279
|
-
const runnable = needsRun || hasPending;
|
|
1280
|
-
await writeConversation(
|
|
1281
|
-
state,
|
|
1282
|
-
lock,
|
|
1283
|
-
withExecutionUpdate(
|
|
1284
|
-
current,
|
|
1285
|
-
{
|
|
1286
|
-
...current.execution,
|
|
1287
|
-
lease: void 0,
|
|
1288
|
-
status: needsRun ? "paused" : hasPending ? "pending" : "idle",
|
|
1289
|
-
lastProgressAtMs: args.madeProgress === false ? current.execution.lastProgressAtMs : nowMs,
|
|
1290
|
-
retryCount: runnable || args.madeProgress === false ? current.execution.retryCount : 0,
|
|
1291
|
-
runId: runnable ? current.execution.runId : void 0,
|
|
1292
|
-
stop: runnable ? current.execution.stop : void 0
|
|
1293
|
-
},
|
|
1294
|
-
nowMs
|
|
1295
|
-
)
|
|
1296
|
-
);
|
|
1297
|
-
return runnable ? "pending" : "completed";
|
|
1298
|
-
});
|
|
1299
|
-
}
|
|
1300
|
-
async function recordAttemptFailure(args) {
|
|
1301
|
-
const nowMs = args.nowMs ?? now();
|
|
1302
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1303
|
-
const current = await readConversation(state, args.conversationId);
|
|
1304
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1305
|
-
return {
|
|
1306
|
-
status: "lost_lease",
|
|
1307
|
-
pendingCount: 0,
|
|
1308
|
-
deadLetteredMessages: [],
|
|
1309
|
-
retryCount: 0
|
|
1310
|
-
};
|
|
1311
|
-
}
|
|
1312
|
-
const pendingIds = new Set(
|
|
1313
|
-
current.execution.pendingMessages.map(
|
|
1314
|
-
(message) => message.inboundMessageId
|
|
1315
|
-
)
|
|
1316
|
-
);
|
|
1317
|
-
if (args.inboundMessageIds.length === 0 || args.inboundMessageIds.some((id) => !pendingIds.has(id))) {
|
|
1318
|
-
return {
|
|
1319
|
-
status: "skipped",
|
|
1320
|
-
pendingCount: current.execution.pendingMessages.length,
|
|
1321
|
-
deadLetteredMessages: [],
|
|
1322
|
-
retryCount: current.execution.retryCount ?? 0
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
const retryCount = (current.execution.retryCount ?? 0) + 1;
|
|
1326
|
-
const retriesExhausted = retryCount >= CONVERSATION_WORK_MAX_RETRIES;
|
|
1327
|
-
const attemptedIds = new Set(args.inboundMessageIds);
|
|
1328
|
-
const deadLetteredMessages = [];
|
|
1329
|
-
const pendingMessages2 = [];
|
|
1330
|
-
for (const message of current.execution.pendingMessages) {
|
|
1331
|
-
if (!attemptedIds.has(message.inboundMessageId)) {
|
|
1332
|
-
if (retriesExhausted) {
|
|
1333
|
-
deadLetteredMessages.push(message);
|
|
1334
|
-
} else {
|
|
1335
|
-
pendingMessages2.push(message);
|
|
1336
|
-
}
|
|
1337
|
-
continue;
|
|
1338
|
-
}
|
|
1339
|
-
const attempted = {
|
|
1340
|
-
...message,
|
|
1341
|
-
attemptCount: (message.attemptCount ?? 0) + 1
|
|
1342
|
-
};
|
|
1343
|
-
if (retriesExhausted || attempted.attemptCount >= CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS) {
|
|
1344
|
-
deadLetteredMessages.push(attempted);
|
|
1345
|
-
continue;
|
|
1346
|
-
}
|
|
1347
|
-
pendingMessages2.push(attempted);
|
|
1348
|
-
}
|
|
1349
|
-
await writeConversation(
|
|
1350
|
-
state,
|
|
1351
|
-
lock,
|
|
1352
|
-
withExecutionUpdate(
|
|
1353
|
-
current,
|
|
1354
|
-
{
|
|
1355
|
-
...current.execution,
|
|
1356
|
-
retryCount,
|
|
1357
|
-
pendingMessages: pendingMessages2
|
|
1358
|
-
},
|
|
1359
|
-
nowMs
|
|
1360
|
-
)
|
|
1361
|
-
);
|
|
1362
|
-
return {
|
|
1363
|
-
status: "recorded",
|
|
1364
|
-
pendingCount: pendingMessages2.length,
|
|
1365
|
-
deadLetteredMessages,
|
|
1366
|
-
retryCount
|
|
1367
|
-
};
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
async function deadLetterAttempt(args) {
|
|
1371
|
-
const nowMs = args.nowMs ?? now();
|
|
1372
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1373
|
-
const current = await readConversation(state, args.conversationId);
|
|
1374
|
-
if (!current || current.execution.lease?.token !== args.leaseToken) {
|
|
1375
|
-
return "lost_lease";
|
|
1376
|
-
}
|
|
1377
|
-
const runnable = pendingMessages(current).length > 0;
|
|
1378
|
-
await writeConversation(
|
|
1379
|
-
state,
|
|
1380
|
-
lock,
|
|
1381
|
-
withExecutionUpdate(
|
|
1382
|
-
current,
|
|
1383
|
-
{
|
|
1384
|
-
...current.execution,
|
|
1385
|
-
lease: void 0,
|
|
1386
|
-
status: runnable ? "pending" : "failed",
|
|
1387
|
-
runId: runnable ? current.execution.runId : void 0,
|
|
1388
|
-
stop: runnable ? current.execution.stop : void 0
|
|
1389
|
-
},
|
|
1390
|
-
nowMs
|
|
1391
|
-
)
|
|
1392
|
-
);
|
|
1393
|
-
return runnable ? "pending" : "failed";
|
|
1394
|
-
});
|
|
1395
|
-
}
|
|
1396
|
-
async function clearExpiredConversationLease(args) {
|
|
1397
|
-
const nowMs = args.nowMs ?? now();
|
|
1398
|
-
return await withConversationMutation(args, async (state, lock) => {
|
|
1399
|
-
const current = await readConversation(state, args.conversationId);
|
|
1400
|
-
if (!current?.execution.lease || current.execution.lease.expiresAtMs > nowMs) {
|
|
1401
|
-
return "not_expired";
|
|
1402
|
-
}
|
|
1403
|
-
const retryCount = (current.execution.retryCount ?? 0) + 1;
|
|
1404
|
-
const stopped = retryCount >= CONVERSATION_WORK_MAX_RETRIES;
|
|
1405
|
-
await writeConversation(
|
|
1406
|
-
state,
|
|
1407
|
-
lock,
|
|
1408
|
-
withExecutionUpdate(
|
|
1409
|
-
current,
|
|
1410
|
-
{
|
|
1411
|
-
...current.execution,
|
|
1412
|
-
lastEnqueuedAtMs: void 0,
|
|
1413
|
-
lease: void 0,
|
|
1414
|
-
retryCount,
|
|
1415
|
-
pendingMessages: stopped ? [] : current.execution.pendingMessages,
|
|
1416
|
-
runId: stopped ? void 0 : current.execution.runId,
|
|
1417
|
-
status: stopped ? "failed" : "paused",
|
|
1418
|
-
stop: stopped ? void 0 : current.execution.stop
|
|
1419
|
-
},
|
|
1420
|
-
nowMs
|
|
1421
|
-
)
|
|
1422
|
-
);
|
|
1423
|
-
return stopped ? "stopped" : "requeued";
|
|
1424
|
-
});
|
|
1425
|
-
}
|
|
1426
|
-
async function removeActiveConversation(args) {
|
|
1427
|
-
const state = await getConnectedState(args.state);
|
|
1428
|
-
await removeIndexEntry({
|
|
1429
|
-
state,
|
|
1430
|
-
indexKey: CONVERSATION_ACTIVE_INDEX_KEY,
|
|
1431
|
-
conversationId: args.conversationId
|
|
1432
|
-
});
|
|
1433
|
-
}
|
|
1434
|
-
async function listActiveConversationIds(args = {}) {
|
|
1435
|
-
const state = await getConnectedState(args.state);
|
|
1436
|
-
const index = await getConversationIndexStore(state);
|
|
1437
|
-
const entries = await index.list({
|
|
1438
|
-
indexKey: CONVERSATION_ACTIVE_INDEX_KEY,
|
|
1439
|
-
limit: args.limit,
|
|
1440
|
-
order: "asc",
|
|
1441
|
-
scoreMax: args.staleBeforeMs
|
|
1442
|
-
});
|
|
1443
|
-
return entries.map((entry) => entry.conversationId);
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// src/chat/task-execution/store.ts
|
|
1447
|
-
function metadataStore(options) {
|
|
1448
|
-
return options.conversationStore ?? getConversationStore();
|
|
1449
|
-
}
|
|
1450
|
-
function duplicateInboundNudgeIdempotencyKey(message, nowMs) {
|
|
1451
|
-
return `duplicate:${message.conversationId}:${message.inboundMessageId}:${nowMs}`;
|
|
1452
|
-
}
|
|
1453
|
-
function hasRecentEnqueueMarker(conversation, nowMs) {
|
|
1454
|
-
const lastEnqueuedAtMs = conversation.execution.lastEnqueuedAtMs;
|
|
1455
|
-
return typeof lastEnqueuedAtMs === "number" && lastEnqueuedAtMs + CONVERSATION_WORK_STALE_ENQUEUE_MS > nowMs;
|
|
1456
|
-
}
|
|
1457
|
-
function now2() {
|
|
1458
|
-
return Date.now();
|
|
1459
|
-
}
|
|
1460
|
-
async function recordExecutionMetadata(args) {
|
|
1461
|
-
const conversation = await getConversation({
|
|
1462
|
-
conversationId: args.conversationId,
|
|
1463
|
-
state: args.state
|
|
1464
|
-
});
|
|
1465
|
-
if (!conversation) {
|
|
1466
|
-
return;
|
|
1467
|
-
}
|
|
1468
|
-
await metadataStore(args).recordExecution({
|
|
1469
|
-
channelName: conversation.channelName,
|
|
1470
|
-
conversationId: conversation.conversationId,
|
|
1471
|
-
createdAtMs: conversation.createdAtMs,
|
|
1472
|
-
destination: conversation.destination,
|
|
1473
|
-
execution: {
|
|
1474
|
-
lastCheckpointAtMs: conversation.execution.lastCheckpointAtMs,
|
|
1475
|
-
lastEnqueuedAtMs: conversation.execution.lastEnqueuedAtMs,
|
|
1476
|
-
runId: conversation.execution.runId,
|
|
1477
|
-
status: conversation.execution.status,
|
|
1478
|
-
updatedAtMs: conversation.execution.updatedAtMs
|
|
1479
|
-
},
|
|
1480
|
-
lastActivityAtMs: conversation.lastActivityAtMs,
|
|
1481
|
-
metrics: null,
|
|
1482
|
-
actor: conversation.actor,
|
|
1483
|
-
source: conversation.source,
|
|
1484
|
-
title: conversation.title,
|
|
1485
|
-
updatedAtMs: conversation.updatedAtMs
|
|
1486
|
-
});
|
|
1487
|
-
}
|
|
1488
|
-
async function getConversation2(args) {
|
|
1489
|
-
return await getConversation(args);
|
|
1490
|
-
}
|
|
1491
|
-
async function getConversationWorkState2(args) {
|
|
1492
|
-
return await getConversationWorkState(args);
|
|
1493
|
-
}
|
|
1494
|
-
async function recordConversationRetry2(args) {
|
|
1495
|
-
const result = await recordConversationRetry(args);
|
|
1496
|
-
await recordExecutionMetadata(args);
|
|
1497
|
-
return result;
|
|
1498
|
-
}
|
|
1499
|
-
function countPendingConversationMessages(conversation) {
|
|
1500
|
-
return conversation.execution.pendingMessages.length;
|
|
1501
|
-
}
|
|
1502
|
-
function hasRunnableConversationWork2(conversation) {
|
|
1503
|
-
return conversation.execution.status !== "idle" || countPendingConversationMessages(conversation) > 0;
|
|
1504
|
-
}
|
|
1505
|
-
async function ensureConversationWake(args) {
|
|
1506
|
-
const nowMs = args.nowMs ?? now2();
|
|
1507
|
-
const conversation = await getConversation({
|
|
1508
|
-
conversationId: args.conversationId,
|
|
1509
|
-
state: args.state
|
|
1510
|
-
});
|
|
1511
|
-
if (!conversation || !hasRunnableConversationWork2(conversation)) {
|
|
1512
|
-
return { status: "no_work" };
|
|
1513
|
-
}
|
|
1514
|
-
if (args.replaceExistingWake !== true && conversation.execution.lease && conversation.execution.lease.expiresAtMs > nowMs) {
|
|
1515
|
-
return { status: "lease_active" };
|
|
1516
|
-
}
|
|
1517
|
-
if (args.replaceExistingWake !== true && hasRecentEnqueueMarker(conversation, nowMs)) {
|
|
1518
|
-
return { status: "already_enqueued" };
|
|
1519
|
-
}
|
|
1520
|
-
const queueResult = await args.queue.send(
|
|
1521
|
-
{
|
|
1522
|
-
schemaVersion: CONVERSATION_QUEUE_SCHEMA_VERSION,
|
|
1523
|
-
conversationId: args.conversationId
|
|
1524
|
-
},
|
|
1525
|
-
{
|
|
1526
|
-
delayMs: args.delayMs,
|
|
1527
|
-
idempotencyKey: args.idempotencyKey
|
|
1528
|
-
}
|
|
1529
|
-
);
|
|
1530
|
-
await markConversationWorkEnqueued2({
|
|
1531
|
-
conversationId: args.conversationId,
|
|
1532
|
-
conversationStore: args.conversationStore,
|
|
1533
|
-
nowMs,
|
|
1534
|
-
state: args.state
|
|
1535
|
-
});
|
|
1536
|
-
return { status: "enqueued", queueMessageId: queueResult?.messageId };
|
|
1537
|
-
}
|
|
1538
|
-
async function enqueueAfterAppend(args) {
|
|
1539
|
-
const nowMs = args.nowMs ?? now2();
|
|
1540
|
-
const appendResult = args.appendResult;
|
|
1541
|
-
if (appendResult.status === "active") return appendResult;
|
|
1542
|
-
let idempotencyKey = args.message.inboundMessageId;
|
|
1543
|
-
if (appendResult.status === "duplicate") {
|
|
1544
|
-
const conversation = await getConversation({
|
|
1545
|
-
conversationId: args.message.conversationId,
|
|
1546
|
-
state: args.state
|
|
1547
|
-
});
|
|
1548
|
-
if (!conversation) {
|
|
1549
|
-
return appendResult;
|
|
1550
|
-
}
|
|
1551
|
-
if (hasRecentEnqueueMarker(conversation, nowMs)) {
|
|
1552
|
-
await recordExecutionMetadata({
|
|
1553
|
-
conversationId: args.message.conversationId,
|
|
1554
|
-
conversationStore: args.conversationStore,
|
|
1555
|
-
state: args.state
|
|
1556
|
-
});
|
|
1557
|
-
return appendResult;
|
|
1558
|
-
}
|
|
1559
|
-
const duplicateStillPending = conversation.execution.pendingMessages.some(
|
|
1560
|
-
(message) => message.inboundMessageId === args.message.inboundMessageId
|
|
1561
|
-
);
|
|
1562
|
-
if (!duplicateStillPending) {
|
|
1563
|
-
await recordExecutionMetadata({
|
|
1564
|
-
conversationId: args.message.conversationId,
|
|
1565
|
-
conversationStore: args.conversationStore,
|
|
1566
|
-
state: args.state
|
|
1567
|
-
});
|
|
1568
|
-
return appendResult;
|
|
1569
|
-
}
|
|
1570
|
-
idempotencyKey = duplicateInboundNudgeIdempotencyKey(args.message, nowMs);
|
|
1571
|
-
}
|
|
1572
|
-
const wake = await ensureConversationWake({
|
|
1573
|
-
conversationId: args.message.conversationId,
|
|
1574
|
-
conversationStore: args.conversationStore,
|
|
1575
|
-
idempotencyKey,
|
|
1576
|
-
nowMs,
|
|
1577
|
-
queue: args.queue,
|
|
1578
|
-
state: args.state
|
|
1579
|
-
});
|
|
1580
|
-
if (wake.status !== "enqueued") {
|
|
1581
|
-
await recordExecutionMetadata({
|
|
1582
|
-
conversationId: args.message.conversationId,
|
|
1583
|
-
conversationStore: args.conversationStore,
|
|
1584
|
-
state: args.state
|
|
1585
|
-
});
|
|
1586
|
-
}
|
|
1587
|
-
return {
|
|
1588
|
-
...appendResult,
|
|
1589
|
-
...wake.status === "enqueued" ? { queueMessageId: wake.queueMessageId } : void 0
|
|
1590
|
-
};
|
|
1591
|
-
}
|
|
1592
|
-
async function appendAndEnqueueInboundMessage(args) {
|
|
1593
|
-
const nowMs = args.nowMs ?? now2();
|
|
1594
|
-
const result = await enqueueAfterAppend({
|
|
1595
|
-
...args,
|
|
1596
|
-
appendResult: await appendInboundMessage({
|
|
1597
|
-
message: args.message,
|
|
1598
|
-
nowMs,
|
|
1599
|
-
state: args.state
|
|
1600
|
-
}),
|
|
1601
|
-
nowMs
|
|
1602
|
-
});
|
|
1603
|
-
if (result.status === "active") {
|
|
1604
|
-
throw new Error("Non-exclusive mailbox enqueue returned active");
|
|
1605
|
-
}
|
|
1606
|
-
return result;
|
|
1607
|
-
}
|
|
1608
|
-
async function appendAndEnqueueExclusiveInboundMessage(args) {
|
|
1609
|
-
const nowMs = args.nowMs ?? now2();
|
|
1610
|
-
return await enqueueAfterAppend({
|
|
1611
|
-
...args,
|
|
1612
|
-
appendResult: await appendExclusiveInboundMessage({
|
|
1613
|
-
message: args.message,
|
|
1614
|
-
nowMs,
|
|
1615
|
-
state: args.state
|
|
1616
|
-
}),
|
|
1617
|
-
nowMs
|
|
1618
|
-
});
|
|
1619
|
-
}
|
|
1620
|
-
async function stopConversationWork2(args) {
|
|
1621
|
-
const result = await stopConversationWork(args);
|
|
1622
|
-
if (result.status === "requested") {
|
|
1623
|
-
await recordExecutionMetadata(args);
|
|
1624
|
-
}
|
|
1625
|
-
return result;
|
|
1626
|
-
}
|
|
1627
|
-
async function completeConversationStop2(args) {
|
|
1628
|
-
const result = await completeConversationStop(args);
|
|
1629
|
-
if (result.status === "cleared") {
|
|
1630
|
-
await recordExecutionMetadata(args);
|
|
1631
|
-
}
|
|
1632
|
-
return result;
|
|
1633
|
-
}
|
|
1634
|
-
async function clearConsumedConversationWake2(args) {
|
|
1635
|
-
const result = await clearConsumedConversationWake(args);
|
|
1636
|
-
if (result) {
|
|
1637
|
-
await recordExecutionMetadata(args);
|
|
1638
|
-
}
|
|
1639
|
-
return result;
|
|
1640
|
-
}
|
|
1641
|
-
async function requestConversationWork2(args) {
|
|
1642
|
-
const result = await requestConversationWork(args);
|
|
1643
|
-
await recordExecutionMetadata({
|
|
1644
|
-
conversationId: args.conversationId,
|
|
1645
|
-
conversationStore: args.conversationStore,
|
|
1646
|
-
state: args.state
|
|
1647
|
-
});
|
|
1648
|
-
return result;
|
|
1649
|
-
}
|
|
1650
|
-
async function markConversationWorkEnqueued2(args) {
|
|
1651
|
-
await markConversationWorkEnqueued(args);
|
|
1652
|
-
await recordExecutionMetadata(args);
|
|
1653
|
-
}
|
|
1654
|
-
async function startConversationWork2(args) {
|
|
1655
|
-
const result = await startConversationWork(args);
|
|
1656
|
-
await recordExecutionMetadata(args);
|
|
1657
|
-
return result;
|
|
1658
|
-
}
|
|
1659
|
-
async function checkInConversationWork2(args) {
|
|
1660
|
-
const result = await checkInConversationWork(args);
|
|
1661
|
-
if (result) {
|
|
1662
|
-
await recordExecutionMetadata(args);
|
|
1663
|
-
}
|
|
1664
|
-
return result;
|
|
1665
|
-
}
|
|
1666
|
-
async function drainConversationMailbox2(args) {
|
|
1667
|
-
const result = await drainConversationMailbox(args);
|
|
1668
|
-
if (result.changed) {
|
|
1669
|
-
await recordExecutionMetadata(args);
|
|
1670
|
-
}
|
|
1671
|
-
return result.messages;
|
|
1672
|
-
}
|
|
1673
|
-
async function ackMessages2(args) {
|
|
1674
|
-
const result = await ackMessages(args);
|
|
1675
|
-
await recordExecutionMetadata(args);
|
|
1676
|
-
return result;
|
|
1677
|
-
}
|
|
1678
|
-
async function cancelHumanFacingPendingMessages2(args) {
|
|
1679
|
-
const result = await cancelHumanFacingPendingMessages(args);
|
|
1680
|
-
if (result.cancelledInboundMessageIds.length > 0) {
|
|
1681
|
-
await recordExecutionMetadata(args);
|
|
1682
|
-
}
|
|
1683
|
-
return result;
|
|
1684
|
-
}
|
|
1685
|
-
async function requestAnotherSlice2(args) {
|
|
1686
|
-
const result = await requestAnotherSlice(args);
|
|
1687
|
-
await recordExecutionMetadata(args);
|
|
1688
|
-
return result;
|
|
1689
|
-
}
|
|
1690
|
-
async function beginConversationResume2(args) {
|
|
1691
|
-
const result = await beginConversationResume(args);
|
|
1692
|
-
if (result) {
|
|
1693
|
-
await recordExecutionMetadata(args);
|
|
1694
|
-
}
|
|
1695
|
-
return result;
|
|
1696
|
-
}
|
|
1697
|
-
async function releaseConversationWork2(args) {
|
|
1698
|
-
const result = await releaseConversationWork(args);
|
|
1699
|
-
await recordExecutionMetadata(args);
|
|
1700
|
-
return result;
|
|
1701
|
-
}
|
|
1702
|
-
async function completeConversationWork2(args) {
|
|
1703
|
-
const result = await completeConversationWork(args);
|
|
1704
|
-
await recordExecutionMetadata(args);
|
|
1705
|
-
return result;
|
|
1706
|
-
}
|
|
1707
|
-
async function recordAttemptFailure2(args) {
|
|
1708
|
-
const result = await recordAttemptFailure(args);
|
|
1709
|
-
if (result.status === "recorded") {
|
|
1710
|
-
await recordExecutionMetadata(args);
|
|
1711
|
-
}
|
|
1712
|
-
return result;
|
|
1713
|
-
}
|
|
1714
|
-
async function deadLetterAttempt2(args) {
|
|
1715
|
-
const result = await deadLetterAttempt(args);
|
|
1716
|
-
await recordExecutionMetadata(args);
|
|
1717
|
-
return result;
|
|
1718
|
-
}
|
|
1719
|
-
async function clearExpiredConversationLease2(args) {
|
|
1720
|
-
const result = await clearExpiredConversationLease(args);
|
|
1721
|
-
await recordExecutionMetadata(args);
|
|
1722
|
-
return result;
|
|
1723
|
-
}
|
|
1724
|
-
async function removeActiveConversation2(args) {
|
|
1725
|
-
return await removeActiveConversation(args);
|
|
1726
|
-
}
|
|
1727
|
-
async function listActiveConversationIds2(args = {}) {
|
|
1728
|
-
return await listActiveConversationIds(args);
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
export {
|
|
1732
|
-
isInvalidConversationRecordError,
|
|
1733
|
-
CONVERSATION_WORK_CHECK_IN_INTERVAL_MS,
|
|
1734
|
-
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
1735
|
-
CONVERSATION_WORK_MAX_RETRIES,
|
|
1736
|
-
isFinalAttempt,
|
|
1737
|
-
hasRunnableConversationWork,
|
|
1738
|
-
getConversation2 as getConversation,
|
|
1739
|
-
getConversationWorkState2 as getConversationWorkState,
|
|
1740
|
-
recordConversationRetry2 as recordConversationRetry,
|
|
1741
|
-
countPendingConversationMessages,
|
|
1742
|
-
hasRunnableConversationWork2,
|
|
1743
|
-
ensureConversationWake,
|
|
1744
|
-
appendAndEnqueueInboundMessage,
|
|
1745
|
-
appendAndEnqueueExclusiveInboundMessage,
|
|
1746
|
-
stopConversationWork2 as stopConversationWork,
|
|
1747
|
-
completeConversationStop2 as completeConversationStop,
|
|
1748
|
-
clearConsumedConversationWake2 as clearConsumedConversationWake,
|
|
1749
|
-
requestConversationWork2 as requestConversationWork,
|
|
1750
|
-
startConversationWork2 as startConversationWork,
|
|
1751
|
-
checkInConversationWork2 as checkInConversationWork,
|
|
1752
|
-
drainConversationMailbox2 as drainConversationMailbox,
|
|
1753
|
-
ackMessages2 as ackMessages,
|
|
1754
|
-
cancelHumanFacingPendingMessages2 as cancelHumanFacingPendingMessages,
|
|
1755
|
-
requestAnotherSlice2 as requestAnotherSlice,
|
|
1756
|
-
beginConversationResume2 as beginConversationResume,
|
|
1757
|
-
releaseConversationWork2 as releaseConversationWork,
|
|
1758
|
-
completeConversationWork2 as completeConversationWork,
|
|
1759
|
-
recordAttemptFailure2 as recordAttemptFailure,
|
|
1760
|
-
deadLetterAttempt2 as deadLetterAttempt,
|
|
1761
|
-
clearExpiredConversationLease2 as clearExpiredConversationLease,
|
|
1762
|
-
removeActiveConversation2 as removeActiveConversation,
|
|
1763
|
-
listActiveConversationIds2 as listActiveConversationIds
|
|
1764
|
-
};
|