@sentry/junior 0.94.0 → 0.95.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-hooks-ZG7IDOIN.js → agent-hooks-FTQ5EGPO.js} +9 -10
- package/dist/api/people/list.js +7 -7
- package/dist/api/people/profile.js +7 -7
- package/dist/api/people/shared.d.ts +2 -2
- package/dist/api-reference.d.ts +1 -1
- package/dist/app.js +427 -196
- package/dist/{catalog-runtime-NZHMSMYC.js → catalog-runtime-2D7IVKUT.js} +3 -3
- package/dist/chat/advisor-request.d.ts +4 -0
- package/dist/chat/agent/request.d.ts +2 -0
- package/dist/chat/agent/resume.d.ts +2 -0
- package/dist/chat/conversations/history.d.ts +128 -0
- package/dist/chat/conversations/legacy-import.d.ts +38 -0
- package/dist/chat/conversations/messages.d.ts +39 -0
- package/dist/chat/conversations/projection.d.ts +94 -0
- package/dist/chat/conversations/retention.d.ts +36 -0
- package/dist/chat/conversations/sql/conversation-row.d.ts +14 -0
- package/dist/chat/conversations/sql/history.d.ts +4 -0
- package/dist/chat/conversations/sql/legacy-history-import.d.ts +55 -0
- package/dist/chat/conversations/sql/messages.d.ts +4 -0
- package/dist/chat/conversations/sql/migrations.d.ts +14 -3
- package/dist/chat/conversations/sql/purge.d.ts +53 -0
- package/dist/chat/conversations/sql/store.d.ts +7 -2
- package/dist/chat/conversations/store.d.ts +19 -0
- package/dist/chat/conversations/visible-compactions.d.ts +11 -0
- package/dist/chat/conversations/visible-messages.d.ts +47 -0
- package/dist/chat/db.d.ts +12 -1
- package/dist/chat/identities/sql.d.ts +1 -1
- package/dist/chat/logging.d.ts +2 -1
- package/dist/chat/resource-events/store.d.ts +2 -1
- package/dist/chat/runtime/reply-executor.d.ts +8 -0
- package/dist/chat/runtime/thread-state.d.ts +2 -0
- package/dist/chat/sandbox/resources.d.ts +4 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +8 -0
- package/dist/chat/services/plugin-auth-orchestration.d.ts +12 -0
- package/dist/chat/services/turn-session-record.d.ts +14 -2
- package/dist/chat/sleep.d.ts +2 -0
- package/dist/chat/state/conversation.d.ts +7 -4
- package/dist/chat/state/session-log.d.ts +23 -1
- package/dist/chat/state/turn-session.d.ts +6 -0
- package/dist/chat/tool-support/private-trace-result.d.ts +4 -0
- package/dist/chat/tool-support/zod-tool.d.ts +1 -0
- package/dist/chat/tools/advisor/tool.d.ts +9 -4
- package/dist/chat/tools/definition.d.ts +2 -0
- package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -2
- package/dist/chat/tools/system-time.d.ts +8 -0
- package/dist/chat/xml.d.ts +2 -0
- package/dist/{chunk-NYWPISSO.js → chunk-2XXEKR44.js} +1 -1
- package/dist/{chunk-QGEWC27H.js → chunk-5XMNOD3S.js} +5 -7
- package/dist/{chunk-NFXSLTYG.js → chunk-6ONME5IG.js} +864 -62
- package/dist/{chunk-LFLTJQVR.js → chunk-7FBGKXPE.js} +4 -0
- package/dist/{chunk-MC4ZZE4Q.js → chunk-AYP4ERVZ.js} +1 -1
- package/dist/{chunk-GHGPTPBL.js → chunk-B7PUBQQM.js} +1 -1
- package/dist/chunk-CM5EZD5F.js +17 -0
- package/dist/chunk-CRRBJ3JP.js +1037 -0
- package/dist/{chunk-G3E7SCME.js → chunk-CZEX6KIQ.js} +23 -0
- package/dist/{chunk-TNUUATT7.js → chunk-E3E2XNCN.js} +2 -2
- package/dist/{chunk-LNCREA5Z.js → chunk-EKNJM5IG.js} +3 -127
- package/dist/{chunk-NAPITCZ6.js → chunk-GUE7HTNR.js} +251 -6
- package/dist/{chunk-BTH37NCU.js → chunk-GVOUCI2O.js} +1 -1
- package/dist/{chunk-YYBX2BD5.js → chunk-GY34VGP5.js} +1 -1
- package/dist/{chunk-KRMANDHI.js → chunk-HCXXB35T.js} +1481 -349
- package/dist/{chunk-YTNPU7I2.js → chunk-HDTO3A74.js} +2 -2
- package/dist/{chunk-YJ4OPVNA.js → chunk-HZNJLKKI.js} +1 -1
- package/dist/{chunk-HDNWZMUN.js → chunk-KDPCGVIT.js} +116 -51
- package/dist/chunk-N4RNJ32C.js +48 -0
- package/dist/{chunk-UUB3D2XI.js → chunk-NSCHU54X.js} +8 -10
- package/dist/{chunk-PFXC67GJ.js → chunk-RAIB6WSG.js} +6 -80
- package/dist/chunk-WAGQ377B.js +724 -0
- package/dist/{chunk-6H4PP63X.js → chunk-WCMQJE4F.js} +24 -14
- package/dist/{chunk-S6QKIGRM.js → chunk-WPOJ443W.js} +15 -25
- package/dist/{chunk-MAVOJ54A.js → chunk-XX4N4E6C.js} +25 -388
- package/dist/cli/chat.js +24 -23
- package/dist/cli/check.js +4 -4
- package/dist/cli/plugins.js +11 -12
- package/dist/cli/snapshot-warmup.js +7 -8
- package/dist/cli/upgrade.js +78 -17
- package/dist/db/schema/agent-steps.d.ts +134 -0
- package/dist/db/schema/conversation-messages.d.ts +153 -0
- package/dist/{chat/conversations/sql → db}/schema/conversations.d.ts +34 -0
- package/dist/{chat/conversations/sql → db}/schema.d.ts +319 -8
- package/dist/db-W55B74OP.js +24 -0
- package/dist/deployment.d.ts +2 -0
- package/dist/handlers/retention.d.ts +6 -0
- package/dist/instrumentation.js +16 -3
- package/dist/legacy-import-ZPLGLAFD.js +17 -0
- package/dist/nitro.js +14 -4
- package/dist/reporting/conversations/activity.d.ts +40 -0
- package/dist/reporting/conversations/context.d.ts +8 -0
- package/dist/reporting/conversations/details.d.ts +6 -0
- package/dist/reporting/conversations/index.d.ts +4 -0
- package/dist/reporting/conversations/shared.d.ts +9 -0
- package/dist/reporting/conversations/statistics.d.ts +4 -0
- package/dist/reporting/conversations/summaries.d.ts +17 -0
- package/dist/reporting/conversations/transcript.d.ts +28 -0
- package/dist/reporting/conversations/types.d.ts +178 -0
- package/dist/reporting/conversations.d.ts +1 -178
- package/dist/reporting.d.ts +4 -3
- package/dist/reporting.js +603 -827
- package/dist/{runner-XAZPJNAQ.js → runner-OOSBDYRK.js} +35 -41
- package/dist/{validation-KYAWETI4.js → validation-QCGRFRFZ.js} +4 -4
- package/migrations/README.md +32 -0
- package/migrations/meta/0000_snapshot.json +978 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +10 -7
- package/dist/chat/sql/schema.d.ts +0 -1049
- package/dist/chat/state/conversation-details.d.ts +0 -47
- package/dist/chunk-7STN2ZSK.js +0 -250
- package/dist/chunk-LE5ANBUZ.js +0 -1040
- package/dist/chunk-QL66APYJ.js +0 -1377
- package/dist/db-YDN6AFJH.js +0 -18
- /package/dist/{chat/sql → db}/db.d.ts +0 -0
- /package/dist/{chat/sql → db}/executor.d.ts +0 -0
- /package/dist/{chat/sql → db}/neon.d.ts +0 -0
- /package/dist/{chat/sql → db}/postgres.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/destinations.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/identities.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/migrations.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/timestamps.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/users.d.ts +0 -0
package/dist/app.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
buildConversationContext,
|
|
3
2
|
buildDeliveredTurnStatePatch,
|
|
4
|
-
createConversationMemoryService,
|
|
5
|
-
estimateTextTokens,
|
|
6
3
|
finalizeFailedTurnReply,
|
|
7
|
-
generateConversationId,
|
|
8
|
-
getAgentContextCompactionTriggerTokens,
|
|
9
4
|
getAgentTurnDiagnosticsAttributes,
|
|
10
|
-
getConversationMessageSlackTs,
|
|
11
|
-
getThreadTitleSourceMessage,
|
|
12
|
-
isHumanConversationMessage,
|
|
13
|
-
markConversationMessage,
|
|
14
|
-
normalizeConversationText,
|
|
15
5
|
processPluginTask,
|
|
16
6
|
requireTurnFailureEventId,
|
|
17
|
-
scheduleSessionCompletedPluginTasks
|
|
18
|
-
|
|
19
|
-
upsertConversationMessage
|
|
20
|
-
} from "./chunk-MAVOJ54A.js";
|
|
7
|
+
scheduleSessionCompletedPluginTasks
|
|
8
|
+
} from "./chunk-XX4N4E6C.js";
|
|
21
9
|
import {
|
|
22
10
|
CONVERSATION_WORK_CHECK_IN_INTERVAL_MS,
|
|
23
11
|
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
@@ -41,12 +29,12 @@ import {
|
|
|
41
29
|
requestConversationContinuation,
|
|
42
30
|
requestConversationWork,
|
|
43
31
|
startConversationWork
|
|
44
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-5XMNOD3S.js";
|
|
45
33
|
import {
|
|
46
34
|
getVercelConversationWorkQueue,
|
|
47
35
|
resolveConversationWorkQueueTopic,
|
|
48
36
|
verifyConversationQueueMessage
|
|
49
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-2XXEKR44.js";
|
|
50
38
|
import {
|
|
51
39
|
PLUGIN_TASK_QUEUE_TOPIC,
|
|
52
40
|
createVercelQueueClient,
|
|
@@ -56,15 +44,13 @@ import {
|
|
|
56
44
|
GET,
|
|
57
45
|
buildSentryConversationUrl,
|
|
58
46
|
conversationVisibilityFromSlackChannelType,
|
|
59
|
-
initConversationContext,
|
|
60
47
|
resolveSlackChannelTypeFromMessage,
|
|
61
|
-
resolveSlackConversationContext
|
|
62
|
-
|
|
63
|
-
} from "./chunk-LNCREA5Z.js";
|
|
48
|
+
resolveSlackConversationContext
|
|
49
|
+
} from "./chunk-EKNJM5IG.js";
|
|
64
50
|
import {
|
|
65
51
|
validatePluginEgressCredentialHooks,
|
|
66
52
|
validatePluginRegistrations
|
|
67
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-AYP4ERVZ.js";
|
|
68
54
|
import {
|
|
69
55
|
defineJuniorPlugins,
|
|
70
56
|
pluginCatalogConfigFromEnv,
|
|
@@ -77,6 +63,7 @@ import {
|
|
|
77
63
|
SANDBOX_EGRESS_PROXY_PATH,
|
|
78
64
|
addReactionToMessage,
|
|
79
65
|
appendSlackLegacyAttachmentText,
|
|
66
|
+
buildSlackOutputMessage,
|
|
80
67
|
buildSteeringPiMessage,
|
|
81
68
|
createAgentRunner,
|
|
82
69
|
createUserTokenStore,
|
|
@@ -85,15 +72,18 @@ import {
|
|
|
85
72
|
deleteMcpServerSessionId,
|
|
86
73
|
deleteMcpStoredOAuthCredentials,
|
|
87
74
|
deliverResourceEventSubscription,
|
|
75
|
+
escapeSlackMrkdwnText,
|
|
88
76
|
executeAgentRun,
|
|
89
77
|
executeCredentialedEgressRequest,
|
|
90
78
|
finalizeMcpAuthorization,
|
|
91
79
|
findMatchingResourceEventSubscriptions,
|
|
92
80
|
formatProviderLabel,
|
|
81
|
+
formatSlackLink,
|
|
93
82
|
getConfigDefaults,
|
|
94
83
|
getMcpStoredOAuthCredentials,
|
|
95
84
|
listThreadReplies,
|
|
96
85
|
normalizeSandboxEgressTracePropagationDomains,
|
|
86
|
+
normalizeSlackStatusText,
|
|
97
87
|
parseOAuthStatePayload,
|
|
98
88
|
parseSandboxEgressCredentialToken,
|
|
99
89
|
postSlackMessage,
|
|
@@ -105,8 +95,10 @@ import {
|
|
|
105
95
|
setConfigDefaults,
|
|
106
96
|
shouldEmitDevAgentTrace,
|
|
107
97
|
shouldPropagateSandboxEgressTrace,
|
|
108
|
-
|
|
109
|
-
|
|
98
|
+
splitSlackReplyText,
|
|
99
|
+
startOAuthFlow,
|
|
100
|
+
truncateStatusText
|
|
101
|
+
} from "./chunk-HCXXB35T.js";
|
|
110
102
|
import {
|
|
111
103
|
CooperativeTurnYieldError,
|
|
112
104
|
TurnInputCommitLostError,
|
|
@@ -129,37 +121,48 @@ import {
|
|
|
129
121
|
markTurnFailed,
|
|
130
122
|
mergeArtifactsState,
|
|
131
123
|
persistCompletedSessionRecord,
|
|
124
|
+
persistThreadRuntimeState,
|
|
132
125
|
persistThreadState,
|
|
133
126
|
persistThreadStateById,
|
|
127
|
+
persistWithRetry,
|
|
134
128
|
persistYieldSessionRecord,
|
|
135
129
|
startActiveTurn
|
|
136
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-KDPCGVIT.js";
|
|
137
131
|
import {
|
|
138
|
-
JUNIOR_THREAD_STATE_TTL_MS,
|
|
139
132
|
coerceThreadConversationState
|
|
140
|
-
} from "./chunk-
|
|
141
|
-
import "./chunk-
|
|
142
|
-
import
|
|
143
|
-
|
|
144
|
-
escapeSlackMrkdwnText,
|
|
145
|
-
formatSlackLink,
|
|
146
|
-
normalizeSlackStatusText,
|
|
147
|
-
splitSlackReplyText,
|
|
148
|
-
truncateStatusText
|
|
149
|
-
} from "./chunk-LE5ANBUZ.js";
|
|
133
|
+
} from "./chunk-RAIB6WSG.js";
|
|
134
|
+
import "./chunk-WCMQJE4F.js";
|
|
135
|
+
import "./chunk-CM5EZD5F.js";
|
|
136
|
+
import "./chunk-N4RNJ32C.js";
|
|
150
137
|
import {
|
|
151
138
|
abandonAgentTurnSessionRecord,
|
|
152
139
|
commitMessages,
|
|
153
|
-
contextProvenance,
|
|
154
140
|
failAgentTurnSessionRecord,
|
|
155
141
|
getAgentTurnSessionRecord,
|
|
156
|
-
instructionProvenanceFor,
|
|
157
142
|
listAgentTurnSessionSummariesForConversation,
|
|
158
143
|
loadProjection,
|
|
159
144
|
loadProjectionWithProvenance,
|
|
160
145
|
recordAgentTurnSessionSummary,
|
|
161
146
|
recordAuthorizationCompleted
|
|
162
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-WAGQ377B.js";
|
|
148
|
+
import {
|
|
149
|
+
JUNIOR_THREAD_STATE_TTL_MS,
|
|
150
|
+
buildConversationContext,
|
|
151
|
+
createConversationMemoryService,
|
|
152
|
+
estimateTextTokens,
|
|
153
|
+
generateConversationId,
|
|
154
|
+
getAgentContextCompactionTriggerTokens,
|
|
155
|
+
getConversationMessageSlackTs,
|
|
156
|
+
getThreadTitleSourceMessage,
|
|
157
|
+
hydrateConversationMessages,
|
|
158
|
+
isHumanConversationMessage,
|
|
159
|
+
markConversationMessage,
|
|
160
|
+
normalizeConversationText,
|
|
161
|
+
persistConversationCompactions,
|
|
162
|
+
persistConversationMessages,
|
|
163
|
+
updateConversationStats,
|
|
164
|
+
upsertConversationMessage
|
|
165
|
+
} from "./chunk-CRRBJ3JP.js";
|
|
163
166
|
import {
|
|
164
167
|
SlackActionError,
|
|
165
168
|
bindSlackDirectCredentialSubject,
|
|
@@ -178,22 +181,29 @@ import {
|
|
|
178
181
|
setPlugins,
|
|
179
182
|
validatePlugins,
|
|
180
183
|
verifySlackDirectCredentialSubject
|
|
181
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-NSCHU54X.js";
|
|
182
185
|
import {
|
|
183
186
|
createPluginLogger,
|
|
184
187
|
createPluginState
|
|
185
|
-
} from "./chunk-
|
|
186
|
-
import "./chunk-G3E7SCME.js";
|
|
188
|
+
} from "./chunk-E3E2XNCN.js";
|
|
187
189
|
import {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
} from "./chunk-7STN2ZSK.js";
|
|
190
|
+
sleep
|
|
191
|
+
} from "./chunk-CZEX6KIQ.js";
|
|
191
192
|
import {
|
|
193
|
+
contextProvenance,
|
|
194
|
+
getAgentStepStore,
|
|
192
195
|
getConversationStore,
|
|
193
|
-
getDb
|
|
194
|
-
|
|
196
|
+
getDb,
|
|
197
|
+
getSqlExecutor,
|
|
198
|
+
instructionProvenanceFor,
|
|
199
|
+
juniorAgentSteps,
|
|
200
|
+
juniorConversationMessages,
|
|
201
|
+
juniorConversations,
|
|
202
|
+
juniorDestinations
|
|
203
|
+
} from "./chunk-6ONME5IG.js";
|
|
195
204
|
import {
|
|
196
205
|
FUNCTION_TIMEOUT_BUFFER_SECONDS,
|
|
206
|
+
acquireActiveLock,
|
|
197
207
|
botConfig,
|
|
198
208
|
completeObject,
|
|
199
209
|
completeText,
|
|
@@ -205,35 +215,36 @@ import {
|
|
|
205
215
|
getSlackClientSecret,
|
|
206
216
|
getSlackReactionConfig,
|
|
207
217
|
getSlackSigningSecret,
|
|
218
|
+
getStateAdapter,
|
|
208
219
|
isProviderRetryError,
|
|
209
220
|
normalizeSlackEmojiName,
|
|
210
221
|
setSlackReactionConfig,
|
|
211
222
|
stripRuntimeTurnContext,
|
|
212
223
|
trimTrailingAssistantMessages,
|
|
213
224
|
unwrapCurrentInstruction
|
|
214
|
-
} from "./chunk-
|
|
225
|
+
} from "./chunk-GUE7HTNR.js";
|
|
215
226
|
import {
|
|
216
227
|
parseSlackThreadId,
|
|
217
228
|
readSlackRawMessageContext,
|
|
218
229
|
resolveSlackChannelIdFromMessage,
|
|
219
230
|
resolveSlackChannelIdFromThreadId
|
|
220
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-GY34VGP5.js";
|
|
221
232
|
import {
|
|
222
233
|
createSlackDestination,
|
|
223
234
|
destinationKey,
|
|
224
235
|
parseDestination,
|
|
225
236
|
requireSlackDestination,
|
|
226
237
|
sameDestination
|
|
227
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-B7PUBQQM.js";
|
|
228
239
|
import {
|
|
229
240
|
discoverSkills
|
|
230
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-HDTO3A74.js";
|
|
231
242
|
import {
|
|
232
243
|
buildOAuthTokenRequest,
|
|
233
244
|
hasRequiredOAuthScope,
|
|
234
245
|
parseOAuthTokenResponse,
|
|
235
246
|
pluginCatalogRuntime
|
|
236
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-GVOUCI2O.js";
|
|
237
248
|
import {
|
|
238
249
|
buildTurnFailureResponse,
|
|
239
250
|
createActor,
|
|
@@ -253,10 +264,9 @@ import {
|
|
|
253
264
|
setSpanAttributes,
|
|
254
265
|
setSpanStatus,
|
|
255
266
|
setTags,
|
|
256
|
-
toStoredSlackActor,
|
|
257
267
|
withContext,
|
|
258
268
|
withSpan
|
|
259
|
-
} from "./chunk-
|
|
269
|
+
} from "./chunk-WPOJ443W.js";
|
|
260
270
|
import {
|
|
261
271
|
toOptionalString
|
|
262
272
|
} from "./chunk-OB42YVAE.js";
|
|
@@ -270,7 +280,7 @@ import {
|
|
|
270
280
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE,
|
|
271
281
|
parseSlackChannelId,
|
|
272
282
|
parseSlackMessageTs
|
|
273
|
-
} from "./chunk-
|
|
283
|
+
} from "./chunk-7FBGKXPE.js";
|
|
274
284
|
import "./chunk-MLKGABMK.js";
|
|
275
285
|
|
|
276
286
|
// src/app.ts
|
|
@@ -449,27 +459,6 @@ async function postSlackApiReplyPosts(args) {
|
|
|
449
459
|
return lastPostedMessageTs;
|
|
450
460
|
}
|
|
451
461
|
|
|
452
|
-
// src/chat/services/persist-retry.ts
|
|
453
|
-
var PERSIST_ATTEMPTS = 3;
|
|
454
|
-
function sleep(ms) {
|
|
455
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
456
|
-
}
|
|
457
|
-
async function persistWithRetry(persist) {
|
|
458
|
-
let lastError;
|
|
459
|
-
for (let attempt = 1; attempt <= PERSIST_ATTEMPTS; attempt += 1) {
|
|
460
|
-
try {
|
|
461
|
-
await persist();
|
|
462
|
-
return;
|
|
463
|
-
} catch (error) {
|
|
464
|
-
lastError = error;
|
|
465
|
-
if (attempt < PERSIST_ATTEMPTS) {
|
|
466
|
-
await sleep(attempt * 100);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
throw lastError;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
462
|
// src/chat/agent-dispatch/signing.ts
|
|
474
463
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
475
464
|
var DISPATCH_CALLBACK_PATH = "/api/internal/agent-dispatch";
|
|
@@ -970,6 +959,7 @@ async function runAgentDispatchSlice(callback, deps) {
|
|
|
970
959
|
dispatch = startedDispatch;
|
|
971
960
|
const persisted = await getPersistedThreadState(conversationId);
|
|
972
961
|
const conversation = coerceThreadConversationState(persisted);
|
|
962
|
+
await hydrateConversationMessages({ conversation, conversationId });
|
|
973
963
|
const deliveredMessage = conversation.messages.find(
|
|
974
964
|
(message) => message.id === getAssistantMessageId(dispatch) && message.meta?.replied === true && typeof message.meta.slackTs === "string"
|
|
975
965
|
);
|
|
@@ -993,6 +983,7 @@ async function runAgentDispatchSlice(callback, deps) {
|
|
|
993
983
|
dispatch,
|
|
994
984
|
nowMs
|
|
995
985
|
});
|
|
986
|
+
await persistConversationMessages({ conversation, conversationId });
|
|
996
987
|
const conversationContext = buildConversationContext(conversation, {
|
|
997
988
|
excludeMessageId: userMessageId
|
|
998
989
|
});
|
|
@@ -1000,7 +991,9 @@ async function runAgentDispatchSlice(callback, deps) {
|
|
|
1000
991
|
input: {
|
|
1001
992
|
messageText: dispatch.input,
|
|
1002
993
|
conversationContext,
|
|
1003
|
-
|
|
994
|
+
// Pi history for redelivered dispatch slices comes from the SQL
|
|
995
|
+
// step-store projection, not a thread-state mirror.
|
|
996
|
+
piMessages: await loadProjection({ conversationId })
|
|
1004
997
|
},
|
|
1005
998
|
routing: {
|
|
1006
999
|
credentialContext: {
|
|
@@ -1147,6 +1140,7 @@ async function runAgentDispatchSlice(callback, deps) {
|
|
|
1147
1140
|
messages: reply.piMessages,
|
|
1148
1141
|
durationMs: reply.diagnostics.durationMs,
|
|
1149
1142
|
usage: reply.diagnostics.usage,
|
|
1143
|
+
reasoningLevel: reply.diagnostics.thinkingLevel,
|
|
1150
1144
|
destination: dispatch.destination,
|
|
1151
1145
|
source: dispatch.source,
|
|
1152
1146
|
actor: dispatch.actor,
|
|
@@ -1262,42 +1256,31 @@ function now() {
|
|
|
1262
1256
|
return Date.now();
|
|
1263
1257
|
}
|
|
1264
1258
|
async function recordExecutionMetadata(args) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
await metadataStore(args).recordExecution({
|
|
1274
|
-
channelName: conversation.channelName,
|
|
1275
|
-
conversationId: conversation.conversationId,
|
|
1276
|
-
createdAtMs: conversation.createdAtMs,
|
|
1277
|
-
destination: conversation.destination,
|
|
1278
|
-
execution: {
|
|
1279
|
-
lastCheckpointAtMs: conversation.execution.lastCheckpointAtMs,
|
|
1280
|
-
lastEnqueuedAtMs: conversation.execution.lastEnqueuedAtMs,
|
|
1281
|
-
runId: conversation.execution.runId,
|
|
1282
|
-
status: conversation.execution.status,
|
|
1283
|
-
updatedAtMs: conversation.execution.updatedAtMs
|
|
1284
|
-
},
|
|
1285
|
-
lastActivityAtMs: conversation.lastActivityAtMs,
|
|
1286
|
-
actor: conversation.actor,
|
|
1287
|
-
source: conversation.source,
|
|
1288
|
-
title: conversation.title,
|
|
1289
|
-
updatedAtMs: conversation.updatedAtMs
|
|
1290
|
-
});
|
|
1291
|
-
} catch (error) {
|
|
1292
|
-
logWarn(
|
|
1293
|
-
"conversation_execution_metadata_update_failed",
|
|
1294
|
-
{ conversationId: args.conversationId },
|
|
1295
|
-
{
|
|
1296
|
-
"exception.message": error instanceof Error ? error.message : String(error)
|
|
1297
|
-
},
|
|
1298
|
-
"Failed to update conversation execution metadata"
|
|
1299
|
-
);
|
|
1259
|
+
const conversation = await getConversation({
|
|
1260
|
+
conversationId: args.conversationId,
|
|
1261
|
+
state: args.state
|
|
1262
|
+
});
|
|
1263
|
+
if (!conversation) {
|
|
1264
|
+
return;
|
|
1300
1265
|
}
|
|
1266
|
+
await metadataStore(args).recordExecution({
|
|
1267
|
+
channelName: conversation.channelName,
|
|
1268
|
+
conversationId: conversation.conversationId,
|
|
1269
|
+
createdAtMs: conversation.createdAtMs,
|
|
1270
|
+
destination: conversation.destination,
|
|
1271
|
+
execution: {
|
|
1272
|
+
lastCheckpointAtMs: conversation.execution.lastCheckpointAtMs,
|
|
1273
|
+
lastEnqueuedAtMs: conversation.execution.lastEnqueuedAtMs,
|
|
1274
|
+
runId: conversation.execution.runId,
|
|
1275
|
+
status: conversation.execution.status,
|
|
1276
|
+
updatedAtMs: conversation.execution.updatedAtMs
|
|
1277
|
+
},
|
|
1278
|
+
lastActivityAtMs: conversation.lastActivityAtMs,
|
|
1279
|
+
actor: conversation.actor,
|
|
1280
|
+
source: conversation.source,
|
|
1281
|
+
title: conversation.title,
|
|
1282
|
+
updatedAtMs: conversation.updatedAtMs
|
|
1283
|
+
});
|
|
1301
1284
|
}
|
|
1302
1285
|
async function getConversationWorkState2(args) {
|
|
1303
1286
|
return await getConversationWorkState(args);
|
|
@@ -1354,13 +1337,26 @@ async function appendAndEnqueueInboundMessage(args) {
|
|
|
1354
1337
|
conversationId: args.message.conversationId,
|
|
1355
1338
|
state: args.state
|
|
1356
1339
|
});
|
|
1357
|
-
if (!conversation
|
|
1340
|
+
if (!conversation) {
|
|
1341
|
+
return appendResult;
|
|
1342
|
+
}
|
|
1343
|
+
if (hasRecentEnqueueMarker(conversation, nowMs)) {
|
|
1344
|
+
await recordExecutionMetadata({
|
|
1345
|
+
conversationId: args.message.conversationId,
|
|
1346
|
+
conversationStore: args.conversationStore,
|
|
1347
|
+
state: args.state
|
|
1348
|
+
});
|
|
1358
1349
|
return appendResult;
|
|
1359
1350
|
}
|
|
1360
1351
|
const duplicateStillPending = conversation.execution.pendingMessages.some(
|
|
1361
1352
|
(message) => message.inboundMessageId === args.message.inboundMessageId
|
|
1362
1353
|
);
|
|
1363
1354
|
if (!duplicateStillPending) {
|
|
1355
|
+
await recordExecutionMetadata({
|
|
1356
|
+
conversationId: args.message.conversationId,
|
|
1357
|
+
conversationStore: args.conversationStore,
|
|
1358
|
+
state: args.state
|
|
1359
|
+
});
|
|
1364
1360
|
return appendResult;
|
|
1365
1361
|
}
|
|
1366
1362
|
idempotencyKey = duplicateInboundNudgeIdempotencyKey(args.message, nowMs);
|
|
@@ -2184,6 +2180,7 @@ async function ingestResourceEvent(input, options) {
|
|
|
2184
2180
|
});
|
|
2185
2181
|
let enqueued = 0;
|
|
2186
2182
|
const errors = [];
|
|
2183
|
+
const waitDeadlineMs = Date.now() + 1e4;
|
|
2187
2184
|
for (const subscription of subscriptions) {
|
|
2188
2185
|
try {
|
|
2189
2186
|
const delivered = await deliverResourceEventSubscription({
|
|
@@ -2194,6 +2191,7 @@ async function ingestResourceEvent(input, options) {
|
|
|
2194
2191
|
nowMs,
|
|
2195
2192
|
state: options.state,
|
|
2196
2193
|
subscription,
|
|
2194
|
+
waitDeadlineMs,
|
|
2197
2195
|
deliver: async (current) => {
|
|
2198
2196
|
const result = await enqueueResourceEventNotification({
|
|
2199
2197
|
event,
|
|
@@ -3042,8 +3040,210 @@ async function GET2(request, waitUntil, options = {}) {
|
|
|
3042
3040
|
return new Response("Accepted", { status: 202 });
|
|
3043
3041
|
}
|
|
3044
3042
|
|
|
3045
|
-
// src/handlers/
|
|
3046
|
-
import {
|
|
3043
|
+
// src/handlers/retention.ts
|
|
3044
|
+
import { timingSafeEqual as timingSafeEqual4 } from "crypto";
|
|
3045
|
+
|
|
3046
|
+
// src/chat/conversations/sql/purge.ts
|
|
3047
|
+
import { and, asc, eq, inArray, isNull, sql } from "drizzle-orm";
|
|
3048
|
+
async function conversationTreeIds(executor, rootConversationId) {
|
|
3049
|
+
const all = /* @__PURE__ */ new Set([rootConversationId]);
|
|
3050
|
+
let frontier = [rootConversationId];
|
|
3051
|
+
while (frontier.length > 0) {
|
|
3052
|
+
const children = await executor.db().select({ id: juniorConversations.conversationId }).from(juniorConversations).where(inArray(juniorConversations.parentConversationId, frontier));
|
|
3053
|
+
frontier = [];
|
|
3054
|
+
for (const child of children) {
|
|
3055
|
+
if (!all.has(child.id)) {
|
|
3056
|
+
all.add(child.id);
|
|
3057
|
+
frontier.push(child.id);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
return [...all];
|
|
3062
|
+
}
|
|
3063
|
+
async function selectExpiredRoots(executor, args) {
|
|
3064
|
+
const publicCutoff = new Date(args.nowMs - args.publicWindowMs).toISOString();
|
|
3065
|
+
const privateCutoff = new Date(
|
|
3066
|
+
args.nowMs - args.privateWindowMs
|
|
3067
|
+
).toISOString();
|
|
3068
|
+
const cutoff = sql`case when ${juniorDestinations.visibility} = 'public' then ${publicCutoff}::timestamptz else ${privateCutoff}::timestamptz end`;
|
|
3069
|
+
const hasTreeWork = sql`exists (
|
|
3070
|
+
with recursive conversation_tree(conversation_id) as (
|
|
3071
|
+
select ${juniorConversations.conversationId}
|
|
3072
|
+
union all
|
|
3073
|
+
select child.conversation_id
|
|
3074
|
+
from junior_conversations child
|
|
3075
|
+
join conversation_tree parent on child.parent_conversation_id = parent.conversation_id
|
|
3076
|
+
)
|
|
3077
|
+
select 1
|
|
3078
|
+
from conversation_tree tree
|
|
3079
|
+
where exists (
|
|
3080
|
+
select 1 from junior_agent_steps steps
|
|
3081
|
+
where steps.conversation_id = tree.conversation_id
|
|
3082
|
+
)
|
|
3083
|
+
or exists (
|
|
3084
|
+
select 1 from junior_conversation_messages messages
|
|
3085
|
+
where messages.conversation_id = tree.conversation_id
|
|
3086
|
+
)
|
|
3087
|
+
or (
|
|
3088
|
+
${juniorDestinations.visibility} is distinct from 'public'
|
|
3089
|
+
and exists (
|
|
3090
|
+
select 1 from junior_conversations metadata
|
|
3091
|
+
where metadata.conversation_id = tree.conversation_id
|
|
3092
|
+
and (
|
|
3093
|
+
metadata.title is not null
|
|
3094
|
+
or metadata.channel_name is not null
|
|
3095
|
+
or metadata.actor_json is not null
|
|
3096
|
+
)
|
|
3097
|
+
)
|
|
3098
|
+
)
|
|
3099
|
+
)`;
|
|
3100
|
+
const rows = await executor.db().select({
|
|
3101
|
+
conversationId: juniorConversations.conversationId,
|
|
3102
|
+
visibility: juniorDestinations.visibility
|
|
3103
|
+
}).from(juniorConversations).leftJoin(
|
|
3104
|
+
juniorDestinations,
|
|
3105
|
+
eq(juniorDestinations.id, juniorConversations.destinationId)
|
|
3106
|
+
).where(
|
|
3107
|
+
and(
|
|
3108
|
+
isNull(juniorConversations.parentConversationId),
|
|
3109
|
+
sql`${juniorConversations.lastActivityAt} < ${cutoff}`,
|
|
3110
|
+
hasTreeWork
|
|
3111
|
+
)
|
|
3112
|
+
).orderBy(
|
|
3113
|
+
asc(juniorConversations.lastActivityAt),
|
|
3114
|
+
asc(juniorConversations.conversationId)
|
|
3115
|
+
).limit(Math.max(0, args.limit));
|
|
3116
|
+
return rows.map((row) => ({
|
|
3117
|
+
conversationId: row.conversationId,
|
|
3118
|
+
visibility: row.visibility
|
|
3119
|
+
}));
|
|
3120
|
+
}
|
|
3121
|
+
async function purgeConversationTree(executor, args) {
|
|
3122
|
+
return await executor.transaction(async () => {
|
|
3123
|
+
const roots = await executor.db().select({
|
|
3124
|
+
destinationId: juniorConversations.destinationId,
|
|
3125
|
+
lastActivityAt: juniorConversations.lastActivityAt,
|
|
3126
|
+
parentConversationId: juniorConversations.parentConversationId
|
|
3127
|
+
}).from(juniorConversations).where(eq(juniorConversations.conversationId, args.rootConversationId)).for("update");
|
|
3128
|
+
const root = roots[0];
|
|
3129
|
+
if (!root || args.retention && root.parentConversationId !== null) {
|
|
3130
|
+
return { purged: false, conversations: 0 };
|
|
3131
|
+
}
|
|
3132
|
+
const destinations = root.destinationId ? await executor.db().select({ visibility: juniorDestinations.visibility }).from(juniorDestinations).where(eq(juniorDestinations.id, root.destinationId)) : [];
|
|
3133
|
+
const isPublic = destinations[0]?.visibility === "public";
|
|
3134
|
+
if (args.retention) {
|
|
3135
|
+
const windowMs = isPublic ? args.retention.publicWindowMs : args.retention.privateWindowMs;
|
|
3136
|
+
if (root.lastActivityAt.getTime() >= args.nowMs - windowMs) {
|
|
3137
|
+
return { purged: false, conversations: 0 };
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
const ids = await conversationTreeIds(executor, args.rootConversationId);
|
|
3141
|
+
await executor.db().delete(juniorAgentSteps).where(inArray(juniorAgentSteps.conversationId, ids));
|
|
3142
|
+
await executor.db().delete(juniorConversationMessages).where(inArray(juniorConversationMessages.conversationId, ids));
|
|
3143
|
+
await executor.db().update(juniorConversations).set({
|
|
3144
|
+
transcriptPurgedAt: new Date(args.nowMs),
|
|
3145
|
+
...(args.retention ? !isPublic : args.scrubMetadata) ? { title: null, channelName: null, actor: null } : {}
|
|
3146
|
+
}).where(inArray(juniorConversations.conversationId, ids));
|
|
3147
|
+
return { purged: true, conversations: ids.length };
|
|
3148
|
+
});
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
// src/chat/conversations/retention.ts
|
|
3152
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
3153
|
+
var CONTENT_RETENTION_MS = {
|
|
3154
|
+
public: 90 * DAY_MS,
|
|
3155
|
+
private: 14 * DAY_MS
|
|
3156
|
+
};
|
|
3157
|
+
var RETENTION_BATCH_LIMIT = 200;
|
|
3158
|
+
async function runRetentionPurge(executor, args) {
|
|
3159
|
+
const limit = args.limit ?? RETENTION_BATCH_LIMIT;
|
|
3160
|
+
const startedAtMs = Date.now();
|
|
3161
|
+
const roots = await selectExpiredRoots(executor, {
|
|
3162
|
+
nowMs: args.nowMs,
|
|
3163
|
+
publicWindowMs: CONTENT_RETENTION_MS.public,
|
|
3164
|
+
privateWindowMs: CONTENT_RETENTION_MS.private,
|
|
3165
|
+
limit
|
|
3166
|
+
});
|
|
3167
|
+
let purged = 0;
|
|
3168
|
+
let failed = 0;
|
|
3169
|
+
let conversations = 0;
|
|
3170
|
+
for (const root of roots) {
|
|
3171
|
+
try {
|
|
3172
|
+
const result = await purgeConversationTree(executor, {
|
|
3173
|
+
rootConversationId: root.conversationId,
|
|
3174
|
+
nowMs: args.nowMs,
|
|
3175
|
+
retention: {
|
|
3176
|
+
publicWindowMs: CONTENT_RETENTION_MS.public,
|
|
3177
|
+
privateWindowMs: CONTENT_RETENTION_MS.private
|
|
3178
|
+
}
|
|
3179
|
+
});
|
|
3180
|
+
if (result.purged) {
|
|
3181
|
+
purged += 1;
|
|
3182
|
+
conversations += result.conversations;
|
|
3183
|
+
}
|
|
3184
|
+
} catch (error) {
|
|
3185
|
+
failed += 1;
|
|
3186
|
+
logException(
|
|
3187
|
+
error,
|
|
3188
|
+
"retention_purge_tree_failed",
|
|
3189
|
+
{ conversationId: root.conversationId },
|
|
3190
|
+
{},
|
|
3191
|
+
"Retention purge failed for one conversation tree"
|
|
3192
|
+
);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
logInfo(
|
|
3196
|
+
"retention_purge_completed",
|
|
3197
|
+
{},
|
|
3198
|
+
{
|
|
3199
|
+
"app.retention.scanned": roots.length,
|
|
3200
|
+
"app.retention.purged": purged,
|
|
3201
|
+
"app.retention.failed": failed,
|
|
3202
|
+
"app.retention.conversations": conversations,
|
|
3203
|
+
"app.retention.duration_ms": Date.now() - startedAtMs
|
|
3204
|
+
},
|
|
3205
|
+
"Retention purge batch completed"
|
|
3206
|
+
);
|
|
3207
|
+
return { scanned: roots.length, purged, failed, conversations };
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
// src/handlers/retention.ts
|
|
3211
|
+
function getRetentionSecret() {
|
|
3212
|
+
return process.env.JUNIOR_SCHEDULER_SECRET?.trim() || process.env.CRON_SECRET?.trim();
|
|
3213
|
+
}
|
|
3214
|
+
function verifyRetentionRequest(request) {
|
|
3215
|
+
const secret = getRetentionSecret();
|
|
3216
|
+
if (!secret) {
|
|
3217
|
+
return false;
|
|
3218
|
+
}
|
|
3219
|
+
const authorization = request.headers.get("authorization")?.trim();
|
|
3220
|
+
if (!authorization?.startsWith("Bearer ")) {
|
|
3221
|
+
return false;
|
|
3222
|
+
}
|
|
3223
|
+
const actual = Buffer.from(authorization.slice("Bearer ".length));
|
|
3224
|
+
const expected = Buffer.from(secret);
|
|
3225
|
+
return actual.length === expected.length && timingSafeEqual4(actual, expected);
|
|
3226
|
+
}
|
|
3227
|
+
async function GET3(request) {
|
|
3228
|
+
if (!verifyRetentionRequest(request)) {
|
|
3229
|
+
return new Response("Unauthorized", { status: 401 });
|
|
3230
|
+
}
|
|
3231
|
+
try {
|
|
3232
|
+
const result = await runRetentionPurge(getSqlExecutor(), {
|
|
3233
|
+
nowMs: Date.now()
|
|
3234
|
+
});
|
|
3235
|
+
return Response.json(result, { status: 200 });
|
|
3236
|
+
} catch (error) {
|
|
3237
|
+
logException(
|
|
3238
|
+
error,
|
|
3239
|
+
"retention_run_failed",
|
|
3240
|
+
{},
|
|
3241
|
+
{},
|
|
3242
|
+
"Retention purge run failed"
|
|
3243
|
+
);
|
|
3244
|
+
return new Response("Retention purge failed", { status: 500 });
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3047
3247
|
|
|
3048
3248
|
// src/chat/runtime/turn-user-message.ts
|
|
3049
3249
|
function getTurnUserMessage(conversation, sessionId) {
|
|
@@ -4184,6 +4384,10 @@ function completeAuthPauseTurn(args) {
|
|
|
4184
4384
|
async function persistAuthPauseTurnState(args) {
|
|
4185
4385
|
const currentState = await getPersistedThreadState(args.threadStateId);
|
|
4186
4386
|
const conversation = coerceThreadConversationState(currentState);
|
|
4387
|
+
await hydrateConversationMessages({
|
|
4388
|
+
conversation,
|
|
4389
|
+
conversationId: args.threadStateId
|
|
4390
|
+
});
|
|
4187
4391
|
completeAuthPauseTurn({
|
|
4188
4392
|
conversation,
|
|
4189
4393
|
sessionId: args.sessionId
|
|
@@ -4292,6 +4496,7 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
|
|
|
4292
4496
|
const threadId = `slack:${channelId}:${threadTs}`;
|
|
4293
4497
|
const currentState = await getPersistedThreadState(threadId);
|
|
4294
4498
|
const conversation = coerceThreadConversationState(currentState);
|
|
4499
|
+
await hydrateConversationMessages({ conversation, conversationId: threadId });
|
|
4295
4500
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
4296
4501
|
const userMessage2 = getTurnUserMessage(conversation, sessionId);
|
|
4297
4502
|
const statePatch = buildDeliveredTurnStatePatch({
|
|
@@ -4330,6 +4535,7 @@ async function persistFailedReplyState(channelId, threadTs, sessionId, expectedV
|
|
|
4330
4535
|
const threadId = `slack:${channelId}:${threadTs}`;
|
|
4331
4536
|
const currentState = await getPersistedThreadState(threadId);
|
|
4332
4537
|
const conversation = coerceThreadConversationState(currentState);
|
|
4538
|
+
await hydrateConversationMessages({ conversation, conversationId: threadId });
|
|
4333
4539
|
clearPendingAuth(conversation, sessionId);
|
|
4334
4540
|
markTurnFailed({
|
|
4335
4541
|
conversation,
|
|
@@ -4361,6 +4567,7 @@ async function resumeAuthorizedMcpTurn(args) {
|
|
|
4361
4567
|
const threadId = `slack:${authSession.channelId}:${authSession.threadTs}`;
|
|
4362
4568
|
const currentState = await getPersistedThreadState(threadId);
|
|
4363
4569
|
const conversation = coerceThreadConversationState(currentState);
|
|
4570
|
+
await hydrateConversationMessages({ conversation, conversationId: threadId });
|
|
4364
4571
|
const pendingAuth = getConversationPendingAuth({
|
|
4365
4572
|
conversation,
|
|
4366
4573
|
kind: "mcp",
|
|
@@ -4397,6 +4604,10 @@ async function resumeAuthorizedMcpTurn(args) {
|
|
|
4397
4604
|
beforeStart: async () => {
|
|
4398
4605
|
const lockedState = await getPersistedThreadState(threadId);
|
|
4399
4606
|
const lockedConversation = coerceThreadConversationState(lockedState);
|
|
4607
|
+
await hydrateConversationMessages({
|
|
4608
|
+
conversation: lockedConversation,
|
|
4609
|
+
conversationId: threadId
|
|
4610
|
+
});
|
|
4400
4611
|
const lockedArtifacts = coerceThreadArtifactsState(lockedState);
|
|
4401
4612
|
const lockedPendingAuth = getConversationPendingAuth({
|
|
4402
4613
|
conversation: lockedConversation,
|
|
@@ -4480,8 +4691,7 @@ async function resumeAuthorizedMcpTurn(args) {
|
|
|
4480
4691
|
authorizationId: mcpAuthorizationId({
|
|
4481
4692
|
provider,
|
|
4482
4693
|
sessionId: lockedSessionId
|
|
4483
|
-
})
|
|
4484
|
-
ttlMs: THREAD_STATE_TTL_MS
|
|
4694
|
+
})
|
|
4485
4695
|
});
|
|
4486
4696
|
const lockedMessageTs = getTurnUserSlackMessageTs(lockedUserMessage);
|
|
4487
4697
|
return {
|
|
@@ -4490,7 +4700,9 @@ async function resumeAuthorizedMcpTurn(args) {
|
|
|
4490
4700
|
replyContext: {
|
|
4491
4701
|
input: {
|
|
4492
4702
|
conversationContext: lockedConversationContext,
|
|
4493
|
-
|
|
4703
|
+
// Pi history is SQL-authoritative: the resumed run reads its
|
|
4704
|
+
// session record first and falls back to the step projection.
|
|
4705
|
+
piMessages: await loadProjection({ conversationId: threadId }),
|
|
4494
4706
|
...getTurnUserReplyAttachmentContext(lockedUserMessage)
|
|
4495
4707
|
},
|
|
4496
4708
|
routing: {
|
|
@@ -4589,7 +4801,7 @@ async function resumeAuthorizedMcpTurn(args) {
|
|
|
4589
4801
|
}
|
|
4590
4802
|
});
|
|
4591
4803
|
}
|
|
4592
|
-
async function
|
|
4804
|
+
async function GET4(request, provider, waitUntil, options) {
|
|
4593
4805
|
const url = new URL(request.url);
|
|
4594
4806
|
const state = url.searchParams.get("state")?.trim();
|
|
4595
4807
|
const code = url.searchParams.get("code")?.trim();
|
|
@@ -4636,9 +4848,6 @@ async function GET3(request, provider, waitUntil, options) {
|
|
|
4636
4848
|
}
|
|
4637
4849
|
}
|
|
4638
4850
|
|
|
4639
|
-
// src/handlers/oauth-callback.ts
|
|
4640
|
-
import { THREAD_STATE_TTL_MS as THREAD_STATE_TTL_MS2 } from "chat";
|
|
4641
|
-
|
|
4642
4851
|
// src/chat/slack/app-home.ts
|
|
4643
4852
|
import fs from "fs";
|
|
4644
4853
|
import path from "path";
|
|
@@ -4801,6 +5010,10 @@ function htmlErrorResponse(title, message, status) {
|
|
|
4801
5010
|
async function persistCompletedOAuthReplyState(args) {
|
|
4802
5011
|
const currentState = await getPersistedThreadState(args.conversationId);
|
|
4803
5012
|
const conversation = coerceThreadConversationState(currentState);
|
|
5013
|
+
await hydrateConversationMessages({
|
|
5014
|
+
conversation,
|
|
5015
|
+
conversationId: args.conversationId
|
|
5016
|
+
});
|
|
4804
5017
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
4805
5018
|
const userMessage2 = getTurnUserMessage(conversation, args.sessionId);
|
|
4806
5019
|
const statePatch = buildDeliveredTurnStatePatch({
|
|
@@ -4841,6 +5054,10 @@ async function failSessionRecordBestEffort2(args) {
|
|
|
4841
5054
|
async function persistFailedOAuthReplyState(args) {
|
|
4842
5055
|
const currentState = await getPersistedThreadState(args.conversationId);
|
|
4843
5056
|
const conversation = coerceThreadConversationState(currentState);
|
|
5057
|
+
await hydrateConversationMessages({
|
|
5058
|
+
conversation,
|
|
5059
|
+
conversationId: args.conversationId
|
|
5060
|
+
});
|
|
4844
5061
|
clearPendingAuth(conversation, args.sessionId);
|
|
4845
5062
|
markTurnFailed({
|
|
4846
5063
|
conversation,
|
|
@@ -4872,6 +5089,10 @@ async function resumeOAuthSessionRecordTurn(stored, options) {
|
|
|
4872
5089
|
stored.resumeConversationId
|
|
4873
5090
|
);
|
|
4874
5091
|
const conversation = coerceThreadConversationState(currentState);
|
|
5092
|
+
await hydrateConversationMessages({
|
|
5093
|
+
conversation,
|
|
5094
|
+
conversationId: stored.resumeConversationId
|
|
5095
|
+
});
|
|
4875
5096
|
const pendingAuth = getConversationPendingAuth({
|
|
4876
5097
|
conversation,
|
|
4877
5098
|
kind: "plugin",
|
|
@@ -4927,6 +5148,10 @@ async function resumeOAuthSessionRecordTurn(stored, options) {
|
|
|
4927
5148
|
stored.resumeConversationId
|
|
4928
5149
|
);
|
|
4929
5150
|
const lockedConversation = coerceThreadConversationState(lockedState);
|
|
5151
|
+
await hydrateConversationMessages({
|
|
5152
|
+
conversation: lockedConversation,
|
|
5153
|
+
conversationId: stored.resumeConversationId
|
|
5154
|
+
});
|
|
4930
5155
|
const lockedArtifacts = coerceThreadArtifactsState(lockedState);
|
|
4931
5156
|
const lockedPendingAuth = getConversationPendingAuth({
|
|
4932
5157
|
conversation: lockedConversation,
|
|
@@ -5011,8 +5236,7 @@ async function resumeOAuthSessionRecordTurn(stored, options) {
|
|
|
5011
5236
|
authorizationId: pluginAuthorizationId({
|
|
5012
5237
|
provider: stored.provider,
|
|
5013
5238
|
sessionId: lockedSessionId
|
|
5014
|
-
})
|
|
5015
|
-
ttlMs: THREAD_STATE_TTL_MS2
|
|
5239
|
+
})
|
|
5016
5240
|
});
|
|
5017
5241
|
const lockedMessageTs = getTurnUserSlackMessageTs(lockedUserMessage);
|
|
5018
5242
|
return {
|
|
@@ -5021,7 +5245,11 @@ async function resumeOAuthSessionRecordTurn(stored, options) {
|
|
|
5021
5245
|
replyContext: {
|
|
5022
5246
|
input: {
|
|
5023
5247
|
conversationContext: lockedConversationContext,
|
|
5024
|
-
|
|
5248
|
+
// Pi history is SQL-authoritative: the resumed run reads its
|
|
5249
|
+
// session record first and falls back to the step projection.
|
|
5250
|
+
piMessages: await loadProjection({
|
|
5251
|
+
conversationId: stored.resumeConversationId
|
|
5252
|
+
}),
|
|
5025
5253
|
...getTurnUserReplyAttachmentContext(lockedUserMessage)
|
|
5026
5254
|
},
|
|
5027
5255
|
routing: {
|
|
@@ -5124,6 +5352,7 @@ async function resumePendingOAuthMessage(stored, options) {
|
|
|
5124
5352
|
const conversation = coerceThreadConversationState(
|
|
5125
5353
|
await getPersistedThreadState(threadId)
|
|
5126
5354
|
);
|
|
5355
|
+
await hydrateConversationMessages({ conversation, conversationId: threadId });
|
|
5127
5356
|
const latestUserMessage = [...conversation.messages].reverse().find((message) => message.role === "user");
|
|
5128
5357
|
const conversationContext = buildConversationContext(conversation, {
|
|
5129
5358
|
excludeMessageId: latestUserMessage?.id
|
|
@@ -5144,7 +5373,8 @@ async function resumePendingOAuthMessage(stored, options) {
|
|
|
5144
5373
|
replyContext: {
|
|
5145
5374
|
input: {
|
|
5146
5375
|
conversationContext,
|
|
5147
|
-
|
|
5376
|
+
// Pi history is SQL-authoritative via the step-store projection.
|
|
5377
|
+
piMessages: await loadProjection({ conversationId: threadId })
|
|
5148
5378
|
},
|
|
5149
5379
|
routing: {
|
|
5150
5380
|
credentialContext: {
|
|
@@ -5178,7 +5408,7 @@ async function resumePendingOAuthMessage(stored, options) {
|
|
|
5178
5408
|
}
|
|
5179
5409
|
});
|
|
5180
5410
|
}
|
|
5181
|
-
async function
|
|
5411
|
+
async function GET5(request, provider, waitUntil, options) {
|
|
5182
5412
|
const providerConfig = pluginCatalogRuntime.getOAuthConfig(provider);
|
|
5183
5413
|
if (!providerConfig) {
|
|
5184
5414
|
return htmlErrorResponse(
|
|
@@ -8305,7 +8535,6 @@ function createSlackTurnRuntime(deps) {
|
|
|
8305
8535
|
}
|
|
8306
8536
|
|
|
8307
8537
|
// src/chat/services/context-compaction.ts
|
|
8308
|
-
import { THREAD_STATE_TTL_MS as THREAD_STATE_TTL_MS3 } from "chat";
|
|
8309
8538
|
import {
|
|
8310
8539
|
estimateContextTokens,
|
|
8311
8540
|
estimateTokens
|
|
@@ -8363,6 +8592,10 @@ function userMessage(text) {
|
|
|
8363
8592
|
timestamp: Date.now()
|
|
8364
8593
|
};
|
|
8365
8594
|
}
|
|
8595
|
+
function piMessageTimestamp(message) {
|
|
8596
|
+
const timestamp = message.timestamp;
|
|
8597
|
+
return typeof timestamp === "number" ? timestamp : Date.now();
|
|
8598
|
+
}
|
|
8366
8599
|
function selectRetainedUserMessageEntries(messages, maxTokens = RETAINED_USER_MESSAGE_TOKENS) {
|
|
8367
8600
|
const selected = [];
|
|
8368
8601
|
let remaining = maxTokens;
|
|
@@ -8545,6 +8778,7 @@ async function maybeCompactWithDeps(args, deps) {
|
|
|
8545
8778
|
});
|
|
8546
8779
|
}
|
|
8547
8780
|
async function writeCompactedThreadContext(args, sourceMessages, summary, context) {
|
|
8781
|
+
const stepStore = getAgentStepStore();
|
|
8548
8782
|
const sourceProjection = await loadProjectionWithProvenance({
|
|
8549
8783
|
conversationId: args.conversationId
|
|
8550
8784
|
});
|
|
@@ -8556,14 +8790,17 @@ async function writeCompactedThreadContext(args, sourceMessages, summary, contex
|
|
|
8556
8790
|
userMessage(`${COMPACTION_SUMMARY_PREFIX}
|
|
8557
8791
|
${summary}`)
|
|
8558
8792
|
];
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8793
|
+
const replacementProvenance = buildReplacementProvenance({
|
|
8794
|
+
retained,
|
|
8795
|
+
sourceProvenance: sourceProjection.provenance
|
|
8796
|
+
});
|
|
8797
|
+
await stepStore.startEpoch(args.conversationId, {
|
|
8798
|
+
reason: "compaction",
|
|
8799
|
+
messages: replacement.map((message, index) => ({
|
|
8800
|
+
message,
|
|
8801
|
+
createdAtMs: piMessageTimestamp(message),
|
|
8802
|
+
provenance: replacementProvenance[index]
|
|
8803
|
+
}))
|
|
8567
8804
|
});
|
|
8568
8805
|
updateConversationStats(args.conversation);
|
|
8569
8806
|
setSpanAttributes({
|
|
@@ -9183,7 +9420,6 @@ function createJuniorRuntimeServices(overrides = {}) {
|
|
|
9183
9420
|
}
|
|
9184
9421
|
|
|
9185
9422
|
// src/chat/runtime/reply-executor.ts
|
|
9186
|
-
import { THREAD_STATE_TTL_MS as THREAD_STATE_TTL_MS4 } from "chat";
|
|
9187
9423
|
import { createSlackSource } from "@sentry/junior-plugin-api";
|
|
9188
9424
|
|
|
9189
9425
|
// src/chat/slack/message.ts
|
|
@@ -9311,8 +9547,8 @@ async function maybeApplyProviderDefaultConfigRequest(args) {
|
|
|
9311
9547
|
}
|
|
9312
9548
|
|
|
9313
9549
|
// src/chat/runtime/reply-executor.ts
|
|
9314
|
-
async function
|
|
9315
|
-
await persistWithRetry(() =>
|
|
9550
|
+
async function persistThreadRuntimeStateWithRetry(thread, patch) {
|
|
9551
|
+
await persistWithRetry(() => persistThreadRuntimeState(thread, patch));
|
|
9316
9552
|
}
|
|
9317
9553
|
function collectCanvasUrls(artifacts) {
|
|
9318
9554
|
return new Set(
|
|
@@ -9322,9 +9558,6 @@ function collectCanvasUrls(artifacts) {
|
|
|
9322
9558
|
].filter((url) => typeof url === "string" && url !== "")
|
|
9323
9559
|
);
|
|
9324
9560
|
}
|
|
9325
|
-
function turnActor(actor) {
|
|
9326
|
-
return toStoredSlackActor(actor);
|
|
9327
|
-
}
|
|
9328
9561
|
function parkedInputKey(message) {
|
|
9329
9562
|
if (message.role !== "user") {
|
|
9330
9563
|
return void 0;
|
|
@@ -9437,9 +9670,8 @@ function collectTurnAttachments(message, queuedMessages) {
|
|
|
9437
9670
|
];
|
|
9438
9671
|
}
|
|
9439
9672
|
async function loadPiMessagesForTurn(args) {
|
|
9440
|
-
const fallback = args.fallback.length > 0 ? [...args.fallback] : void 0;
|
|
9441
9673
|
if (!args.conversationId) {
|
|
9442
|
-
return {
|
|
9674
|
+
return {};
|
|
9443
9675
|
}
|
|
9444
9676
|
if (args.activeTurnId) {
|
|
9445
9677
|
const sessionRecord = await getAgentTurnSessionRecord(
|
|
@@ -9463,7 +9695,7 @@ async function loadPiMessagesForTurn(args) {
|
|
|
9463
9695
|
piMessages: projection
|
|
9464
9696
|
};
|
|
9465
9697
|
}
|
|
9466
|
-
return {
|
|
9698
|
+
return {};
|
|
9467
9699
|
}
|
|
9468
9700
|
function createReplyToThread(deps) {
|
|
9469
9701
|
return async function replyToThread(thread, message, options) {
|
|
@@ -9540,7 +9772,6 @@ function createReplyToThread(deps) {
|
|
|
9540
9772
|
deps.services.lookupSlackUser
|
|
9541
9773
|
) : void 0;
|
|
9542
9774
|
const executionActor = "type" in credentialContext.actor ? actor : credentialContext.actor;
|
|
9543
|
-
const storedActor = actor ? turnActor(actor) : void 0;
|
|
9544
9775
|
const slackActorId = actor?.userId;
|
|
9545
9776
|
const preparedState = options.preparedState ?? await deps.prepareTurnState({
|
|
9546
9777
|
thread,
|
|
@@ -9676,8 +9907,7 @@ function createReplyToThread(deps) {
|
|
|
9676
9907
|
provenance: [
|
|
9677
9908
|
...projection.provenance,
|
|
9678
9909
|
...missing.map((pair) => pair.provenance)
|
|
9679
|
-
]
|
|
9680
|
-
ttlMs: THREAD_STATE_TTL_MS4
|
|
9910
|
+
]
|
|
9681
9911
|
});
|
|
9682
9912
|
return true;
|
|
9683
9913
|
} finally {
|
|
@@ -9854,37 +10084,6 @@ function createReplyToThread(deps) {
|
|
|
9854
10084
|
"Failed to record running turn summary"
|
|
9855
10085
|
);
|
|
9856
10086
|
});
|
|
9857
|
-
void initConversationContext(conversationId, {
|
|
9858
|
-
channelName,
|
|
9859
|
-
originSurface: "slack",
|
|
9860
|
-
originActor: storedActor,
|
|
9861
|
-
startedAtMs: turnStartedAtMs
|
|
9862
|
-
}).catch((error) => {
|
|
9863
|
-
logException(
|
|
9864
|
-
error,
|
|
9865
|
-
"conversation_details_context_init_failed",
|
|
9866
|
-
turnTraceContext,
|
|
9867
|
-
{ "app.agent.turn.state": "running" },
|
|
9868
|
-
"Failed to init conversation context at turn start"
|
|
9869
|
-
);
|
|
9870
|
-
});
|
|
9871
|
-
const existingAssistantTitle = preparedState.artifacts.assistantTitle?.trim();
|
|
9872
|
-
if (existingAssistantTitle) {
|
|
9873
|
-
void setConversationTitle(conversationId, {
|
|
9874
|
-
displayTitle: existingAssistantTitle,
|
|
9875
|
-
...preparedState.artifacts.assistantTitleSourceMessageId ? {
|
|
9876
|
-
titleSourceMessageId: preparedState.artifacts.assistantTitleSourceMessageId
|
|
9877
|
-
} : {}
|
|
9878
|
-
}).catch((error) => {
|
|
9879
|
-
logException(
|
|
9880
|
-
error,
|
|
9881
|
-
"conversation_details_title_refresh_failed",
|
|
9882
|
-
turnTraceContext,
|
|
9883
|
-
{ "app.agent.turn.state": "running" },
|
|
9884
|
-
"Failed to refresh conversation title from artifacts"
|
|
9885
|
-
);
|
|
9886
|
-
});
|
|
9887
|
-
}
|
|
9888
10087
|
}
|
|
9889
10088
|
setTags({
|
|
9890
10089
|
conversationId
|
|
@@ -9967,8 +10166,7 @@ function createReplyToThread(deps) {
|
|
|
9967
10166
|
try {
|
|
9968
10167
|
const loadedPiMessages = await loadPiMessagesForTurn({
|
|
9969
10168
|
conversationId,
|
|
9970
|
-
activeTurnId
|
|
9971
|
-
fallback: preparedState.conversation.piMessages
|
|
10169
|
+
activeTurnId
|
|
9972
10170
|
});
|
|
9973
10171
|
let piMessages = loadedPiMessages.piMessages;
|
|
9974
10172
|
if (conversationId && loadedPiMessages.canCompact && piMessages?.length) {
|
|
@@ -10043,17 +10241,19 @@ function createReplyToThread(deps) {
|
|
|
10043
10241
|
};
|
|
10044
10242
|
if (conversationId && titleUpdateResult.title) {
|
|
10045
10243
|
try {
|
|
10046
|
-
await
|
|
10047
|
-
|
|
10048
|
-
|
|
10244
|
+
await getConversationStore().recordActivity({
|
|
10245
|
+
activityAtMs: message.metadata.dateSent.getTime(),
|
|
10246
|
+
conversationId,
|
|
10247
|
+
nowMs: Date.now(),
|
|
10248
|
+
title: titleUpdateResult.title
|
|
10049
10249
|
});
|
|
10050
10250
|
} catch (error) {
|
|
10051
10251
|
logException(
|
|
10052
10252
|
error,
|
|
10053
|
-
"
|
|
10253
|
+
"conversation_title_persist_failed",
|
|
10054
10254
|
turnTraceContext,
|
|
10055
10255
|
{},
|
|
10056
|
-
"Failed to
|
|
10256
|
+
"Failed to persist generated conversation title"
|
|
10057
10257
|
);
|
|
10058
10258
|
}
|
|
10059
10259
|
}
|
|
@@ -10369,6 +10569,7 @@ function createReplyToThread(deps) {
|
|
|
10369
10569
|
conversationId,
|
|
10370
10570
|
durationMs: reply.diagnostics.durationMs,
|
|
10371
10571
|
usage: reply.diagnostics.usage,
|
|
10572
|
+
reasoningLevel: reply.diagnostics.thinkingLevel,
|
|
10372
10573
|
destination,
|
|
10373
10574
|
destinationVisibility,
|
|
10374
10575
|
source,
|
|
@@ -10403,11 +10604,15 @@ function createReplyToThread(deps) {
|
|
|
10403
10604
|
traceId: getActiveTraceId()
|
|
10404
10605
|
});
|
|
10405
10606
|
}
|
|
10406
|
-
await
|
|
10407
|
-
|
|
10408
|
-
|
|
10607
|
+
await persistWithRetry(
|
|
10608
|
+
() => persistConversationMessages({
|
|
10609
|
+
conversation: completedState.conversation,
|
|
10610
|
+
conversationId
|
|
10611
|
+
})
|
|
10612
|
+
);
|
|
10613
|
+
await persistThreadRuntimeStateWithRetry(thread, completedState);
|
|
10409
10614
|
if (completedState.artifacts && (assistantTitleArtifacts.assistantTitle !== void 0 || assistantTitleArtifacts.assistantTitleSourceMessageId !== void 0) && (completedState.artifacts.assistantTitle !== assistantTitleArtifacts.assistantTitle || completedState.artifacts.assistantTitleSourceMessageId !== assistantTitleArtifacts.assistantTitleSourceMessageId)) {
|
|
10410
|
-
await
|
|
10615
|
+
await persistThreadRuntimeStateWithRetry(thread, {
|
|
10411
10616
|
artifacts: latestArtifacts
|
|
10412
10617
|
});
|
|
10413
10618
|
}
|
|
@@ -10755,6 +10960,8 @@ function createPrepareTurnState(deps) {
|
|
|
10755
10960
|
) : void 0;
|
|
10756
10961
|
const artifacts = coerceThreadArtifactsState(existingState);
|
|
10757
10962
|
const conversation = coerceThreadConversationState(existingState);
|
|
10963
|
+
const conversationId = args.context.threadId ?? args.context.runId;
|
|
10964
|
+
await hydrateConversationMessages({ conversation, conversationId });
|
|
10758
10965
|
const channelConfiguration = getChannelConfigurationService(args.thread);
|
|
10759
10966
|
const configuration = await channelConfiguration.resolveValues();
|
|
10760
10967
|
await seedConversationBackfill(args.thread, conversation, {
|
|
@@ -10794,12 +11001,16 @@ function createPrepareTurnState(deps) {
|
|
|
10794
11001
|
threadTs: getThreadTs(args.context.threadId)
|
|
10795
11002
|
});
|
|
10796
11003
|
}
|
|
11004
|
+
await persistConversationMessages({ conversation, conversationId });
|
|
10797
11005
|
await deps.compactConversationIfNeeded(conversation, {
|
|
10798
11006
|
threadId: args.context.threadId,
|
|
10799
11007
|
channelId: args.context.channelId,
|
|
10800
11008
|
actorId: args.context.actorId,
|
|
10801
11009
|
runId: args.context.runId
|
|
10802
11010
|
});
|
|
11011
|
+
if (conversationId) {
|
|
11012
|
+
await persistConversationCompactions({ conversation, conversationId });
|
|
11013
|
+
}
|
|
10803
11014
|
const conversationContext = buildConversationContext(conversation, {
|
|
10804
11015
|
excludeMessageId: userMessageId
|
|
10805
11016
|
});
|
|
@@ -10994,14 +11205,15 @@ function createJuniorSlackAdapter(config) {
|
|
|
10994
11205
|
|
|
10995
11206
|
// src/chat/runtime/agent-continue-runner.ts
|
|
10996
11207
|
var AGENT_CONTINUE_LOCK_RETRY_DELAYS_MS = [250, 1e3, 2e3];
|
|
10997
|
-
function sleep2(ms) {
|
|
10998
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10999
|
-
}
|
|
11000
11208
|
async function persistCompletedReplyState2(args) {
|
|
11001
11209
|
const currentState = await getPersistedThreadState(
|
|
11002
11210
|
args.sessionRecord.conversationId
|
|
11003
11211
|
);
|
|
11004
11212
|
const conversation = coerceThreadConversationState(currentState);
|
|
11213
|
+
await hydrateConversationMessages({
|
|
11214
|
+
conversation,
|
|
11215
|
+
conversationId: args.sessionRecord.conversationId
|
|
11216
|
+
});
|
|
11005
11217
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
11006
11218
|
const userMessage2 = getTurnUserMessage(
|
|
11007
11219
|
conversation,
|
|
@@ -11044,6 +11256,10 @@ async function persistFailedReplyState2(sessionRecord) {
|
|
|
11044
11256
|
sessionRecord.conversationId
|
|
11045
11257
|
);
|
|
11046
11258
|
const conversation = coerceThreadConversationState(currentState);
|
|
11259
|
+
await hydrateConversationMessages({
|
|
11260
|
+
conversation,
|
|
11261
|
+
conversationId: sessionRecord.conversationId
|
|
11262
|
+
});
|
|
11047
11263
|
clearPendingAuth(conversation, sessionRecord.sessionId);
|
|
11048
11264
|
markTurnFailed({
|
|
11049
11265
|
conversation,
|
|
@@ -11145,6 +11361,10 @@ async function continueSlackAgentRun(payload, options) {
|
|
|
11145
11361
|
payload.conversationId
|
|
11146
11362
|
);
|
|
11147
11363
|
const conversation = coerceThreadConversationState(currentState);
|
|
11364
|
+
await hydrateConversationMessages({
|
|
11365
|
+
conversation,
|
|
11366
|
+
conversationId: payload.conversationId
|
|
11367
|
+
});
|
|
11148
11368
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
11149
11369
|
const userMessage2 = getTurnUserMessage(conversation, payload.sessionId);
|
|
11150
11370
|
if (!userMessage2?.author?.userId) {
|
|
@@ -11208,7 +11428,11 @@ async function continueSlackAgentRun(payload, options) {
|
|
|
11208
11428
|
replyContext: {
|
|
11209
11429
|
input: {
|
|
11210
11430
|
conversationContext,
|
|
11211
|
-
|
|
11431
|
+
// Pi history is SQL-authoritative: the resumed run reads its
|
|
11432
|
+
// session record first and falls back to the step projection.
|
|
11433
|
+
piMessages: await loadProjection({
|
|
11434
|
+
conversationId: payload.conversationId
|
|
11435
|
+
}),
|
|
11212
11436
|
...getTurnUserReplyAttachmentContext(userMessage2)
|
|
11213
11437
|
},
|
|
11214
11438
|
routing: {
|
|
@@ -11307,6 +11531,10 @@ async function failStrandedSessionWithFallback(args) {
|
|
|
11307
11531
|
});
|
|
11308
11532
|
const currentState = await getPersistedThreadState(args.conversationId);
|
|
11309
11533
|
const conversation = coerceThreadConversationState(currentState);
|
|
11534
|
+
await hydrateConversationMessages({
|
|
11535
|
+
conversation,
|
|
11536
|
+
conversationId: args.conversationId
|
|
11537
|
+
});
|
|
11310
11538
|
markTurnFailed({
|
|
11311
11539
|
conversation,
|
|
11312
11540
|
nowMs: Date.now(),
|
|
@@ -11476,7 +11704,7 @@ async function continueSlackAgentRunWithLockRetry(payload, options) {
|
|
|
11476
11704
|
},
|
|
11477
11705
|
"Agent continuation lock was busy; retrying"
|
|
11478
11706
|
);
|
|
11479
|
-
await
|
|
11707
|
+
await sleep(delayMs);
|
|
11480
11708
|
}
|
|
11481
11709
|
}
|
|
11482
11710
|
return true;
|
|
@@ -11900,12 +12128,12 @@ async function createApp(options) {
|
|
|
11900
12128
|
app.get("/", () => GET());
|
|
11901
12129
|
app.get("/health", () => GET());
|
|
11902
12130
|
app.get("/api/oauth/callback/mcp/:provider", (c) => {
|
|
11903
|
-
return
|
|
12131
|
+
return GET4(c.req.raw, c.req.param("provider"), waitUntil, {
|
|
11904
12132
|
agentRunner
|
|
11905
12133
|
});
|
|
11906
12134
|
});
|
|
11907
12135
|
app.get("/api/oauth/callback/:provider", (c) => {
|
|
11908
|
-
return
|
|
12136
|
+
return GET5(c.req.raw, c.req.param("provider"), waitUntil, {
|
|
11909
12137
|
agentRunner
|
|
11910
12138
|
});
|
|
11911
12139
|
});
|
|
@@ -11940,6 +12168,9 @@ async function createApp(options) {
|
|
|
11940
12168
|
app.get("/api/internal/heartbeat", (c) => {
|
|
11941
12169
|
return GET2(c.req.raw, waitUntil);
|
|
11942
12170
|
});
|
|
12171
|
+
app.get("/api/internal/retention", (c) => {
|
|
12172
|
+
return GET3(c.req.raw);
|
|
12173
|
+
});
|
|
11943
12174
|
app.post("/api/webhooks/slack", (c) => {
|
|
11944
12175
|
return POST3(c.req.raw, waitUntil, slackWebhookServices);
|
|
11945
12176
|
});
|