@sentry/junior 0.234.0 → 0.236.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.
Files changed (71) hide show
  1. package/dist/{agent-hooks-BcH6E48y.js → agent-hooks-Da_H0jHv.js} +17 -10
  2. package/dist/{agent-runner-DUkGlK89.js → agent-runner-uP7QRc4c.js} +484 -162
  3. package/dist/api/schema.d.ts +288 -2
  4. package/dist/api/schema.js +5 -4
  5. package/dist/api.d.ts +8 -2
  6. package/dist/api.js +524 -83
  7. package/dist/{app-xk2-Id1T.d.ts → app-MEd7wbF0.d.ts} +83 -49
  8. package/dist/app.d.ts +3 -3
  9. package/dist/app.js +164 -119
  10. package/dist/{types-Du-HbEun.js → automation-B9Kc1gcf.js} +304 -33
  11. package/dist/{briefs-lyAQbDxJ.js → briefs-DrjBPQFy.js} +4 -4
  12. package/dist/{catalog-runtime-BSgsPVnr.js → catalog-runtime-C7339Cfm.js} +1 -1
  13. package/dist/{checkpoint-BNfXlq_1.js → checkpoint-DaD7_Gsb.js} +16 -9
  14. package/dist/cli/chat.d.ts +1 -1
  15. package/dist/cli/chat.js +14 -14
  16. package/dist/cli/check.js +4 -4
  17. package/dist/cli/main.js +1 -1
  18. package/dist/cli/plugins.d.ts +1 -1
  19. package/dist/cli/plugins.js +4 -4
  20. package/dist/cli/snapshot-create.js +3 -3
  21. package/dist/cli/upgrade.d.ts +1 -1
  22. package/dist/cli/upgrade.js +5 -5
  23. package/dist/{client-BX5lJRqW.js → client-Ch9Hg9NU.js} +2 -2
  24. package/dist/{config-DuCzUoCo.js → config-JR9wke1W.js} +57 -17
  25. package/dist/{conversation-CPjHYOV5.js → conversation-9Fxa1Zbq.js} +14 -1
  26. package/dist/{conversation-privacy-CSxvdSoV.js → conversation-privacy-au02dyZK.js} +1 -1
  27. package/dist/{credential-sync-BO4DfH9a.js → credential-sync-BWTA3LnL.js} +14 -14
  28. package/dist/{executor--jWf-Nnm.js → executor-BW9XWgUQ.js} +70 -6
  29. package/dist/{images-BaL19wFC.js → images-BdG7zcNf.js} +3 -3
  30. package/dist/instrumentation.js +2 -2
  31. package/dist/{job-queue-cwHVOwVZ.js → job-queue-BqXd0ZPV.js} +1 -1
  32. package/dist/{logging-Cox1Mgcv.js → logging-B4sKwmCG.js} +1 -1
  33. package/dist/nitro.d.ts +2 -2
  34. package/dist/nitro.js +5 -5
  35. package/dist/{oauth-authorization-CC8a1JKP.js → oauth-authorization-BjRN99dc.js} +1 -1
  36. package/dist/{oauth-callback-server-Z7QSt416.js → oauth-callback-server-B_1p98Mb.js} +2 -2
  37. package/dist/{pending-auth-DQhC3eSR.js → pending-auth-WqF4Gh8Z.js} +1 -1
  38. package/dist/{plugins-BT2l4We3.d.ts → plugins-CjfUP5gJ.d.ts} +1 -0
  39. package/dist/{profile-BdApelHS.js → profile-BamYnmhO.js} +4 -4
  40. package/dist/{prompt-3D0sSbTC.js → prompt-Ctwy6hSI.js} +1 -1
  41. package/dist/queue-B5SnqRln.d.ts +25 -0
  42. package/dist/{registry-DiY6B8CN.js → registry-CXNv9fDX.js} +38 -2
  43. package/dist/{resolve-VpJoiDpc.js → resolve-C9ETkt4T.js} +2 -2
  44. package/dist/{runner-BIMegnPE.js → runner-DnBGVRnW.js} +9 -9
  45. package/dist/{sandbox-egress-signals-Cbtxe492.js → sandbox-egress-signals-DwJ7Boi_.js} +1 -1
  46. package/dist/{schema-CxwnlTDN.js → schema-CJiqDc5r.js} +26 -3
  47. package/dist/{skills-WttpPJUy.js → skills-Dd8O9Aav.js} +3 -3
  48. package/dist/{spawn-DhfMKt4y.js → spawn-DFdRspSD.js} +2 -2
  49. package/dist/{task-queue-CZqUNJD0.js → task-queue-DGQEOk1A.js} +16 -10
  50. package/dist/{task-runner-BZaqoUCT.js → task-runner-C5XCIDSF.js} +9 -9
  51. package/dist/{thread-state-8tXZhu0y.js → thread-state-D3E29wZk.js} +5 -5
  52. package/dist/{turn-failure-response-DFJ9L9NQ.js → turn-failure-response-TDoj0aZz.js} +8 -8
  53. package/dist/{turn-lifecycle-WbpTUQ_r.js → turn-lifecycle-DOnU45p7.js} +1 -1
  54. package/dist/{turn-session-routing--EhI76rH.js → turn-session-routing-DbpZZoin.js} +1 -1
  55. package/dist/{validation-0F9IgG3b.js → validation-B9lMbisx.js} +1 -1
  56. package/dist/{version-A7-RRBOE.js → version-CWkIGcLU.js} +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/{web-authorization-BJggXofy.js → web-authorization-PPaoj2ns.js} +6 -6
  59. package/dist/{web-input-B-siN5Dr.js → web-input-CfNxXtHm.js} +86 -34
  60. package/dist/web-message-id-xPI_EFSC.js +239 -0
  61. package/dist/{work-CNc0ejGG.js → work-DNaoFrEe.js} +7 -7
  62. package/dist/{worker-BHbqpUAu.js → worker-xeJLxYwm.js} +5 -5
  63. package/migrations/0045_conversation_forks.sql +3 -0
  64. package/migrations/0046_automation_versions.sql +71 -0
  65. package/migrations/meta/0045_snapshot.json +3503 -0
  66. package/migrations/meta/0046_snapshot.json +3707 -0
  67. package/migrations/meta/_journal.json +15 -1
  68. package/package.json +5 -5
  69. package/dist/web-message-id-CVVCTWUb.js +0 -464
  70. package/dist/{package-discovery-7a9YqLhE.js → package-discovery-BVvSnQBB.js} +1 -1
  71. package/dist/{plugin-module-BKGOXca2.js → plugin-module-CVvEUSMH.js} +1 -1
package/dist/app.js CHANGED
@@ -1,36 +1,36 @@
1
- import { A as requestAttachmentDeletion, At as clearExpiredConversationLease, B as listScheduledAutomations, Bt as listActiveConversationIds, C as readPublicArtifact, Dn as createUserTokenStore, En as slackExternalRefIdSchema, Fn as setConfigDefaults, G as saveScheduledAutomationInLock, It as ensureConversationWake, Jt as stopConversationWork, K as scheduledRunId, Kt as requestConversationWork, Lt as getConversation, M as parseSlackThreadId, O as collectAttachmentGarbage, Pn as getConfigDefaults, Q as collectEventAutomationMatchKeys, Qt as hasRunnableConversationWork$1, R as logScheduledAutomationRunSkipped, Rt as getConversationWorkState, S as publicArtifactHeaders, T as lookupSlackUserProfile, Tn as slackEntitySchema, Tt as appendAndEnqueueInboundMessage, U as readScheduledAutomation, V as listScheduledAutomationsForTeam, Wt as removeActiveConversation, Xt as CONVERSATION_WORK_STALE_ENQUEUE_MS, Z as effectiveTaskOutcomes, _t as ingestEvent, a as isExperimentalFeatureEnabled, an as normalizeSandboxEgressTracePropagationDomains, bt as getEventCatalog, cn as clearSandboxEgressSignals, dn as parseSandboxEgressCredentialToken, en as isInvalidConversationRecordError, f as deleteMcpAuthSessionsForUserProvider, gn as startOAuthFlow, gt as processWorkspaceSnapshotJob, i as getExperimentalFeatures, in as resolveSandboxEgressProviderForHost, l as executeCredentialedEgressRequest, ln as consumeSandboxEgressAuthRequiredSignal, m as deleteMcpStoredOAuthCredentials, o as setExperimentalFeatures, on as shouldPropagateSandboxEgressTrace, p as deleteMcpServerSessionId, pn as formatProviderLabel, q as withScheduledAutomationLock, s as executeAgentRun, sn as SANDBOX_EGRESS_PROXY_PATH, t as createAgentRunner, tn as renderTaskInput, tt as findMatchingEventAutomations, un as consumeSandboxEgressPermissionDeniedSignal, w as unpublishedArtifactHeaders, xt as eventGuidance, z as scheduledAutomationRunAttributes, zt as hasRunnableConversationWork } from "./agent-runner-DUkGlK89.js";
2
- import { C as withLogContext, O as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, S as withContext, d as logException, f as logInfo, j as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, p as logWarn, r as createRequestContext, v as setSpanAttributes, w as withSpan, y as setSpanStatus } from "./logging-Cox1Mgcv.js";
1
+ import { A as requestAttachmentDeletion, B as scheduledAutomationRunAttributes, C as isExperimentalFeatureEnabled, Ct as ingestEvent, Dn as slackMention, Dt as eventGuidance, Et as getEventCatalog, Gt as hasRunnableConversationWork, H as listScheduledAutomationsForTeam, Hn as setConfigDefaults, Ht as ensureConversationWake, It as clearExpiredConversationLease, J as withScheduledAutomationLock, K as saveScheduledAutomationInLock, Kt as listActiveConversationIds, M as parseSlackThreadId, Mn as slackEntitySchema, Nn as slackExternalRefIdSchema, O as collectAttachmentGarbage, Pn as createUserTokenStore, Q as effectiveTaskOutcomes, Qt as requestConversationWork, S as getExperimentalFeatures, Sn as startOAuthFlow, St as processWorkspaceSnapshotJob, T as lookupSlackUserProfile, Ut as getConversation, V as listScheduledAutomations, Vn as getConfigDefaults, W as readScheduledAutomation, Wt as getConversationWorkState, Xt as removeActiveConversation, _n as parseSandboxEgressCredentialToken, a as executeCredentialedEgressRequest, b as unpublishedArtifactHeaders, c as deleteMcpAuthSessionsForUserProvider, dn as normalizeSandboxEgressTracePropagationDomains, en as stopConversationWork, et as collectEventAutomationMatchKeys, fn as shouldPropagateSandboxEgressTrace, gn as consumeSandboxEgressPermissionDeniedSignal, hn as consumeSandboxEgressAuthRequiredSignal, in as hasRunnableConversationWork$1, jt as appendAndEnqueueInboundMessage, l as deleteMcpServerSessionId, mn as clearSandboxEgressSignals, nn as CONVERSATION_WORK_STALE_ENQUEUE_MS, on as isInvalidConversationRecordError, pn as SANDBOX_EGRESS_PROXY_PATH, q as scheduledRunId, r as executeAgentRun, rt as findMatchingEventAutomations, sn as renderTaskInput, t as createAgentRunner, u as deleteMcpStoredOAuthCredentials, un as resolveSandboxEgressProviderForHost, v as publicArtifactHeaders, w as setExperimentalFeatures, y as readPublicArtifact, yn as formatProviderLabel, z as logScheduledAutomationRunSkipped } from "./agent-runner-uP7QRc4c.js";
2
+ import { C as withLogContext, O as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, S as withContext, d as logException, f as logInfo, j as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, p as logWarn, r as createRequestContext, v as setSpanAttributes, w as withSpan, y as setSpanStatus } from "./logging-B4sKwmCG.js";
3
3
  import { r as continueTrace } from "./sentry-CgWZM_kV.js";
4
- import { t as JUNIOR_VERSION } from "./version-A7-RRBOE.js";
5
- import { a as getChatConfig, f as setBotModelConfig, i as configureFunctionMaxDurationSeconds, m as setSlackReactionConfig, n as botConfig, p as setProfiles, s as getSlackBotToken, u as getSlackReactionConfig } from "./config-DuCzUoCo.js";
4
+ import { t as JUNIOR_VERSION } from "./version-CWkIGcLU.js";
5
+ import { _ as snapshotRuntimeConfig, d as restoreRuntimeConfig, f as setBotModelConfig, g as setSlackReactionConfig, h as setRuntimeLimits, i as getChatConfig, m as setProfiles, n as botConfig, o as getSlackBotToken, p as setCrossActorMidRunMode, u as resetRuntimeConfig } from "./config-JR9wke1W.js";
6
6
  import { _ as slackChannelIdSchema, g as parseSlackUserId, h as parseSlackTeamId, u as parseActorUserId, v as slackTeamIdSchema, x as slackMessageTsSchema, y as slackUserIdSchema } from "./context-0Et9iVSB.js";
7
- import { $t as getConversationStore, Ct as createPluginLogger, F as bindSlackDirectCredentialSubject, G as isDmChannel, I as verifyEventAutomationCredentialSubject, L as verifyScheduledAutomationCredentialSubject, N as bindEventAutomationCredentialSubject, P as bindScheduledAutomationCredentialSubject, Q as readActorIdentity, R as verifySlackDirectCredentialSubject, U as getSlackClient, Vt as resolveRootVisibility, Wt as listConversationAnnotations, X as runWithWorkspaceTeamId, Y as getWorkspaceTeamId, Zt as getConversationEventStore, a as getPluginRoutes, bt as createPluginState, ct as collectEventMatchKeys, d as setPlugins, en as getDb, f as validatePlugins, ft as findMatchingWatches, gt as getDashboardConversationLink, h as setBriefsConfig, i as getPluginApiRoutes, in as withConversationMutationLock, mn as deleteProviderIdentityForSlackUser, mt as takeDueTimerWatches, ot as cancelSubscriptions, rn as withConversationEventLock, tn as getSqlExecutor, u as getPlugins, vt as getDashboardTaskLink, wt as readConversationAccessFromSql, yt as setDashboardConversationLinkOptions } from "./agent-hooks-BcH6E48y.js";
7
+ import { $ as readActorIdentity, F as bindScheduledAutomationCredentialSubject, Gt as listConversationAnnotations, Ht as resolveRootVisibility, I as bindSlackDirectCredentialSubject, K as isDmChannel, L as verifyEventAutomationCredentialSubject, P as bindEventAutomationCredentialSubject, Qt as getConversationEventStore, R as verifyScheduledAutomationCredentialSubject, Tt as readConversationAccessFromSql, W as getSlackClient, X as getWorkspaceTeamId, Z as runWithWorkspaceTeamId, _t as getDashboardConversationLink, a as getPluginRoutes, an as withConversationMutationLock, bt as setDashboardConversationLinkOptions, d as setPlugins, en as getConversationStore, f as validatePlugins, h as setBriefsConfig, hn as deleteProviderIdentityForSlackUser, ht as takeDueTimerWatches, i as getPluginApiRoutes, in as withConversationEventLock, lt as collectEventMatchKeys, nn as getSqlExecutor, pt as findMatchingWatches, st as cancelSubscriptions, tn as getDb, u as getPlugins, wt as createPluginLogger, xt as createPluginState, yt as getDashboardTaskLink, z as verifySlackDirectCredentialSubject } from "./agent-hooks-Da_H0jHv.js";
8
8
  import { n as juniorDestinations } from "./destinations-BeBiJeEM.js";
9
- import { E as juniorConversations, a as juniorSchedulerRuns, f as juniorAgentBindings, g as juniorConversationBriefs, o as juniorSchedulerTasks, p as juniorAgentInvocations, y as juniorConversationEvents } from "./executor--jWf-Nnm.js";
10
- import { z as annotationCard } from "./conversation-CPjHYOV5.js";
11
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BSgsPVnr.js";
12
- import { X as projectConversationMessages, q as appendConversationMessages } from "./checkpoint-BNfXlq_1.js";
13
- import { O as withLock$1, w as getStateAdapter } from "./profile-BdApelHS.js";
14
- import { f as setSandboxResourceConfig, u as getSandboxResourceConfig } from "./resolve-VpJoiDpc.js";
15
- import { a as getVercelConversationWorkQueue, g as isConversationQueueMessageRejectedError, h as conversationQueueMessageSchema, i as verifyWorkspaceSnapshotJobMessage, o as resolveConversationWorkQueueTopic, s as verifyConversationQueueMessage, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-cwHVOwVZ.js";
16
- import { f as getNextRunAtMs, r as scheduledRunSchema } from "./types-Du-HbEun.js";
17
- import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation-0F9IgG3b.js";
9
+ import { D as juniorConversations, _ as juniorConversationBriefs, a as juniorSchedulerRuns, b as juniorConversationEvents, m as juniorAgentInvocations, o as juniorSchedulerTasks, p as juniorAgentBindings } from "./executor-BW9XWgUQ.js";
10
+ import { V as annotationCard } from "./conversation-9Fxa1Zbq.js";
11
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-C7339Cfm.js";
12
+ import { J as appendConversationMessages, Z as projectConversationMessages, et as settleConversationTitleWork } from "./checkpoint-DaD7_Gsb.js";
13
+ import { O as withLock$1, w as getStateAdapter } from "./profile-BamYnmhO.js";
14
+ import { f as setSandboxResourceConfig, u as getSandboxResourceConfig } from "./resolve-C9ETkt4T.js";
15
+ import { a as getVercelConversationWorkQueue, g as isConversationQueueMessageRejectedError, h as conversationQueueMessageSchema, i as verifyWorkspaceSnapshotJobMessage, o as resolveConversationWorkQueueTopic, s as verifyConversationQueueMessage, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-BqXd0ZPV.js";
16
+ import { D as scheduledRunSchema, I as getNextRunAtMs } from "./automation-B9Kc1gcf.js";
17
+ import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation-B9lMbisx.js";
18
18
  import { a as pluginRuntimeRegistrationsFromPluginSet, n as pluginCatalogConfigFromEnv, r as pluginCatalogConfigFromPluginSet, t as defineJuniorPlugins } from "./plugins-egKWjgue.js";
19
- import { A as THREAD_OPTOUT_ACK, C as verifySlackSignature, D as withNormalizedThreadId, E as normalizeIncomingSlackThreadId, F as createVercelAttachmentStorage, L as enqueueAgentDispatch, M as parseContent, N as getThreadStopDecision, O as getAuthPausedConversationTurnId, P as renderSlackObjectCard, R as GET$3, S as runWithSlackInstallation, T as stopSlackThread, a as webActorFromEmail, b as clearSlackPendingReactions, c as getProductionSlackAdapter, g as readViewerAutomationSummary, i as recordWebConversationActivity, j as startProcessingReaction, n as conversationTurnIdForMessage, o as createProductionConversationWorkOptions, s as createProductionSlackWebhookServices, t as appendAndEnqueueWebMessage, v as recordSkippedConversationMessage, w as isSlackMessageStopped, y as buildSlackInboundMessage } from "./web-input-B-siN5Dr.js";
20
- import { O as recordAutomationExecution, _ as markDispatchFailed, a as confirmDispatchMailboxAppend, d as getPluginDispatchProjection, f as isTerminalDispatchStatus, l as getDispatchRecord, o as createOrGetDispatch, p as listPendingDispatchMailboxAppends, s as getDispatchConversationId } from "./task-runner-BZaqoUCT.js";
21
- import { c as listPendingAgentInvocationMailboxAppends, r as enqueueAgentInvocation } from "./work-CNc0ejGG.js";
22
- import { s as coerceThreadConversationState } from "./thread-state-8tXZhu0y.js";
23
- import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-BO4DfH9a.js";
24
- import { a as registerVercelPluginTaskDevConsumer, n as createVercelPluginTaskCallback, s as queueCallback } from "./task-queue-CZqUNJD0.js";
25
- import { t as processConversationWork } from "./worker-BHbqpUAu.js";
26
- import { t as bindSpawnAgent } from "./spawn-DhfMKt4y.js";
19
+ import { A as withNormalizedThreadId, B as enqueueAgentDispatch, C as clearSlackPendingReactions, D as isSlackMessageStopped, E as verifySlackSignature, F as parseContent, I as getThreadStopDecision, L as renderSlackObjectCard, N as THREAD_OPTOUT_ACK, O as stopSlackThread, P as startProcessingReaction, R as createVercelAttachmentStorage, S as buildSlackInboundMessage, T as runWithSlackInstallation, V as GET$3, _ as readViewerAutomationSummary, a as recordWebConversationActivity, c as createProductionSlackWebhookServices, j as getAuthPausedConversationTurnId, k as normalizeIncomingSlackThreadId, l as getProductionSlackAdapter, n as conversationTurnIdForMessage, o as webActorFromEmail, s as createProductionConversationWorkOptions, t as appendAndEnqueueWebMessage, x as recordSkippedConversationMessage } from "./web-input-CfNxXtHm.js";
20
+ import { O as recordAutomationExecution, _ as markDispatchFailed, a as confirmDispatchMailboxAppend, d as getPluginDispatchProjection, f as isTerminalDispatchStatus, l as getDispatchRecord, o as createOrGetDispatch, p as listPendingDispatchMailboxAppends, s as getDispatchConversationId, t as processPluginTask } from "./task-runner-C5XCIDSF.js";
21
+ import { c as listPendingAgentInvocationMailboxAppends, r as enqueueAgentInvocation } from "./work-DNaoFrEe.js";
22
+ import { s as coerceThreadConversationState } from "./thread-state-D3E29wZk.js";
23
+ import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-BWTA3LnL.js";
24
+ import { a as registerVercelPluginTaskDevConsumer, n as createVercelPluginTaskCallback, s as queueCallback } from "./task-queue-DGQEOk1A.js";
25
+ import { t as processConversationWork } from "./worker-xeJLxYwm.js";
26
+ import { t as bindSpawnAgent } from "./spawn-DFdRspSD.js";
27
27
  import { createRequire } from "node:module";
28
- import { pathToFileURL } from "node:url";
29
28
  import { Hono } from "hono";
30
29
  import { z } from "zod";
31
30
  import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
32
31
  import { and, asc, eq, inArray, isNotNull, isNull, lte, or, sql } from "drizzle-orm";
33
32
  import { EVENT_SUMMARY_MAX_LENGTH, EVENT_TEXT_MAX_LENGTH, dispatchOptionsSchema, eventSchema, isSlackDestination, userSchema } from "@sentry/junior-plugin-api";
33
+ import { pathToFileURL } from "node:url";
34
34
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
35
35
  import { createRemoteJWKSet, decodeJwt, jwtVerify } from "jose";
36
36
  import { ChannelImpl, ThreadImpl } from "chat";
@@ -652,6 +652,7 @@ function singleLineMetadataValue(value) {
652
652
  /** Render the due scheduled automation as plain agent input. */
653
653
  function buildDispatchInput(task) {
654
654
  return renderTaskInput({
655
+ creator: slackMention(task.createdBy.slackUserId),
655
656
  instructions: task.task.text,
656
657
  outcomes: effectiveTaskOutcomes(task.outcomes, task.destination)
657
658
  });
@@ -2791,14 +2792,35 @@ function resolveConversationWorkVisibilityTimeoutSeconds(functionMaxDurationSeco
2791
2792
  /** Process one Vercel Queue payload with the generic conversation worker. */
2792
2793
  async function processConversationQueueMessage(message, options) {
2793
2794
  const parsed = parseConversationQueueMessage(message);
2794
- return await processConversationWork(parsed, {
2795
- checkInIntervalMs: options.checkInIntervalMs,
2796
- conversationStore: options.conversationStore,
2797
- nowMs: options.nowMs,
2798
- queue: options.queue ?? getVercelConversationWorkQueue(),
2799
- run: options.run,
2800
- softYieldAfterMs: options.softYieldAfterMs,
2801
- state: options.state
2795
+ try {
2796
+ return await processConversationWork(parsed, {
2797
+ checkInIntervalMs: options.checkInIntervalMs,
2798
+ conversationStore: options.conversationStore,
2799
+ nowMs: options.nowMs,
2800
+ queue: options.queue ?? getVercelConversationWorkQueue(),
2801
+ run: options.run,
2802
+ softYieldAfterMs: options.softYieldAfterMs,
2803
+ state: options.state
2804
+ });
2805
+ } finally {
2806
+ options.waitUntil?.(settleConversationTitleWork(parsed.conversationId));
2807
+ }
2808
+ }
2809
+ /**
2810
+ * Run one queue message through the worker without a Vercel push callback.
2811
+ * In-process queues use this. The callback's kill switch, request deadline,
2812
+ * and permanent rejection rules apply; signature checks do not.
2813
+ */
2814
+ async function consumeConversationQueueMessage(message, options) {
2815
+ const nowMs = Date.now();
2816
+ await conversationWorkCallback(options).consume(message, {
2817
+ consumerGroup: "in_process",
2818
+ createdAt: new Date(nowMs),
2819
+ deliveryCount: 1,
2820
+ expiresAt: new Date(nowMs + 3e4),
2821
+ messageId: options.messageId,
2822
+ region: "local",
2823
+ topicName: resolveConversationWorkQueueTopic(options)
2802
2824
  });
2803
2825
  }
2804
2826
  function logConversationQueueMessageRejected(reason, metadata, error) {
@@ -2923,6 +2945,7 @@ function eventInput(task, event) {
2923
2945
  const guidance = eventGuidance(getEventCatalog(), event.namespace, task.trigger.resourceType, event.eventType);
2924
2946
  return renderTaskInput({
2925
2947
  about: task.trigger.label,
2948
+ creator: slackMention(task.createdBy.slackUserId),
2926
2949
  instructions: task.task.text,
2927
2950
  outcomes: effectiveTaskOutcomes(task.outcomes, task.destination),
2928
2951
  guidance,
@@ -4802,82 +4825,15 @@ async function handleAcpAuthorizationPage(args) {
4802
4825
  return renderResult(args.agentName, result);
4803
4826
  }
4804
4827
  //#endregion
4805
- //#region src/app.ts
4806
- /** Resolve the public deployment URL used by ACP browser authorization. */
4807
- function resolveAcpBaseURL(dashboard) {
4808
- const configured = dashboard?.baseURL?.trim() || process.env.JUNIOR_BASE_URL?.trim();
4809
- if (configured) return configured;
4810
- const vercelURL = process.env.VERCEL_PROJECT_PRODUCTION_URL?.trim() || process.env.VERCEL_URL?.trim();
4811
- if (!vercelURL) return void 0;
4812
- return /^https?:\/\//.test(vercelURL) ? vercelURL : `https://${vercelURL}`;
4813
- }
4828
+ //#region src/dashboard-routes.ts
4814
4829
  const DASHBOARD_PACKAGE_NAME = "@sentry/junior-dashboard";
4815
- /** Build a `WaitUntilFn`, preferring Vercel's lifetime extension when available. */
4816
- async function defaultWaitUntil() {
4817
- try {
4818
- const { waitUntil } = await import("@vercel/functions");
4819
- return (task) => {
4820
- const promise = typeof task === "function" ? task() : task;
4821
- waitUntil(promise);
4822
- };
4823
- } catch {
4824
- return (task) => {
4825
- (typeof task === "function" ? task() : task).catch(console.error);
4826
- };
4827
- }
4828
- }
4829
- /** Resolve build-time configuration from the virtual module injected by juniorNitro(). */
4830
- async function resolveVirtualConfig() {
4831
- try {
4832
- const mod = await import("#junior/config");
4833
- return {
4834
- createDashboardApp: mod.createDashboardApp,
4835
- functionMaxDurationSeconds: mod.functionMaxDurationSeconds,
4836
- dashboard: mod.dashboard,
4837
- pluginSet: mod.pluginSet,
4838
- plugins: mod.plugins,
4839
- pluginRuntimeRegistrations: mod.pluginRuntimeRegistrations ?? []
4840
- };
4841
- } catch (error) {
4842
- if (!isMissingVirtualConfig(error)) throw error;
4843
- return;
4844
- }
4845
- }
4846
- function isMissingVirtualConfig(error) {
4847
- if (!(error instanceof Error)) return false;
4848
- const code = error.code;
4849
- return (code === "ERR_PACKAGE_IMPORT_NOT_DEFINED" || code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && error.message.includes("#junior/config");
4850
- }
4851
- function hasConfiguredPluginCatalog(config) {
4852
- if (!config) return false;
4853
- return Boolean(config.inlineManifests?.length || config.packages?.length || Object.keys(config.manifests ?? {}).length);
4854
- }
4855
- function warnUnregisteredConfigDefaults(defaults) {
4856
- for (const key of Object.keys(defaults ?? {})) if (!pluginCatalogRuntime.isConfigKey(key)) logWarn("config.default.unregistered", { "app.config.key": key });
4857
- }
4858
- function pluginPackageNames(config) {
4859
- return config?.packages ?? [];
4860
- }
4861
- function validateBuildIncludesPluginPackages(pluginConfig, virtualConfig) {
4862
- if (!virtualConfig?.plugins) return;
4863
- const bundled = new Set(pluginPackageNames(virtualConfig.plugins));
4864
- const missing = pluginPackageNames(pluginConfig).filter((packageName) => !bundled.has(packageName));
4865
- if (missing.length === 0) return;
4866
- throw new Error(`createApp() registered plugin package(s) not bundled by juniorNitro(): ${missing.join(", ")}. Point juniorNitro({ plugins: "./plugins" }) at the runtime plugin module or pass the same defineJuniorPlugins(...) set to juniorNitro({ plugins }) and createApp({ plugins }).`);
4867
- }
4868
- function validateBuildIncludesPluginRuntimeRegistrations(runtimeRegistrations, virtualConfig) {
4869
- const bundledRuntimeRegistrations = virtualConfig?.pluginRuntimeRegistrations ?? [];
4870
- if (bundledRuntimeRegistrations.length === 0) return;
4871
- const registered = new Set(runtimeRegistrations.map((plugin) => plugin.manifest.name));
4872
- const missing = bundledRuntimeRegistrations.filter((pluginName) => !registered.has(pluginName));
4873
- if (missing.length === 0) return;
4874
- throw new Error(`createApp() is missing plugin registration(s) with runtime code bundled by juniorNitro(): ${missing.join(", ")}. Pass a runtime-safe plugin module to juniorNitro({ plugins: "./plugins" }) or pass the same defineJuniorPlugins(...) set to createApp({ plugins }).`);
4875
- }
4830
+ /** Mount the dashboard app on the dashboard-owned host paths. */
4876
4831
  async function createDashboardRouteRegistrations(args) {
4877
4832
  if (!args.dashboard || args.dashboard.disabled) return [];
4878
4833
  const createDashboardApp = args.createDashboardApp ?? await loadDashboardAppFactory();
4879
4834
  return dashboardRouteRegistrations({
4880
4835
  authenticatedRoutes: args.authenticatedRoutes,
4836
+ conversationWorkQueue: args.conversationWorkQueue,
4881
4837
  dashboard: args.dashboard,
4882
4838
  createDashboardApp,
4883
4839
  pluginRoutes: args.pluginRoutes
@@ -4920,6 +4876,7 @@ function dashboardHostRoutePaths(dashboard, authenticatedRoutes = []) {
4920
4876
  const pagePaths = [
4921
4877
  basePath,
4922
4878
  pagePath("code"),
4879
+ `${pagePath("code")}/*`,
4923
4880
  conversationsPath,
4924
4881
  `${conversationsPath}/*`,
4925
4882
  pagePath("locations"),
@@ -4962,6 +4919,7 @@ function dashboardHostRoutePaths(dashboard, authenticatedRoutes = []) {
4962
4919
  "/api/automations/*",
4963
4920
  "/api/skills",
4964
4921
  "/api/code",
4922
+ "/api/code/*",
4965
4923
  "/api/stats",
4966
4924
  "/api/conversations",
4967
4925
  "/api/conversations/*",
@@ -5020,6 +4978,7 @@ function dashboardRouteRegistrations(args) {
5020
4978
  ...args.dashboard,
5021
4979
  agentName: botConfig.userName,
5022
4980
  authenticatedRoutes: args.authenticatedRoutes,
4981
+ conversationWorkQueue: args.conversationWorkQueue,
5023
4982
  pluginRoutes: args.pluginRoutes
5024
4983
  };
5025
4984
  app ??= args.createDashboardApp(dashboardOptions);
@@ -5031,10 +4990,82 @@ function dashboardRouteRegistrations(args) {
5031
4990
  path
5032
4991
  }));
5033
4992
  }
4993
+ /** Reject plugin routes that would shadow dashboard or auth paths. */
5034
4994
  function validateDashboardRouteOwnership(args) {
5035
4995
  if (!args.dashboard || args.dashboard.disabled) return;
5036
4996
  for (const route of args.routes) if (dashboardOwnedRoutePath(route.path, args.dashboard, args.authenticatedRoutes)) throw new Error(`Plugin "${route.pluginName}" route "${route.path}" conflicts with core dashboard routes`);
5037
4997
  }
4998
+ //#endregion
4999
+ //#region src/app.ts
5000
+ /** Resolve the public deployment URL used by ACP browser authorization. */
5001
+ function resolveAcpBaseURL(dashboard) {
5002
+ const configured = dashboard?.baseURL?.trim() || process.env.JUNIOR_BASE_URL?.trim();
5003
+ if (configured) return configured;
5004
+ const vercelURL = process.env.VERCEL_PROJECT_PRODUCTION_URL?.trim() || process.env.VERCEL_URL?.trim();
5005
+ if (!vercelURL) return void 0;
5006
+ return /^https?:\/\//.test(vercelURL) ? vercelURL : `https://${vercelURL}`;
5007
+ }
5008
+ /** Build a `WaitUntilFn`, preferring Vercel's lifetime extension when available. */
5009
+ async function defaultWaitUntil() {
5010
+ try {
5011
+ const { waitUntil } = await import("@vercel/functions");
5012
+ return (task) => {
5013
+ const promise = typeof task === "function" ? task() : task;
5014
+ waitUntil(promise);
5015
+ };
5016
+ } catch {
5017
+ return (task) => {
5018
+ (typeof task === "function" ? task() : task).catch(console.error);
5019
+ };
5020
+ }
5021
+ }
5022
+ /** Resolve build-time configuration from the virtual module injected by juniorNitro(). */
5023
+ async function resolveVirtualConfig() {
5024
+ try {
5025
+ const mod = await import("#junior/config");
5026
+ return {
5027
+ createDashboardApp: mod.createDashboardApp,
5028
+ functionMaxDurationSeconds: mod.functionMaxDurationSeconds,
5029
+ dashboard: mod.dashboard,
5030
+ pluginSet: mod.pluginSet,
5031
+ plugins: mod.plugins,
5032
+ pluginRuntimeRegistrations: mod.pluginRuntimeRegistrations ?? []
5033
+ };
5034
+ } catch (error) {
5035
+ if (!isMissingVirtualConfig(error)) throw error;
5036
+ return;
5037
+ }
5038
+ }
5039
+ function isMissingVirtualConfig(error) {
5040
+ if (!(error instanceof Error)) return false;
5041
+ const code = error.code;
5042
+ return (code === "ERR_PACKAGE_IMPORT_NOT_DEFINED" || code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && error.message.includes("#junior/config");
5043
+ }
5044
+ function hasConfiguredPluginCatalog(config) {
5045
+ if (!config) return false;
5046
+ return Boolean(config.inlineManifests?.length || config.packages?.length || Object.keys(config.manifests ?? {}).length);
5047
+ }
5048
+ function warnUnregisteredConfigDefaults(defaults) {
5049
+ for (const key of Object.keys(defaults ?? {})) if (!pluginCatalogRuntime.isConfigKey(key)) logWarn("config.default.unregistered", { "app.config.key": key });
5050
+ }
5051
+ function pluginPackageNames(config) {
5052
+ return config?.packages ?? [];
5053
+ }
5054
+ function validateBuildIncludesPluginPackages(pluginConfig, virtualConfig) {
5055
+ if (!virtualConfig?.plugins) return;
5056
+ const bundled = new Set(pluginPackageNames(virtualConfig.plugins));
5057
+ const missing = pluginPackageNames(pluginConfig).filter((packageName) => !bundled.has(packageName));
5058
+ if (missing.length === 0) return;
5059
+ throw new Error(`createApp() registered plugin package(s) not bundled by juniorNitro(): ${missing.join(", ")}. Point juniorNitro({ plugins: "./plugins" }) at the runtime plugin module or pass the same defineJuniorPlugins(...) set to juniorNitro({ plugins }) and createApp({ plugins }).`);
5060
+ }
5061
+ function validateBuildIncludesPluginRuntimeRegistrations(runtimeRegistrations, virtualConfig) {
5062
+ const bundledRuntimeRegistrations = virtualConfig?.pluginRuntimeRegistrations ?? [];
5063
+ if (bundledRuntimeRegistrations.length === 0) return;
5064
+ const registered = new Set(runtimeRegistrations.map((plugin) => plugin.manifest.name));
5065
+ const missing = bundledRuntimeRegistrations.filter((pluginName) => !registered.has(pluginName));
5066
+ if (missing.length === 0) return;
5067
+ throw new Error(`createApp() is missing plugin registration(s) with runtime code bundled by juniorNitro(): ${missing.join(", ")}. Pass a runtime-safe plugin module to juniorNitro({ plugins: "./plugins" }) or pass the same defineJuniorPlugins(...) set to createApp({ plugins }).`);
5068
+ }
5038
5069
  /** Mount HTTP handlers before core routes claim those paths. */
5039
5070
  function mountRoutes(app, routes) {
5040
5071
  for (const route of routes) {
@@ -5048,7 +5079,6 @@ function mountRoutes(app, routes) {
5048
5079
  /** Create a Hono app with all Junior routes. */
5049
5080
  async function createApp(options) {
5050
5081
  const virtualConfig = await resolveVirtualConfig();
5051
- if (virtualConfig?.functionMaxDurationSeconds !== void 0) configureFunctionMaxDurationSeconds(virtualConfig.functionMaxDurationSeconds);
5052
5082
  const dashboard = options?.dashboard ?? virtualConfig?.dashboard;
5053
5083
  const configuredPlugins = options?.plugins ?? virtualConfig?.pluginSet;
5054
5084
  const plugins = pluginRuntimeRegistrationsFromPluginSet(configuredPlugins);
@@ -5058,21 +5088,19 @@ async function createApp(options) {
5058
5088
  validatePlugins(plugins);
5059
5089
  getDb();
5060
5090
  const shouldValidatePluginCatalog = hasConfiguredPluginCatalog(pluginConfig) || Boolean(configuredPlugins?.registrations.length) || Boolean(Object.keys(options?.configDefaults ?? {}).length);
5061
- const previousBotConfig = { ...botConfig };
5091
+ const previousRuntimeConfig = snapshotRuntimeConfig();
5062
5092
  const previousPluginCatalogConfig = pluginCatalogRuntime.setConfig(pluginConfig);
5063
5093
  const previousPlugins = setPlugins(plugins);
5064
5094
  const previousConfigDefaults = getConfigDefaults();
5065
- const previousSlackReactionConfig = getSlackReactionConfig();
5066
5095
  const previousSandboxResources = getSandboxResourceConfig();
5067
5096
  const previousExperimentalFeatures = getExperimentalFeatures();
5068
5097
  const previousBriefsConfig = setBriefsConfig(options?.briefs);
5069
5098
  const previousDashboardLinkOptions = setDashboardConversationLinkOptions(dashboard);
5070
- const restoreRuntimeConfig = () => {
5099
+ const restoreRuntimeConfig$1 = () => {
5071
5100
  pluginCatalogRuntime.setConfig(previousPluginCatalogConfig);
5072
5101
  setPlugins(previousPlugins);
5073
5102
  setConfigDefaults(previousConfigDefaults);
5074
- Object.assign(botConfig, previousBotConfig);
5075
- setSlackReactionConfig(previousSlackReactionConfig);
5103
+ restoreRuntimeConfig(previousRuntimeConfig);
5076
5104
  setSandboxResourceConfig(previousSandboxResources);
5077
5105
  setExperimentalFeatures(previousExperimentalFeatures);
5078
5106
  setBriefsConfig(previousBriefsConfig);
@@ -5080,7 +5108,10 @@ async function createApp(options) {
5080
5108
  };
5081
5109
  let pluginRoutes = [];
5082
5110
  let pluginApiRoutes = [];
5083
- const events = createEventAppPublisher({ conversationWork: () => getConversationWorkOptions() });
5111
+ const events = createEventAppPublisher({ conversationWork: () => ({
5112
+ ...getConversationWorkOptions(),
5113
+ queue: conversationWorkQueue
5114
+ }) });
5084
5115
  let sandboxEgressTracePropagationDomains = [];
5085
5116
  try {
5086
5117
  sandboxEgressTracePropagationDomains = normalizeSandboxEgressTracePropagationDomains(options?.sandbox?.egressTracePropagationDomains);
@@ -5088,9 +5119,12 @@ async function createApp(options) {
5088
5119
  setExperimentalFeatures(options?.experimental);
5089
5120
  setConfigDefaults(options?.configDefaults);
5090
5121
  warnUnregisteredConfigDefaults(options?.configDefaults);
5122
+ resetRuntimeConfig(virtualConfig?.functionMaxDurationSeconds);
5091
5123
  if (options?.profiles || options?.defaultProfile) setProfiles(options.profiles, options.defaultProfile);
5092
- if (options) setBotModelConfig(options);
5093
- if (options?.slack) setSlackReactionConfig(options.slack);
5124
+ setBotModelConfig(options ?? {});
5125
+ setRuntimeLimits(options?.limits);
5126
+ setSlackReactionConfig(options?.slack ?? {});
5127
+ if (options?.slack?.crossActorMidRunMode) setCrossActorMidRunMode(options.slack.crossActorMidRunMode);
5094
5128
  if (shouldValidatePluginCatalog) {
5095
5129
  pluginCatalogRuntime.getSignature();
5096
5130
  validatePluginRegistrations(configuredPlugins?.registrations ?? []);
@@ -5099,12 +5133,16 @@ async function createApp(options) {
5099
5133
  pluginRoutes = getPluginRoutes({ events });
5100
5134
  if (dashboard && !dashboard.disabled) pluginApiRoutes = getPluginApiRoutes();
5101
5135
  } catch (error) {
5102
- restoreRuntimeConfig();
5136
+ restoreRuntimeConfig$1();
5103
5137
  throw error;
5104
5138
  }
5105
5139
  const waitUntil = options?.waitUntil ?? await defaultWaitUntil();
5106
5140
  const tracePropagation = { domains: sandboxEgressTracePropagationDomains };
5107
- const conversationWorkQueue = getVercelConversationWorkQueue();
5141
+ const conversationWorkQueue = options?.conversationWork?.queue ?? options?.conversationWorkQueue?.((message, delivery) => consumeConversationQueueMessage(message, {
5142
+ ...getConversationWorkOptions(),
5143
+ messageId: delivery.messageId
5144
+ })) ?? getVercelConversationWorkQueue();
5145
+ const pluginTaskQueue = options?.pluginTaskQueue?.(processPluginTask);
5108
5146
  const attachmentStorage = createVercelAttachmentStorage();
5109
5147
  const agentRunner = createAgentRunner(executeAgentRun, {
5110
5148
  attachmentStorage,
@@ -5120,7 +5158,10 @@ async function createApp(options) {
5120
5158
  const getConversationWorkOptions = () => {
5121
5159
  conversationWorkOptions ??= options?.conversationWork ?? createProductionConversationWorkOptions({
5122
5160
  agentRunner,
5123
- services: runtimeServiceOverrides
5161
+ queue: conversationWorkQueue,
5162
+ ...pluginTaskQueue ? { sendPluginTask: (message) => pluginTaskQueue.send(message) } : void 0,
5163
+ services: runtimeServiceOverrides,
5164
+ waitUntil: (task) => waitUntil(task)
5124
5165
  });
5125
5166
  return conversationWorkOptions;
5126
5167
  };
@@ -5136,7 +5177,7 @@ async function createApp(options) {
5136
5177
  conversations: createAcpConversations({
5137
5178
  conversationStore: work.conversationStore,
5138
5179
  eventStore: getConversationEventStore(),
5139
- queue: work.queue ?? getVercelConversationWorkQueue(),
5180
+ queue: conversationWorkQueue,
5140
5181
  state
5141
5182
  }),
5142
5183
  onError: (error, event, attributes) => void logException(error, event, {
@@ -5167,10 +5208,13 @@ async function createApp(options) {
5167
5208
  routes: pluginRoutes
5168
5209
  });
5169
5210
  } catch (error) {
5170
- restoreRuntimeConfig();
5211
+ restoreRuntimeConfig$1();
5171
5212
  throw error;
5172
5213
  }
5173
- const slackWebhookServices = createProductionSlackWebhookServices({ services: runtimeServiceOverrides });
5214
+ const slackWebhookServices = createProductionSlackWebhookServices({
5215
+ queue: conversationWorkQueue,
5216
+ services: runtimeServiceOverrides
5217
+ });
5174
5218
  const app = new Hono();
5175
5219
  app.onError((err, c) => {
5176
5220
  logException(err, "route.unhandled.exception");
@@ -5187,6 +5231,7 @@ async function createApp(options) {
5187
5231
  mountRoutes(app, pluginRoutes);
5188
5232
  mountRoutes(app, await createDashboardRouteRegistrations({
5189
5233
  authenticatedRoutes,
5234
+ conversationWorkQueue,
5190
5235
  dashboard,
5191
5236
  createDashboardApp: virtualConfig?.createDashboardApp,
5192
5237
  pluginRoutes: pluginApiRoutes
@@ -5198,10 +5243,10 @@ async function createApp(options) {
5198
5243
  storage: attachmentStorage
5199
5244
  }));
5200
5245
  app.get("/api/oauth/callback/mcp/:provider", (c) => {
5201
- return GET$4(c.req.raw, c.req.param("provider"), waitUntil, { conversationWorkQueue: getVercelConversationWorkQueue() });
5246
+ return GET$4(c.req.raw, c.req.param("provider"), waitUntil, { conversationWorkQueue });
5202
5247
  });
5203
5248
  app.get("/api/oauth/callback/:provider", (c) => {
5204
- return GET$5(c.req.raw, c.req.param("provider"), waitUntil, { conversationWorkQueue: getVercelConversationWorkQueue() });
5249
+ return GET$5(c.req.raw, c.req.param("provider"), waitUntil, { conversationWorkQueue });
5205
5250
  });
5206
5251
  app.get("/api/internal/sandbox-egress/signals", (c) => {
5207
5252
  return GET(c.req.raw);
@@ -5233,7 +5278,7 @@ async function createApp(options) {
5233
5278
  return workspaceSnapshotJobPOST(c.req.raw);
5234
5279
  });
5235
5280
  app.get("/api/internal/heartbeat", (c) => {
5236
- return GET$2(c.req.raw, waitUntil);
5281
+ return GET$2(c.req.raw, waitUntil, { conversationWorkQueue });
5237
5282
  });
5238
5283
  app.get("/api/internal/retention", (c) => {
5239
5284
  return GET$1(c.req.raw);