@sentry/junior 0.132.0 → 0.133.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 (58) hide show
  1. package/dist/{agent-hooks-ONXOJDR6.js → agent-hooks-5BUIXVIX.js} +9 -9
  2. package/dist/api.js +16 -16
  3. package/dist/app.js +84 -37
  4. package/dist/{catalog-runtime-BATAY4R7.js → catalog-runtime-VGB3DWXZ.js} +5 -5
  5. package/dist/chat/config.d.ts +2 -0
  6. package/dist/chat/conversations/projection.d.ts +3 -1
  7. package/dist/chat/conversations/sql/bindings.d.ts +13 -0
  8. package/dist/chat/conversations/sql/store.d.ts +3 -0
  9. package/dist/chat/conversations/store.d.ts +15 -0
  10. package/dist/chat/runtime/reply-executor.d.ts +1 -0
  11. package/dist/chat/runtime/slack-runtime.d.ts +2 -0
  12. package/dist/chat/slack/dispatch-turn.d.ts +1 -0
  13. package/dist/chat/slack/reply.d.ts +1 -1
  14. package/dist/{chunk-JYQAE2ZU.js → chunk-5ZAZHLIW.js} +1 -1
  15. package/dist/{chunk-G3WYA2RS.js → chunk-AH5HTUYX.js} +1 -1
  16. package/dist/{chunk-GPXVDJML.js → chunk-ECUILEUX.js} +24 -15
  17. package/dist/{chunk-GOEZU33G.js → chunk-EJRJWBKG.js} +1 -1
  18. package/dist/{chunk-WEJIS7OC.js → chunk-FX6BLEDP.js} +1 -1
  19. package/dist/{chunk-V44FFBO3.js → chunk-HJ4KDO4N.js} +1 -1
  20. package/dist/{chunk-SKWIIUS7.js → chunk-HTGXUNEC.js} +7 -7
  21. package/dist/{chunk-2425Q4OR.js → chunk-IKO5LFIU.js} +1 -1
  22. package/dist/{chunk-BKE47OOW.js → chunk-IVTHTAVK.js} +2 -2
  23. package/dist/{chunk-B7IY6SVJ.js → chunk-JLN4XSPR.js} +1 -1
  24. package/dist/{chunk-NNHUGGO4.js → chunk-LDRO4OQ4.js} +19 -3
  25. package/dist/{chunk-WYQP7QSB.js → chunk-LNYNTR27.js} +101 -61
  26. package/dist/{chunk-KB2M27DL.js → chunk-QWGZ273D.js} +78 -36
  27. package/dist/{chunk-ZMV2YBT6.js → chunk-T5FPIBU2.js} +14 -14
  28. package/dist/{chunk-AW5Z3T7V.js → chunk-TBVS7GBE.js} +4 -4
  29. package/dist/{chunk-ODIP5CEM.js → chunk-TLN54TOQ.js} +1 -1
  30. package/dist/{chunk-GTKNPQNN.js → chunk-TU7P77FI.js} +36 -24
  31. package/dist/{chunk-U76PS7AT.js → chunk-V365UVCU.js} +2 -2
  32. package/dist/{chunk-ISNRPCPG.js → chunk-VL7OYSHD.js} +1 -1
  33. package/dist/{chunk-O2UXPUVQ.js → chunk-VQA25AL4.js} +6 -6
  34. package/dist/{chunk-ALDPUN3Z.js → chunk-WHEMUEXT.js} +5 -5
  35. package/dist/{chunk-XN656LB4.js → chunk-XTQGVNM3.js} +3 -3
  36. package/dist/cli/chat.js +24 -24
  37. package/dist/cli/check.js +6 -6
  38. package/dist/cli/init.js +1 -0
  39. package/dist/cli/plugins.js +12 -12
  40. package/dist/cli/snapshot-create.js +9 -9
  41. package/dist/cli/upgrade.js +9 -8
  42. package/dist/db/executor.d.ts +2 -1
  43. package/dist/db/neon.d.ts +1 -0
  44. package/dist/db/postgres.d.ts +1 -0
  45. package/dist/db/schema/conversation-bindings.d.ts +110 -0
  46. package/dist/db/schema.d.ts +111 -1
  47. package/dist/{db-QFFZACXF.js → db-RICMPUFT.js} +7 -7
  48. package/dist/instrumentation.js +4 -4
  49. package/dist/nitro.js +2 -2
  50. package/dist/{oauth-callback-server-5WXLD533.js → oauth-callback-server-YFVS4SAX.js} +17 -17
  51. package/dist/{runner-Y3LTUNAA.js → runner-A3LVGZR6.js} +11 -11
  52. package/dist/{skills-7M5C24GM.js → skills-P7Q6Z6PN.js} +6 -6
  53. package/dist/{validation-MRILMYDI.js → validation-RYHOWBET.js} +6 -6
  54. package/dist/version.js +1 -1
  55. package/migrations/0018_curvy_excalibur.sql +12 -0
  56. package/migrations/meta/0018_snapshot.json +1756 -0
  57. package/migrations/meta/_journal.json +8 -1
  58. package/package.json +5 -5
@@ -11,19 +11,19 @@ import {
11
11
  getPlugins,
12
12
  setPlugins,
13
13
  validatePlugins
14
- } from "./chunk-ALDPUN3Z.js";
15
- import "./chunk-WYQP7QSB.js";
16
- import "./chunk-KB2M27DL.js";
17
- import "./chunk-ODIP5CEM.js";
18
- import "./chunk-NNHUGGO4.js";
14
+ } from "./chunk-WHEMUEXT.js";
15
+ import "./chunk-LNYNTR27.js";
16
+ import "./chunk-QWGZ273D.js";
17
+ import "./chunk-TLN54TOQ.js";
18
+ import "./chunk-LDRO4OQ4.js";
19
19
  import "./chunk-VFUK3X5B.js";
20
- import "./chunk-ISNRPCPG.js";
20
+ import "./chunk-VL7OYSHD.js";
21
21
  import "./chunk-HZF5P5UN.js";
22
22
  import "./chunk-F3B2YJ76.js";
23
- import "./chunk-GOEZU33G.js";
23
+ import "./chunk-EJRJWBKG.js";
24
24
  import "./chunk-6GWA276C.js";
25
- import "./chunk-WEJIS7OC.js";
26
- import "./chunk-2425Q4OR.js";
25
+ import "./chunk-FX6BLEDP.js";
26
+ import "./chunk-IKO5LFIU.js";
27
27
  import "./chunk-MLKGABMK.js";
28
28
  export {
29
29
  PluginHookDeniedError,
package/dist/api.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  formatSlackConversationRedactedLabel,
33
33
  readHealthReport,
34
34
  resolveSlackConversationContextFromThreadId
35
- } from "./chunk-U76PS7AT.js";
35
+ } from "./chunk-V365UVCU.js";
36
36
  import {
37
37
  buildSentryConversationUrl
38
38
  } from "./chunk-4CODA7P5.js";
@@ -54,10 +54,10 @@ import {
54
54
  listPublicEventTasksForTeams,
55
55
  listPublicScheduledTasksForTeams,
56
56
  readStats
57
- } from "./chunk-XN656LB4.js";
57
+ } from "./chunk-XTQGVNM3.js";
58
58
  import {
59
59
  parseSlackThreadId
60
- } from "./chunk-G3WYA2RS.js";
60
+ } from "./chunk-AH5HTUYX.js";
61
61
  import {
62
62
  agentTurnUsageSchema,
63
63
  hasAgentTurnUsage,
@@ -70,38 +70,38 @@ import {
70
70
  listConversationAnnotations,
71
71
  renderPluginConversationEvent,
72
72
  resolveViewerUser
73
- } from "./chunk-ALDPUN3Z.js";
73
+ } from "./chunk-WHEMUEXT.js";
74
74
  import {
75
75
  decodeStoredConversationEvent,
76
76
  getDb,
77
77
  getSqlExecutor,
78
78
  locationFromRow,
79
79
  parseSessionSource
80
- } from "./chunk-WYQP7QSB.js";
80
+ } from "./chunk-LNYNTR27.js";
81
81
  import {
82
82
  juniorApiTokens,
83
83
  juniorConversationEvents,
84
84
  juniorConversations,
85
85
  juniorIdentities,
86
86
  juniorUsers
87
- } from "./chunk-KB2M27DL.js";
88
- import "./chunk-ODIP5CEM.js";
89
- import "./chunk-NNHUGGO4.js";
87
+ } from "./chunk-QWGZ273D.js";
88
+ import "./chunk-TLN54TOQ.js";
89
+ import "./chunk-LDRO4OQ4.js";
90
90
  import {
91
91
  juniorDestinations
92
92
  } from "./chunk-VFUK3X5B.js";
93
93
  import {
94
94
  canExposeConversationPayload
95
- } from "./chunk-ISNRPCPG.js";
95
+ } from "./chunk-VL7OYSHD.js";
96
96
  import "./chunk-HZF5P5UN.js";
97
97
  import {
98
98
  parseSlackChannelId,
99
99
  parseSlackTeamId
100
100
  } from "./chunk-F3B2YJ76.js";
101
- import "./chunk-GOEZU33G.js";
101
+ import "./chunk-EJRJWBKG.js";
102
102
  import "./chunk-6GWA276C.js";
103
- import "./chunk-WEJIS7OC.js";
104
- import "./chunk-2425Q4OR.js";
103
+ import "./chunk-FX6BLEDP.js";
104
+ import "./chunk-IKO5LFIU.js";
105
105
  import "./chunk-MLKGABMK.js";
106
106
 
107
107
  // src/api.ts
@@ -2027,7 +2027,7 @@ function readDescriptionText(home) {
2027
2027
  }
2028
2028
  }
2029
2029
  async function readSkillReports() {
2030
- const { discoverSkills } = await import("./skills-7M5C24GM.js");
2030
+ const { discoverSkills } = await import("./skills-P7Q6Z6PN.js");
2031
2031
  const skills = await discoverSkills();
2032
2032
  return skillReportsSchema.parse(
2033
2033
  skills.map((skill) => ({
@@ -2037,7 +2037,7 @@ async function readSkillReports() {
2037
2037
  );
2038
2038
  }
2039
2039
  async function readPlugins() {
2040
- const { pluginCatalogRuntime } = await import("./catalog-runtime-BATAY4R7.js");
2040
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-VGB3DWXZ.js");
2041
2041
  return pluginsSchema.parse(
2042
2042
  pluginCatalogRuntime.getProviders().map((plugin) => ({
2043
2043
  configKeys: plugin.manifest.configKeys ?? [],
@@ -2050,7 +2050,7 @@ async function readPlugins() {
2050
2050
  async function readRuntimeInfoReport() {
2051
2051
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
2052
2052
  import("./discovery-GUFTFBTL.js"),
2053
- import("./catalog-runtime-BATAY4R7.js"),
2053
+ import("./catalog-runtime-VGB3DWXZ.js"),
2054
2054
  readPlugins(),
2055
2055
  readSkillReports()
2056
2056
  ]);
@@ -2066,7 +2066,7 @@ async function readRuntimeInfoReport() {
2066
2066
  }
2067
2067
  async function readPluginOperationalReportFeed() {
2068
2068
  const nowMs = Date.now();
2069
- const { getPluginOperationalReports } = await import("./agent-hooks-ONXOJDR6.js");
2069
+ const { getPluginOperationalReports } = await import("./agent-hooks-5BUIXVIX.js");
2070
2070
  return pluginOperationalReportFeedSchema.parse({
2071
2071
  source: "plugins",
2072
2072
  generatedAt: new Date(nowMs).toISOString(),
package/dist/app.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  startConversationWork,
51
51
  startSlackProcessingReaction,
52
52
  stripLeadingBotMention
53
- } from "./chunk-GTKNPQNN.js";
53
+ } from "./chunk-TU7P77FI.js";
54
54
  import "./chunk-FA6POGLH.js";
55
55
  import {
56
56
  ConversationTurnLifecycleService,
@@ -65,13 +65,13 @@ import {
65
65
  processPluginTask,
66
66
  requireTurnFailureEventId,
67
67
  scheduleSessionCompletedPluginTasks
68
- } from "./chunk-O2UXPUVQ.js";
68
+ } from "./chunk-VQA25AL4.js";
69
69
  import {
70
70
  GET,
71
71
  conversationVisibilityFromSlackChannelType,
72
72
  resolveSlackChannelTypeFromMessage,
73
73
  resolveSlackConversationContext
74
- } from "./chunk-U76PS7AT.js";
74
+ } from "./chunk-V365UVCU.js";
75
75
  import "./chunk-4CODA7P5.js";
76
76
  import "./chunk-UTL3MHPC.js";
77
77
  import {
@@ -90,7 +90,7 @@ import {
90
90
  import {
91
91
  validatePluginEgressCredentialHooks,
92
92
  validatePluginRegistrations
93
- } from "./chunk-JYQAE2ZU.js";
93
+ } from "./chunk-5ZAZHLIW.js";
94
94
  import {
95
95
  defineJuniorPlugins,
96
96
  pluginCatalogConfigFromEnv,
@@ -125,7 +125,7 @@ import {
125
125
  setConfigDefaults,
126
126
  shouldEmitDevAgentTrace,
127
127
  shouldPropagateSandboxEgressTrace
128
- } from "./chunk-ZMV2YBT6.js";
128
+ } from "./chunk-T5FPIBU2.js";
129
129
  import "./chunk-DIB4GX3G.js";
130
130
  import {
131
131
  RetryableDeliveryError,
@@ -136,7 +136,7 @@ import {
136
136
  formatProviderLabel,
137
137
  postSlackMessage,
138
138
  startOAuthFlow
139
- } from "./chunk-SKWIIUS7.js";
139
+ } from "./chunk-HTGXUNEC.js";
140
140
  import {
141
141
  ConversationTurnBoundaryError,
142
142
  CooperativeTurnYieldError,
@@ -192,19 +192,19 @@ import {
192
192
  trimTrailingAssistantMessages,
193
193
  updateConversationStats,
194
194
  upsertConversationMessage
195
- } from "./chunk-GPXVDJML.js";
195
+ } from "./chunk-ECUILEUX.js";
196
196
  import "./chunk-EPBBYMNE.js";
197
197
  import {
198
198
  getSandboxResourceConfig,
199
199
  setSandboxResourceConfig
200
- } from "./chunk-AW5Z3T7V.js";
200
+ } from "./chunk-TBVS7GBE.js";
201
201
  import {
202
202
  createSchedulerSqlStore,
203
203
  findMatchingEventTasks
204
- } from "./chunk-XN656LB4.js";
204
+ } from "./chunk-XTQGVNM3.js";
205
205
  import {
206
206
  parseSlackThreadId
207
- } from "./chunk-G3WYA2RS.js";
207
+ } from "./chunk-AH5HTUYX.js";
208
208
  import "./chunk-HX236W2U.js";
209
209
  import "./chunk-PDO5BLNM.js";
210
210
  import "./chunk-UIE3R5XU.js";
@@ -232,7 +232,7 @@ import {
232
232
  verifyEventTaskCredentialSubject,
233
233
  verifyScheduledTaskCredentialSubject,
234
234
  verifySlackDirectCredentialSubject
235
- } from "./chunk-ALDPUN3Z.js";
235
+ } from "./chunk-WHEMUEXT.js";
236
236
  import {
237
237
  contextProvenance,
238
238
  createSlackDestination,
@@ -243,16 +243,16 @@ import {
243
243
  instructionProvenanceFor,
244
244
  requireSlackDestination,
245
245
  withConversationEventLock
246
- } from "./chunk-WYQP7QSB.js";
246
+ } from "./chunk-LNYNTR27.js";
247
247
  import {
248
248
  juniorConversationEvents,
249
249
  juniorConversations
250
- } from "./chunk-KB2M27DL.js";
250
+ } from "./chunk-QWGZ273D.js";
251
251
  import {
252
252
  acquireActiveLock,
253
253
  getStateAdapter,
254
254
  sleep
255
- } from "./chunk-ODIP5CEM.js";
255
+ } from "./chunk-TLN54TOQ.js";
256
256
  import {
257
257
  STANDARD_MODEL_PROFILE,
258
258
  botConfig,
@@ -270,16 +270,16 @@ import {
270
270
  modelIdForProfile,
271
271
  setSlackReactionConfig,
272
272
  standardModelId
273
- } from "./chunk-NNHUGGO4.js";
273
+ } from "./chunk-LDRO4OQ4.js";
274
274
  import {
275
275
  juniorDestinations
276
276
  } from "./chunk-VFUK3X5B.js";
277
- import "./chunk-ISNRPCPG.js";
278
- import "./chunk-BKE47OOW.js";
277
+ import "./chunk-VL7OYSHD.js";
278
+ import "./chunk-IVTHTAVK.js";
279
279
  import {
280
280
  pluginCatalogRuntime
281
- } from "./chunk-B7IY6SVJ.js";
282
- import "./chunk-V44FFBO3.js";
281
+ } from "./chunk-JLN4XSPR.js";
282
+ import "./chunk-HJ4KDO4N.js";
283
283
  import {
284
284
  credentialSubjectSchema
285
285
  } from "./chunk-77VDLF3Z.js";
@@ -311,7 +311,7 @@ import {
311
311
  withContext,
312
312
  withLogContext,
313
313
  withSpan
314
- } from "./chunk-GOEZU33G.js";
314
+ } from "./chunk-EJRJWBKG.js";
315
315
  import {
316
316
  continueTrace
317
317
  } from "./chunk-6GWA276C.js";
@@ -319,10 +319,10 @@ import "./chunk-OOUNJNMR.js";
319
319
  import "./chunk-H4HBKISO.js";
320
320
  import {
321
321
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
322
- } from "./chunk-WEJIS7OC.js";
322
+ } from "./chunk-FX6BLEDP.js";
323
323
  import {
324
324
  JUNIOR_VERSION
325
- } from "./chunk-2425Q4OR.js";
325
+ } from "./chunk-IKO5LFIU.js";
326
326
  import "./chunk-MLKGABMK.js";
327
327
 
328
328
  // src/app.ts
@@ -2804,8 +2804,9 @@ async function lookupSlackUser(teamId, userId) {
2804
2804
  }
2805
2805
 
2806
2806
  // src/chat/slack/message-control.ts
2807
+ var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
2807
2808
  function stripLeadingSteeringOverride(text) {
2808
- return text.replace(/^\s*!!\s*/, "");
2809
+ return text.replace(LEADING_MENTION_BEFORE_STEERING_RE, "$1").replace(/^\s*!!\s*/, "");
2809
2810
  }
2810
2811
 
2811
2812
  // src/chat/task-execution/slack-work.ts
@@ -3326,6 +3327,7 @@ function createSlackConversationWorker(options) {
3326
3327
  try {
3327
3328
  if (route === "mention") {
3328
3329
  await options.runtime.handleNewMention(thread, latestMessage, {
3330
+ conversationId: context.conversationId,
3329
3331
  destination: context.destination,
3330
3332
  messageContext,
3331
3333
  drainSteeringMessages,
@@ -3338,6 +3340,7 @@ function createSlackConversationWorker(options) {
3338
3340
  thread,
3339
3341
  latestMessage,
3340
3342
  {
3343
+ conversationId: context.conversationId,
3341
3344
  destination: context.destination,
3342
3345
  messageContext,
3343
3346
  drainSteeringMessages,
@@ -3720,10 +3723,32 @@ function shouldIgnoreMessage(message) {
3720
3723
  function shouldPersistBeforeAck(body) {
3721
3724
  return body.event?.type === "app_mention" || body.event?.type === "message";
3722
3725
  }
3726
+ async function resolveSlackConversationId(args) {
3727
+ const providerThread = parseSlackThreadId(args.canonicalThreadId);
3728
+ const conversationStore = args.conversationStore ?? getConversationStore();
3729
+ if (!providerThread) {
3730
+ return args.canonicalThreadId;
3731
+ }
3732
+ return await conversationStore.getConversationIdByProviderConversation({
3733
+ provider: "slack",
3734
+ providerDestinationId: providerThread.channelId,
3735
+ providerTenantId: args.installation.teamId ?? "",
3736
+ providerConversationId: providerThread.threadTs
3737
+ }) ?? args.canonicalThreadId;
3738
+ }
3723
3739
  async function persistSlackMessage(args) {
3740
+ const canonicalThreadId = normalizeIncomingSlackThreadId(
3741
+ args.message.threadId,
3742
+ args.message
3743
+ );
3744
+ const conversationId = args.conversationId ?? await resolveSlackConversationId({
3745
+ canonicalThreadId,
3746
+ conversationStore: args.conversationStore,
3747
+ installation: args.installation
3748
+ });
3724
3749
  const thread = await buildThread(args);
3725
3750
  const inbound = buildSlackInboundMessage({
3726
- conversationId: thread.id,
3751
+ conversationId,
3727
3752
  installation: args.installation,
3728
3753
  message: args.message,
3729
3754
  receivedAtMs: args.receivedAtMs,
@@ -3743,12 +3768,17 @@ async function routeParsedMessage(args) {
3743
3768
  if (shouldIgnoreMessage(args.message)) {
3744
3769
  return;
3745
3770
  }
3746
- const threadId = normalizeMessageThreadId(args.message);
3771
+ const canonicalThreadId = normalizeMessageThreadId(args.message);
3772
+ const conversationId = await resolveSlackConversationId({
3773
+ canonicalThreadId,
3774
+ conversationStore: args.conversationStore,
3775
+ installation: args.installation
3776
+ });
3747
3777
  const isMention = args.event.type === "app_mention" || textMentionsBot2(args.event, args.adapter.botUserId);
3748
3778
  if (isMention) {
3749
3779
  args.message.isMention = true;
3750
3780
  }
3751
- const route = isDmEvent(args.event) || isMention ? "mention" : await args.state.isSubscribed(threadId) ? "subscribed" : void 0;
3781
+ const route = isDmEvent(args.event) || isMention ? "mention" : await args.state.isSubscribed(canonicalThreadId) ? "subscribed" : void 0;
3752
3782
  if (!route) {
3753
3783
  return;
3754
3784
  }
@@ -3756,6 +3786,7 @@ async function routeParsedMessage(args) {
3756
3786
  adapter: args.adapter,
3757
3787
  installation: args.installation,
3758
3788
  message: args.message,
3789
+ conversationId,
3759
3790
  conversationStore: args.conversationStore,
3760
3791
  queue: args.queue,
3761
3792
  receivedAtMs: args.receivedAtMs,
@@ -5639,6 +5670,7 @@ function createSlackTurnRuntime(deps) {
5639
5670
  await deps.replyToThread(thread, message, {
5640
5671
  explicitMention: true,
5641
5672
  beforeFirstResponsePost: hooks.beforeFirstResponsePost,
5673
+ conversationId: hooks.conversationId,
5642
5674
  destination: hooks.destination,
5643
5675
  queuedMessages,
5644
5676
  ack,
@@ -5903,6 +5935,7 @@ function createSlackTurnRuntime(deps) {
5903
5935
  );
5904
5936
  await deps.replyToThread(thread, message, {
5905
5937
  explicitMention: Boolean(message.isMention),
5938
+ conversationId: hooks.conversationId,
5906
5939
  destination: hooks.destination,
5907
5940
  preparedState,
5908
5941
  beforeFirstResponsePost: hooks.beforeFirstResponsePost,
@@ -6824,8 +6857,8 @@ function createReplyToThread(deps) {
6824
6857
  destination,
6825
6858
  visibility: options.execution?.destinationVisibility ?? conversationVisibilityFromSlackChannelType(slackChannelType)
6826
6859
  });
6827
- const threadTs = getThreadTs(threadId);
6828
6860
  const assistantThreadContext = getAssistantThreadContext(message);
6861
+ const threadTs = getThreadTs(threadId) ?? assistantThreadContext?.threadTs;
6829
6862
  const messageTs = getMessageTs(message);
6830
6863
  const teamId = destination.teamId;
6831
6864
  const source = options.execution?.source ?? createSlackSource2({
@@ -6837,7 +6870,7 @@ function createReplyToThread(deps) {
6837
6870
  });
6838
6871
  const slackActionToken = readSlackActionToken(message);
6839
6872
  const runId = options.execution?.dispatch?.id ?? getRunId(thread, message);
6840
- const conversationId = threadId ?? runId;
6873
+ const conversationId = options.conversationId ?? threadId ?? runId;
6841
6874
  if (!conversationId) {
6842
6875
  throw new Error("Slack reply execution requires a conversation id");
6843
6876
  }
@@ -7289,11 +7322,11 @@ function createReplyToThread(deps) {
7289
7322
  return;
7290
7323
  }
7291
7324
  boundaryFailureCode = "delivery_failed";
7292
- let slackTs;
7325
+ let slackMessageTs2 = [];
7293
7326
  await beforeFirstResponsePost();
7294
7327
  try {
7295
7328
  if (channelId && thread.adapter.name === "slack") {
7296
- slackTs = await sendSlackReply({
7329
+ slackMessageTs2 = await sendSlackReply({
7297
7330
  channelId,
7298
7331
  conversationId,
7299
7332
  replyAttribution: options.execution?.dispatch?.replyAttribution,
@@ -7302,7 +7335,10 @@ function createReplyToThread(deps) {
7302
7335
  });
7303
7336
  } else {
7304
7337
  for (const part of splitSlackReplyText(text)) {
7305
- slackTs = (await thread.post(buildSlackOutputMessage(part))).id;
7338
+ const postedMessageTs = (await thread.post(buildSlackOutputMessage(part))).id;
7339
+ if (postedMessageTs) {
7340
+ slackMessageTs2.push(postedMessageTs);
7341
+ }
7306
7342
  }
7307
7343
  }
7308
7344
  } catch (error) {
@@ -7320,6 +7356,7 @@ function createReplyToThread(deps) {
7320
7356
  failureCode: "delivery_failed"
7321
7357
  });
7322
7358
  }
7359
+ const slackTs = slackMessageTs2.at(-1);
7323
7360
  assistantMessageDelivered = true;
7324
7361
  acceptedDeliveryId = slackTs;
7325
7362
  options.onTurnDeliveryAccepted?.(slackTs);
@@ -7337,17 +7374,26 @@ function createReplyToThread(deps) {
7337
7374
  );
7338
7375
  }
7339
7376
  try {
7377
+ const providerConversationIds = threadTs ? [threadTs] : slackMessageTs2;
7340
7378
  await persistWithRetry(
7341
- () => agentMessage && conversationId ? commitAcceptedReply({
7342
- agentMessage,
7379
+ () => commitAcceptedReply({
7380
+ ...agentMessage ? { agentMessage } : {},
7343
7381
  conversation: preparedState.conversation,
7344
7382
  conversationMessageId: recordedMessageId,
7345
- conversationId
7346
- }) : persistConversationMessages({
7347
- conversation: preparedState.conversation,
7348
- conversationId
7383
+ conversationId,
7384
+ ...options.execution?.dispatch && providerConversationIds.length > 0 ? {
7385
+ providerConversationBindings: providerConversationIds.map(
7386
+ (providerConversationId) => ({
7387
+ provider: "slack",
7388
+ providerDestinationId: destination.channelId,
7389
+ providerTenantId: destination.teamId,
7390
+ providerConversationId
7391
+ })
7392
+ )
7393
+ } : {}
7349
7394
  })
7350
7395
  );
7396
+ await options.onTurnStatePersisted?.();
7351
7397
  } catch (error) {
7352
7398
  logException(
7353
7399
  new Error("Accepted assistant message persistence failed"),
@@ -8254,6 +8300,7 @@ function createSlackDispatchTurnRunner(options) {
8254
8300
  const routing = buildDispatchRoutingContext(dispatch2);
8255
8301
  await options.replyToThread(thread, message, {
8256
8302
  ack: hooks.ack,
8303
+ conversationId,
8257
8304
  destination: dispatch2.destination,
8258
8305
  execution: {
8259
8306
  authorizationFlowMode: "disabled",
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-B7IY6SVJ.js";
4
- import "./chunk-V44FFBO3.js";
3
+ } from "./chunk-JLN4XSPR.js";
4
+ import "./chunk-HJ4KDO4N.js";
5
5
  import "./chunk-77VDLF3Z.js";
6
6
  import "./chunk-HZF5P5UN.js";
7
7
  import "./chunk-F3B2YJ76.js";
8
- import "./chunk-GOEZU33G.js";
8
+ import "./chunk-EJRJWBKG.js";
9
9
  import "./chunk-6GWA276C.js";
10
10
  import "./chunk-OOUNJNMR.js";
11
11
  import "./chunk-H4HBKISO.js";
12
- import "./chunk-WEJIS7OC.js";
13
- import "./chunk-2425Q4OR.js";
12
+ import "./chunk-FX6BLEDP.js";
13
+ import "./chunk-IKO5LFIU.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
  export {
16
16
  pluginCatalogRuntime
@@ -1,5 +1,6 @@
1
1
  import { type TurnReasoningLevel } from "@/chat/reasoning-level";
2
2
  import { type ExecutionProfileConfig } from "@/chat/model-profile";
3
+ export declare const DEFAULT_SQL_STATEMENT_TIMEOUT_MS = 30000;
3
4
  /**
4
5
  * Buffer between the Vercel function timeout and the agent turn timeout so
5
6
  * Junior can abort, persist, and schedule continuation before host teardown.
@@ -32,6 +33,7 @@ export interface ChatConfig {
32
33
  sql: {
33
34
  databaseUrl: string;
34
35
  driver: SqlDriver;
36
+ statementTimeoutMs: number | false;
35
37
  };
36
38
  slack: {
37
39
  botToken?: string;
@@ -2,6 +2,7 @@ import { type PiMessage } from "@/chat/pi/messages";
2
2
  import { type ConversationMessageProvenance } from "@/chat/conversations/provenance";
3
3
  import type { AuthorizationKind, ConversationEvent } from "@/chat/conversations/history";
4
4
  import type { JuniorSqlDatabase } from "@/db/db";
5
+ import { type ProviderConversationBinding } from "@/chat/conversations/sql/bindings";
5
6
  import { type PiConversationEventProjection, type PiConversationProjection } from "@/chat/pi/conversation-events";
6
7
  import type { ModelProfile } from "@/chat/model-profile";
7
8
  import type { TurnReasoningLevel } from "@/chat/reasoning-level";
@@ -73,10 +74,11 @@ export declare function commitMessages(args: {
73
74
  * produced it.
74
75
  */
75
76
  export declare function commitAcceptedReply(args: {
76
- agentMessage: AssistantMessage;
77
+ agentMessage?: AssistantMessage;
77
78
  conversation: ThreadConversationState;
78
79
  conversationMessageId: string;
79
80
  conversationId: string;
81
+ providerConversationBindings?: Array<Omit<ProviderConversationBinding, "conversationId">>;
80
82
  repliedAtMs?: number;
81
83
  }): Promise<void>;
82
84
  /** Record a successful MCP provider connection without duplicating the fact. */
@@ -0,0 +1,13 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ export interface ProviderConversationBinding {
3
+ conversationId: string;
4
+ provider: string;
5
+ providerDestinationId: string;
6
+ providerTenantId: string;
7
+ providerConversationId: string;
8
+ }
9
+ export type ProviderConversationReference = Omit<ProviderConversationBinding, "conversationId">;
10
+ /** Resolve the durable conversation bound to provider-owned coordinates. */
11
+ export declare function getConversationIdByProviderConversation(executor: JuniorSqlDatabase, args: ProviderConversationReference): Promise<string | undefined>;
12
+ /** Bind provider coordinates to a durable conversation in the caller's SQL scope. */
13
+ export declare function bindProviderConversation(executor: JuniorSqlDatabase, args: ProviderConversationBinding): Promise<void>;
@@ -4,9 +4,12 @@ import type { StoredSlackActor } from "@/chat/actor";
4
4
  import type { JuniorSqlDatabase } from "@/db/db";
5
5
  import type { Conversation, ConversationExecution, ConversationSource, ConversationStore } from "../store";
6
6
  import type { AgentTurnUsage } from "@/chat/usage";
7
+ import { type ProviderConversationBinding, type ProviderConversationReference } from "./bindings";
7
8
  export declare class SqlStore implements ConversationStore {
8
9
  private readonly executor;
9
10
  constructor(executor: JuniorSqlDatabase);
11
+ getConversationIdByProviderConversation(args: ProviderConversationReference): Promise<string | undefined>;
12
+ bindProviderConversation(args: ProviderConversationBinding): Promise<void>;
10
13
  get(args: {
11
14
  conversationId: string;
12
15
  }): Promise<Conversation | undefined>;
@@ -51,6 +51,21 @@ export interface ConversationStore {
51
51
  get(args: {
52
52
  conversationId: string;
53
53
  }): Promise<Conversation | undefined>;
54
+ /** Resolve the durable conversation bound to one provider conversation. */
55
+ getConversationIdByProviderConversation(args: {
56
+ provider: string;
57
+ providerDestinationId: string;
58
+ providerTenantId: string;
59
+ providerConversationId: string;
60
+ }): Promise<string | undefined>;
61
+ /** Bind one provider conversation to its pre-existing durable conversation. */
62
+ bindProviderConversation(args: {
63
+ conversationId: string;
64
+ provider: string;
65
+ providerDestinationId: string;
66
+ providerTenantId: string;
67
+ providerConversationId: string;
68
+ }): Promise<void>;
54
69
  /** Read confirmed public/private visibility for one destination. */
55
70
  getDestinationVisibility(args: {
56
71
  provider: string;
@@ -55,6 +55,7 @@ interface ReplyExecutorDeps {
55
55
  /** Build the shared reply handler that prepares, advances, and commits a turn. */
56
56
  export declare function createReplyToThread(deps: ReplyExecutorDeps): (thread: Thread, message: Message, options: {
57
57
  beforeFirstResponsePost?: () => Promise<void>;
58
+ conversationId?: string;
58
59
  destination: Destination;
59
60
  explicitMention?: boolean;
60
61
  ack?: () => Promise<void>;
@@ -38,6 +38,7 @@ interface SteeringDrainContext {
38
38
  conversationContext?: string;
39
39
  }
40
40
  export interface SlackTurnOptions extends ReplyHooks {
41
+ conversationId?: string;
41
42
  destination: Destination;
42
43
  }
43
44
  export interface SlackTurnRuntimeDependencies<TPreparedState> {
@@ -93,6 +94,7 @@ export interface SlackTurnRuntimeDependencies<TPreparedState> {
93
94
  prepareTurnState: (args: PrepareTurnStateInput) => Promise<TPreparedState>;
94
95
  replyToThread: (thread: Thread, message: Message, options: {
95
96
  beforeFirstResponsePost?: () => Promise<void>;
97
+ conversationId?: string;
96
98
  destination: Destination;
97
99
  explicitMention?: boolean;
98
100
  ack?: () => Promise<void>;
@@ -5,6 +5,7 @@ import type { DispatchRecord } from "@/chat/agent-dispatch/types";
5
5
  interface DispatchReplyToThread {
6
6
  (thread: ThreadImpl, message: Message, options: {
7
7
  ack?: () => Promise<void>;
8
+ conversationId?: string;
8
9
  destination: DispatchRecord["destination"];
9
10
  execution: DispatchTurnContext;
10
11
  onTurnDeliveryAccepted?: (messageId?: string) => void;
@@ -16,4 +16,4 @@ export declare function sendSlackReply(args: {
16
16
  replyAttribution?: ReplyAttribution;
17
17
  text: string;
18
18
  threadTs?: string;
19
- }): Promise<string | undefined>;
19
+ }): Promise<string[]>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-B7IY6SVJ.js";
3
+ } from "./chunk-JLN4XSPR.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-F3B2YJ76.js";
6
6
  import {
7
7
  toOptionalString
8
- } from "./chunk-GOEZU33G.js";
8
+ } from "./chunk-EJRJWBKG.js";
9
9
 
10
10
  // src/chat/slack/context.ts
11
11
  import { z } from "zod";