@sentry/junior 0.188.0 → 0.189.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-5RQEVLQD.js → agent-hooks-6QRYH6PX.js} +11 -11
- package/dist/api/acp/conversations.d.ts +2 -2
- package/dist/api/conversations/list.d.ts +7 -0
- package/dist/api/people/shared.d.ts +54 -0
- package/dist/api.js +41 -52
- package/dist/app.d.ts +1 -1
- package/dist/app.js +1003 -346
- package/dist/{catalog-runtime-L4A6BJ3U.js → catalog-runtime-IETJLJFG.js} +4 -4
- package/dist/chat/agent/resume.d.ts +0 -2
- package/dist/chat/agent/types.d.ts +8 -9
- package/dist/chat/agent-dispatch/work.d.ts +1 -10
- package/dist/chat/agent-invocations/spawn.d.ts +1 -1
- package/dist/chat/agent-invocations/types.d.ts +296 -96
- package/dist/chat/app/conversation-work.d.ts +16 -8
- package/dist/chat/conversation-privacy.d.ts +7 -7
- package/dist/chat/conversations/destination.d.ts +12 -0
- package/dist/chat/conversations/projection.d.ts +2 -2
- package/dist/chat/conversations/sql/location.d.ts +13 -4
- package/dist/chat/{api-turns → conversations}/stop.d.ts +2 -2
- package/dist/chat/conversations/store.d.ts +4 -4
- package/dist/chat/conversations/structured-events.d.ts +1 -1
- package/dist/chat/{api-turns/authorization.d.ts → conversations/web-authorization.d.ts} +1 -0
- package/dist/chat/conversations/web-input.d.ts +98 -0
- package/dist/chat/conversations/web-mailbox.d.ts +12 -0
- package/dist/chat/event-tasks/tool-support.d.ts +0 -6
- package/dist/chat/providers/slack/runtime.d.ts +1 -0
- package/dist/chat/providers/slack/system-turn.d.ts +8 -0
- package/dist/chat/resource-events/actor.d.ts +13 -12
- package/dist/chat/resource-events/notification.d.ts +1 -1
- package/dist/chat/services/guardian-action-policy.d.ts +1 -1
- package/dist/chat/services/turn-session-routing.d.ts +2 -2
- package/dist/chat/task-execution/assistant-message.d.ts +32 -0
- package/dist/chat/task-execution/conversation-turn.d.ts +8 -0
- package/dist/chat/{api-turns → task-execution}/mailbox-input.d.ts +1 -2
- package/dist/chat/task-execution/mailbox-turn.d.ts +42 -0
- package/dist/chat/task-execution/paused-turn.d.ts +1 -1
- package/dist/chat/task-execution/slack-work.d.ts +0 -2
- package/dist/{chunk-AW77HH54.js → chunk-4RHJ3CXR.js} +14 -295
- package/dist/{chunk-ZX7RSBQ6.js → chunk-5CXCGDIL.js} +1 -1
- package/dist/{chunk-QVH6FW3T.js → chunk-5VWAY27R.js} +7 -3
- package/dist/{chunk-XJIPMHKI.js → chunk-6AUR6PWR.js} +3 -3
- package/dist/{chunk-QDHJTKPE.js → chunk-7R5JRPCY.js} +8 -6
- package/dist/{chunk-6JZGXLL2.js → chunk-AC7MDOJW.js} +5 -7
- package/dist/{chunk-Q7O74WOO.js → chunk-BYBSI5TI.js} +2 -2
- package/dist/{chunk-VFZAUQ5V.js → chunk-CMWIMFM6.js} +4 -182
- package/dist/{chunk-IUUQWIG2.js → chunk-CUYFCI4G.js} +59 -11
- package/dist/chunk-DA2KGZZI.js +13 -0
- package/dist/{chunk-FIUCHYT6.js → chunk-DYXVAO2E.js} +1 -1
- package/dist/{chunk-NZLZ4KYZ.js → chunk-E3PDZPGV.js} +1 -1
- package/dist/{chunk-Z5SKZE5B.js → chunk-GP32KD2J.js} +4 -12
- package/dist/{chunk-XI4PVY2T.js → chunk-KN32OWL2.js} +5 -5
- package/dist/chunk-LHKZKAZ4.js +285 -0
- package/dist/{chunk-6YGFBU3A.js → chunk-MFSET7Q7.js} +44 -334
- package/dist/{chunk-QCGNHSMA.js → chunk-MI6ZBDTS.js} +6 -6
- package/dist/{chunk-CIG6WI7Q.js → chunk-MRXMFB4L.js} +5 -5
- package/dist/{chunk-CVBDVIF4.js → chunk-MVPLEPSI.js} +1 -1
- package/dist/{chunk-32XSSFZV.js → chunk-NY2F7BZA.js} +1 -1
- package/dist/chunk-O35GZCKL.js +311 -0
- package/dist/{chunk-HCIVBCP5.js → chunk-OEIITG5F.js} +1 -1
- package/dist/{chunk-UVUXFRYN.js → chunk-PCPSX4ES.js} +209 -7
- package/dist/{chunk-QIMN3FXL.js → chunk-PY3EIEAF.js} +1 -1
- package/dist/{chunk-RMB7CERI.js → chunk-QNIOBNOY.js} +282 -121
- package/dist/{chunk-WGZJ5SU4.js → chunk-S3SGZUOI.js} +1 -1
- package/dist/chunk-SR6OMO5C.js +703 -0
- package/dist/{chunk-CDSLOYOR.js → chunk-UCWO5MKP.js} +6 -6
- package/dist/{chunk-PSHMPRIU.js → chunk-VKQWU4PO.js} +2 -2
- package/dist/{chunk-X55FOVZO.js → chunk-WDHPN2GH.js} +3 -3
- package/dist/{chunk-WW2Y7JIA.js → chunk-WMUAKAIF.js} +43 -44
- package/dist/{chunk-MQDIIFZM.js → chunk-WN6VLHOU.js} +12 -5
- package/dist/{chunk-W42ENMJW.js → chunk-WWYUYKKV.js} +1 -1
- package/dist/{chunk-ERZMACYA.js → chunk-WYDF6PGK.js} +3 -3
- package/dist/{chunk-SC67CH3C.js → chunk-YNZPOFF3.js} +14 -17
- package/dist/{chunk-3HEZWDS5.js → chunk-YYSEH2WC.js} +2 -2
- package/dist/{chunk-W2DDJCPS.js → chunk-YYZNESC3.js} +8 -8
- package/dist/{chunk-CZRWU4ZM.js → chunk-ZUPDSJUE.js} +2 -5
- package/dist/{chunk-QIOUTXTZ.js → chunk-ZV6PFUA4.js} +1 -1
- package/dist/cli/chat.js +34 -33
- package/dist/cli/check.js +5 -5
- package/dist/cli/plugins.js +12 -12
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +6 -6
- package/dist/db/schema/agent-invocations.d.ts +0 -36
- package/dist/db/schema/conversations.d.ts +62 -0
- package/dist/db/schema.d.ts +31 -36
- package/dist/{db-YPRZAA2T.js → db-LPJKR2EO.js} +6 -6
- package/dist/instrumentation.js +3 -3
- package/dist/nitro.js +6 -6
- package/dist/{oauth-callback-server-DBBIR3XG.js → oauth-callback-server-DMXF4TTQ.js} +30 -28
- package/dist/{runner-FKVFFPLO.js → runner-L5DPVYCN.js} +25 -21
- package/dist/{skills-4RBAZEMV.js → skills-NXG3LBCK.js} +5 -5
- package/dist/spawn-VRUIGKWW.js +42 -0
- package/dist/task-runner-7YTBSPXW.js +36 -0
- package/dist/{validation-E6Z5LHZM.js → validation-CH36LTOS.js} +5 -5
- package/dist/version.js +1 -1
- package/dist/{work-OFTXWOK4.js → work-HBC5Y5VZ.js} +22 -21
- package/dist/{worker-OMWNOKTJ.js → worker-5RDZHLXH.js} +10 -10
- package/migrations/0037_conversation_location.sql +23 -0
- package/migrations/meta/0037_snapshot.json +3192 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/dist/chat/api-turns/assistant-message.d.ts +0 -12
- package/dist/chat/api-turns/cancellation.d.ts +0 -24
- package/dist/chat/api-turns/routing.d.ts +0 -51
- package/dist/chat/api-turns/work.d.ts +0 -99
- package/dist/chat/task-execution/slack-resource-event.d.ts +0 -55
- package/dist/chunk-6FGN7ZEG.js +0 -221
- package/dist/chunk-LODJKINF.js +0 -1502
- package/dist/spawn-CO7QFCNJ.js +0 -41
- package/dist/task-runner-DUGZGI7V.js +0 -34
package/dist/app.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processConversationWork
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UCWO5MKP.js";
|
|
4
4
|
import {
|
|
5
5
|
bindSpawnAgent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZUPDSJUE.js";
|
|
7
7
|
import {
|
|
8
8
|
createAgentInvocationWorker,
|
|
9
9
|
enqueueAgentInvocation,
|
|
10
10
|
listPendingAgentInvocationMailboxAppends,
|
|
11
|
-
|
|
12
|
-
} from "./chunk-
|
|
11
|
+
resolveAgentInvocationId
|
|
12
|
+
} from "./chunk-YNZPOFF3.js";
|
|
13
13
|
import {
|
|
14
14
|
GET as GET2,
|
|
15
15
|
GET2 as GET3,
|
|
@@ -37,30 +37,12 @@ import {
|
|
|
37
37
|
startProcessingReaction,
|
|
38
38
|
stripLeadingBotMention,
|
|
39
39
|
wakePausedTurn
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-WMUAKAIF.js";
|
|
41
41
|
import "./chunk-FA6POGLH.js";
|
|
42
|
-
import {
|
|
43
|
-
GET,
|
|
44
|
-
apiTurnIdForMessage,
|
|
45
|
-
appendAndEnqueueApiConversationMessage,
|
|
46
|
-
conversationVisibilityFromSlackChannelType,
|
|
47
|
-
createApiTurnCancellation,
|
|
48
|
-
createApiTurnWorker,
|
|
49
|
-
createVercelAttachmentStorage,
|
|
50
|
-
getAuthPausedApiTurnId,
|
|
51
|
-
lookupSlackUser,
|
|
52
|
-
readConversationAccessFromSql,
|
|
53
|
-
recordApiConversationActivity,
|
|
54
|
-
resolveSlackChannelTypeFromMessage,
|
|
55
|
-
resolveSlackConversationContext,
|
|
56
|
-
routeApiTurnWork,
|
|
57
|
-
webActorFromEmail
|
|
58
|
-
} from "./chunk-LODJKINF.js";
|
|
59
|
-
import "./chunk-PSHMPRIU.js";
|
|
60
42
|
import {
|
|
61
43
|
AgentRunError,
|
|
62
44
|
executeTurn
|
|
63
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-WYDF6PGK.js";
|
|
64
46
|
import {
|
|
65
47
|
buildDeliveredTurnStatePatch,
|
|
66
48
|
completeAuthPauseTurn,
|
|
@@ -71,7 +53,7 @@ import {
|
|
|
71
53
|
getTurnUserSlackMessageTs,
|
|
72
54
|
persistAuthPauseTurnState,
|
|
73
55
|
requireTurnFailureEventId
|
|
74
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-7R5JRPCY.js";
|
|
75
57
|
import {
|
|
76
58
|
claimDispatchMailboxAppend,
|
|
77
59
|
confirmDispatchMailboxAppend,
|
|
@@ -88,14 +70,14 @@ import {
|
|
|
88
70
|
markDispatchCompleted,
|
|
89
71
|
markDispatchFailed,
|
|
90
72
|
markDispatchRunning,
|
|
91
|
-
|
|
92
|
-
resolveConversationRouting,
|
|
73
|
+
processPluginTask,
|
|
93
74
|
resolveTurnSessionRouting,
|
|
94
75
|
scheduleSessionCompletedPluginTasks
|
|
95
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-4RHJ3CXR.js";
|
|
96
77
|
import {
|
|
78
|
+
ConversationTurnLifecycleService,
|
|
97
79
|
getTurnLifecycle
|
|
98
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-WWYUYKKV.js";
|
|
99
81
|
import {
|
|
100
82
|
coerceThreadConversationState,
|
|
101
83
|
getLocationConfigurationService,
|
|
@@ -104,17 +86,39 @@ import {
|
|
|
104
86
|
persistThreadRuntimeState,
|
|
105
87
|
persistThreadState,
|
|
106
88
|
persistThreadStateById
|
|
107
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-MRXMFB4L.js";
|
|
90
|
+
import {
|
|
91
|
+
GET,
|
|
92
|
+
appendAndEnqueueWebMessage,
|
|
93
|
+
conversationTurnIdForMessage,
|
|
94
|
+
conversationVisibilityFromSlackChannelType,
|
|
95
|
+
createVercelAttachmentStorage,
|
|
96
|
+
legacyWebMailboxMetadataSchema,
|
|
97
|
+
lookupSlackUser,
|
|
98
|
+
readConversationAccessFromSql,
|
|
99
|
+
recordWebConversationActivity,
|
|
100
|
+
resolveConversationDestination,
|
|
101
|
+
resolveSlackChannelTypeFromMessage,
|
|
102
|
+
resolveSlackConversationContext,
|
|
103
|
+
webActorFromEmail
|
|
104
|
+
} from "./chunk-SR6OMO5C.js";
|
|
105
|
+
import {
|
|
106
|
+
createWebAuthorization,
|
|
107
|
+
deleteWebAuthorization
|
|
108
|
+
} from "./chunk-VKQWU4PO.js";
|
|
109
|
+
import {
|
|
110
|
+
recordTaskExecution
|
|
111
|
+
} from "./chunk-LHKZKAZ4.js";
|
|
108
112
|
import "./chunk-UTL3MHPC.js";
|
|
109
113
|
import {
|
|
110
114
|
createVercelPluginTaskCallback,
|
|
111
115
|
queueCallback,
|
|
112
116
|
registerVercelPluginTaskDevConsumer
|
|
113
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-KN32OWL2.js";
|
|
114
118
|
import {
|
|
115
119
|
validatePluginEgressCredentialHooks,
|
|
116
120
|
validatePluginRegistrations
|
|
117
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-OEIITG5F.js";
|
|
118
122
|
import {
|
|
119
123
|
defineJuniorPlugins,
|
|
120
124
|
pluginCatalogConfigFromEnv,
|
|
@@ -122,6 +126,8 @@ import {
|
|
|
122
126
|
pluginRuntimeRegistrationsFromPluginSet
|
|
123
127
|
} from "./chunk-CM5HNV2W.js";
|
|
124
128
|
import {
|
|
129
|
+
RESOURCE_EVENT_MESSAGE_AUTHOR,
|
|
130
|
+
RESOURCE_EVENT_SYSTEM_ACTOR,
|
|
125
131
|
SANDBOX_EGRESS_PROXY_PATH,
|
|
126
132
|
buildSteeringPiMessage,
|
|
127
133
|
clearSandboxEgressSignals,
|
|
@@ -133,6 +139,8 @@ import {
|
|
|
133
139
|
getConfigDefaults,
|
|
134
140
|
getNextRunAtMs,
|
|
135
141
|
ingestResourceEvent,
|
|
142
|
+
isResourceEventConversationMessage,
|
|
143
|
+
isResourceEventMailboxMetadata,
|
|
136
144
|
latestReportedProgress,
|
|
137
145
|
listThreadReplies,
|
|
138
146
|
logScheduledTaskRunSkipped,
|
|
@@ -143,18 +151,18 @@ import {
|
|
|
143
151
|
readPublicArtifact,
|
|
144
152
|
renderAttachmentText,
|
|
145
153
|
renderBlockText,
|
|
146
|
-
|
|
154
|
+
renderTaskInput,
|
|
147
155
|
resolveSandboxEgressProviderForHost,
|
|
148
156
|
scheduledTaskRunAttributes,
|
|
149
157
|
setConfigDefaults,
|
|
150
158
|
shouldEmitDevAgentTrace,
|
|
151
159
|
shouldPropagateSandboxEgressTrace,
|
|
152
160
|
unpublishedArtifactHeaders
|
|
153
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-QNIOBNOY.js";
|
|
154
162
|
import {
|
|
155
163
|
AuthorizationFlowDisabledError,
|
|
156
164
|
PluginCredentialFailureError
|
|
157
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-AC7MDOJW.js";
|
|
158
166
|
import "./chunk-6Y5B5PEX.js";
|
|
159
167
|
import "./chunk-DIB4GX3G.js";
|
|
160
168
|
import {
|
|
@@ -162,63 +170,19 @@ import {
|
|
|
162
170
|
deleteMcpAuthSessionsForUserProvider,
|
|
163
171
|
deleteMcpServerSessionId,
|
|
164
172
|
deleteMcpStoredOAuthCredentials
|
|
165
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-YYZNESC3.js";
|
|
166
174
|
import {
|
|
175
|
+
RetryableDeliveryError,
|
|
176
|
+
createAgentRunner,
|
|
167
177
|
formatProviderLabel,
|
|
168
178
|
postSlackMessage,
|
|
169
179
|
startOAuthFlow
|
|
170
|
-
} from "./chunk-
|
|
171
|
-
import {
|
|
172
|
-
RESOURCE_EVENT_AUTHOR_ID,
|
|
173
|
-
RESOURCE_EVENT_MESSAGE_AUTHOR,
|
|
174
|
-
RESOURCE_EVENT_SYSTEM_ACTOR,
|
|
175
|
-
collectAttachmentGarbage,
|
|
176
|
-
collectEventTaskMatchKeys,
|
|
177
|
-
findMatchingEventTasks,
|
|
178
|
-
getResourceEventCatalog,
|
|
179
|
-
isResourceEventConversationMessage,
|
|
180
|
-
isResourceEventMailboxMetadata,
|
|
181
|
-
isResourceEventSlackMessage,
|
|
182
|
-
listScheduledTasks,
|
|
183
|
-
listScheduledTasksForTeam,
|
|
184
|
-
readScheduledTask,
|
|
185
|
-
renderTaskInput,
|
|
186
|
-
requestAttachmentDeletion,
|
|
187
|
-
resourceEventGuidance,
|
|
188
|
-
saveScheduledTaskInLock,
|
|
189
|
-
scheduledRunId,
|
|
190
|
-
scheduledRunSchema,
|
|
191
|
-
withScheduledTaskLock
|
|
192
|
-
} from "./chunk-VFZAUQ5V.js";
|
|
193
|
-
import {
|
|
194
|
-
parseSlackThreadId
|
|
195
|
-
} from "./chunk-CVBDVIF4.js";
|
|
196
|
-
import {
|
|
197
|
-
RetryableDeliveryError,
|
|
198
|
-
createAgentRunner
|
|
199
|
-
} from "./chunk-6FGN7ZEG.js";
|
|
200
|
-
import {
|
|
201
|
-
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
202
|
-
appendAndEnqueueInboundMessage,
|
|
203
|
-
clearExpiredConversationLease,
|
|
204
|
-
ensureConversationWake,
|
|
205
|
-
getConversation,
|
|
206
|
-
getConversationWorkState,
|
|
207
|
-
hasRunnableConversationWork,
|
|
208
|
-
hasRunnableConversationWork2,
|
|
209
|
-
isInvalidConversationRecordError,
|
|
210
|
-
listActiveConversationIds,
|
|
211
|
-
removeActiveConversation,
|
|
212
|
-
requestConversationWork,
|
|
213
|
-
stopConversationWork
|
|
214
|
-
} from "./chunk-MQDIIFZM.js";
|
|
180
|
+
} from "./chunk-PCPSX4ES.js";
|
|
215
181
|
import {
|
|
216
182
|
ConversationTurnBoundaryError,
|
|
217
183
|
CooperativeTurnYieldError,
|
|
218
184
|
TurnInputCommitLostError,
|
|
219
185
|
TurnInputDeferredError,
|
|
220
|
-
buildDeterministicAssistantMessageId,
|
|
221
|
-
buildDeterministicTurnId,
|
|
222
186
|
clearPendingAuth,
|
|
223
187
|
getAssistantReplyText,
|
|
224
188
|
getConversationTurnBoundaryError,
|
|
@@ -229,7 +193,7 @@ import {
|
|
|
229
193
|
markTurnCompleted,
|
|
230
194
|
markTurnFailed,
|
|
231
195
|
startActiveTurn
|
|
232
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-GP32KD2J.js";
|
|
233
197
|
import {
|
|
234
198
|
abandonTurnRecord,
|
|
235
199
|
appendThreadContextMessages,
|
|
@@ -265,22 +229,63 @@ import {
|
|
|
265
229
|
trimTrailingAssistantMessages,
|
|
266
230
|
turnHasReply,
|
|
267
231
|
upsertConversationMessage
|
|
268
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-MFSET7Q7.js";
|
|
269
233
|
import {
|
|
270
234
|
getExperimentalFeatures,
|
|
271
235
|
isExperimentalFeatureEnabled,
|
|
272
236
|
setExperimentalFeatures
|
|
273
237
|
} from "./chunk-2LYHWMR4.js";
|
|
238
|
+
import {
|
|
239
|
+
collectAttachmentGarbage,
|
|
240
|
+
collectEventTaskMatchKeys,
|
|
241
|
+
findMatchingEventTasks,
|
|
242
|
+
getResourceEventCatalog,
|
|
243
|
+
listScheduledTasks,
|
|
244
|
+
listScheduledTasksForTeam,
|
|
245
|
+
readScheduledTask,
|
|
246
|
+
requestAttachmentDeletion,
|
|
247
|
+
resourceEventGuidance,
|
|
248
|
+
saveScheduledTaskInLock,
|
|
249
|
+
scheduledRunId,
|
|
250
|
+
scheduledRunSchema,
|
|
251
|
+
withScheduledTaskLock
|
|
252
|
+
} from "./chunk-CMWIMFM6.js";
|
|
253
|
+
import {
|
|
254
|
+
parseSlackThreadId
|
|
255
|
+
} from "./chunk-MVPLEPSI.js";
|
|
256
|
+
import {
|
|
257
|
+
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
258
|
+
appendAndEnqueueInboundMessage,
|
|
259
|
+
clearExpiredConversationLease,
|
|
260
|
+
ensureConversationWake,
|
|
261
|
+
getConversation,
|
|
262
|
+
getConversationWorkState,
|
|
263
|
+
hasRunnableConversationWork,
|
|
264
|
+
hasRunnableConversationWork2,
|
|
265
|
+
isInvalidConversationRecordError,
|
|
266
|
+
listActiveConversationIds,
|
|
267
|
+
removeActiveConversation,
|
|
268
|
+
requestConversationWork,
|
|
269
|
+
stopConversationWork
|
|
270
|
+
} from "./chunk-WN6VLHOU.js";
|
|
271
|
+
import {
|
|
272
|
+
buildDeterministicAssistantMessageId,
|
|
273
|
+
buildDeterministicTurnId
|
|
274
|
+
} from "./chunk-DA2KGZZI.js";
|
|
275
|
+
import "./chunk-O35GZCKL.js";
|
|
274
276
|
import {
|
|
275
277
|
getSandboxResourceConfig,
|
|
276
278
|
setSandboxResourceConfig
|
|
277
|
-
} from "./chunk-
|
|
279
|
+
} from "./chunk-6AUR6PWR.js";
|
|
278
280
|
import "./chunk-PDO5BLNM.js";
|
|
279
281
|
import "./chunk-UIE3R5XU.js";
|
|
280
282
|
import {
|
|
281
283
|
WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC,
|
|
282
284
|
verifyWorkspaceSnapshotJobMessage
|
|
283
285
|
} from "./chunk-X6GDDWQH.js";
|
|
286
|
+
import {
|
|
287
|
+
getTurnRequestDeadline
|
|
288
|
+
} from "./chunk-S3SGZUOI.js";
|
|
284
289
|
import {
|
|
285
290
|
getVercelConversationWorkQueue,
|
|
286
291
|
resolveConversationWorkQueueTopic,
|
|
@@ -291,9 +296,6 @@ import {
|
|
|
291
296
|
isConversationQueueMessageRejectedError
|
|
292
297
|
} from "./chunk-JAL3CH4G.js";
|
|
293
298
|
import "./chunk-7H2VZTWN.js";
|
|
294
|
-
import {
|
|
295
|
-
getTurnRequestDeadline
|
|
296
|
-
} from "./chunk-WGZJ5SU4.js";
|
|
297
299
|
import {
|
|
298
300
|
SlackActionError,
|
|
299
301
|
bindEventTaskCredentialSubject,
|
|
@@ -319,7 +321,7 @@ import {
|
|
|
319
321
|
verifyEventTaskCredentialSubject,
|
|
320
322
|
verifyScheduledTaskCredentialSubject,
|
|
321
323
|
verifySlackDirectCredentialSubject
|
|
322
|
-
} from "./chunk-
|
|
324
|
+
} from "./chunk-MI6ZBDTS.js";
|
|
323
325
|
import "./chunk-3Y47VMHV.js";
|
|
324
326
|
import {
|
|
325
327
|
createSlackDestination,
|
|
@@ -331,7 +333,7 @@ import {
|
|
|
331
333
|
requireSlackDestination,
|
|
332
334
|
withConversationEventLock,
|
|
333
335
|
withConversationMutationLock
|
|
334
|
-
} from "./chunk-
|
|
336
|
+
} from "./chunk-CUYFCI4G.js";
|
|
335
337
|
import {
|
|
336
338
|
juniorAgentBindings,
|
|
337
339
|
juniorAgentInvocations,
|
|
@@ -339,15 +341,14 @@ import {
|
|
|
339
341
|
juniorConversations,
|
|
340
342
|
juniorSchedulerRuns,
|
|
341
343
|
juniorSchedulerTasks
|
|
342
|
-
} from "./chunk-
|
|
343
|
-
import "./chunk-
|
|
344
|
+
} from "./chunk-5VWAY27R.js";
|
|
345
|
+
import "./chunk-WDHPN2GH.js";
|
|
344
346
|
import {
|
|
345
347
|
acquireActiveLock,
|
|
346
348
|
getStateAdapter,
|
|
347
349
|
withActiveLock
|
|
348
|
-
} from "./chunk-
|
|
350
|
+
} from "./chunk-5CXCGDIL.js";
|
|
349
351
|
import {
|
|
350
|
-
contextProvenance,
|
|
351
352
|
instructionProvenanceFor
|
|
352
353
|
} from "./chunk-GFBR4S3Q.js";
|
|
353
354
|
import {
|
|
@@ -368,17 +369,17 @@ import {
|
|
|
368
369
|
isProviderRetryError,
|
|
369
370
|
setProfiles,
|
|
370
371
|
setSlackReactionConfig
|
|
371
|
-
} from "./chunk-
|
|
372
|
+
} from "./chunk-BYBSI5TI.js";
|
|
372
373
|
import {
|
|
373
374
|
defaultModelId,
|
|
374
375
|
modelIdForProfile
|
|
375
376
|
} from "./chunk-D4YV5TDV.js";
|
|
376
|
-
import "./chunk-
|
|
377
|
-
import "./chunk-
|
|
377
|
+
import "./chunk-DYXVAO2E.js";
|
|
378
|
+
import "./chunk-YYSEH2WC.js";
|
|
378
379
|
import {
|
|
379
380
|
pluginCatalogRuntime
|
|
380
|
-
} from "./chunk-
|
|
381
|
-
import "./chunk-
|
|
381
|
+
} from "./chunk-E3PDZPGV.js";
|
|
382
|
+
import "./chunk-ZV6PFUA4.js";
|
|
382
383
|
import {
|
|
383
384
|
credentialContextForActor
|
|
384
385
|
} from "./chunk-CEMMLV5L.js";
|
|
@@ -414,13 +415,13 @@ import {
|
|
|
414
415
|
withContext,
|
|
415
416
|
withLogContext,
|
|
416
417
|
withSpan
|
|
417
|
-
} from "./chunk-
|
|
418
|
+
} from "./chunk-PY3EIEAF.js";
|
|
418
419
|
import {
|
|
419
420
|
continueTrace
|
|
420
421
|
} from "./chunk-PEQXYSSE.js";
|
|
421
422
|
import {
|
|
422
423
|
JUNIOR_VERSION
|
|
423
|
-
} from "./chunk-
|
|
424
|
+
} from "./chunk-NY2F7BZA.js";
|
|
424
425
|
|
|
425
426
|
// src/app.ts
|
|
426
427
|
import { createRequire } from "module";
|
|
@@ -569,7 +570,6 @@ function buildDispatchRoutingContext(dispatch2) {
|
|
|
569
570
|
dispatch2.actor,
|
|
570
571
|
dispatch2.credentialSubject
|
|
571
572
|
),
|
|
572
|
-
destinationVisibility: dispatch2.destinationVisibility,
|
|
573
573
|
dispatch: {
|
|
574
574
|
actor: dispatch2.actor,
|
|
575
575
|
id: dispatch2.id,
|
|
@@ -689,12 +689,6 @@ async function resolveAgentDispatchId(context) {
|
|
|
689
689
|
const dispatch2 = await getDispatchRecord(durableDispatchId);
|
|
690
690
|
return dispatch2 && !isTerminalDispatchStatus(dispatch2.status) ? durableDispatchId : void 0;
|
|
691
691
|
}
|
|
692
|
-
function createAgentDispatchWorkRouter(options) {
|
|
693
|
-
return async (context) => {
|
|
694
|
-
const dispatchId = await resolveAgentDispatchId(context);
|
|
695
|
-
return dispatchId ? await options.dispatchWorker(context, dispatchId) : await options.fallbackWorker(context);
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
692
|
async function readDispatchTurnResult(dispatch2) {
|
|
699
693
|
const conversationId = getDispatchConversationId(dispatch2);
|
|
700
694
|
const turnId = getDispatchTurnId(dispatch2.id);
|
|
@@ -2742,13 +2736,13 @@ async function GET6(request) {
|
|
|
2742
2736
|
// src/chat/ingress/slack-webhook.ts
|
|
2743
2737
|
import {
|
|
2744
2738
|
ChannelImpl,
|
|
2745
|
-
ThreadImpl as
|
|
2739
|
+
ThreadImpl as ThreadImpl2
|
|
2746
2740
|
} from "chat";
|
|
2747
2741
|
|
|
2748
2742
|
// src/chat/task-execution/slack-work.ts
|
|
2749
2743
|
import {
|
|
2750
|
-
Message as
|
|
2751
|
-
ThreadImpl
|
|
2744
|
+
Message as Message2,
|
|
2745
|
+
ThreadImpl
|
|
2752
2746
|
} from "chat";
|
|
2753
2747
|
import { z as z3 } from "zod";
|
|
2754
2748
|
|
|
@@ -2938,85 +2932,6 @@ async function ensureSlackMessageActorIdentity(message, teamId, lookupSlackUser2
|
|
|
2938
2932
|
return actor;
|
|
2939
2933
|
}
|
|
2940
2934
|
|
|
2941
|
-
// src/chat/task-execution/slack-resource-event.ts
|
|
2942
|
-
import { Message as Message2, ThreadImpl } from "chat";
|
|
2943
|
-
async function resolveSlackResourceEventThread(args) {
|
|
2944
|
-
const routing = await resolveConversationRouting({
|
|
2945
|
-
conversationId: args.conversationId,
|
|
2946
|
-
conversationStore: args.conversationStore
|
|
2947
|
-
});
|
|
2948
|
-
const destination = requireSlackDestination(
|
|
2949
|
-
routing?.destination ?? args.destination,
|
|
2950
|
-
"Slack resource-event turn"
|
|
2951
|
-
);
|
|
2952
|
-
const threadTs = routing?.source?.platform === "slack" ? routing.source.threadTs?.trim() : void 0;
|
|
2953
|
-
if (!threadTs) {
|
|
2954
|
-
return void 0;
|
|
2955
|
-
}
|
|
2956
|
-
return { destination, threadTs };
|
|
2957
|
-
}
|
|
2958
|
-
function isPlainResourceEventRecord(record) {
|
|
2959
|
-
return record.source === "resource_event" && isResourceEventMailboxMetadata(record.input.metadata) && !hasSlackConversationMetadata(record.input.metadata);
|
|
2960
|
-
}
|
|
2961
|
-
function hasSlackConversationMetadata(value) {
|
|
2962
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2963
|
-
return false;
|
|
2964
|
-
}
|
|
2965
|
-
const record = value;
|
|
2966
|
-
return record.platform === "slack" && typeof record.thread === "object" && record.thread !== null && typeof record.message === "object" && record.message !== null;
|
|
2967
|
-
}
|
|
2968
|
-
function buildResourceEventSlackMessage(args) {
|
|
2969
|
-
if (!isResourceEventMailboxMetadata(args.record.input.metadata)) {
|
|
2970
|
-
throw new Error(
|
|
2971
|
-
"Resource-event Slack turn requires resource-event metadata"
|
|
2972
|
-
);
|
|
2973
|
-
}
|
|
2974
|
-
const event = args.record.input.metadata.resourceEvent;
|
|
2975
|
-
const messageId = `resource-event-${event.subscriptionId}-${event.eventKey}`;
|
|
2976
|
-
const threadId = `slack:${args.channelId}:${args.threadTs}`;
|
|
2977
|
-
return new Message2({
|
|
2978
|
-
id: messageId,
|
|
2979
|
-
threadId,
|
|
2980
|
-
text: args.record.input.text,
|
|
2981
|
-
author: {
|
|
2982
|
-
...RESOURCE_EVENT_MESSAGE_AUTHOR,
|
|
2983
|
-
isMe: false
|
|
2984
|
-
},
|
|
2985
|
-
isMention: false,
|
|
2986
|
-
attachments: [],
|
|
2987
|
-
metadata: {
|
|
2988
|
-
dateSent: new Date(args.record.createdAtMs),
|
|
2989
|
-
edited: false
|
|
2990
|
-
},
|
|
2991
|
-
formatted: { type: "root", children: [] },
|
|
2992
|
-
raw: {
|
|
2993
|
-
channel: args.channelId,
|
|
2994
|
-
event_type: "resource_event",
|
|
2995
|
-
resource_event_type: event.eventType,
|
|
2996
|
-
thread_ts: args.threadTs,
|
|
2997
|
-
type: "message",
|
|
2998
|
-
user: RESOURCE_EVENT_AUTHOR_ID
|
|
2999
|
-
}
|
|
3000
|
-
});
|
|
3001
|
-
}
|
|
3002
|
-
function buildResourceEventSlackThread(args) {
|
|
3003
|
-
const threadId = normalizeIncomingSlackThreadId(
|
|
3004
|
-
`slack:${args.channelId}:${args.threadTs}`,
|
|
3005
|
-
args.message
|
|
3006
|
-
);
|
|
3007
|
-
const message = withNormalizedThreadId(args.message, threadId);
|
|
3008
|
-
return new ThreadImpl({
|
|
3009
|
-
adapter: args.adapter,
|
|
3010
|
-
stateAdapter: args.state,
|
|
3011
|
-
id: threadId,
|
|
3012
|
-
channelId: args.channelId,
|
|
3013
|
-
currentMessage: message,
|
|
3014
|
-
initialMessage: message,
|
|
3015
|
-
isDM: args.channelId.startsWith("D"),
|
|
3016
|
-
isSubscribedContext: true
|
|
3017
|
-
});
|
|
3018
|
-
}
|
|
3019
|
-
|
|
3020
2935
|
// src/chat/slack/message-control.ts
|
|
3021
2936
|
var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
|
|
3022
2937
|
function stripLeadingSteeringOverride(text) {
|
|
@@ -3251,9 +3166,6 @@ function compareInboundMessages(left, right) {
|
|
|
3251
3166
|
}
|
|
3252
3167
|
function routeForRecords(records) {
|
|
3253
3168
|
return records.some((record) => {
|
|
3254
|
-
if (isPlainResourceEventRecord(record)) {
|
|
3255
|
-
return false;
|
|
3256
|
-
}
|
|
3257
3169
|
const metadata = parseSlackMetadata(record.input.metadata);
|
|
3258
3170
|
if (!metadata) {
|
|
3259
3171
|
throw new Error("Conversation mailbox record is not Slack metadata");
|
|
@@ -3262,23 +3174,11 @@ function routeForRecords(records) {
|
|
|
3262
3174
|
}) ? "mention" : "subscribed";
|
|
3263
3175
|
}
|
|
3264
3176
|
function restoreMessage(args) {
|
|
3265
|
-
if (isPlainResourceEventRecord(args.record)) {
|
|
3266
|
-
if (!args.threadTs) {
|
|
3267
|
-
throw new Error(
|
|
3268
|
-
"Resource-event Slack turn requires a thread timestamp"
|
|
3269
|
-
);
|
|
3270
|
-
}
|
|
3271
|
-
return buildResourceEventSlackMessage({
|
|
3272
|
-
channelId: args.channelId,
|
|
3273
|
-
record: args.record,
|
|
3274
|
-
threadTs: args.threadTs
|
|
3275
|
-
});
|
|
3276
|
-
}
|
|
3277
3177
|
const metadata = parseSlackMetadata(args.record.input.metadata);
|
|
3278
3178
|
if (!metadata) {
|
|
3279
3179
|
throw new Error("Conversation mailbox record is not a Slack message");
|
|
3280
3180
|
}
|
|
3281
|
-
const message =
|
|
3181
|
+
const message = Message2.fromJSON(metadata.message);
|
|
3282
3182
|
message.attachments = message.attachments.map(
|
|
3283
3183
|
(attachment) => args.adapter.rehydrateAttachment(attachment)
|
|
3284
3184
|
);
|
|
@@ -3288,9 +3188,6 @@ function restoreMessage(args) {
|
|
|
3288
3188
|
async function bindSlackActorIdentities(args) {
|
|
3289
3189
|
const byAuthorId = /* @__PURE__ */ new Map();
|
|
3290
3190
|
for (const message of args.messages) {
|
|
3291
|
-
if (isResourceEventSlackMessage(message)) {
|
|
3292
|
-
continue;
|
|
3293
|
-
}
|
|
3294
3191
|
const authorId = requireSlackAuthorId(message);
|
|
3295
3192
|
byAuthorId.set(authorId, [...byAuthorId.get(authorId) ?? [], message]);
|
|
3296
3193
|
}
|
|
@@ -3315,7 +3212,7 @@ function restoreThread(args) {
|
|
|
3315
3212
|
args.message
|
|
3316
3213
|
);
|
|
3317
3214
|
const message = withNormalizedThreadId(args.message, threadId);
|
|
3318
|
-
return new
|
|
3215
|
+
return new ThreadImpl({
|
|
3319
3216
|
adapter: args.adapter,
|
|
3320
3217
|
stateAdapter: args.state,
|
|
3321
3218
|
id: threadId,
|
|
@@ -3380,10 +3277,9 @@ function createSlackConversationWorker(options) {
|
|
|
3380
3277
|
if (!latestRecord) {
|
|
3381
3278
|
return { status: "completed" };
|
|
3382
3279
|
}
|
|
3383
|
-
const
|
|
3384
|
-
const
|
|
3385
|
-
|
|
3386
|
-
if (!isPlainResourceEventRecord(latestRecord) && !latestMetadata) {
|
|
3280
|
+
const publishExternally = latestRecord.publishExternally ?? context.publishExternally;
|
|
3281
|
+
const latestMetadata = parseSlackMetadata(latestRecord.input.metadata);
|
|
3282
|
+
if (!latestMetadata) {
|
|
3387
3283
|
throw new Error(
|
|
3388
3284
|
"Latest conversation mailbox record is not Slack metadata"
|
|
3389
3285
|
);
|
|
@@ -3391,34 +3287,19 @@ function createSlackConversationWorker(options) {
|
|
|
3391
3287
|
if (!await context.checkIn()) {
|
|
3392
3288
|
return { status: "lost_lease" };
|
|
3393
3289
|
}
|
|
3394
|
-
const resourceEventThread = hasPlainResourceEvent ? await resolveSlackResourceEventThread({
|
|
3395
|
-
conversationId: context.conversationId,
|
|
3396
|
-
conversationStore: options.conversationStore,
|
|
3397
|
-
destination: context.destination
|
|
3398
|
-
}) : void 0;
|
|
3399
|
-
if (hasPlainResourceEvent && !resourceEventThread) {
|
|
3400
|
-
logWarn("conversation.work.resource_event.missing_thread", {
|
|
3401
|
-
"app.inbound.message_count": records.length
|
|
3402
|
-
});
|
|
3403
|
-
await context.attempt.ack();
|
|
3404
|
-
return { status: "completed" };
|
|
3405
|
-
}
|
|
3406
3290
|
const turnResult = await runWithSlackInstallation({
|
|
3407
3291
|
adapter,
|
|
3408
|
-
installation:
|
|
3292
|
+
installation: getInstallation(records),
|
|
3409
3293
|
state,
|
|
3410
3294
|
task: async () => {
|
|
3411
|
-
const destination =
|
|
3295
|
+
const destination = requireSlackDestination(
|
|
3412
3296
|
context.destination,
|
|
3413
3297
|
"Slack conversation work"
|
|
3414
3298
|
);
|
|
3415
|
-
const threadTs = resourceEventThread?.threadTs;
|
|
3416
3299
|
const messages = records.map(
|
|
3417
3300
|
(record) => restoreMessage({
|
|
3418
3301
|
adapter,
|
|
3419
|
-
|
|
3420
|
-
record,
|
|
3421
|
-
...threadTs ? { threadTs } : void 0
|
|
3302
|
+
record
|
|
3422
3303
|
})
|
|
3423
3304
|
);
|
|
3424
3305
|
await bindSlackActorIdentities({
|
|
@@ -3431,13 +3312,7 @@ function createSlackConversationWorker(options) {
|
|
|
3431
3312
|
return;
|
|
3432
3313
|
}
|
|
3433
3314
|
const route = routeForRecords(records);
|
|
3434
|
-
const thread =
|
|
3435
|
-
adapter,
|
|
3436
|
-
channelId: destination.channelId,
|
|
3437
|
-
message: latestMessage,
|
|
3438
|
-
state,
|
|
3439
|
-
threadTs
|
|
3440
|
-
}) : restoreThread({
|
|
3315
|
+
const thread = restoreThread({
|
|
3441
3316
|
adapter,
|
|
3442
3317
|
isSubscribedContext: route === "subscribed",
|
|
3443
3318
|
message: latestMessage,
|
|
@@ -3449,7 +3324,7 @@ function createSlackConversationWorker(options) {
|
|
|
3449
3324
|
skipped,
|
|
3450
3325
|
totalSinceLastHandler: messages.length
|
|
3451
3326
|
};
|
|
3452
|
-
const activeAuthorId =
|
|
3327
|
+
const activeAuthorId = requireSlackAuthorId(latestMessage);
|
|
3453
3328
|
let initialMessagesAcked = false;
|
|
3454
3329
|
const ack = async () => {
|
|
3455
3330
|
if (initialMessagesAcked) {
|
|
@@ -3467,17 +3342,15 @@ function createSlackConversationWorker(options) {
|
|
|
3467
3342
|
const drainSteeringMessages = async (accept) => {
|
|
3468
3343
|
await context.attempt.drain(async (pendingRecords) => {
|
|
3469
3344
|
const candidates = pendingRecords.filter(
|
|
3470
|
-
(record) =>
|
|
3345
|
+
(record) => record.publishExternally === publishExternally
|
|
3471
3346
|
).map((record) => ({
|
|
3472
3347
|
inboundMessageId: record.inboundMessageId,
|
|
3473
3348
|
message: restoreMessage({
|
|
3474
3349
|
adapter,
|
|
3475
|
-
|
|
3476
|
-
record,
|
|
3477
|
-
...threadTs ? { threadTs } : void 0
|
|
3350
|
+
record
|
|
3478
3351
|
})
|
|
3479
3352
|
})).filter(
|
|
3480
|
-
(candidate) => crossActorMidRunMode === "steer" ||
|
|
3353
|
+
(candidate) => crossActorMidRunMode === "steer" || requireSlackAuthorId(candidate.message) === activeAuthorId || hasSteeringOverride(candidate.message.text)
|
|
3481
3354
|
);
|
|
3482
3355
|
return candidates.length > 0 ? await accept(candidates) : [];
|
|
3483
3356
|
});
|
|
@@ -3635,7 +3508,7 @@ function textMentionsBot(text, botUserId) {
|
|
|
3635
3508
|
}
|
|
3636
3509
|
|
|
3637
3510
|
// src/chat/ingress/message-changed.ts
|
|
3638
|
-
import { Message as
|
|
3511
|
+
import { Message as Message3 } from "chat";
|
|
3639
3512
|
function getEditedMentionMessageId(messageTs) {
|
|
3640
3513
|
return `${messageTs}:message_changed_mention`;
|
|
3641
3514
|
}
|
|
@@ -3702,7 +3575,7 @@ function extractMessageChangedMention(body, botUserId, adapter) {
|
|
|
3702
3575
|
...sourceTeam ? { source_team: sourceTeam } : void 0,
|
|
3703
3576
|
...botId ? { bot_id: botId } : void 0
|
|
3704
3577
|
};
|
|
3705
|
-
const message = new
|
|
3578
|
+
const message = new Message3({
|
|
3706
3579
|
id: getEditedMentionMessageId(messageTs),
|
|
3707
3580
|
threadId,
|
|
3708
3581
|
text: newText,
|
|
@@ -3941,7 +3814,7 @@ function normalizeMessageThreadId(message) {
|
|
|
3941
3814
|
}
|
|
3942
3815
|
async function buildThread(args) {
|
|
3943
3816
|
const normalized = normalizeMessageThreadId(args.message);
|
|
3944
|
-
return new
|
|
3817
|
+
return new ThreadImpl2({
|
|
3945
3818
|
adapter: args.adapter,
|
|
3946
3819
|
stateAdapter: args.state,
|
|
3947
3820
|
id: normalized.threadId,
|
|
@@ -5531,8 +5404,7 @@ function createSlackTurnRuntime(deps) {
|
|
|
5531
5404
|
const threadId = getThreadId(thread, message);
|
|
5532
5405
|
const channelId = getChannelId(thread, message);
|
|
5533
5406
|
const runId = getRunId(thread, message);
|
|
5534
|
-
const
|
|
5535
|
-
const actorId = isResourceEventNotification ? void 0 : message.author.userId;
|
|
5407
|
+
const actorId = message.author.userId;
|
|
5536
5408
|
const turnContext = logContext({
|
|
5537
5409
|
threadId,
|
|
5538
5410
|
actorId,
|
|
@@ -5565,7 +5437,7 @@ function createSlackTurnRuntime(deps) {
|
|
|
5565
5437
|
});
|
|
5566
5438
|
const combinedText = combineTurnText(queuedMessages, currentText);
|
|
5567
5439
|
const turnIsExplicitMention = Boolean(message.isMention) || queuedMessages.some((queued) => queued.explicitMention);
|
|
5568
|
-
const preflightDecision =
|
|
5440
|
+
const preflightDecision = getSubscribedReplyPreflightDecision({
|
|
5569
5441
|
botUserName: deps.assistantUserName,
|
|
5570
5442
|
rawText: combinedText.rawText,
|
|
5571
5443
|
text: combinedText.userText,
|
|
@@ -5583,7 +5455,7 @@ function createSlackTurnRuntime(deps) {
|
|
|
5583
5455
|
});
|
|
5584
5456
|
return;
|
|
5585
5457
|
}
|
|
5586
|
-
if (!
|
|
5458
|
+
if (!turnIsExplicitMention && !isExperimentalFeatureEnabled("passive-routing")) {
|
|
5587
5459
|
const decision2 = await deps.decideSubscribedReply({
|
|
5588
5460
|
rawText: combinedText.rawText,
|
|
5589
5461
|
text: combinedText.userText,
|
|
@@ -5621,7 +5493,7 @@ function createSlackTurnRuntime(deps) {
|
|
|
5621
5493
|
thread,
|
|
5622
5494
|
preparedState
|
|
5623
5495
|
});
|
|
5624
|
-
const decision =
|
|
5496
|
+
const decision = await deps.decideSubscribedReply({
|
|
5625
5497
|
rawText: combinedText.rawText,
|
|
5626
5498
|
text: combinedText.userText,
|
|
5627
5499
|
conversationContext: deps.getPreparedConversationContext(preparedState),
|
|
@@ -6431,6 +6303,21 @@ async function maybeApplyProviderDefaultConfigRequest(args) {
|
|
|
6431
6303
|
};
|
|
6432
6304
|
}
|
|
6433
6305
|
|
|
6306
|
+
// src/chat/conversations/destination-visibility.ts
|
|
6307
|
+
async function resolveDestinationVisibility(args) {
|
|
6308
|
+
if (args.visibility) {
|
|
6309
|
+
return args.visibility;
|
|
6310
|
+
}
|
|
6311
|
+
if (args.destination.platform === "local") {
|
|
6312
|
+
return "private";
|
|
6313
|
+
}
|
|
6314
|
+
return await getConversationStore().getDestinationVisibility({
|
|
6315
|
+
provider: "slack",
|
|
6316
|
+
providerDestinationId: args.destination.channelId,
|
|
6317
|
+
providerTenantId: args.destination.teamId
|
|
6318
|
+
});
|
|
6319
|
+
}
|
|
6320
|
+
|
|
6434
6321
|
// src/chat/providers/slack/input.ts
|
|
6435
6322
|
function steeringMessageKey(message) {
|
|
6436
6323
|
if (message.role !== "user") {
|
|
@@ -6488,9 +6375,6 @@ function inboundMessageActor(queued) {
|
|
|
6488
6375
|
};
|
|
6489
6376
|
}
|
|
6490
6377
|
function inboundMessageProvenance(queued, teamId) {
|
|
6491
|
-
if (isResourceEventSlackMessage(queued.message)) {
|
|
6492
|
-
return contextProvenance;
|
|
6493
|
-
}
|
|
6494
6378
|
const identity = getMessageActorIdentity(queued.message);
|
|
6495
6379
|
const author = identity && "platform" in identity ? identity : createActor(
|
|
6496
6380
|
{ userId: parseActorUserId(queued.message.author.userId) },
|
|
@@ -6650,6 +6534,15 @@ function createSlackTurn(deps) {
|
|
|
6650
6534
|
modelId: defaultModelId(botConfig)
|
|
6651
6535
|
},
|
|
6652
6536
|
async () => {
|
|
6537
|
+
await getConversationStore().recordActivity({
|
|
6538
|
+
activityAtMs: message.metadata.dateSent.getTime(),
|
|
6539
|
+
channelName,
|
|
6540
|
+
conversationId,
|
|
6541
|
+
destination,
|
|
6542
|
+
sessionSource: source,
|
|
6543
|
+
source: "slack",
|
|
6544
|
+
visibility: destinationVisibility
|
|
6545
|
+
});
|
|
6653
6546
|
const content = parseContent(message);
|
|
6654
6547
|
const strippedUserText = stripLeadingBotMention(
|
|
6655
6548
|
stripLeadingSteeringOverride(content.topLevelText),
|
|
@@ -6663,7 +6556,7 @@ function createSlackTurn(deps) {
|
|
|
6663
6556
|
userText: replaceTopLevelText(content, strippedUserText)
|
|
6664
6557
|
};
|
|
6665
6558
|
await Promise.all(
|
|
6666
|
-
(options.queuedMessages ?? []).
|
|
6559
|
+
(options.queuedMessages ?? []).map(
|
|
6667
6560
|
(queued) => ensureSlackMessageActorIdentity(
|
|
6668
6561
|
queued.message,
|
|
6669
6562
|
teamId,
|
|
@@ -6677,9 +6570,6 @@ function createSlackTurn(deps) {
|
|
|
6677
6570
|
if (options.execution) {
|
|
6678
6571
|
executionActor = options.execution.dispatch.actor;
|
|
6679
6572
|
credentialContext = options.execution.credentialContext;
|
|
6680
|
-
} else if (isResourceEventSlackMessage(message)) {
|
|
6681
|
-
executionActor = RESOURCE_EVENT_SYSTEM_ACTOR;
|
|
6682
|
-
credentialContext = credentialContextForActor(executionActor);
|
|
6683
6573
|
} else {
|
|
6684
6574
|
executionActor = await ensureSlackMessageActorIdentity(
|
|
6685
6575
|
message,
|
|
@@ -6769,7 +6659,7 @@ function createSlackTurn(deps) {
|
|
|
6769
6659
|
omittedImageAttachmentCount: !isVisionEnabled() && hasPotentialImageAttachment(attachments) ? countPotentialImageAttachments(attachments) : 0,
|
|
6770
6660
|
attachments: await deps.resolveUserAttachments(attachments, {
|
|
6771
6661
|
threadId,
|
|
6772
|
-
actorId:
|
|
6662
|
+
actorId: queued.message.author.userId,
|
|
6773
6663
|
channelId,
|
|
6774
6664
|
runId,
|
|
6775
6665
|
conversation: preparedState.conversation,
|
|
@@ -6859,8 +6749,7 @@ function createSlackTurn(deps) {
|
|
|
6859
6749
|
await abandonTurnRecord({
|
|
6860
6750
|
conversationId,
|
|
6861
6751
|
turnId: activeTurnId,
|
|
6862
|
-
|
|
6863
|
-
errorMessage: "Auth-parked session superseded by a new user message"
|
|
6752
|
+
errorMessage: "Auth-paused Turn superseded by new input"
|
|
6864
6753
|
});
|
|
6865
6754
|
markTurnClosed({
|
|
6866
6755
|
conversation: preparedState.conversation,
|
|
@@ -7277,16 +7166,15 @@ function createSlackTurn(deps) {
|
|
|
7277
7166
|
},
|
|
7278
7167
|
history: piMessages,
|
|
7279
7168
|
credentialContext,
|
|
7280
|
-
// Always set the execution
|
|
7281
|
-
// carry the system principal; interactive turns carry the Slack user.
|
|
7169
|
+
// Always set the execution Actor when known.
|
|
7282
7170
|
actor: executionActor,
|
|
7283
7171
|
slackConversation,
|
|
7284
|
-
source
|
|
7172
|
+
source,
|
|
7173
|
+
...location ? { location } : void 0,
|
|
7285
7174
|
destination,
|
|
7286
7175
|
publishExternally: shouldPublishExternally2(
|
|
7287
7176
|
options.publishExternally
|
|
7288
7177
|
),
|
|
7289
|
-
...destinationVisibility ? { destinationVisibility } : void 0,
|
|
7290
7178
|
surface: options.execution?.surface ?? "slack",
|
|
7291
7179
|
dispatch: options.execution?.dispatch,
|
|
7292
7180
|
toolChannelId,
|
|
@@ -7313,10 +7201,7 @@ function createSlackTurn(deps) {
|
|
|
7313
7201
|
});
|
|
7314
7202
|
}
|
|
7315
7203
|
},
|
|
7316
|
-
delivery:
|
|
7317
|
-
...location && shouldPublishExternally2(options.publishExternally) ? { location } : void 0,
|
|
7318
|
-
send: deliverAssistantMessage
|
|
7319
|
-
},
|
|
7204
|
+
delivery: deliverAssistantMessage,
|
|
7320
7205
|
durability: {
|
|
7321
7206
|
onInputCommitted: options.ack,
|
|
7322
7207
|
drainSteeringMessages,
|
|
@@ -7738,11 +7623,6 @@ async function persistConversationVisionCache(conversationId, vision) {
|
|
|
7738
7623
|
|
|
7739
7624
|
// src/chat/runtime/conversation-message.ts
|
|
7740
7625
|
var NON_TEXT_MESSAGE_TEXT = "[non-text message]";
|
|
7741
|
-
function resourceEventType(entry) {
|
|
7742
|
-
if (!entry.raw || typeof entry.raw !== "object") return void 0;
|
|
7743
|
-
const raw = entry.raw;
|
|
7744
|
-
return raw.event_type === "resource_event" && typeof raw.resource_event_type === "string" ? raw.resource_event_type : void 0;
|
|
7745
|
-
}
|
|
7746
7626
|
function resolveMessageText(args) {
|
|
7747
7627
|
const text = normalizeConversationText(args.text);
|
|
7748
7628
|
return text || NON_TEXT_MESSAGE_TEXT;
|
|
@@ -7767,7 +7647,6 @@ function toConversationMessage(args) {
|
|
|
7767
7647
|
},
|
|
7768
7648
|
meta: {
|
|
7769
7649
|
attachmentCount: args.entry.attachments.length,
|
|
7770
|
-
eventType: resourceEventType(args.entry),
|
|
7771
7650
|
explicitMention: args.explicitMention,
|
|
7772
7651
|
imageAttachmentCount: imageAttachmentCount > 0 ? imageAttachmentCount : void 0,
|
|
7773
7652
|
imagesHydrated: !messageHasPotentialImageAttachment,
|
|
@@ -7937,14 +7816,14 @@ function createPrepareTurnState(deps) {
|
|
|
7937
7816
|
}
|
|
7938
7817
|
|
|
7939
7818
|
// src/chat/slack/dispatch-turn.ts
|
|
7940
|
-
import { Message as
|
|
7819
|
+
import { Message as Message4, ThreadImpl as ThreadImpl3 } from "chat";
|
|
7941
7820
|
function createSlackDispatchTurnRunner(options) {
|
|
7942
7821
|
return async function runSlackDispatchTurn(dispatch2, hooks) {
|
|
7943
7822
|
const state = getStateAdapter();
|
|
7944
7823
|
await state.connect();
|
|
7945
7824
|
const conversationId = getDispatchConversationId(dispatch2);
|
|
7946
7825
|
const adapter = options.getSlackAdapter();
|
|
7947
|
-
const message = new
|
|
7826
|
+
const message = new Message4({
|
|
7948
7827
|
id: getDispatchInputMessageId(dispatch2.id),
|
|
7949
7828
|
threadId: conversationId,
|
|
7950
7829
|
text: dispatch2.input,
|
|
@@ -7967,7 +7846,7 @@ function createSlackDispatchTurnRunner(options) {
|
|
|
7967
7846
|
}
|
|
7968
7847
|
});
|
|
7969
7848
|
message.isMention = true;
|
|
7970
|
-
const thread = new
|
|
7849
|
+
const thread = new ThreadImpl3({
|
|
7971
7850
|
adapter,
|
|
7972
7851
|
stateAdapter: state,
|
|
7973
7852
|
id: conversationId,
|
|
@@ -8400,6 +8279,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
|
|
|
8400
8279
|
return false;
|
|
8401
8280
|
}
|
|
8402
8281
|
const activeTurn = turn;
|
|
8282
|
+
const { dispatch: dispatch2, surface } = options.routingContext ?? {};
|
|
8403
8283
|
const currentState = await getPersistedThreadState(
|
|
8404
8284
|
payload.conversationId
|
|
8405
8285
|
);
|
|
@@ -8408,7 +8288,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
|
|
|
8408
8288
|
conversation,
|
|
8409
8289
|
conversationId: payload.conversationId
|
|
8410
8290
|
});
|
|
8411
|
-
const dispatchId = activeTurn.dispatchId ??
|
|
8291
|
+
const dispatchId = activeTurn.dispatchId ?? dispatch2?.id;
|
|
8412
8292
|
const dispatchUserMessage = dispatchId ? conversation.messages.find(
|
|
8413
8293
|
(message) => message.role === "user" && options.inputMessageIds?.includes(message.id)
|
|
8414
8294
|
) : void 0;
|
|
@@ -8451,21 +8331,19 @@ async function runPausedTurnInContext(payload, options, runOptions) {
|
|
|
8451
8331
|
const routingDestination = routing.destination;
|
|
8452
8332
|
const turnMessages = activeTurn.turnStartMessageIndex === void 0 ? [] : activeTurn.piMessages.slice(activeTurn.turnStartMessageIndex);
|
|
8453
8333
|
const recordDispatchOutcome = async (dispatchOutcome) => {
|
|
8454
|
-
|
|
8455
|
-
if (!dispatchId2) {
|
|
8334
|
+
if (!dispatch2) {
|
|
8456
8335
|
return;
|
|
8457
8336
|
}
|
|
8458
8337
|
await recordTurnSummary({
|
|
8459
8338
|
conversationId: payload.conversationId,
|
|
8460
8339
|
destination: routingDestination,
|
|
8461
|
-
|
|
8462
|
-
dispatchId: dispatchId2,
|
|
8340
|
+
dispatchId: dispatch2.id,
|
|
8463
8341
|
dispatchOutcome,
|
|
8464
8342
|
turnId: payload.turnId,
|
|
8465
8343
|
sliceId: activeTurn.sliceId,
|
|
8466
8344
|
source,
|
|
8467
8345
|
state: "failed",
|
|
8468
|
-
surface:
|
|
8346
|
+
surface: surface ?? "slack"
|
|
8469
8347
|
});
|
|
8470
8348
|
};
|
|
8471
8349
|
return {
|
|
@@ -8481,21 +8359,24 @@ async function runPausedTurnInContext(payload, options, runOptions) {
|
|
|
8481
8359
|
...getTurnUserReplyAttachmentContext(userMessage),
|
|
8482
8360
|
text: userMessage.text
|
|
8483
8361
|
},
|
|
8484
|
-
//
|
|
8485
|
-
//
|
|
8486
|
-
//
|
|
8487
|
-
// projection so queued steering remains visible.
|
|
8362
|
+
// A dispatch reads only history saved for this Turn. Other input
|
|
8363
|
+
// must not become part of a system Turn. Other Turns read
|
|
8364
|
+
// Conversation history. This keeps queued steering visible.
|
|
8488
8365
|
history: dispatchId ? activeTurn.piMessages : await loadProjection({
|
|
8489
8366
|
conversationId: payload.conversationId
|
|
8490
8367
|
}),
|
|
8491
|
-
...options.routingContext,
|
|
8492
|
-
credentialContext,
|
|
8493
8368
|
actor,
|
|
8369
|
+
credentialContext,
|
|
8494
8370
|
destination: routingDestination,
|
|
8371
|
+
...dispatch2 ? { dispatch: dispatch2 } : void 0,
|
|
8372
|
+
...routing.location ? { location: routing.location } : void 0,
|
|
8495
8373
|
// Slack resume publishes unless the checkpoint opted out.
|
|
8496
8374
|
// Missing means legacy/in-flight Slack turns still post.
|
|
8375
|
+
// TODO(dcramer): Remove this missing-as-publish fallback after no
|
|
8376
|
+
// stored Turn checkpoint can omit publishExternally.
|
|
8497
8377
|
publishExternally: activeTurn.publishExternally !== false,
|
|
8498
8378
|
source,
|
|
8379
|
+
...surface ? { surface } : void 0,
|
|
8499
8380
|
toolChannelId: destination.channelId,
|
|
8500
8381
|
environment: {
|
|
8501
8382
|
locationConfiguration
|
|
@@ -8709,30 +8590,794 @@ async function runNextPausedTurnInContext(conversationId, options, runOptions) {
|
|
|
8709
8590
|
return false;
|
|
8710
8591
|
}
|
|
8711
8592
|
|
|
8593
|
+
// src/chat/task-execution/conversation-turn.ts
|
|
8594
|
+
import { createHash } from "crypto";
|
|
8595
|
+
|
|
8596
|
+
// src/chat/task-execution/assistant-message.ts
|
|
8597
|
+
async function commitAssistantMessage(args) {
|
|
8598
|
+
const conversationMessageId = recordDeliveredAssistantMessage({
|
|
8599
|
+
conversation: args.conversation,
|
|
8600
|
+
sessionId: args.sessionId,
|
|
8601
|
+
source: args.source,
|
|
8602
|
+
text: args.text,
|
|
8603
|
+
userMessageId: args.userMessageId
|
|
8604
|
+
});
|
|
8605
|
+
if (args.publishedMessage?.providerMessageId) {
|
|
8606
|
+
markConversationMessage(args.conversation, conversationMessageId, {
|
|
8607
|
+
slackTs: args.publishedMessage.providerMessageId
|
|
8608
|
+
});
|
|
8609
|
+
}
|
|
8610
|
+
try {
|
|
8611
|
+
await persistWithRetry(
|
|
8612
|
+
() => commitAcceptedReply({
|
|
8613
|
+
...args.agentMessage ? { agentMessage: args.agentMessage } : void 0,
|
|
8614
|
+
conversation: args.conversation,
|
|
8615
|
+
conversationMessageId,
|
|
8616
|
+
conversationId: args.conversationId,
|
|
8617
|
+
providerConversationBindings: args.publishedMessage?.providerConversationBindings
|
|
8618
|
+
})
|
|
8619
|
+
);
|
|
8620
|
+
} catch (error) {
|
|
8621
|
+
logException(
|
|
8622
|
+
new Error("Assistant message persistence failed"),
|
|
8623
|
+
"conversation.assistant.message_persist.failed",
|
|
8624
|
+
{
|
|
8625
|
+
"error.type": error instanceof Error ? error.name : typeof error
|
|
8626
|
+
}
|
|
8627
|
+
);
|
|
8628
|
+
}
|
|
8629
|
+
}
|
|
8630
|
+
|
|
8631
|
+
// src/chat/task-execution/mailbox-turn.ts
|
|
8632
|
+
import {
|
|
8633
|
+
createLocalSource,
|
|
8634
|
+
createWebSource
|
|
8635
|
+
} from "@sentry/junior-plugin-api";
|
|
8636
|
+
function turnInputFactsFromConversationMessage(message) {
|
|
8637
|
+
if (isResourceEventConversationMessage(message)) {
|
|
8638
|
+
return {
|
|
8639
|
+
actor: RESOURCE_EVENT_SYSTEM_ACTOR,
|
|
8640
|
+
author: message.author ?? RESOURCE_EVENT_MESSAGE_AUTHOR,
|
|
8641
|
+
source: "resource_event"
|
|
8642
|
+
};
|
|
8643
|
+
}
|
|
8644
|
+
const actor = createActor(message.author, {
|
|
8645
|
+
platform: "web",
|
|
8646
|
+
userId: message.author?.userId
|
|
8647
|
+
});
|
|
8648
|
+
if (actor?.platform !== "web") {
|
|
8649
|
+
return void 0;
|
|
8650
|
+
}
|
|
8651
|
+
return {
|
|
8652
|
+
actor,
|
|
8653
|
+
author: message.author ?? { userId: actor.userId },
|
|
8654
|
+
source: "web"
|
|
8655
|
+
};
|
|
8656
|
+
}
|
|
8657
|
+
function sourceFromTurnInput(args) {
|
|
8658
|
+
switch (args.source) {
|
|
8659
|
+
case "resource_event":
|
|
8660
|
+
return args.location ? createWebSource(
|
|
8661
|
+
args.conversationId,
|
|
8662
|
+
args.visibility === "private" ? "private" : "public"
|
|
8663
|
+
) : createLocalSource(args.conversationId);
|
|
8664
|
+
case "web":
|
|
8665
|
+
return createWebSource(
|
|
8666
|
+
args.conversationId,
|
|
8667
|
+
args.visibility === "private" ? "private" : "public"
|
|
8668
|
+
);
|
|
8669
|
+
}
|
|
8670
|
+
}
|
|
8671
|
+
function hasResourceEventActor(actors) {
|
|
8672
|
+
return Boolean(
|
|
8673
|
+
actors?.some(
|
|
8674
|
+
(actor) => actor.platform === "system" && actor.name === RESOURCE_EVENT_SYSTEM_ACTOR.name
|
|
8675
|
+
)
|
|
8676
|
+
);
|
|
8677
|
+
}
|
|
8678
|
+
async function getActiveConversationTurnId(conversationId) {
|
|
8679
|
+
const summaries = await listTurnSummaries(conversationId);
|
|
8680
|
+
const active = summaries.filter(
|
|
8681
|
+
(summary) => summary.surface === "api" && !summary.dispatchId && (summary.state === "paused" || summary.state === "running")
|
|
8682
|
+
);
|
|
8683
|
+
if (active.length > 1) {
|
|
8684
|
+
throw new Error(
|
|
8685
|
+
`Conversation ${conversationId} has multiple active web turns`
|
|
8686
|
+
);
|
|
8687
|
+
}
|
|
8688
|
+
const turnId = active[0]?.turnId;
|
|
8689
|
+
if (!turnId) return void 0;
|
|
8690
|
+
const record = await getTurnRecord(conversationId, turnId);
|
|
8691
|
+
return record && record.surface === "api" && !record.dispatchId && (record.state === "paused" || record.state === "running") ? turnId : void 0;
|
|
8692
|
+
}
|
|
8693
|
+
async function getActiveMailboxTurnId(conversationId) {
|
|
8694
|
+
const summaries = await listTurnSummaries(conversationId);
|
|
8695
|
+
const active = (await Promise.all(
|
|
8696
|
+
summaries.filter(
|
|
8697
|
+
(summary) => !summary.dispatchId && (summary.state === "paused" || summary.state === "running")
|
|
8698
|
+
).map((summary) => getTurnRecord(conversationId, summary.turnId))
|
|
8699
|
+
)).filter(
|
|
8700
|
+
(record) => record && !record.dispatchId && (record.surface === "api" || hasResourceEventActor(record.actors)) && (record.state === "paused" || record.state === "running")
|
|
8701
|
+
);
|
|
8702
|
+
if (active.length > 1) {
|
|
8703
|
+
throw new Error(
|
|
8704
|
+
`Conversation ${conversationId} has multiple active mailbox Turns`
|
|
8705
|
+
);
|
|
8706
|
+
}
|
|
8707
|
+
return active[0]?.turnId;
|
|
8708
|
+
}
|
|
8709
|
+
async function getAuthPausedConversationTurnId(conversationId) {
|
|
8710
|
+
const turnId = await getActiveConversationTurnId(conversationId);
|
|
8711
|
+
if (!turnId) return void 0;
|
|
8712
|
+
const record = await getTurnRecord(conversationId, turnId);
|
|
8713
|
+
return record?.state === "paused" && record.resumeReason === "auth" ? turnId : void 0;
|
|
8714
|
+
}
|
|
8715
|
+
function parseWebMessages(messages) {
|
|
8716
|
+
if (messages.length === 0) {
|
|
8717
|
+
return [];
|
|
8718
|
+
}
|
|
8719
|
+
const parsed = messages.map((message) => ({
|
|
8720
|
+
message,
|
|
8721
|
+
metadata: legacyWebMailboxMetadataSchema.safeParse(message.input.metadata)
|
|
8722
|
+
}));
|
|
8723
|
+
if (parsed.every((entry) => !entry.metadata.success)) {
|
|
8724
|
+
return [];
|
|
8725
|
+
}
|
|
8726
|
+
if (parsed.some((entry) => !entry.metadata.success)) {
|
|
8727
|
+
throw new Error("A Turn cannot combine different kinds of input");
|
|
8728
|
+
}
|
|
8729
|
+
return parsed.map((entry) => {
|
|
8730
|
+
if (!entry.metadata.success) {
|
|
8731
|
+
throw new Error("User message has invalid metadata");
|
|
8732
|
+
}
|
|
8733
|
+
const metadata = entry.metadata.data;
|
|
8734
|
+
const actor = {
|
|
8735
|
+
platform: "web",
|
|
8736
|
+
userId: metadata.authorUserId,
|
|
8737
|
+
email: metadata.authorEmail.trim().toLowerCase(),
|
|
8738
|
+
...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0,
|
|
8739
|
+
...metadata.authorUserName ? { userName: metadata.authorUserName } : void 0
|
|
8740
|
+
};
|
|
8741
|
+
return {
|
|
8742
|
+
actor,
|
|
8743
|
+
author: {
|
|
8744
|
+
email: actor.email,
|
|
8745
|
+
...actor.fullName ? { fullName: actor.fullName } : void 0,
|
|
8746
|
+
userId: actor.userId,
|
|
8747
|
+
...actor.userName ? { userName: actor.userName } : void 0
|
|
8748
|
+
},
|
|
8749
|
+
message: entry.message,
|
|
8750
|
+
source: "web"
|
|
8751
|
+
};
|
|
8752
|
+
});
|
|
8753
|
+
}
|
|
8754
|
+
function parseResourceEventMessages(messages) {
|
|
8755
|
+
if (messages.length === 0) {
|
|
8756
|
+
return [];
|
|
8757
|
+
}
|
|
8758
|
+
if (!messages.every(
|
|
8759
|
+
(message) => message.source === "resource_event" && isResourceEventMailboxMetadata(message.input.metadata)
|
|
8760
|
+
)) {
|
|
8761
|
+
return [];
|
|
8762
|
+
}
|
|
8763
|
+
return messages.map((message) => {
|
|
8764
|
+
if (!isResourceEventMailboxMetadata(message.input.metadata)) {
|
|
8765
|
+
throw new Error("Resource event has invalid metadata");
|
|
8766
|
+
}
|
|
8767
|
+
return {
|
|
8768
|
+
actor: RESOURCE_EVENT_SYSTEM_ACTOR,
|
|
8769
|
+
author: RESOURCE_EVENT_MESSAGE_AUTHOR,
|
|
8770
|
+
message,
|
|
8771
|
+
source: "resource_event"
|
|
8772
|
+
};
|
|
8773
|
+
});
|
|
8774
|
+
}
|
|
8775
|
+
async function resolveMailboxTurnWork(context) {
|
|
8776
|
+
const batch = parseWebMessages(context.attempt.messages);
|
|
8777
|
+
if (batch.length > 0) {
|
|
8778
|
+
return { kind: "mailbox", batch };
|
|
8779
|
+
}
|
|
8780
|
+
const resourceBatch = parseResourceEventMessages(context.attempt.messages);
|
|
8781
|
+
if (resourceBatch.length > 0) {
|
|
8782
|
+
return { kind: "mailbox", batch: resourceBatch };
|
|
8783
|
+
}
|
|
8784
|
+
if (context.attempt.messages.length > 0) {
|
|
8785
|
+
return void 0;
|
|
8786
|
+
}
|
|
8787
|
+
const turnId = await getActiveMailboxTurnId(context.conversationId);
|
|
8788
|
+
return turnId ? { kind: "resume", turnId } : void 0;
|
|
8789
|
+
}
|
|
8790
|
+
|
|
8791
|
+
// src/chat/task-execution/mailbox-input.ts
|
|
8792
|
+
function joinMailboxText(messages) {
|
|
8793
|
+
return messages.map((message) => message.input.text.trim()).filter(Boolean).join("\n\n");
|
|
8794
|
+
}
|
|
8795
|
+
|
|
8796
|
+
// src/chat/task-execution/conversation-turn.ts
|
|
8797
|
+
function stableHex(...parts) {
|
|
8798
|
+
return createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 24);
|
|
8799
|
+
}
|
|
8800
|
+
function captureConversationTurnFailure(args) {
|
|
8801
|
+
const eventId = logException(
|
|
8802
|
+
args.error,
|
|
8803
|
+
`conversation.turn.${args.failureCode}`,
|
|
8804
|
+
{
|
|
8805
|
+
conversationId: args.conversationId,
|
|
8806
|
+
...args.runId ? { runId: args.runId } : void 0,
|
|
8807
|
+
turnId: args.turnId
|
|
8808
|
+
}
|
|
8809
|
+
);
|
|
8810
|
+
return typeof eventId === "string" ? eventId : void 0;
|
|
8811
|
+
}
|
|
8812
|
+
function hasLostTurnInputCommit(error) {
|
|
8813
|
+
const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
|
|
8814
|
+
return isTurnInputCommitLostError(error) || isTurnInputCommitLostError(cause);
|
|
8815
|
+
}
|
|
8816
|
+
async function completeCancelledConversationTurn(args) {
|
|
8817
|
+
const pendingAuthorization = args.conversation.processing.pendingAuth?.sessionId === args.turnId ? args.conversation.processing.pendingAuth : void 0;
|
|
8818
|
+
await abandonTurnRecord({
|
|
8819
|
+
conversationId: args.conversationId,
|
|
8820
|
+
turnId: args.turnId,
|
|
8821
|
+
errorMessage: "Turn cancelled"
|
|
8822
|
+
});
|
|
8823
|
+
clearPendingAuth(args.conversation, args.turnId);
|
|
8824
|
+
markConversationMessage(args.conversation, args.userMessageId, {
|
|
8825
|
+
replied: false,
|
|
8826
|
+
skippedReason: "turn cancelled"
|
|
8827
|
+
});
|
|
8828
|
+
markTurnClosed({
|
|
8829
|
+
conversation: args.conversation,
|
|
8830
|
+
nowMs: Date.now(),
|
|
8831
|
+
sessionId: args.turnId
|
|
8832
|
+
});
|
|
8833
|
+
if (pendingAuthorization) {
|
|
8834
|
+
await deleteWebAuthorization({
|
|
8835
|
+
actorId: pendingAuthorization.actorId,
|
|
8836
|
+
conversationId: args.conversationId
|
|
8837
|
+
});
|
|
8838
|
+
}
|
|
8839
|
+
await persistThreadStateById(args.conversationId, {
|
|
8840
|
+
conversation: args.conversation,
|
|
8841
|
+
sandboxRef: args.sandboxRef
|
|
8842
|
+
});
|
|
8843
|
+
await new ConversationTurnLifecycleService(
|
|
8844
|
+
getConversationEventStore()
|
|
8845
|
+
).complete({
|
|
8846
|
+
conversationId: args.conversationId,
|
|
8847
|
+
createdAtMs: Date.now(),
|
|
8848
|
+
outcome: "cancelled",
|
|
8849
|
+
turnId: args.turnId
|
|
8850
|
+
});
|
|
8851
|
+
await args.acknowledge();
|
|
8852
|
+
}
|
|
8853
|
+
function createConversationTurnWorker(agentRunner, publishMessage) {
|
|
8854
|
+
return async (context, resolved) => {
|
|
8855
|
+
const lifecycle = new ConversationTurnLifecycleService(
|
|
8856
|
+
getConversationEventStore()
|
|
8857
|
+
);
|
|
8858
|
+
const isResume = resolved.kind === "resume";
|
|
8859
|
+
let turnInputFacts;
|
|
8860
|
+
let text = "";
|
|
8861
|
+
let turnId = "";
|
|
8862
|
+
let userMessageId = "";
|
|
8863
|
+
let startedAtMs = Date.now();
|
|
8864
|
+
let inputMessageIds = [];
|
|
8865
|
+
const storedConversation = await getConversationStore().get({
|
|
8866
|
+
conversationId: context.conversationId
|
|
8867
|
+
});
|
|
8868
|
+
const mailboxDestination = resolved.kind === "mailbox" ? resolved.batch[0]?.message.destination : void 0;
|
|
8869
|
+
const destination = resolveConversationDestination({
|
|
8870
|
+
conversationId: context.conversationId,
|
|
8871
|
+
existing: context.destination ?? mailboxDestination ?? storedConversation?.destination
|
|
8872
|
+
});
|
|
8873
|
+
if (resolved.kind === "mailbox") {
|
|
8874
|
+
const first = resolved.batch[0];
|
|
8875
|
+
text = joinMailboxText(resolved.batch.map((entry) => entry.message));
|
|
8876
|
+
startedAtMs = first.message.createdAtMs;
|
|
8877
|
+
userMessageId = first.message.inboundMessageId;
|
|
8878
|
+
turnId = buildDeterministicTurnId(userMessageId);
|
|
8879
|
+
inputMessageIds = resolved.batch.map(
|
|
8880
|
+
(entry) => entry.message.inboundMessageId
|
|
8881
|
+
);
|
|
8882
|
+
turnInputFacts = first;
|
|
8883
|
+
} else {
|
|
8884
|
+
turnId = resolved.turnId;
|
|
8885
|
+
}
|
|
8886
|
+
const persisted = await getPersistedThreadState(context.conversationId);
|
|
8887
|
+
const conversation = coerceThreadConversationState(persisted);
|
|
8888
|
+
await hydrateConversationMessages({
|
|
8889
|
+
conversation,
|
|
8890
|
+
conversationId: context.conversationId
|
|
8891
|
+
});
|
|
8892
|
+
if (isResume) {
|
|
8893
|
+
const userMessage = getTurnUserMessage(conversation, turnId);
|
|
8894
|
+
if (!userMessage) {
|
|
8895
|
+
throw new Error(
|
|
8896
|
+
`Unable to locate the persisted user message for Turn "${turnId}"`
|
|
8897
|
+
);
|
|
8898
|
+
}
|
|
8899
|
+
turnInputFacts = turnInputFactsFromConversationMessage(userMessage);
|
|
8900
|
+
userMessageId = userMessage.id;
|
|
8901
|
+
text = userMessage.text;
|
|
8902
|
+
startedAtMs = userMessage.createdAtMs;
|
|
8903
|
+
inputMessageIds = [userMessageId];
|
|
8904
|
+
}
|
|
8905
|
+
if (!turnInputFacts) {
|
|
8906
|
+
throw new Error(
|
|
8907
|
+
`Resumed Turn is missing an Actor for Conversation ${context.conversationId}`
|
|
8908
|
+
);
|
|
8909
|
+
}
|
|
8910
|
+
const { actor, author } = turnInputFacts;
|
|
8911
|
+
const source = sourceFromTurnInput({
|
|
8912
|
+
conversationId: context.conversationId,
|
|
8913
|
+
location: storedConversation?.location,
|
|
8914
|
+
source: turnInputFacts.source,
|
|
8915
|
+
visibility: storedConversation?.visibility
|
|
8916
|
+
});
|
|
8917
|
+
const webActor = actor.platform === "web" ? actor : void 0;
|
|
8918
|
+
const savedTurn = isResume ? await getTurnRecord(context.conversationId, turnId) : void 0;
|
|
8919
|
+
const publish = turnInputFacts.source === "resource_event" && storedConversation?.location ? savedTurn?.publishExternally ?? true : false;
|
|
8920
|
+
const surface = publish ? "slack" : "api";
|
|
8921
|
+
return await withLogContext(
|
|
8922
|
+
{
|
|
8923
|
+
conversationId: context.conversationId,
|
|
8924
|
+
platform: actor.platform,
|
|
8925
|
+
...webActor ? {
|
|
8926
|
+
userId: webActor.userId,
|
|
8927
|
+
...webActor.userName ? { userName: webActor.userName } : void 0
|
|
8928
|
+
} : void 0
|
|
8929
|
+
},
|
|
8930
|
+
async () => {
|
|
8931
|
+
let acknowledged = isResume || context.attempt.messages.length === 0;
|
|
8932
|
+
const acknowledge = async () => {
|
|
8933
|
+
if (acknowledged) {
|
|
8934
|
+
return;
|
|
8935
|
+
}
|
|
8936
|
+
try {
|
|
8937
|
+
await context.attempt.ack();
|
|
8938
|
+
} catch {
|
|
8939
|
+
throw new TurnInputCommitLostError(
|
|
8940
|
+
`Conversation work lease lost before mailbox Message acknowledgement for ${context.conversationId}`
|
|
8941
|
+
);
|
|
8942
|
+
}
|
|
8943
|
+
acknowledged = true;
|
|
8944
|
+
};
|
|
8945
|
+
let sandboxRef = getPersistedSandboxState(persisted);
|
|
8946
|
+
const initialSandboxRef = sandboxRef;
|
|
8947
|
+
const stopSignal = context.stopSignal?.();
|
|
8948
|
+
const completeCancelledTurn = async () => {
|
|
8949
|
+
try {
|
|
8950
|
+
await completeCancelledConversationTurn({
|
|
8951
|
+
acknowledge,
|
|
8952
|
+
conversation,
|
|
8953
|
+
conversationId: context.conversationId,
|
|
8954
|
+
sandboxRef,
|
|
8955
|
+
turnId,
|
|
8956
|
+
userMessageId
|
|
8957
|
+
});
|
|
8958
|
+
} catch (error) {
|
|
8959
|
+
if (hasLostTurnInputCommit(error)) {
|
|
8960
|
+
return { status: "lost_lease" };
|
|
8961
|
+
}
|
|
8962
|
+
throw error;
|
|
8963
|
+
}
|
|
8964
|
+
return { status: "completed" };
|
|
8965
|
+
};
|
|
8966
|
+
if (isResume) {
|
|
8967
|
+
if (stopSignal?.aborted) {
|
|
8968
|
+
return await completeCancelledTurn();
|
|
8969
|
+
}
|
|
8970
|
+
} else {
|
|
8971
|
+
upsertConversationMessage(conversation, {
|
|
8972
|
+
id: userMessageId,
|
|
8973
|
+
role: "user",
|
|
8974
|
+
text: normalizeConversationText(text),
|
|
8975
|
+
createdAtMs: startedAtMs,
|
|
8976
|
+
author,
|
|
8977
|
+
meta: {
|
|
8978
|
+
explicitMention: true,
|
|
8979
|
+
replied: false,
|
|
8980
|
+
...turnInputFacts.source === "web" ? { source: "web" } : void 0
|
|
8981
|
+
}
|
|
8982
|
+
});
|
|
8983
|
+
await persistConversationMessages({
|
|
8984
|
+
conversation,
|
|
8985
|
+
conversationId: context.conversationId
|
|
8986
|
+
});
|
|
8987
|
+
await lifecycle.start({
|
|
8988
|
+
conversationId: context.conversationId,
|
|
8989
|
+
createdAtMs: Date.now(),
|
|
8990
|
+
inputMessageIds,
|
|
8991
|
+
surface,
|
|
8992
|
+
turnId
|
|
8993
|
+
});
|
|
8994
|
+
if (stopSignal?.aborted) {
|
|
8995
|
+
return await completeCancelledTurn();
|
|
8996
|
+
}
|
|
8997
|
+
startActiveTurn({
|
|
8998
|
+
conversation,
|
|
8999
|
+
nextTurnId: turnId
|
|
9000
|
+
});
|
|
9001
|
+
}
|
|
9002
|
+
let currentRunId;
|
|
9003
|
+
let assistantMessageDelivered = false;
|
|
9004
|
+
let failureCode = "persistence_failed";
|
|
9005
|
+
let modelFailureEventId;
|
|
9006
|
+
let modelFailureCaptureAttempted = false;
|
|
9007
|
+
let completedSuccessfully = false;
|
|
9008
|
+
const deliverAssistantMessage = async (value) => {
|
|
9009
|
+
const agentMessage = typeof value === "string" ? void 0 : value;
|
|
9010
|
+
const replyText = typeof value === "string" ? value : getAssistantReplyText(value);
|
|
9011
|
+
if (!replyText?.trim()) {
|
|
9012
|
+
return;
|
|
9013
|
+
}
|
|
9014
|
+
failureCode = "delivery_failed";
|
|
9015
|
+
const location = storedConversation?.location;
|
|
9016
|
+
if (publish && (!location || !publishMessage)) {
|
|
9017
|
+
throw new Error(
|
|
9018
|
+
`Conversation ${context.conversationId} cannot publish its system Turn`
|
|
9019
|
+
);
|
|
9020
|
+
}
|
|
9021
|
+
const publishedMessage = publish && location && publishMessage ? await publishMessage({
|
|
9022
|
+
conversationId: context.conversationId,
|
|
9023
|
+
location,
|
|
9024
|
+
text: replyText
|
|
9025
|
+
}) : void 0;
|
|
9026
|
+
await commitAssistantMessage({
|
|
9027
|
+
...agentMessage ? { agentMessage } : void 0,
|
|
9028
|
+
conversation,
|
|
9029
|
+
conversationId: context.conversationId,
|
|
9030
|
+
...publishedMessage ? { publishedMessage } : void 0,
|
|
9031
|
+
sessionId: turnId,
|
|
9032
|
+
...publishedMessage ? { source: "slack" } : turnInputFacts.source === "web" ? { source: "web" } : void 0,
|
|
9033
|
+
text: replyText,
|
|
9034
|
+
userMessageId
|
|
9035
|
+
});
|
|
9036
|
+
assistantMessageDelivered = true;
|
|
9037
|
+
failureCode = "agent_run_failed";
|
|
9038
|
+
};
|
|
9039
|
+
try {
|
|
9040
|
+
if (stopSignal?.aborted) {
|
|
9041
|
+
return await completeCancelledTurn();
|
|
9042
|
+
}
|
|
9043
|
+
if (!isResume) {
|
|
9044
|
+
const pendingAuthorizationActorId = conversation.processing.pendingAuth?.actorId;
|
|
9045
|
+
const authParked = (await listTurnSummaries(context.conversationId)).filter(
|
|
9046
|
+
(summary) => summary.surface === "api" && !summary.dispatchId && summary.state === "paused" && summary.resumeReason === "auth"
|
|
9047
|
+
);
|
|
9048
|
+
for (const parked of authParked) {
|
|
9049
|
+
if (stopSignal?.aborted) {
|
|
9050
|
+
return await completeCancelledTurn();
|
|
9051
|
+
}
|
|
9052
|
+
await abandonTurnRecord({
|
|
9053
|
+
conversationId: context.conversationId,
|
|
9054
|
+
turnId: parked.turnId,
|
|
9055
|
+
errorMessage: "Auth-paused Turn superseded by new input"
|
|
9056
|
+
});
|
|
9057
|
+
markTurnClosed({
|
|
9058
|
+
conversation,
|
|
9059
|
+
nowMs: Date.now(),
|
|
9060
|
+
sessionId: parked.turnId
|
|
9061
|
+
});
|
|
9062
|
+
}
|
|
9063
|
+
if (authParked.length > 0 && pendingAuthorizationActorId) {
|
|
9064
|
+
await deleteWebAuthorization({
|
|
9065
|
+
actorId: pendingAuthorizationActorId,
|
|
9066
|
+
conversationId: context.conversationId
|
|
9067
|
+
});
|
|
9068
|
+
}
|
|
9069
|
+
}
|
|
9070
|
+
await persistThreadStateById(context.conversationId, {
|
|
9071
|
+
conversation
|
|
9072
|
+
});
|
|
9073
|
+
if (stopSignal?.aborted) {
|
|
9074
|
+
return await completeCancelledTurn();
|
|
9075
|
+
}
|
|
9076
|
+
const piMessages = await loadProjection({
|
|
9077
|
+
conversationId: context.conversationId
|
|
9078
|
+
});
|
|
9079
|
+
failureCode = "agent_run_failed";
|
|
9080
|
+
currentRunId = `conversation-run:${stableHex(turnId, String(startedAtMs))}`;
|
|
9081
|
+
setTags({ runId: currentRunId });
|
|
9082
|
+
const outcome = await executeTurn(
|
|
9083
|
+
agentRunner,
|
|
9084
|
+
{
|
|
9085
|
+
conversationId: context.conversationId,
|
|
9086
|
+
turnId,
|
|
9087
|
+
runId: currentRunId,
|
|
9088
|
+
instruction: {
|
|
9089
|
+
text,
|
|
9090
|
+
context: buildConversationContext(conversation, {
|
|
9091
|
+
excludeMessageId: userMessageId
|
|
9092
|
+
})
|
|
9093
|
+
},
|
|
9094
|
+
history: piMessages,
|
|
9095
|
+
actor,
|
|
9096
|
+
credentialContext: credentialContextForActor(actor),
|
|
9097
|
+
// TODO(dcramer): Remove AgentRun.destination after agent and tool
|
|
9098
|
+
// code reads AgentRun.location and no Run consumer needs it.
|
|
9099
|
+
destination,
|
|
9100
|
+
// TODO(dcramer): Remove AgentRun.publishExternally after the
|
|
9101
|
+
// saved Turn publish choice controls optional Delivery.
|
|
9102
|
+
publishExternally: publish,
|
|
9103
|
+
source,
|
|
9104
|
+
...storedConversation?.location ? { location: storedConversation.location } : void 0,
|
|
9105
|
+
surface,
|
|
9106
|
+
...stopSignal ? { signal: stopSignal } : void 0,
|
|
9107
|
+
...webActor ? {
|
|
9108
|
+
authorization: createWebAuthorization({
|
|
9109
|
+
actorId: webActor.userId,
|
|
9110
|
+
conversationId: context.conversationId
|
|
9111
|
+
})
|
|
9112
|
+
} : { disabledFeatures: ["interactive-auth"] },
|
|
9113
|
+
state: {
|
|
9114
|
+
pendingAuth: conversation.processing.pendingAuth,
|
|
9115
|
+
sandboxRef
|
|
9116
|
+
},
|
|
9117
|
+
delivery: deliverAssistantMessage,
|
|
9118
|
+
durability: {
|
|
9119
|
+
onInputCommitted: acknowledge,
|
|
9120
|
+
shouldYield: context.shouldYield,
|
|
9121
|
+
onSandboxRefChanged: async (nextSandboxRef) => {
|
|
9122
|
+
sandboxRef = nextSandboxRef;
|
|
9123
|
+
await persistThreadStateById(context.conversationId, {
|
|
9124
|
+
conversation,
|
|
9125
|
+
sandboxRef
|
|
9126
|
+
});
|
|
9127
|
+
},
|
|
9128
|
+
recordPendingAuth: async (pendingAuth) => {
|
|
9129
|
+
conversation.processing.pendingAuth = pendingAuth;
|
|
9130
|
+
await persistThreadStateById(context.conversationId, {
|
|
9131
|
+
conversation,
|
|
9132
|
+
sandboxRef
|
|
9133
|
+
});
|
|
9134
|
+
}
|
|
9135
|
+
}
|
|
9136
|
+
},
|
|
9137
|
+
async (result) => {
|
|
9138
|
+
if (stopSignal?.aborted) {
|
|
9139
|
+
throw stopSignal.reason ?? new DOMException("Turn cancelled", "AbortError");
|
|
9140
|
+
}
|
|
9141
|
+
modelFailureCaptureAttempted = result.diagnostics.outcome !== "success";
|
|
9142
|
+
const finalized = finalizeFailedTurnReplyWithEvent({
|
|
9143
|
+
reply: result,
|
|
9144
|
+
logException
|
|
9145
|
+
});
|
|
9146
|
+
const modelFailureReason = finalized.failureReason;
|
|
9147
|
+
const reply = finalized.reply;
|
|
9148
|
+
modelFailureEventId = finalized.eventId;
|
|
9149
|
+
if (reply.diagnostics.outcome !== "success") {
|
|
9150
|
+
await deliverAssistantMessage(reply.text);
|
|
9151
|
+
}
|
|
9152
|
+
const completedState = buildDeliveredTurnStatePatch({
|
|
9153
|
+
conversation,
|
|
9154
|
+
reply,
|
|
9155
|
+
sessionId: turnId,
|
|
9156
|
+
userMessageId
|
|
9157
|
+
});
|
|
9158
|
+
await persistThreadStateById(context.conversationId, {
|
|
9159
|
+
conversation: completedState.conversation,
|
|
9160
|
+
sandboxRef: reply.sandboxRef ?? sandboxRef
|
|
9161
|
+
});
|
|
9162
|
+
if (reply.piMessages?.length) {
|
|
9163
|
+
const latest = await getTurnRecord(
|
|
9164
|
+
context.conversationId,
|
|
9165
|
+
turnId
|
|
9166
|
+
);
|
|
9167
|
+
await saveTurnCheckpoint({
|
|
9168
|
+
mode: "completed",
|
|
9169
|
+
conversationId: context.conversationId,
|
|
9170
|
+
turnId,
|
|
9171
|
+
sliceId: latest?.sliceId ?? 1,
|
|
9172
|
+
messages: reply.piMessages,
|
|
9173
|
+
durationMs: reply.diagnostics.durationMs,
|
|
9174
|
+
usage: reply.diagnostics.usage,
|
|
9175
|
+
// TODO(dcramer): Remove checkpoint Destination after resume
|
|
9176
|
+
// reads the Conversation Location.
|
|
9177
|
+
destination,
|
|
9178
|
+
publishExternally: publish,
|
|
9179
|
+
source,
|
|
9180
|
+
actor,
|
|
9181
|
+
surface
|
|
9182
|
+
});
|
|
9183
|
+
}
|
|
9184
|
+
completedSuccessfully = reply.diagnostics.outcome === "success";
|
|
9185
|
+
return completedSuccessfully ? {
|
|
9186
|
+
outcome: assistantMessageDelivered ? "success" : "no_reply"
|
|
9187
|
+
} : {
|
|
9188
|
+
...modelFailureEventId ? { eventId: modelFailureEventId } : void 0,
|
|
9189
|
+
failureCode: "model_execution_failed",
|
|
9190
|
+
...modelFailureReason ? { failureReason: modelFailureReason } : void 0,
|
|
9191
|
+
outcome: "failed"
|
|
9192
|
+
};
|
|
9193
|
+
}
|
|
9194
|
+
);
|
|
9195
|
+
if (outcome.status !== "completed" && stopSignal?.aborted) {
|
|
9196
|
+
return await completeCancelledTurn();
|
|
9197
|
+
}
|
|
9198
|
+
if (outcome.status === "suspended") {
|
|
9199
|
+
return { status: "yielded" };
|
|
9200
|
+
}
|
|
9201
|
+
if (outcome.status === "awaiting_auth") {
|
|
9202
|
+
completeAuthPauseTurn({
|
|
9203
|
+
conversation,
|
|
9204
|
+
sessionId: turnId
|
|
9205
|
+
});
|
|
9206
|
+
await persistThreadStateById(context.conversationId, {
|
|
9207
|
+
conversation,
|
|
9208
|
+
sandboxRef
|
|
9209
|
+
});
|
|
9210
|
+
await acknowledge();
|
|
9211
|
+
return { status: "paused" };
|
|
9212
|
+
}
|
|
9213
|
+
if (completedSuccessfully) {
|
|
9214
|
+
try {
|
|
9215
|
+
await scheduleSessionCompletedPluginTasks(
|
|
9216
|
+
{
|
|
9217
|
+
conversationId: context.conversationId,
|
|
9218
|
+
sessionId: turnId
|
|
9219
|
+
},
|
|
9220
|
+
{
|
|
9221
|
+
send: async (message) => {
|
|
9222
|
+
try {
|
|
9223
|
+
await processPluginTask(message);
|
|
9224
|
+
} catch (error) {
|
|
9225
|
+
logException(
|
|
9226
|
+
error,
|
|
9227
|
+
"conversation.plugin.session_completion_task.failed",
|
|
9228
|
+
{
|
|
9229
|
+
conversationId: context.conversationId,
|
|
9230
|
+
pluginName: message.plugin,
|
|
9231
|
+
taskName: message.name,
|
|
9232
|
+
turnId
|
|
9233
|
+
}
|
|
9234
|
+
);
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
}
|
|
9238
|
+
);
|
|
9239
|
+
} catch (error) {
|
|
9240
|
+
logException(
|
|
9241
|
+
error,
|
|
9242
|
+
"conversation.plugin.session_completion_task.failed",
|
|
9243
|
+
{
|
|
9244
|
+
conversationId: context.conversationId,
|
|
9245
|
+
turnId
|
|
9246
|
+
}
|
|
9247
|
+
);
|
|
9248
|
+
}
|
|
9249
|
+
}
|
|
9250
|
+
await acknowledge();
|
|
9251
|
+
return { status: "completed" };
|
|
9252
|
+
} catch (error) {
|
|
9253
|
+
const failure = error instanceof AgentRunError ? error.cause : error;
|
|
9254
|
+
if (hasLostTurnInputCommit(failure)) {
|
|
9255
|
+
return { status: "lost_lease" };
|
|
9256
|
+
}
|
|
9257
|
+
if (stopSignal?.aborted) {
|
|
9258
|
+
return await completeCancelledTurn();
|
|
9259
|
+
}
|
|
9260
|
+
if (!context.attempt.isFinalAttempt) {
|
|
9261
|
+
throw failure;
|
|
9262
|
+
}
|
|
9263
|
+
const failureEventId = modelFailureCaptureAttempted && failureCode === "agent_run_failed" ? modelFailureEventId : captureConversationTurnFailure({
|
|
9264
|
+
conversationId: context.conversationId,
|
|
9265
|
+
error: failure,
|
|
9266
|
+
failureCode,
|
|
9267
|
+
runId: currentRunId,
|
|
9268
|
+
turnId
|
|
9269
|
+
});
|
|
9270
|
+
try {
|
|
9271
|
+
markTurnFailed({
|
|
9272
|
+
conversation,
|
|
9273
|
+
nowMs: Date.now(),
|
|
9274
|
+
sessionId: turnId,
|
|
9275
|
+
userMessageId,
|
|
9276
|
+
markConversationMessage
|
|
9277
|
+
});
|
|
9278
|
+
await persistThreadStateById(context.conversationId, {
|
|
9279
|
+
conversation,
|
|
9280
|
+
sandboxRef: initialSandboxRef ?? null
|
|
9281
|
+
});
|
|
9282
|
+
} catch (persistenceError) {
|
|
9283
|
+
captureConversationTurnFailure({
|
|
9284
|
+
conversationId: context.conversationId,
|
|
9285
|
+
error: persistenceError,
|
|
9286
|
+
failureCode: "persistence_failed",
|
|
9287
|
+
runId: currentRunId,
|
|
9288
|
+
turnId
|
|
9289
|
+
});
|
|
9290
|
+
}
|
|
9291
|
+
await lifecycle.fail({
|
|
9292
|
+
conversationId: context.conversationId,
|
|
9293
|
+
createdAtMs: Date.now(),
|
|
9294
|
+
...failureEventId ? { eventId: failureEventId } : void 0,
|
|
9295
|
+
failureCode,
|
|
9296
|
+
turnId
|
|
9297
|
+
});
|
|
9298
|
+
await acknowledge();
|
|
9299
|
+
return { status: "completed" };
|
|
9300
|
+
}
|
|
9301
|
+
}
|
|
9302
|
+
);
|
|
9303
|
+
};
|
|
9304
|
+
}
|
|
9305
|
+
|
|
9306
|
+
// src/chat/providers/slack/system-turn.ts
|
|
9307
|
+
function createSlackSystemTurnPublisher(args) {
|
|
9308
|
+
return async ({ conversationId, location, text }) => {
|
|
9309
|
+
if (location.provider !== "slack") {
|
|
9310
|
+
throw new Error(
|
|
9311
|
+
`Slack system Turn cannot publish to ${location.provider} Location`
|
|
9312
|
+
);
|
|
9313
|
+
}
|
|
9314
|
+
let messageIds;
|
|
9315
|
+
try {
|
|
9316
|
+
messageIds = await runWithSlackInstallation({
|
|
9317
|
+
adapter: args.getSlackAdapter(),
|
|
9318
|
+
installation: { teamId: location.teamId },
|
|
9319
|
+
state: args.state,
|
|
9320
|
+
task: async () => await sendSlackReply({
|
|
9321
|
+
channelId: location.channelId,
|
|
9322
|
+
conversationId,
|
|
9323
|
+
text,
|
|
9324
|
+
...location.threadTs ? { threadTs: location.threadTs } : void 0
|
|
9325
|
+
})
|
|
9326
|
+
});
|
|
9327
|
+
} catch (error) {
|
|
9328
|
+
if (isRetryableSlackPostError(error)) {
|
|
9329
|
+
throw new RetryableDeliveryError(error);
|
|
9330
|
+
}
|
|
9331
|
+
throw error;
|
|
9332
|
+
}
|
|
9333
|
+
const providerMessageId = messageIds.at(-1);
|
|
9334
|
+
const providerConversationId = location.threadTs ?? messageIds[0];
|
|
9335
|
+
return {
|
|
9336
|
+
...providerMessageId ? { providerMessageId } : void 0,
|
|
9337
|
+
...providerConversationId ? {
|
|
9338
|
+
providerConversationBindings: [
|
|
9339
|
+
{
|
|
9340
|
+
provider: "slack",
|
|
9341
|
+
providerDestinationId: location.channelId,
|
|
9342
|
+
providerTenantId: location.teamId,
|
|
9343
|
+
providerConversationId
|
|
9344
|
+
}
|
|
9345
|
+
]
|
|
9346
|
+
} : void 0
|
|
9347
|
+
};
|
|
9348
|
+
};
|
|
9349
|
+
}
|
|
9350
|
+
|
|
8712
9351
|
// src/chat/app/conversation-work.ts
|
|
8713
9352
|
function createConversationWork(options) {
|
|
8714
|
-
const apiTurnCancellation = createApiTurnCancellation();
|
|
8715
9353
|
const pausedTurns = createPausedTurns({
|
|
8716
9354
|
conversationStore: options.conversationStore,
|
|
8717
9355
|
queue: options.queue,
|
|
8718
9356
|
...options.state ? { state: options.state } : void 0
|
|
8719
9357
|
});
|
|
8720
|
-
const
|
|
9358
|
+
const baseRuntime = createSlackRuntime({
|
|
8721
9359
|
getSlackAdapter: options.getSlackAdapter,
|
|
8722
9360
|
pausedTurns,
|
|
9361
|
+
...options.sendPluginTask ? { sendPluginTask: options.sendPluginTask } : void 0,
|
|
8723
9362
|
services: {
|
|
8724
9363
|
...options.services,
|
|
8725
9364
|
agentRunner: options.agentRunner
|
|
8726
9365
|
}
|
|
8727
9366
|
});
|
|
9367
|
+
const runtime = options.wrapRuntime?.(baseRuntime) ?? baseRuntime;
|
|
9368
|
+
const scheduleCompletedPluginTasks = options.sendPluginTask ? async (params) => await scheduleSessionCompletedPluginTasks(params, {
|
|
9369
|
+
send: options.sendPluginTask
|
|
9370
|
+
}) : void 0;
|
|
8728
9371
|
const slackWorker = createSlackConversationWorker({
|
|
8729
9372
|
getSlackAdapter: options.getSlackAdapter,
|
|
8730
|
-
conversationStore: options.conversationStore,
|
|
8731
9373
|
runNextPausedTurn: async (conversationId, runOptions) => await runNextPausedTurn(
|
|
8732
9374
|
conversationId,
|
|
8733
9375
|
{
|
|
8734
9376
|
agentRunner: options.agentRunner,
|
|
8735
|
-
wakePausedTurn: pausedTurns.wake
|
|
9377
|
+
wakePausedTurn: pausedTurns.wake,
|
|
9378
|
+
...scheduleCompletedPluginTasks ? {
|
|
9379
|
+
scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
|
|
9380
|
+
} : void 0
|
|
8736
9381
|
},
|
|
8737
9382
|
runOptions
|
|
8738
9383
|
),
|
|
@@ -8747,13 +9392,24 @@ function createConversationWork(options) {
|
|
|
8747
9392
|
agentRunner: options.agentRunner,
|
|
8748
9393
|
inputMessageIds: [getDispatchInputMessageId(dispatch2.id)],
|
|
8749
9394
|
routingContext: buildDispatchRoutingContext(dispatch2),
|
|
8750
|
-
wakePausedTurn: pausedTurns.wake
|
|
9395
|
+
wakePausedTurn: pausedTurns.wake,
|
|
9396
|
+
...scheduleCompletedPluginTasks ? {
|
|
9397
|
+
scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
|
|
9398
|
+
} : void 0
|
|
8751
9399
|
},
|
|
8752
9400
|
{ shouldYield: hooks.shouldYield }
|
|
8753
9401
|
);
|
|
8754
9402
|
},
|
|
8755
9403
|
runTurn: runtime.runDispatchTurn
|
|
8756
9404
|
});
|
|
9405
|
+
const invocationWorker = createAgentInvocationWorker(options.agentRunner);
|
|
9406
|
+
const conversationTurnWorker = createConversationTurnWorker(
|
|
9407
|
+
options.agentRunner,
|
|
9408
|
+
createSlackSystemTurnPublisher({
|
|
9409
|
+
getSlackAdapter: options.getSlackAdapter,
|
|
9410
|
+
state: options.state
|
|
9411
|
+
})
|
|
9412
|
+
);
|
|
8757
9413
|
const destinationWorker = async (context) => {
|
|
8758
9414
|
const destination = context.destination;
|
|
8759
9415
|
if (!destination) {
|
|
@@ -8768,24 +9424,25 @@ function createConversationWork(options) {
|
|
|
8768
9424
|
`Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`
|
|
8769
9425
|
);
|
|
8770
9426
|
};
|
|
8771
|
-
const
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
9427
|
+
const run = async (context) => {
|
|
9428
|
+
const mailboxTurn = await resolveMailboxTurnWork(context);
|
|
9429
|
+
if (mailboxTurn) {
|
|
9430
|
+
return await conversationTurnWorker(context, mailboxTurn);
|
|
9431
|
+
}
|
|
9432
|
+
const invocationId = await resolveAgentInvocationId(context);
|
|
9433
|
+
if (invocationId) {
|
|
9434
|
+
return await invocationWorker(context, invocationId);
|
|
9435
|
+
}
|
|
9436
|
+
const dispatchId = await resolveAgentDispatchId(context);
|
|
9437
|
+
if (dispatchId) {
|
|
9438
|
+
return await dispatchWorker(context, dispatchId);
|
|
9439
|
+
}
|
|
9440
|
+
return await destinationWorker(context);
|
|
9441
|
+
};
|
|
8775
9442
|
return {
|
|
8776
|
-
apiTurnCancellation,
|
|
8777
9443
|
conversationStore: options.conversationStore,
|
|
8778
9444
|
queue: options.queue,
|
|
8779
|
-
run
|
|
8780
|
-
apiTurnWorker: createApiTurnWorker(
|
|
8781
|
-
options.agentRunner,
|
|
8782
|
-
apiTurnCancellation
|
|
8783
|
-
),
|
|
8784
|
-
fallbackWorker: routeAgentInvocationWork({
|
|
8785
|
-
invocationWorker: createAgentInvocationWorker(options.agentRunner),
|
|
8786
|
-
fallbackWorker: providerWorker
|
|
8787
|
-
})
|
|
8788
|
-
}),
|
|
9445
|
+
run,
|
|
8789
9446
|
runtime,
|
|
8790
9447
|
state: options.state
|
|
8791
9448
|
};
|
|
@@ -8865,7 +9522,7 @@ async function publicArtifactGET(args) {
|
|
|
8865
9522
|
}
|
|
8866
9523
|
|
|
8867
9524
|
// src/chat/event-tasks/ingest.ts
|
|
8868
|
-
import { createHash } from "crypto";
|
|
9525
|
+
import { createHash as createHash2 } from "crypto";
|
|
8869
9526
|
import {
|
|
8870
9527
|
createSlackSource as createSlackSource3,
|
|
8871
9528
|
RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
|
|
@@ -8873,7 +9530,7 @@ import {
|
|
|
8873
9530
|
resourceEventSchema
|
|
8874
9531
|
} from "@sentry/junior-plugin-api";
|
|
8875
9532
|
function eventTaskDispatchKey(taskId, namespace, eventKey) {
|
|
8876
|
-
return `event-task:${
|
|
9533
|
+
return `event-task:${createHash2("sha256").update(`${taskId}\0${namespace}\0${eventKey}`).digest("hex").slice(0, 32)}`;
|
|
8877
9534
|
}
|
|
8878
9535
|
function oneLine(value) {
|
|
8879
9536
|
return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 512);
|
|
@@ -9014,8 +9671,8 @@ function createResourceEventAppPublisher(args) {
|
|
|
9014
9671
|
};
|
|
9015
9672
|
}
|
|
9016
9673
|
|
|
9017
|
-
// src/chat/
|
|
9018
|
-
async function
|
|
9674
|
+
// src/chat/conversations/stop.ts
|
|
9675
|
+
async function stopConversationTurn(args) {
|
|
9019
9676
|
const nowMs = args.nowMs ?? Date.now();
|
|
9020
9677
|
const stop = async () => await stopConversationWork({
|
|
9021
9678
|
conversationId: args.conversationId,
|
|
@@ -9024,7 +9681,7 @@ async function stopApiConversationTurn(args) {
|
|
|
9024
9681
|
state: args.state
|
|
9025
9682
|
});
|
|
9026
9683
|
let result = await stop();
|
|
9027
|
-
if (result.status === "no_work" && await
|
|
9684
|
+
if (result.status === "no_work" && await getAuthPausedConversationTurnId(args.conversationId)) {
|
|
9028
9685
|
const conversation = await getConversation({
|
|
9029
9686
|
conversationId: args.conversationId,
|
|
9030
9687
|
state: args.state
|
|
@@ -9042,7 +9699,7 @@ async function stopApiConversationTurn(args) {
|
|
|
9042
9699
|
await ensureConversationWake({
|
|
9043
9700
|
conversationId: args.conversationId,
|
|
9044
9701
|
conversationStore: args.conversationStore,
|
|
9045
|
-
idempotencyKey: `
|
|
9702
|
+
idempotencyKey: `conversation-stop:${args.conversationId}:${result.runId}`,
|
|
9046
9703
|
nowMs,
|
|
9047
9704
|
queue: args.queue,
|
|
9048
9705
|
replaceExistingWake: true,
|
|
@@ -9096,7 +9753,7 @@ function createAcpConversations(options) {
|
|
|
9096
9753
|
if (!await hasConversationAccess(conversationId, user)) {
|
|
9097
9754
|
return "not_found";
|
|
9098
9755
|
}
|
|
9099
|
-
await
|
|
9756
|
+
await stopConversationTurn({
|
|
9100
9757
|
conversationId,
|
|
9101
9758
|
conversationStore: options.conversationStore,
|
|
9102
9759
|
queue: options.queue,
|
|
@@ -9105,7 +9762,7 @@ function createAcpConversations(options) {
|
|
|
9105
9762
|
return "cancelled";
|
|
9106
9763
|
},
|
|
9107
9764
|
async create({ conversationId, user }) {
|
|
9108
|
-
await
|
|
9765
|
+
await recordWebConversationActivity({
|
|
9109
9766
|
actor: actorFromUser(user),
|
|
9110
9767
|
conversationId,
|
|
9111
9768
|
conversationStore: options.conversationStore,
|
|
@@ -9124,10 +9781,10 @@ function createAcpConversations(options) {
|
|
|
9124
9781
|
options.eventStore,
|
|
9125
9782
|
conversationId
|
|
9126
9783
|
);
|
|
9127
|
-
if (await
|
|
9784
|
+
if (await getAuthPausedConversationTurnId(conversationId)) {
|
|
9128
9785
|
return { status: "active" };
|
|
9129
9786
|
}
|
|
9130
|
-
const
|
|
9787
|
+
const result = await appendAndEnqueueWebMessage(
|
|
9131
9788
|
{
|
|
9132
9789
|
actor: actorFromUser(user),
|
|
9133
9790
|
conversationId,
|
|
@@ -9141,12 +9798,12 @@ function createAcpConversations(options) {
|
|
|
9141
9798
|
state: options.state
|
|
9142
9799
|
}
|
|
9143
9800
|
);
|
|
9144
|
-
if (
|
|
9801
|
+
if (result.status === "active") return { status: "active" };
|
|
9145
9802
|
return {
|
|
9146
|
-
afterCursor:
|
|
9147
|
-
messageId:
|
|
9803
|
+
afterCursor: result.status === "duplicate" ? 0 : currentCursor,
|
|
9804
|
+
messageId: result.messageId,
|
|
9148
9805
|
status: "accepted",
|
|
9149
|
-
turnId:
|
|
9806
|
+
turnId: conversationTurnIdForMessage(result.messageId)
|
|
9150
9807
|
};
|
|
9151
9808
|
},
|
|
9152
9809
|
async readMessages(conversationId) {
|
|
@@ -9204,12 +9861,12 @@ function createAcpConversations(options) {
|
|
|
9204
9861
|
}
|
|
9205
9862
|
|
|
9206
9863
|
// src/api/acp/route.ts
|
|
9207
|
-
import { createHash as
|
|
9864
|
+
import { createHash as createHash5 } from "crypto";
|
|
9208
9865
|
import * as acp4 from "@agentclientprotocol/sdk";
|
|
9209
9866
|
|
|
9210
9867
|
// src/api/acp/auth.ts
|
|
9211
9868
|
import {
|
|
9212
|
-
createHash as
|
|
9869
|
+
createHash as createHash4,
|
|
9213
9870
|
randomBytes,
|
|
9214
9871
|
randomUUID as randomUUID2,
|
|
9215
9872
|
timingSafeEqual as timingSafeEqual3
|
|
@@ -9254,7 +9911,7 @@ async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
|
|
|
9254
9911
|
}
|
|
9255
9912
|
|
|
9256
9913
|
// src/api/acp/transport.ts
|
|
9257
|
-
import { createHash as
|
|
9914
|
+
import { createHash as createHash3, randomUUID } from "crypto";
|
|
9258
9915
|
import * as acp2 from "@agentclientprotocol/sdk";
|
|
9259
9916
|
import { userSchema } from "@sentry/junior-plugin-api";
|
|
9260
9917
|
import { z as z7 } from "zod";
|
|
@@ -9434,8 +10091,8 @@ var acpRequestReceiptSchema = z7.object({
|
|
|
9434
10091
|
sessionId: z7.string().min(1).optional()
|
|
9435
10092
|
}).strict();
|
|
9436
10093
|
var acpStreamCursorSchema = z7.object({ itemId: z7.string().min(1) }).strict();
|
|
9437
|
-
function
|
|
9438
|
-
return
|
|
10094
|
+
function stableHex2(value) {
|
|
10095
|
+
return createHash3("sha256").update(value).digest("hex").slice(0, 32);
|
|
9439
10096
|
}
|
|
9440
10097
|
function connectionKey(connectionId) {
|
|
9441
10098
|
return `junior:acp:v1:connection:${connectionId}`;
|
|
@@ -9450,7 +10107,7 @@ function connectionLockKey(connectionId) {
|
|
|
9450
10107
|
return `${connectionKey(connectionId)}:lock`;
|
|
9451
10108
|
}
|
|
9452
10109
|
function streamKey(route) {
|
|
9453
|
-
const suffix = route.sessionId ? `session:${
|
|
10110
|
+
const suffix = route.sessionId ? `session:${stableHex2(route.sessionId)}` : "connection";
|
|
9454
10111
|
return `${connectionKey(route.connectionId)}:stream:${suffix}`;
|
|
9455
10112
|
}
|
|
9456
10113
|
function streamListKey(route) {
|
|
@@ -9466,7 +10123,7 @@ function streamAppendLockKey(route) {
|
|
|
9466
10123
|
return `${streamKey(route)}:append`;
|
|
9467
10124
|
}
|
|
9468
10125
|
function requestStreamItemId(requestKey2, index) {
|
|
9469
|
-
return `acp-item:${
|
|
10126
|
+
return `acp-item:${stableHex2(`${requestKey2}:${index}`)}`;
|
|
9470
10127
|
}
|
|
9471
10128
|
function parseStreamItem(value) {
|
|
9472
10129
|
return storedAcpStreamItemSchema.parse(value);
|
|
@@ -10075,7 +10732,7 @@ function authorizationPointerLockKey(connectionId) {
|
|
|
10075
10732
|
return `${authorizationPointerKey(connectionId)}:lock`;
|
|
10076
10733
|
}
|
|
10077
10734
|
function credentialHash(value) {
|
|
10078
|
-
return
|
|
10735
|
+
return createHash4("sha256").update(value).digest("hex");
|
|
10079
10736
|
}
|
|
10080
10737
|
function createUserCode() {
|
|
10081
10738
|
const value = randomBytes(6).toString("hex").toUpperCase();
|
|
@@ -10539,8 +11196,8 @@ function promptText(prompt) {
|
|
|
10539
11196
|
}
|
|
10540
11197
|
return text;
|
|
10541
11198
|
}
|
|
10542
|
-
function
|
|
10543
|
-
return
|
|
11199
|
+
function stableHex3(value, length = 32) {
|
|
11200
|
+
return createHash5("sha256").update(value).digest("hex").slice(0, length);
|
|
10544
11201
|
}
|
|
10545
11202
|
function canonicalJson(value) {
|
|
10546
11203
|
if (Array.isArray(value)) return value.map(canonicalJson);
|
|
@@ -10550,11 +11207,11 @@ function canonicalJson(value) {
|
|
|
10550
11207
|
);
|
|
10551
11208
|
}
|
|
10552
11209
|
function requestKey(call) {
|
|
10553
|
-
const id = call.id === null ? "null" : `${typeof call.id}:${
|
|
11210
|
+
const id = call.id === null ? "null" : `${typeof call.id}:${stableHex3(String(call.id))}`;
|
|
10554
11211
|
const payload = JSON.stringify(
|
|
10555
11212
|
canonicalJson({ method: call.method, params: call.params ?? null })
|
|
10556
11213
|
);
|
|
10557
|
-
return `${id}:${
|
|
11214
|
+
return `${id}:${stableHex3(payload)}`;
|
|
10558
11215
|
}
|
|
10559
11216
|
function sessionIdFromCall(call) {
|
|
10560
11217
|
if (!call) return void 0;
|
|
@@ -10607,7 +11264,7 @@ async function createSession(args) {
|
|
|
10607
11264
|
args.call.params
|
|
10608
11265
|
);
|
|
10609
11266
|
rejectUnsupportedMcpServers(params.mcpServers);
|
|
10610
|
-
const sessionId = `${ACP_CONVERSATION_PREFIX}${
|
|
11267
|
+
const sessionId = `${ACP_CONVERSATION_PREFIX}${stableHex3(
|
|
10611
11268
|
`${args.connection.nonce}:${args.requestKey}`
|
|
10612
11269
|
)}`;
|
|
10613
11270
|
await args.conversations.create({
|
|
@@ -10621,16 +11278,16 @@ async function acceptPrompt(args) {
|
|
|
10621
11278
|
promptParamsSchema,
|
|
10622
11279
|
args.call.params
|
|
10623
11280
|
);
|
|
10624
|
-
const
|
|
11281
|
+
const result = await args.conversations.prompt({
|
|
10625
11282
|
conversationId: params.sessionId,
|
|
10626
11283
|
idempotencyKey: `${args.connection.nonce}:${args.requestKey}`,
|
|
10627
11284
|
text: promptText(params.prompt),
|
|
10628
11285
|
user: args.user
|
|
10629
11286
|
});
|
|
10630
|
-
if (
|
|
11287
|
+
if (result.status === "not_found") {
|
|
10631
11288
|
throw acp4.RequestError.resourceNotFound(params.sessionId);
|
|
10632
11289
|
}
|
|
10633
|
-
if (
|
|
11290
|
+
if (result.status === "active") {
|
|
10634
11291
|
throw acp4.RequestError.invalidParams(
|
|
10635
11292
|
{ field: "sessionId" },
|
|
10636
11293
|
"This ACP session already has an active prompt"
|
|
@@ -10638,11 +11295,11 @@ async function acceptPrompt(args) {
|
|
|
10638
11295
|
}
|
|
10639
11296
|
return {
|
|
10640
11297
|
output: {
|
|
10641
|
-
afterSeq:
|
|
11298
|
+
afterSeq: result.afterCursor,
|
|
10642
11299
|
kind: "prompt",
|
|
10643
|
-
messageId:
|
|
11300
|
+
messageId: result.messageId,
|
|
10644
11301
|
requestId: args.requestId,
|
|
10645
|
-
turnId:
|
|
11302
|
+
turnId: result.turnId
|
|
10646
11303
|
},
|
|
10647
11304
|
sessionId: params.sessionId
|
|
10648
11305
|
};
|