@sentry/junior 0.162.0 → 0.164.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/README.md +2 -0
- package/dist/{agent-hooks-TL2SGC5W.js → agent-hooks-WTBPNRTC.js} +10 -10
- package/dist/api/acp/route.d.ts +13 -0
- package/dist/api/schema/workspace.d.ts +47 -0
- package/dist/api/schema.d.ts +2 -0
- package/dist/api/schema.js +15 -3
- package/dist/api/workspaces/routes.d.ts +4 -0
- package/dist/api.js +321 -408
- package/dist/app.d.ts +2 -2
- package/dist/app.js +482 -38
- package/dist/{catalog-runtime-IGSMIADJ.js → catalog-runtime-CZ2SQINY.js} +5 -5
- package/dist/chat/agent/sandbox.d.ts +4 -0
- package/dist/chat/api-turns/cancellation.d.ts +27 -0
- package/dist/chat/api-turns/routing.d.ts +31 -0
- package/dist/chat/api-turns/work.d.ts +12 -29
- package/dist/chat/app/conversation-work.d.ts +6 -1
- package/dist/chat/app/production.d.ts +2 -2
- package/dist/chat/conversations/history.d.ts +3 -0
- package/dist/chat/conversations/turn-lifecycle.d.ts +1 -1
- package/dist/chat/experimental.d.ts +1 -1
- package/dist/chat/plugins/agent-hooks.d.ts +4 -0
- package/dist/chat/repository-instructions.d.ts +1 -1
- package/dist/chat/sandbox/paths.d.ts +1 -0
- package/dist/chat/sandbox/prepare-workspace.d.ts +11 -0
- package/dist/chat/sandbox/ref.d.ts +1 -0
- package/dist/chat/sandbox/sandbox.d.ts +4 -0
- package/dist/chat/sandbox/session.d.ts +4 -0
- package/dist/chat/sandbox/snapshot/profile.d.ts +4 -3
- package/dist/chat/sandbox/snapshot/resolve.d.ts +4 -0
- package/dist/chat/sandbox/workspace.d.ts +4 -0
- package/dist/chat/tools/types.d.ts +5 -0
- package/dist/chat/workspaces/checkout-path.d.ts +4 -0
- package/dist/chat/workspaces/store.d.ts +37 -0
- package/dist/chat/workspaces/tools.d.ts +4 -0
- package/dist/chat/workspaces/types.d.ts +13 -0
- package/dist/chat/workspaces/validation.d.ts +21 -0
- package/dist/{chunk-THXMSSFZ.js → chunk-26JYGL2L.js} +1 -1
- package/dist/{chunk-OPNJRQDP.js → chunk-2K25MRZK.js} +9 -6
- package/dist/{chunk-C3KUKA27.js → chunk-3L23VTY7.js} +17 -17
- package/dist/{chunk-JJ3VXFDI.js → chunk-4GTOFUQF.js} +1 -1
- package/dist/{chunk-RDV4BQRZ.js → chunk-5FWQ73UZ.js} +1 -1
- package/dist/{chunk-BPZQWAZJ.js → chunk-5GLGQHO3.js} +4 -1
- package/dist/{chunk-K7IV6UV3.js → chunk-6BXV63YX.js} +5 -5
- package/dist/{chunk-4WYGQ47U.js → chunk-6ENAACWN.js} +5 -5
- package/dist/{chunk-EHQLTK3X.js → chunk-7WKWMMYQ.js} +323 -127
- package/dist/chunk-BVREIWBD.js +131 -0
- package/dist/{chunk-DZC3F2UI.js → chunk-BXBZDV3C.js} +1 -1
- package/dist/{chunk-HW4BW3PC.js → chunk-CGCNFEAU.js} +4 -4
- package/dist/{chunk-JRVURR3H.js → chunk-FKDY7NTC.js} +543 -164
- package/dist/{chunk-MNCEGXEH.js → chunk-FX4PX3SA.js} +2 -2
- package/dist/{chunk-OBFRMQBY.js → chunk-H36GJVJV.js} +9 -9
- package/dist/{chunk-V7QL4QMW.js → chunk-HHW6ZVIZ.js} +12 -7
- package/dist/{chunk-O6P7DZ6O.js → chunk-JW23XD4I.js} +6 -6
- package/dist/{chunk-DDQ43S5Q.js → chunk-LPLVNMVN.js} +4 -4
- package/dist/{chunk-5NEBOHRG.js → chunk-NAGI2XH3.js} +4 -4
- package/dist/{chunk-FEWT5KPP.js → chunk-NLTQRYNP.js} +2 -2
- package/dist/{chunk-SA6BEEAB.js → chunk-PU45BSBS.js} +108 -74
- package/dist/{chunk-7DTPFFQX.js → chunk-RBV4JHCP.js} +1 -1
- package/dist/{chunk-6BJFIWEV.js → chunk-RJHZNPDH.js} +46 -87
- package/dist/{chunk-FESUWAYU.js → chunk-RULIISEI.js} +1 -1
- package/dist/{chunk-MMBMDSRK.js → chunk-RYYEHWIL.js} +1 -1
- package/dist/{chunk-Y75ZDQB5.js → chunk-VHSEMJTS.js} +1 -1
- package/dist/{chunk-5IDFPCON.js → chunk-VRS6WDK5.js} +1 -1
- package/dist/{chunk-EBEHJPFF.js → chunk-VV2DN24T.js} +1 -1
- package/dist/{chunk-WHAJ3QVY.js → chunk-WJUKESU2.js} +1 -1
- package/dist/{chunk-H2KW7AZC.js → chunk-XAIRI54J.js} +1 -1
- package/dist/{chunk-AJ7J2HWY.js → chunk-Y2B6AXZQ.js} +6 -6
- package/dist/{chunk-QHCIZLIX.js → chunk-YHCTPDXS.js} +356 -13
- package/dist/{chunk-CZ6EHOU5.js → chunk-ZSNABC2E.js} +40 -2
- package/dist/{chunk-KQSO4DJ4.js → chunk-ZUTAGCPH.js} +9 -9
- package/dist/cli/chat.js +32 -32
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/workspaces.d.ts +169 -0
- package/dist/db/schema.d.ts +169 -1
- package/dist/{db-66XZ4HHQ.js → db-32KRFS6L.js} +7 -7
- package/dist/{experimental-HH6OM6UH.js → experimental-XVDOSRBS.js} +1 -1
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-FMLKDUUF.js → oauth-callback-server-CGZP2Z6U.js} +24 -24
- package/dist/{runner-YZONUMNY.js → runner-S5N4Q2XL.js} +32 -34
- package/dist/{skills-3UDJJXSO.js → skills-KYPSHSQR.js} +6 -6
- package/dist/spawn-EGOB3CLV.js +37 -0
- package/dist/{validation-3HTDBONC.js → validation-SZBE7JNF.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-O4YTIS54.js → work-GCZKHEZX.js} +18 -18
- package/dist/worker-6MY5Q4A2.js +24 -0
- package/migrations/0029_dizzy_barracuda.sql +19 -0
- package/migrations/meta/0029_snapshot.json +2709 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +7 -4
- package/dist/chunk-EM225ITJ.js +0 -56
- package/dist/spawn-TBPVA5S2.js +0 -37
- package/dist/worker-WHURUEYX.js +0 -24
package/dist/app.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processConversationWork
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CGCNFEAU.js";
|
|
4
4
|
import {
|
|
5
5
|
bindSpawnAgent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XAIRI54J.js";
|
|
7
7
|
import {
|
|
8
8
|
createAgentInvocationWorker,
|
|
9
9
|
enqueueAgentInvocation,
|
|
10
10
|
listPendingAgentInvocationMailboxAppends,
|
|
11
11
|
routeAgentInvocationWork
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-Y2B6AXZQ.js";
|
|
13
13
|
import {
|
|
14
14
|
GET as GET2,
|
|
15
15
|
GET2 as GET3,
|
|
@@ -36,23 +36,30 @@ import {
|
|
|
36
36
|
startSlackProcessingReaction,
|
|
37
37
|
stripLeadingBotMention,
|
|
38
38
|
wakePausedTurn
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-3L23VTY7.js";
|
|
40
40
|
import "./chunk-FA6POGLH.js";
|
|
41
41
|
import {
|
|
42
42
|
getTurnRequestDeadline,
|
|
43
43
|
runWithTurnRequestDeadline
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-RYYEHWIL.js";
|
|
45
45
|
import {
|
|
46
46
|
GET,
|
|
47
|
+
apiTurnIdForMessage,
|
|
48
|
+
appendAndEnqueueApiConversationMessage,
|
|
49
|
+
authenticatePersonalToken,
|
|
47
50
|
conversationVisibilityFromSlackChannelType,
|
|
51
|
+
createApiTurnCancellation,
|
|
48
52
|
createApiTurnWorker,
|
|
49
53
|
createVercelAttachmentStorage,
|
|
50
54
|
lookupSlackUser,
|
|
55
|
+
readConversationAccessFromSql,
|
|
56
|
+
recordApiConversationActivity,
|
|
51
57
|
resolveSlackChannelTypeFromMessage,
|
|
52
58
|
resolveSlackConversationContext,
|
|
53
|
-
routeApiTurnWork
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
routeApiTurnWork,
|
|
60
|
+
webActorFromEmail
|
|
61
|
+
} from "./chunk-FKDY7NTC.js";
|
|
62
|
+
import "./chunk-5FWQ73UZ.js";
|
|
56
63
|
import {
|
|
57
64
|
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
58
65
|
appendAndEnqueueInboundMessage,
|
|
@@ -63,7 +70,7 @@ import {
|
|
|
63
70
|
isInvalidConversationRecordError,
|
|
64
71
|
listActiveConversationIds,
|
|
65
72
|
removeActiveConversation
|
|
66
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-NAGI2XH3.js";
|
|
67
74
|
import {
|
|
68
75
|
buildDeliveredTurnStatePatch,
|
|
69
76
|
claimDispatchMailboxAppend,
|
|
@@ -94,7 +101,7 @@ import {
|
|
|
94
101
|
requireTurnFailureEventId,
|
|
95
102
|
resolveTurnSessionRouting,
|
|
96
103
|
scheduleSessionCompletedPluginTasks
|
|
97
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-ZUTAGCPH.js";
|
|
98
105
|
import {
|
|
99
106
|
ConversationTurnLifecycleService,
|
|
100
107
|
coerceThreadConversationState,
|
|
@@ -104,7 +111,7 @@ import {
|
|
|
104
111
|
persistThreadRuntimeState,
|
|
105
112
|
persistThreadState,
|
|
106
113
|
persistThreadStateById
|
|
107
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-2K25MRZK.js";
|
|
108
115
|
import "./chunk-UTL3MHPC.js";
|
|
109
116
|
import {
|
|
110
117
|
getVercelConversationWorkQueue,
|
|
@@ -123,7 +130,7 @@ import {
|
|
|
123
130
|
import {
|
|
124
131
|
validatePluginEgressCredentialHooks,
|
|
125
132
|
validatePluginRegistrations
|
|
126
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-4GTOFUQF.js";
|
|
127
134
|
import {
|
|
128
135
|
defineJuniorPlugins,
|
|
129
136
|
pluginCatalogConfigFromEnv,
|
|
@@ -158,11 +165,11 @@ import {
|
|
|
158
165
|
shouldEmitDevAgentTrace,
|
|
159
166
|
shouldPropagateSandboxEgressTrace,
|
|
160
167
|
unpublishedArtifactHeaders
|
|
161
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-7WKWMMYQ.js";
|
|
162
169
|
import {
|
|
163
170
|
AuthorizationFlowDisabledError,
|
|
164
171
|
PluginCredentialFailureError
|
|
165
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-6BXV63YX.js";
|
|
166
173
|
import "./chunk-DIB4GX3G.js";
|
|
167
174
|
import {
|
|
168
175
|
createAgentRunner,
|
|
@@ -170,7 +177,7 @@ import {
|
|
|
170
177
|
deleteMcpAuthSessionsForUserProvider,
|
|
171
178
|
deleteMcpServerSessionId,
|
|
172
179
|
deleteMcpStoredOAuthCredentials
|
|
173
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-H36GJVJV.js";
|
|
174
181
|
import {
|
|
175
182
|
RetryableDeliveryError
|
|
176
183
|
} from "./chunk-RF6J3DIO.js";
|
|
@@ -178,16 +185,17 @@ import {
|
|
|
178
185
|
formatProviderLabel,
|
|
179
186
|
postSlackMessage,
|
|
180
187
|
startOAuthFlow
|
|
181
|
-
} from "./chunk-
|
|
188
|
+
} from "./chunk-JW23XD4I.js";
|
|
182
189
|
import "./chunk-7MA4HV4W.js";
|
|
183
190
|
import {
|
|
184
191
|
getExperimentalFeatures,
|
|
192
|
+
isExperimentalFeatureEnabled,
|
|
185
193
|
setExperimentalFeatures
|
|
186
|
-
} from "./chunk-
|
|
194
|
+
} from "./chunk-VRS6WDK5.js";
|
|
187
195
|
import {
|
|
188
196
|
getSandboxResourceConfig,
|
|
189
197
|
setSandboxResourceConfig
|
|
190
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-RJHZNPDH.js";
|
|
191
199
|
import {
|
|
192
200
|
collectAttachmentGarbage,
|
|
193
201
|
createSchedulerSqlStore,
|
|
@@ -195,10 +203,10 @@ import {
|
|
|
195
203
|
logScheduledTaskRunSkipped,
|
|
196
204
|
requestAttachmentDeletion,
|
|
197
205
|
scheduledTaskRunAttributes
|
|
198
|
-
} from "./chunk-
|
|
206
|
+
} from "./chunk-6ENAACWN.js";
|
|
199
207
|
import {
|
|
200
208
|
parseSlackThreadId
|
|
201
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-WJUKESU2.js";
|
|
202
210
|
import {
|
|
203
211
|
ConversationTurnBoundaryError,
|
|
204
212
|
CooperativeTurnYieldError,
|
|
@@ -238,6 +246,7 @@ import {
|
|
|
238
246
|
persistConversationMessageSummaries,
|
|
239
247
|
persistConversationMessages,
|
|
240
248
|
persistWithRetry,
|
|
249
|
+
projectConversationMessages,
|
|
241
250
|
recordDeliveredAssistantMessage,
|
|
242
251
|
recordSubscribedReplyRoute,
|
|
243
252
|
recordTurnSummary,
|
|
@@ -248,7 +257,7 @@ import {
|
|
|
248
257
|
trimTrailingAssistantMessages,
|
|
249
258
|
turnHasReply,
|
|
250
259
|
upsertConversationMessage
|
|
251
|
-
} from "./chunk-
|
|
260
|
+
} from "./chunk-HHW6ZVIZ.js";
|
|
252
261
|
import "./chunk-3Y47VMHV.js";
|
|
253
262
|
import "./chunk-PDO5BLNM.js";
|
|
254
263
|
import "./chunk-UIE3R5XU.js";
|
|
@@ -268,6 +277,7 @@ import {
|
|
|
268
277
|
getWorkspaceTeamId,
|
|
269
278
|
isDmChannel,
|
|
270
279
|
normalizeSlackConversationId,
|
|
280
|
+
resolveViewerUser,
|
|
271
281
|
runWithSlackInstallationToken,
|
|
272
282
|
runWithWorkspaceTeamId,
|
|
273
283
|
setDashboardConversationLinkOptions,
|
|
@@ -276,7 +286,7 @@ import {
|
|
|
276
286
|
verifyEventTaskCredentialSubject,
|
|
277
287
|
verifyScheduledTaskCredentialSubject,
|
|
278
288
|
verifySlackDirectCredentialSubject
|
|
279
|
-
} from "./chunk-
|
|
289
|
+
} from "./chunk-YHCTPDXS.js";
|
|
280
290
|
import {
|
|
281
291
|
contextProvenance,
|
|
282
292
|
createSlackDestination,
|
|
@@ -289,19 +299,21 @@ import {
|
|
|
289
299
|
requireSlackDestination,
|
|
290
300
|
withConversationEventLock,
|
|
291
301
|
withConversationMutationLock
|
|
292
|
-
} from "./chunk-
|
|
302
|
+
} from "./chunk-LPLVNMVN.js";
|
|
293
303
|
import {
|
|
294
304
|
juniorAgentBindings,
|
|
295
305
|
juniorAgentInvocations,
|
|
296
306
|
juniorConversationEvents,
|
|
297
307
|
juniorConversations
|
|
298
|
-
} from "./chunk-
|
|
299
|
-
import
|
|
308
|
+
} from "./chunk-ZSNABC2E.js";
|
|
309
|
+
import {
|
|
310
|
+
sleep
|
|
311
|
+
} from "./chunk-BVREIWBD.js";
|
|
300
312
|
import {
|
|
301
313
|
acquireActiveLock,
|
|
302
314
|
getStateAdapter,
|
|
303
315
|
withActiveLock
|
|
304
|
-
} from "./chunk-
|
|
316
|
+
} from "./chunk-BXBZDV3C.js";
|
|
305
317
|
import {
|
|
306
318
|
STANDARD_MODEL_PROFILE,
|
|
307
319
|
botConfig,
|
|
@@ -319,16 +331,16 @@ import {
|
|
|
319
331
|
modelIdForProfile,
|
|
320
332
|
setSlackReactionConfig,
|
|
321
333
|
standardModelId
|
|
322
|
-
} from "./chunk-
|
|
334
|
+
} from "./chunk-FX4PX3SA.js";
|
|
323
335
|
import {
|
|
324
336
|
juniorDestinations
|
|
325
337
|
} from "./chunk-VFUK3X5B.js";
|
|
326
|
-
import "./chunk-
|
|
327
|
-
import "./chunk-
|
|
338
|
+
import "./chunk-RBV4JHCP.js";
|
|
339
|
+
import "./chunk-NLTQRYNP.js";
|
|
328
340
|
import {
|
|
329
341
|
pluginCatalogRuntime
|
|
330
|
-
} from "./chunk-
|
|
331
|
-
import "./chunk-
|
|
342
|
+
} from "./chunk-RULIISEI.js";
|
|
343
|
+
import "./chunk-VV2DN24T.js";
|
|
332
344
|
import {
|
|
333
345
|
credentialContextForActor
|
|
334
346
|
} from "./chunk-BDUENQD3.js";
|
|
@@ -360,7 +372,7 @@ import {
|
|
|
360
372
|
withContext,
|
|
361
373
|
withLogContext,
|
|
362
374
|
withSpan
|
|
363
|
-
} from "./chunk-
|
|
375
|
+
} from "./chunk-VHSEMJTS.js";
|
|
364
376
|
import {
|
|
365
377
|
continueTrace
|
|
366
378
|
} from "./chunk-6GWA276C.js";
|
|
@@ -368,10 +380,10 @@ import "./chunk-OOUNJNMR.js";
|
|
|
368
380
|
import "./chunk-H4HBKISO.js";
|
|
369
381
|
import {
|
|
370
382
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
|
|
371
|
-
} from "./chunk-
|
|
383
|
+
} from "./chunk-26JYGL2L.js";
|
|
372
384
|
import {
|
|
373
385
|
JUNIOR_VERSION
|
|
374
|
-
} from "./chunk-
|
|
386
|
+
} from "./chunk-5GLGQHO3.js";
|
|
375
387
|
import "./chunk-MLKGABMK.js";
|
|
376
388
|
|
|
377
389
|
// src/app.ts
|
|
@@ -8402,6 +8414,7 @@ async function runNextPausedTurnInContext(conversationId, options, runOptions) {
|
|
|
8402
8414
|
|
|
8403
8415
|
// src/chat/app/conversation-work.ts
|
|
8404
8416
|
function createConversationWork(options) {
|
|
8417
|
+
const apiTurnCancellation = createApiTurnCancellation();
|
|
8405
8418
|
const services = {
|
|
8406
8419
|
...options.services,
|
|
8407
8420
|
replyExecutor: {
|
|
@@ -8457,11 +8470,13 @@ function createConversationWork(options) {
|
|
|
8457
8470
|
fallbackWorker: slackWorker
|
|
8458
8471
|
});
|
|
8459
8472
|
return {
|
|
8473
|
+
apiTurnCancellation,
|
|
8460
8474
|
conversationStore: options.conversationStore,
|
|
8461
8475
|
queue: options.queue,
|
|
8462
8476
|
run: routeApiTurnWork({
|
|
8463
8477
|
apiTurnWorker: createApiTurnWorker({
|
|
8464
|
-
agentRunner: options.agentRunner
|
|
8478
|
+
agentRunner: options.agentRunner,
|
|
8479
|
+
cancellation: apiTurnCancellation
|
|
8465
8480
|
}),
|
|
8466
8481
|
fallbackWorker: routeAgentInvocationWork({
|
|
8467
8482
|
invocationWorker: createAgentInvocationWorker({
|
|
@@ -8774,6 +8789,415 @@ async function ingestEventTasks(input, options) {
|
|
|
8774
8789
|
return { dispatched };
|
|
8775
8790
|
}
|
|
8776
8791
|
|
|
8792
|
+
// src/api/acp/route.ts
|
|
8793
|
+
import { randomUUID } from "crypto";
|
|
8794
|
+
import * as acp from "@agentclientprotocol/sdk";
|
|
8795
|
+
import { AcpServer } from "@agentclientprotocol/sdk/experimental/server";
|
|
8796
|
+
var ACP_CONNECTION_ID_HEADER = "Acp-Connection-Id";
|
|
8797
|
+
var ACP_CONVERSATION_PREFIX = "local:acp:";
|
|
8798
|
+
var EVENT_PAGE_SIZE = 50;
|
|
8799
|
+
var EVENT_POLL_INTERVAL_MS = 25;
|
|
8800
|
+
var MAX_PROMPT_TEXT_LENGTH = 32e3;
|
|
8801
|
+
function bearerToken(request) {
|
|
8802
|
+
const authorization = request.headers.get("Authorization");
|
|
8803
|
+
const match = authorization?.match(/^Bearer ([^\s]+)$/);
|
|
8804
|
+
return match?.[1];
|
|
8805
|
+
}
|
|
8806
|
+
async function authenticateRequest(request) {
|
|
8807
|
+
const token = bearerToken(request);
|
|
8808
|
+
if (!token) return void 0;
|
|
8809
|
+
const email = await authenticatePersonalToken(token);
|
|
8810
|
+
if (!email) return void 0;
|
|
8811
|
+
const user = await resolveViewerUser(email);
|
|
8812
|
+
if (!user) return void 0;
|
|
8813
|
+
return {
|
|
8814
|
+
actor: webActorFromEmail(
|
|
8815
|
+
user.email ?? email,
|
|
8816
|
+
user.displayName ? { fullName: user.displayName } : void 0
|
|
8817
|
+
),
|
|
8818
|
+
user
|
|
8819
|
+
};
|
|
8820
|
+
}
|
|
8821
|
+
function rejectUnsupportedMcpServers(mcpServers) {
|
|
8822
|
+
if (mcpServers.length > 0) {
|
|
8823
|
+
throw acp.RequestError.invalidParams(
|
|
8824
|
+
{ field: "mcpServers" },
|
|
8825
|
+
"Junior does not accept client MCP servers"
|
|
8826
|
+
);
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
async function requireOwnedSession(sessionId, user) {
|
|
8830
|
+
if (!sessionId.startsWith(ACP_CONVERSATION_PREFIX)) {
|
|
8831
|
+
throw acp.RequestError.resourceNotFound(sessionId);
|
|
8832
|
+
}
|
|
8833
|
+
const access = (await readConversationAccessFromSql(getDb(), [sessionId], user)).get(sessionId);
|
|
8834
|
+
if (!access?.isParticipant) {
|
|
8835
|
+
throw acp.RequestError.resourceNotFound(sessionId);
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
function promptText(prompt) {
|
|
8839
|
+
if (prompt.length === 0) {
|
|
8840
|
+
throw acp.RequestError.invalidParams(
|
|
8841
|
+
{ field: "prompt" },
|
|
8842
|
+
"Junior accepts one or more text blocks only"
|
|
8843
|
+
);
|
|
8844
|
+
}
|
|
8845
|
+
const blocks = [];
|
|
8846
|
+
for (const block of prompt) {
|
|
8847
|
+
if (block.type !== "text") {
|
|
8848
|
+
throw acp.RequestError.invalidParams(
|
|
8849
|
+
{ field: "prompt" },
|
|
8850
|
+
"Junior accepts one or more text blocks only"
|
|
8851
|
+
);
|
|
8852
|
+
}
|
|
8853
|
+
if (!block.text.trim()) {
|
|
8854
|
+
throw acp.RequestError.invalidParams(
|
|
8855
|
+
{ field: "prompt" },
|
|
8856
|
+
"Junior accepts non-empty text blocks only"
|
|
8857
|
+
);
|
|
8858
|
+
}
|
|
8859
|
+
blocks.push(block.text);
|
|
8860
|
+
}
|
|
8861
|
+
const text = blocks.join("\n");
|
|
8862
|
+
if (text.length > MAX_PROMPT_TEXT_LENGTH) {
|
|
8863
|
+
throw acp.RequestError.invalidParams(
|
|
8864
|
+
{ field: "prompt" },
|
|
8865
|
+
`Junior accepts at most ${MAX_PROMPT_TEXT_LENGTH} prompt characters`
|
|
8866
|
+
);
|
|
8867
|
+
}
|
|
8868
|
+
return text;
|
|
8869
|
+
}
|
|
8870
|
+
function requestIdKey(requestId) {
|
|
8871
|
+
if (requestId === null) return "null";
|
|
8872
|
+
return `${typeof requestId}:${requestId}`;
|
|
8873
|
+
}
|
|
8874
|
+
async function latestEventSeq(eventStore, conversationId) {
|
|
8875
|
+
const page = await eventStore.query(conversationId, { limit: 1 });
|
|
8876
|
+
return page.events.at(-1)?.seq ?? 0;
|
|
8877
|
+
}
|
|
8878
|
+
async function replaySession(eventStore, sessionId, client) {
|
|
8879
|
+
const history = await eventStore.loadMessageHistory(sessionId);
|
|
8880
|
+
for (const message of projectConversationMessages(history)) {
|
|
8881
|
+
if (message.role === "system") continue;
|
|
8882
|
+
await client.notify(acp.methods.client.session.update, {
|
|
8883
|
+
sessionId,
|
|
8884
|
+
update: {
|
|
8885
|
+
sessionUpdate: message.role === "user" ? "user_message_chunk" : "agent_message_chunk",
|
|
8886
|
+
content: { type: "text", text: message.text },
|
|
8887
|
+
messageId: message.id
|
|
8888
|
+
}
|
|
8889
|
+
});
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8892
|
+
async function waitForTurn(args) {
|
|
8893
|
+
let cursor = args.afterSeq;
|
|
8894
|
+
const assistantPrefix = `${args.turnId}:assistant:`;
|
|
8895
|
+
const sentMessageIds = /* @__PURE__ */ new Set();
|
|
8896
|
+
while (true) {
|
|
8897
|
+
if (args.signal.aborted) {
|
|
8898
|
+
throw acp.RequestError.requestCancelled();
|
|
8899
|
+
}
|
|
8900
|
+
const page = await args.eventStore.query(args.sessionId, {
|
|
8901
|
+
afterSeq: cursor,
|
|
8902
|
+
limit: EVENT_PAGE_SIZE,
|
|
8903
|
+
types: ["message", "turn_completed", "turn_failed"]
|
|
8904
|
+
});
|
|
8905
|
+
if (page.events.length === 0) {
|
|
8906
|
+
try {
|
|
8907
|
+
await sleep(EVENT_POLL_INTERVAL_MS, args.signal);
|
|
8908
|
+
} catch (error) {
|
|
8909
|
+
if (args.signal.aborted) {
|
|
8910
|
+
throw acp.RequestError.requestCancelled();
|
|
8911
|
+
}
|
|
8912
|
+
throw error;
|
|
8913
|
+
}
|
|
8914
|
+
continue;
|
|
8915
|
+
}
|
|
8916
|
+
for (const event of page.events) {
|
|
8917
|
+
cursor = event.seq;
|
|
8918
|
+
const data = event.data;
|
|
8919
|
+
if (data.type === "message" && data.role === "assistant" && data.messageId.startsWith(assistantPrefix) && !sentMessageIds.has(data.messageId)) {
|
|
8920
|
+
sentMessageIds.add(data.messageId);
|
|
8921
|
+
await args.client.notify(acp.methods.client.session.update, {
|
|
8922
|
+
sessionId: args.sessionId,
|
|
8923
|
+
update: {
|
|
8924
|
+
sessionUpdate: "agent_message_chunk",
|
|
8925
|
+
content: { type: "text", text: data.text },
|
|
8926
|
+
messageId: data.messageId
|
|
8927
|
+
}
|
|
8928
|
+
});
|
|
8929
|
+
continue;
|
|
8930
|
+
}
|
|
8931
|
+
if (data.type === "turn_completed" && data.turnId === args.turnId) {
|
|
8932
|
+
args.cancellation.finish(args.sessionId, args.cancellationSignal);
|
|
8933
|
+
return {
|
|
8934
|
+
stopReason: data.outcome === "cancelled" ? "cancelled" : "end_turn"
|
|
8935
|
+
};
|
|
8936
|
+
}
|
|
8937
|
+
if (data.type === "turn_failed" && data.turnId === args.turnId) {
|
|
8938
|
+
args.cancellation.finish(args.sessionId, args.cancellationSignal);
|
|
8939
|
+
throw acp.RequestError.internalError(
|
|
8940
|
+
{ failureCode: data.failureCode },
|
|
8941
|
+
"Junior Turn failed"
|
|
8942
|
+
);
|
|
8943
|
+
}
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
}
|
|
8947
|
+
async function runAcpOperation(authenticated, operation, conversationId, callback) {
|
|
8948
|
+
const name = `acp.${operation}`;
|
|
8949
|
+
return await withSpan(
|
|
8950
|
+
name,
|
|
8951
|
+
name,
|
|
8952
|
+
{
|
|
8953
|
+
actorId: authenticated.actor.userId,
|
|
8954
|
+
conversationId,
|
|
8955
|
+
platform: "acp",
|
|
8956
|
+
userId: authenticated.actor.userId
|
|
8957
|
+
},
|
|
8958
|
+
async () => {
|
|
8959
|
+
try {
|
|
8960
|
+
return await callback();
|
|
8961
|
+
} catch (error) {
|
|
8962
|
+
if (!(error instanceof acp.RequestError)) {
|
|
8963
|
+
logException(error, `${name}.failed`);
|
|
8964
|
+
}
|
|
8965
|
+
throw error;
|
|
8966
|
+
}
|
|
8967
|
+
}
|
|
8968
|
+
);
|
|
8969
|
+
}
|
|
8970
|
+
function createActorAgent(authenticated, connectionNonce, options) {
|
|
8971
|
+
const conversationStore = options.conversationStore ?? getConversationStore();
|
|
8972
|
+
const eventStore = getConversationEventStore();
|
|
8973
|
+
return acp.agent({ name: "junior" }).onRequest(
|
|
8974
|
+
acp.methods.agent.initialize,
|
|
8975
|
+
() => runAcpOperation(authenticated, "initialize", void 0, () => ({
|
|
8976
|
+
protocolVersion: acp.PROTOCOL_VERSION,
|
|
8977
|
+
agentCapabilities: {
|
|
8978
|
+
loadSession: true,
|
|
8979
|
+
promptCapabilities: {
|
|
8980
|
+
image: false,
|
|
8981
|
+
audio: false,
|
|
8982
|
+
embeddedContext: false
|
|
8983
|
+
}
|
|
8984
|
+
},
|
|
8985
|
+
authMethods: [],
|
|
8986
|
+
agentInfo: { name: "junior", version: JUNIOR_VERSION }
|
|
8987
|
+
}))
|
|
8988
|
+
).onRequest(acp.methods.agent.session.new, async (context) => {
|
|
8989
|
+
return await runAcpOperation(
|
|
8990
|
+
authenticated,
|
|
8991
|
+
"session_new",
|
|
8992
|
+
void 0,
|
|
8993
|
+
async () => {
|
|
8994
|
+
rejectUnsupportedMcpServers(context.params.mcpServers);
|
|
8995
|
+
const sessionId = `${ACP_CONVERSATION_PREFIX}${randomUUID()}`;
|
|
8996
|
+
await recordApiConversationActivity({
|
|
8997
|
+
actor: authenticated.actor,
|
|
8998
|
+
conversationId: sessionId,
|
|
8999
|
+
conversationStore,
|
|
9000
|
+
nowMs: Date.now(),
|
|
9001
|
+
rootVisibility: "private"
|
|
9002
|
+
});
|
|
9003
|
+
return { sessionId };
|
|
9004
|
+
}
|
|
9005
|
+
);
|
|
9006
|
+
}).onRequest(acp.methods.agent.session.load, async (context) => {
|
|
9007
|
+
return await runAcpOperation(
|
|
9008
|
+
authenticated,
|
|
9009
|
+
"session_load",
|
|
9010
|
+
context.params.sessionId,
|
|
9011
|
+
async () => {
|
|
9012
|
+
rejectUnsupportedMcpServers(context.params.mcpServers);
|
|
9013
|
+
await requireOwnedSession(
|
|
9014
|
+
context.params.sessionId,
|
|
9015
|
+
authenticated.user
|
|
9016
|
+
);
|
|
9017
|
+
await replaySession(
|
|
9018
|
+
eventStore,
|
|
9019
|
+
context.params.sessionId,
|
|
9020
|
+
context.client
|
|
9021
|
+
);
|
|
9022
|
+
return {};
|
|
9023
|
+
}
|
|
9024
|
+
);
|
|
9025
|
+
}).onRequest(acp.methods.agent.session.prompt, async (context) => {
|
|
9026
|
+
return await runAcpOperation(
|
|
9027
|
+
authenticated,
|
|
9028
|
+
"session_prompt",
|
|
9029
|
+
context.params.sessionId,
|
|
9030
|
+
async () => {
|
|
9031
|
+
await requireOwnedSession(
|
|
9032
|
+
context.params.sessionId,
|
|
9033
|
+
authenticated.user
|
|
9034
|
+
);
|
|
9035
|
+
const text = promptText(context.params.prompt);
|
|
9036
|
+
const currentSeq = await latestEventSeq(
|
|
9037
|
+
eventStore,
|
|
9038
|
+
context.params.sessionId
|
|
9039
|
+
);
|
|
9040
|
+
const cancellationSignal = options.cancellation.begin(
|
|
9041
|
+
context.params.sessionId
|
|
9042
|
+
);
|
|
9043
|
+
if (!cancellationSignal) {
|
|
9044
|
+
throw acp.RequestError.invalidParams(
|
|
9045
|
+
{ field: "sessionId" },
|
|
9046
|
+
"This ACP session already has an active prompt"
|
|
9047
|
+
);
|
|
9048
|
+
}
|
|
9049
|
+
const recordDisconnect = () => options.cancellation.disconnect(
|
|
9050
|
+
context.params.sessionId,
|
|
9051
|
+
cancellationSignal
|
|
9052
|
+
);
|
|
9053
|
+
if (context.signal.aborted) {
|
|
9054
|
+
recordDisconnect();
|
|
9055
|
+
} else {
|
|
9056
|
+
context.signal.addEventListener("abort", recordDisconnect, {
|
|
9057
|
+
once: true
|
|
9058
|
+
});
|
|
9059
|
+
}
|
|
9060
|
+
let accepted;
|
|
9061
|
+
try {
|
|
9062
|
+
accepted = await appendAndEnqueueApiConversationMessage(
|
|
9063
|
+
{
|
|
9064
|
+
actor: authenticated.actor,
|
|
9065
|
+
conversationId: context.params.sessionId,
|
|
9066
|
+
idempotencyKey: `${connectionNonce}:${requestIdKey(context.requestId)}`,
|
|
9067
|
+
message: text
|
|
9068
|
+
},
|
|
9069
|
+
{
|
|
9070
|
+
conversationStore,
|
|
9071
|
+
queue: options.queue,
|
|
9072
|
+
state: options.state
|
|
9073
|
+
}
|
|
9074
|
+
);
|
|
9075
|
+
} catch (error) {
|
|
9076
|
+
options.cancellation.finish(
|
|
9077
|
+
context.params.sessionId,
|
|
9078
|
+
cancellationSignal
|
|
9079
|
+
);
|
|
9080
|
+
throw error;
|
|
9081
|
+
}
|
|
9082
|
+
const afterSeq = accepted.status === "duplicate" ? 0 : currentSeq;
|
|
9083
|
+
return await waitForTurn({
|
|
9084
|
+
afterSeq,
|
|
9085
|
+
cancellation: options.cancellation,
|
|
9086
|
+
cancellationSignal,
|
|
9087
|
+
client: context.client,
|
|
9088
|
+
eventStore,
|
|
9089
|
+
sessionId: context.params.sessionId,
|
|
9090
|
+
signal: context.signal,
|
|
9091
|
+
turnId: apiTurnIdForMessage(accepted.messageId)
|
|
9092
|
+
});
|
|
9093
|
+
}
|
|
9094
|
+
);
|
|
9095
|
+
}).onNotification(acp.methods.agent.session.cancel, async (context) => {
|
|
9096
|
+
await runAcpOperation(
|
|
9097
|
+
authenticated,
|
|
9098
|
+
"session_cancel",
|
|
9099
|
+
context.params.sessionId,
|
|
9100
|
+
async () => {
|
|
9101
|
+
await requireOwnedSession(
|
|
9102
|
+
context.params.sessionId,
|
|
9103
|
+
authenticated.user
|
|
9104
|
+
);
|
|
9105
|
+
if (!options.cancellation.cancel(context.params.sessionId)) {
|
|
9106
|
+
return;
|
|
9107
|
+
}
|
|
9108
|
+
const nowMs = Date.now();
|
|
9109
|
+
await ensureConversationWake({
|
|
9110
|
+
conversationId: context.params.sessionId,
|
|
9111
|
+
conversationStore,
|
|
9112
|
+
idempotencyKey: `acp-cancel:${context.params.sessionId}:${nowMs}`,
|
|
9113
|
+
nowMs,
|
|
9114
|
+
queue: options.queue,
|
|
9115
|
+
replaceExistingWake: true,
|
|
9116
|
+
state: options.state
|
|
9117
|
+
});
|
|
9118
|
+
}
|
|
9119
|
+
);
|
|
9120
|
+
});
|
|
9121
|
+
}
|
|
9122
|
+
function isJsonRpcId(value) {
|
|
9123
|
+
return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
9124
|
+
}
|
|
9125
|
+
async function hasSafeAcpEnvelope(request) {
|
|
9126
|
+
if (request.method !== "POST") return true;
|
|
9127
|
+
let value;
|
|
9128
|
+
try {
|
|
9129
|
+
value = await request.clone().json();
|
|
9130
|
+
} catch {
|
|
9131
|
+
return true;
|
|
9132
|
+
}
|
|
9133
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
9134
|
+
return true;
|
|
9135
|
+
}
|
|
9136
|
+
if (!("jsonrpc" in value) || value.jsonrpc !== "2.0") {
|
|
9137
|
+
return false;
|
|
9138
|
+
}
|
|
9139
|
+
if (!("method" in value) || typeof value.method !== "string") {
|
|
9140
|
+
return false;
|
|
9141
|
+
}
|
|
9142
|
+
return !("id" in value) || isJsonRpcId(value.id);
|
|
9143
|
+
}
|
|
9144
|
+
async function initializationSucceeded(response) {
|
|
9145
|
+
try {
|
|
9146
|
+
const value = await response.clone().json();
|
|
9147
|
+
return typeof value === "object" && value !== null && "result" in value;
|
|
9148
|
+
} catch {
|
|
9149
|
+
return false;
|
|
9150
|
+
}
|
|
9151
|
+
}
|
|
9152
|
+
function createAcpHttpHandler(options) {
|
|
9153
|
+
const server = new AcpServer({ agent: acp.agent({ name: "junior" }) });
|
|
9154
|
+
const connectionActors = /* @__PURE__ */ new Map();
|
|
9155
|
+
return async (request) => {
|
|
9156
|
+
const authenticated = await authenticateRequest(request);
|
|
9157
|
+
if (!authenticated) {
|
|
9158
|
+
return new Response("Unauthorized", { status: 401 });
|
|
9159
|
+
}
|
|
9160
|
+
const connectionId = request.headers.get(ACP_CONNECTION_ID_HEADER);
|
|
9161
|
+
const connectionActorId = connectionId ? connectionActors.get(connectionId) : void 0;
|
|
9162
|
+
if (connectionId && connectionActorId === void 0) {
|
|
9163
|
+
return new Response("Unknown Acp-Connection-Id", { status: 404 });
|
|
9164
|
+
}
|
|
9165
|
+
if (connectionActorId !== void 0 && connectionActorId !== authenticated.actor.userId) {
|
|
9166
|
+
return new Response("Unknown Acp-Connection-Id", { status: 404 });
|
|
9167
|
+
}
|
|
9168
|
+
if (!await hasSafeAcpEnvelope(request)) {
|
|
9169
|
+
return new Response("Invalid JSON-RPC message", { status: 400 });
|
|
9170
|
+
}
|
|
9171
|
+
const response = await server.handleRequest(request, {
|
|
9172
|
+
agent: createActorAgent(authenticated, randomUUID(), options)
|
|
9173
|
+
});
|
|
9174
|
+
const responseConnectionId = response.headers.get(ACP_CONNECTION_ID_HEADER);
|
|
9175
|
+
if (response.ok && responseConnectionId && !connectionId) {
|
|
9176
|
+
if (await initializationSucceeded(response)) {
|
|
9177
|
+
connectionActors.set(responseConnectionId, authenticated.actor.userId);
|
|
9178
|
+
} else {
|
|
9179
|
+
await server.handleRequest(
|
|
9180
|
+
new Request(request.url, {
|
|
9181
|
+
method: "DELETE",
|
|
9182
|
+
headers: { [ACP_CONNECTION_ID_HEADER]: responseConnectionId }
|
|
9183
|
+
})
|
|
9184
|
+
);
|
|
9185
|
+
const headers = new Headers(response.headers);
|
|
9186
|
+
headers.delete(ACP_CONNECTION_ID_HEADER);
|
|
9187
|
+
return new Response(response.body, {
|
|
9188
|
+
headers,
|
|
9189
|
+
status: response.status,
|
|
9190
|
+
statusText: response.statusText
|
|
9191
|
+
});
|
|
9192
|
+
}
|
|
9193
|
+
}
|
|
9194
|
+
if (request.method === "DELETE" && response.ok && connectionId) {
|
|
9195
|
+
connectionActors.delete(connectionId);
|
|
9196
|
+
}
|
|
9197
|
+
return response;
|
|
9198
|
+
};
|
|
9199
|
+
}
|
|
9200
|
+
|
|
8777
9201
|
// src/app.ts
|
|
8778
9202
|
var DASHBOARD_PACKAGE_NAME = "@sentry/junior-dashboard";
|
|
8779
9203
|
async function defaultWaitUntil() {
|
|
@@ -8975,6 +9399,8 @@ function dashboardHostRoutePaths(dashboard) {
|
|
|
8975
9399
|
"/api/people/*",
|
|
8976
9400
|
"/api/personal-tokens",
|
|
8977
9401
|
"/api/personal-tokens/*",
|
|
9402
|
+
"/api/workspaces",
|
|
9403
|
+
"/api/workspaces/*",
|
|
8978
9404
|
"/api/config",
|
|
8979
9405
|
"/api/me",
|
|
8980
9406
|
authPath,
|
|
@@ -9065,11 +9491,11 @@ function validateDashboardRouteOwnership(args) {
|
|
|
9065
9491
|
function mountRoutes(app, routes) {
|
|
9066
9492
|
for (const route of routes) {
|
|
9067
9493
|
const handler = (c) => route.handler(c.req.raw);
|
|
9068
|
-
const
|
|
9069
|
-
const explicitMethods =
|
|
9494
|
+
const methods2 = Array.isArray(route.method) ? route.method : [route.method ?? "ALL"];
|
|
9495
|
+
const explicitMethods = methods2.filter(
|
|
9070
9496
|
(method) => method !== "ALL"
|
|
9071
9497
|
);
|
|
9072
|
-
if (
|
|
9498
|
+
if (methods2.includes("ALL")) {
|
|
9073
9499
|
app.all(route.path, handler);
|
|
9074
9500
|
} else if (explicitMethods.length > 0) {
|
|
9075
9501
|
app.on(explicitMethods, route.path, handler);
|
|
@@ -9245,6 +9671,24 @@ async function createApp(options) {
|
|
|
9245
9671
|
});
|
|
9246
9672
|
return conversationWorkOptions;
|
|
9247
9673
|
};
|
|
9674
|
+
if (isExperimentalFeatureEnabled("acp")) {
|
|
9675
|
+
const work = getConversationWorkOptions();
|
|
9676
|
+
const cancellation = work.apiTurnCancellation;
|
|
9677
|
+
if (!cancellation) {
|
|
9678
|
+
throw new Error("Experimental ACP requires API Turn cancellation wiring");
|
|
9679
|
+
}
|
|
9680
|
+
const handleAcpRequest = createAcpHttpHandler({
|
|
9681
|
+
cancellation,
|
|
9682
|
+
conversationStore: work.conversationStore,
|
|
9683
|
+
queue: work.queue ?? getVercelConversationWorkQueue(),
|
|
9684
|
+
state: work.state
|
|
9685
|
+
});
|
|
9686
|
+
app.on(
|
|
9687
|
+
["GET", "POST", "DELETE"],
|
|
9688
|
+
"/api/acp",
|
|
9689
|
+
(c) => handleAcpRequest(c.req.raw)
|
|
9690
|
+
);
|
|
9691
|
+
}
|
|
9248
9692
|
if (process.env.NODE_ENV === "development") {
|
|
9249
9693
|
registerVercelConversationWorkDevConsumer(getConversationWorkOptions());
|
|
9250
9694
|
registerVercelPluginTaskDevConsumer();
|