@sentry/junior 0.235.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-DS7k0ZWY.js → agent-hooks-Da_H0jHv.js} +8 -8
  2. package/dist/{agent-runner-BlDI1zV2.js → agent-runner-uP7QRc4c.js} +353 -117
  3. package/dist/api/schema.d.ts +223 -2
  4. package/dist/api/schema.js +5 -4
  5. package/dist/api.d.ts +8 -2
  6. package/dist/api.js +404 -47
  7. package/dist/{app-pGsR__aT.d.ts → app-MEd7wbF0.d.ts} +82 -48
  8. package/dist/app.d.ts +3 -3
  9. package/dist/app.js +162 -119
  10. package/dist/{types-Du-HbEun.js → automation-B9Kc1gcf.js} +304 -33
  11. package/dist/{briefs-C3jhszOz.js → briefs-DrjBPQFy.js} +4 -4
  12. package/dist/{catalog-runtime-B9u_3-GW.js → catalog-runtime-C7339Cfm.js} +1 -1
  13. package/dist/{checkpoint-DLcJ5mKL.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-BSnNHO0R.js → client-Ch9Hg9NU.js} +2 -2
  24. package/dist/{config-Bmw4xTPK.js → config-JR9wke1W.js} +57 -17
  25. package/dist/{conversation-C_aYrISI.js → conversation-9Fxa1Zbq.js} +13 -1
  26. package/dist/{conversation-privacy-BV2dtba2.js → conversation-privacy-au02dyZK.js} +1 -1
  27. package/dist/{credential-sync-CukzQJ1x.js → credential-sync-BWTA3LnL.js} +14 -14
  28. package/dist/{executor-B9ksWZCv.js → executor-BW9XWgUQ.js} +38 -6
  29. package/dist/{images-CEXcQ0Id.js → images-BdG7zcNf.js} +3 -3
  30. package/dist/instrumentation.js +2 -2
  31. package/dist/{job-queue-CY1L2YRn.js → job-queue-BqXd0ZPV.js} +1 -1
  32. package/dist/{logging-F--48Q7Q.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-LasSG3Qc.js → oauth-authorization-BjRN99dc.js} +1 -1
  36. package/dist/{oauth-callback-server-D07ZzVMs.js → oauth-callback-server-B_1p98Mb.js} +2 -2
  37. package/dist/{pending-auth-DrG9Mkje.js → pending-auth-WqF4Gh8Z.js} +1 -1
  38. package/dist/{plugins-BT2l4We3.d.ts → plugins-CjfUP5gJ.d.ts} +1 -0
  39. package/dist/{profile-DZ2DUdd1.js → profile-BamYnmhO.js} +4 -4
  40. package/dist/{prompt-BM_5mAU3.js → prompt-Ctwy6hSI.js} +1 -1
  41. package/dist/queue-B5SnqRln.d.ts +25 -0
  42. package/dist/{registry-_JLY0x7b.js → registry-CXNv9fDX.js} +38 -2
  43. package/dist/{resolve-Cuoj3MML.js → resolve-C9ETkt4T.js} +2 -2
  44. package/dist/{runner-BfelmbMv.js → runner-DnBGVRnW.js} +9 -9
  45. package/dist/{sandbox-egress-signals-D5QUIO7Z.js → sandbox-egress-signals-DwJ7Boi_.js} +1 -1
  46. package/dist/{schema-CrdDxGbx.js → schema-CJiqDc5r.js} +3 -2
  47. package/dist/{skills-DAegjk5Y.js → skills-Dd8O9Aav.js} +3 -3
  48. package/dist/{spawn-DCfV7zGK.js → spawn-DFdRspSD.js} +2 -2
  49. package/dist/{task-queue-GcuFtzor.js → task-queue-DGQEOk1A.js} +16 -10
  50. package/dist/{task-runner-B0-P_3aq.js → task-runner-C5XCIDSF.js} +9 -9
  51. package/dist/{thread-state-TezcEhuH.js → thread-state-D3E29wZk.js} +5 -5
  52. package/dist/{turn-failure-response-Drhj_-t4.js → turn-failure-response-TDoj0aZz.js} +8 -8
  53. package/dist/{turn-lifecycle-BpIW3zOx.js → turn-lifecycle-DOnU45p7.js} +1 -1
  54. package/dist/{turn-session-routing-Dg8GDgyc.js → turn-session-routing-DbpZZoin.js} +1 -1
  55. package/dist/{validation-DAkYeKDT.js → validation-B9lMbisx.js} +1 -1
  56. package/dist/{version-9CB4Z-J4.js → version-CWkIGcLU.js} +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/{web-authorization-Cu33voNg.js → web-authorization-PPaoj2ns.js} +6 -6
  59. package/dist/{web-input-B3k0J7WB.js → web-input-CfNxXtHm.js} +86 -34
  60. package/dist/web-message-id-xPI_EFSC.js +239 -0
  61. package/dist/{work-PmkvcY9l.js → work-DNaoFrEe.js} +7 -7
  62. package/dist/{worker-COcaq2J6.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 +4 -4
  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 isExperimentalFeatureEnabled, 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 getExperimentalFeatures, 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 executeCredentialedEgressRequest, an as normalizeSandboxEgressTracePropagationDomains, b as unpublishedArtifactHeaders, bt as getEventCatalog, c as deleteMcpAuthSessionsForUserProvider, cn as clearSandboxEgressSignals, dn as parseSandboxEgressCredentialToken, en as isInvalidConversationRecordError, gn as startOAuthFlow, gt as processWorkspaceSnapshotJob, in as resolveSandboxEgressProviderForHost, l as deleteMcpServerSessionId, ln as consumeSandboxEgressAuthRequiredSignal, on as shouldPropagateSandboxEgressTrace, pn as formatProviderLabel, q as withScheduledAutomationLock, r as executeAgentRun, sn as SANDBOX_EGRESS_PROXY_PATH, t as createAgentRunner, tn as renderTaskInput, tt as findMatchingEventAutomations, u as deleteMcpStoredOAuthCredentials, un as consumeSandboxEgressPermissionDeniedSignal, v as publicArtifactHeaders, w as setExperimentalFeatures, xt as eventGuidance, y as readPublicArtifact, z as scheduledAutomationRunAttributes, zt as hasRunnableConversationWork } from "./agent-runner-BlDI1zV2.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-F--48Q7Q.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-9CB4Z-J4.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-Bmw4xTPK.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 { $ 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-DS7k0ZWY.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-B9ksWZCv.js";
10
- import { z as annotationCard } from "./conversation-C_aYrISI.js";
11
- import { n as pluginCatalogRuntime } from "./catalog-runtime-B9u_3-GW.js";
12
- import { X as projectConversationMessages, q as appendConversationMessages } from "./checkpoint-DLcJ5mKL.js";
13
- import { O as withLock$1, w as getStateAdapter } from "./profile-DZ2DUdd1.js";
14
- import { f as setSandboxResourceConfig, u as getSandboxResourceConfig } from "./resolve-Cuoj3MML.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-CY1L2YRn.js";
16
- import { f as getNextRunAtMs, r as scheduledRunSchema } from "./types-Du-HbEun.js";
17
- import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation-DAkYeKDT.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-B3k0J7WB.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-B0-P_3aq.js";
21
- import { c as listPendingAgentInvocationMailboxAppends, r as enqueueAgentInvocation } from "./work-PmkvcY9l.js";
22
- import { s as coerceThreadConversationState } from "./thread-state-TezcEhuH.js";
23
- import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-CukzQJ1x.js";
24
- import { a as registerVercelPluginTaskDevConsumer, n as createVercelPluginTaskCallback, s as queueCallback } from "./task-queue-GcuFtzor.js";
25
- import { t as processConversationWork } from "./worker-COcaq2J6.js";
26
- import { t as bindSpawnAgent } from "./spawn-DCfV7zGK.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
@@ -5022,6 +4978,7 @@ function dashboardRouteRegistrations(args) {
5022
4978
  ...args.dashboard,
5023
4979
  agentName: botConfig.userName,
5024
4980
  authenticatedRoutes: args.authenticatedRoutes,
4981
+ conversationWorkQueue: args.conversationWorkQueue,
5025
4982
  pluginRoutes: args.pluginRoutes
5026
4983
  };
5027
4984
  app ??= args.createDashboardApp(dashboardOptions);
@@ -5033,10 +4990,82 @@ function dashboardRouteRegistrations(args) {
5033
4990
  path
5034
4991
  }));
5035
4992
  }
4993
+ /** Reject plugin routes that would shadow dashboard or auth paths. */
5036
4994
  function validateDashboardRouteOwnership(args) {
5037
4995
  if (!args.dashboard || args.dashboard.disabled) return;
5038
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`);
5039
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
+ }
5040
5069
  /** Mount HTTP handlers before core routes claim those paths. */
5041
5070
  function mountRoutes(app, routes) {
5042
5071
  for (const route of routes) {
@@ -5050,7 +5079,6 @@ function mountRoutes(app, routes) {
5050
5079
  /** Create a Hono app with all Junior routes. */
5051
5080
  async function createApp(options) {
5052
5081
  const virtualConfig = await resolveVirtualConfig();
5053
- if (virtualConfig?.functionMaxDurationSeconds !== void 0) configureFunctionMaxDurationSeconds(virtualConfig.functionMaxDurationSeconds);
5054
5082
  const dashboard = options?.dashboard ?? virtualConfig?.dashboard;
5055
5083
  const configuredPlugins = options?.plugins ?? virtualConfig?.pluginSet;
5056
5084
  const plugins = pluginRuntimeRegistrationsFromPluginSet(configuredPlugins);
@@ -5060,21 +5088,19 @@ async function createApp(options) {
5060
5088
  validatePlugins(plugins);
5061
5089
  getDb();
5062
5090
  const shouldValidatePluginCatalog = hasConfiguredPluginCatalog(pluginConfig) || Boolean(configuredPlugins?.registrations.length) || Boolean(Object.keys(options?.configDefaults ?? {}).length);
5063
- const previousBotConfig = { ...botConfig };
5091
+ const previousRuntimeConfig = snapshotRuntimeConfig();
5064
5092
  const previousPluginCatalogConfig = pluginCatalogRuntime.setConfig(pluginConfig);
5065
5093
  const previousPlugins = setPlugins(plugins);
5066
5094
  const previousConfigDefaults = getConfigDefaults();
5067
- const previousSlackReactionConfig = getSlackReactionConfig();
5068
5095
  const previousSandboxResources = getSandboxResourceConfig();
5069
5096
  const previousExperimentalFeatures = getExperimentalFeatures();
5070
5097
  const previousBriefsConfig = setBriefsConfig(options?.briefs);
5071
5098
  const previousDashboardLinkOptions = setDashboardConversationLinkOptions(dashboard);
5072
- const restoreRuntimeConfig = () => {
5099
+ const restoreRuntimeConfig$1 = () => {
5073
5100
  pluginCatalogRuntime.setConfig(previousPluginCatalogConfig);
5074
5101
  setPlugins(previousPlugins);
5075
5102
  setConfigDefaults(previousConfigDefaults);
5076
- Object.assign(botConfig, previousBotConfig);
5077
- setSlackReactionConfig(previousSlackReactionConfig);
5103
+ restoreRuntimeConfig(previousRuntimeConfig);
5078
5104
  setSandboxResourceConfig(previousSandboxResources);
5079
5105
  setExperimentalFeatures(previousExperimentalFeatures);
5080
5106
  setBriefsConfig(previousBriefsConfig);
@@ -5082,7 +5108,10 @@ async function createApp(options) {
5082
5108
  };
5083
5109
  let pluginRoutes = [];
5084
5110
  let pluginApiRoutes = [];
5085
- const events = createEventAppPublisher({ conversationWork: () => getConversationWorkOptions() });
5111
+ const events = createEventAppPublisher({ conversationWork: () => ({
5112
+ ...getConversationWorkOptions(),
5113
+ queue: conversationWorkQueue
5114
+ }) });
5086
5115
  let sandboxEgressTracePropagationDomains = [];
5087
5116
  try {
5088
5117
  sandboxEgressTracePropagationDomains = normalizeSandboxEgressTracePropagationDomains(options?.sandbox?.egressTracePropagationDomains);
@@ -5090,9 +5119,12 @@ async function createApp(options) {
5090
5119
  setExperimentalFeatures(options?.experimental);
5091
5120
  setConfigDefaults(options?.configDefaults);
5092
5121
  warnUnregisteredConfigDefaults(options?.configDefaults);
5122
+ resetRuntimeConfig(virtualConfig?.functionMaxDurationSeconds);
5093
5123
  if (options?.profiles || options?.defaultProfile) setProfiles(options.profiles, options.defaultProfile);
5094
- if (options) setBotModelConfig(options);
5095
- 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);
5096
5128
  if (shouldValidatePluginCatalog) {
5097
5129
  pluginCatalogRuntime.getSignature();
5098
5130
  validatePluginRegistrations(configuredPlugins?.registrations ?? []);
@@ -5101,12 +5133,16 @@ async function createApp(options) {
5101
5133
  pluginRoutes = getPluginRoutes({ events });
5102
5134
  if (dashboard && !dashboard.disabled) pluginApiRoutes = getPluginApiRoutes();
5103
5135
  } catch (error) {
5104
- restoreRuntimeConfig();
5136
+ restoreRuntimeConfig$1();
5105
5137
  throw error;
5106
5138
  }
5107
5139
  const waitUntil = options?.waitUntil ?? await defaultWaitUntil();
5108
5140
  const tracePropagation = { domains: sandboxEgressTracePropagationDomains };
5109
- 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);
5110
5146
  const attachmentStorage = createVercelAttachmentStorage();
5111
5147
  const agentRunner = createAgentRunner(executeAgentRun, {
5112
5148
  attachmentStorage,
@@ -5122,7 +5158,10 @@ async function createApp(options) {
5122
5158
  const getConversationWorkOptions = () => {
5123
5159
  conversationWorkOptions ??= options?.conversationWork ?? createProductionConversationWorkOptions({
5124
5160
  agentRunner,
5125
- services: runtimeServiceOverrides
5161
+ queue: conversationWorkQueue,
5162
+ ...pluginTaskQueue ? { sendPluginTask: (message) => pluginTaskQueue.send(message) } : void 0,
5163
+ services: runtimeServiceOverrides,
5164
+ waitUntil: (task) => waitUntil(task)
5126
5165
  });
5127
5166
  return conversationWorkOptions;
5128
5167
  };
@@ -5138,7 +5177,7 @@ async function createApp(options) {
5138
5177
  conversations: createAcpConversations({
5139
5178
  conversationStore: work.conversationStore,
5140
5179
  eventStore: getConversationEventStore(),
5141
- queue: work.queue ?? getVercelConversationWorkQueue(),
5180
+ queue: conversationWorkQueue,
5142
5181
  state
5143
5182
  }),
5144
5183
  onError: (error, event, attributes) => void logException(error, event, {
@@ -5169,10 +5208,13 @@ async function createApp(options) {
5169
5208
  routes: pluginRoutes
5170
5209
  });
5171
5210
  } catch (error) {
5172
- restoreRuntimeConfig();
5211
+ restoreRuntimeConfig$1();
5173
5212
  throw error;
5174
5213
  }
5175
- const slackWebhookServices = createProductionSlackWebhookServices({ services: runtimeServiceOverrides });
5214
+ const slackWebhookServices = createProductionSlackWebhookServices({
5215
+ queue: conversationWorkQueue,
5216
+ services: runtimeServiceOverrides
5217
+ });
5176
5218
  const app = new Hono();
5177
5219
  app.onError((err, c) => {
5178
5220
  logException(err, "route.unhandled.exception");
@@ -5189,6 +5231,7 @@ async function createApp(options) {
5189
5231
  mountRoutes(app, pluginRoutes);
5190
5232
  mountRoutes(app, await createDashboardRouteRegistrations({
5191
5233
  authenticatedRoutes,
5234
+ conversationWorkQueue,
5192
5235
  dashboard,
5193
5236
  createDashboardApp: virtualConfig?.createDashboardApp,
5194
5237
  pluginRoutes: pluginApiRoutes
@@ -5200,10 +5243,10 @@ async function createApp(options) {
5200
5243
  storage: attachmentStorage
5201
5244
  }));
5202
5245
  app.get("/api/oauth/callback/mcp/:provider", (c) => {
5203
- 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 });
5204
5247
  });
5205
5248
  app.get("/api/oauth/callback/:provider", (c) => {
5206
- 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 });
5207
5250
  });
5208
5251
  app.get("/api/internal/sandbox-egress/signals", (c) => {
5209
5252
  return GET(c.req.raw);
@@ -5235,7 +5278,7 @@ async function createApp(options) {
5235
5278
  return workspaceSnapshotJobPOST(c.req.raw);
5236
5279
  });
5237
5280
  app.get("/api/internal/heartbeat", (c) => {
5238
- return GET$2(c.req.raw, waitUntil);
5281
+ return GET$2(c.req.raw, waitUntil, { conversationWorkQueue });
5239
5282
  });
5240
5283
  app.get("/api/internal/retention", (c) => {
5241
5284
  return GET$1(c.req.raw);