@sentry/junior 0.124.2 → 0.126.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 (87) hide show
  1. package/dist/{agent-hooks-HJQTURNC.js → agent-hooks-HDSNWDQM.js} +9 -10
  2. package/dist/api/conversations/auxiliary-costs.d.ts +6 -0
  3. package/dist/api/conversations/detail.d.ts +10 -0
  4. package/dist/api/conversations/list.d.ts +11 -0
  5. package/dist/api/conversations/projection.d.ts +2 -1
  6. package/dist/api/locations/detail.d.ts +20 -0
  7. package/dist/api/people/profile.d.ts +10 -0
  8. package/dist/api/people/shared.d.ts +36 -0
  9. package/dist/api/plugin-reports.d.ts +1 -0
  10. package/dist/api/schema/conversation.d.ts +40 -0
  11. package/dist/api/schema/location.d.ts +10 -0
  12. package/dist/api/schema/person.d.ts +10 -0
  13. package/dist/api/schema.d.ts +2 -2
  14. package/dist/api/schema.js +4 -2
  15. package/dist/api.js +339 -180
  16. package/dist/app.js +52 -41
  17. package/dist/{catalog-runtime-F356WNZS.js → catalog-runtime-BDC3UWPG.js} +5 -6
  18. package/dist/chat/agent/prompt.d.ts +1 -0
  19. package/dist/chat/agent/request.d.ts +2 -1
  20. package/dist/chat/agent/resume.d.ts +2 -0
  21. package/dist/chat/agent-dispatch/types.d.ts +2 -1
  22. package/dist/chat/conversation-privacy.d.ts +7 -12
  23. package/dist/chat/conversations/destination-visibility.d.ts +7 -0
  24. package/dist/chat/conversations/history.d.ts +4 -2
  25. package/dist/chat/conversations/sql/conversation-row.d.ts +7 -4
  26. package/dist/chat/conversations/sql/store.d.ts +2 -1
  27. package/dist/chat/conversations/store.d.ts +12 -4
  28. package/dist/chat/pi/client.d.ts +1 -0
  29. package/dist/chat/plugins/agent-hooks.d.ts +1 -0
  30. package/dist/chat/plugins/conversation-event-stats.d.ts +3 -0
  31. package/dist/chat/plugins/conversation-events.d.ts +1 -1
  32. package/dist/chat/services/turn-session-record.d.ts +4 -1
  33. package/dist/chat/slack/conversation-context.d.ts +4 -7
  34. package/dist/chat/slack/footer.d.ts +10 -1
  35. package/dist/chat/slack/reply.d.ts +9 -2
  36. package/dist/chat/slack/source-link.d.ts +5 -0
  37. package/dist/chat/source.d.ts +16 -0
  38. package/dist/chat/state/turn-session.d.ts +2 -6
  39. package/dist/{chunk-L7EZRQ2J.js → chunk-4PV73JHH.js} +11 -13
  40. package/dist/{chunk-IXTIJQ7Z.js → chunk-6KWO5DU3.js} +167 -20
  41. package/dist/{chunk-AYQZCJZJ.js → chunk-6ZBSTNYN.js} +14 -0
  42. package/dist/chunk-72SDEHFP.js +102 -0
  43. package/dist/{chunk-SMTAXLX4.js → chunk-ACJZZY5W.js} +2 -2
  44. package/dist/{chunk-KYKLQYSU.js → chunk-APYVVX2Y.js} +1 -1
  45. package/dist/{chunk-EOSC6JOC.js → chunk-EFQX6XBW.js} +1 -1
  46. package/dist/{chunk-IMLJE2NY.js → chunk-EQMSKORN.js} +2 -2
  47. package/dist/{chunk-ZO6E537B.js → chunk-GHNO2WUH.js} +1 -1
  48. package/dist/{chunk-WKBPFZ25.js → chunk-GK55KLEH.js} +1 -1
  49. package/dist/{chunk-PR3M62LK.js → chunk-HX236W2U.js} +6 -4
  50. package/dist/{chunk-7LDOW4QA.js → chunk-JFW62B3Y.js} +1 -1
  51. package/dist/{chunk-ASK74NM6.js → chunk-JP2ZOSQK.js} +15 -5
  52. package/dist/{chunk-NNKVDYXN.js → chunk-KISG7E24.js} +57 -36
  53. package/dist/{chunk-DW6SLS5F.js → chunk-KP7E267S.js} +83 -24
  54. package/dist/{chunk-VMRKIKGO.js → chunk-LCRWDMCH.js} +1 -1
  55. package/dist/{chunk-AQKVWIPR.js → chunk-LIDEU7QS.js} +4 -4
  56. package/dist/{chunk-GCGJGSQL.js → chunk-S4PUICSB.js} +2 -0
  57. package/dist/{chunk-SS7MAJF5.js → chunk-TUHUIBDX.js} +60 -40
  58. package/dist/{chunk-PE44LDDQ.js → chunk-UTL3MHPC.js} +1 -0
  59. package/dist/{chunk-S7G34U75.js → chunk-VUBUFT66.js} +5 -121
  60. package/dist/{chunk-CMYDYVOD.js → chunk-WRH7DWFO.js} +15 -12
  61. package/dist/{chunk-574YK7QW.js → chunk-XLIAQRDI.js} +25 -10
  62. package/dist/{chunk-7P7YVJKH.js → chunk-XVKJJXHF.js} +17 -15
  63. package/dist/{chunk-4JW3YNQZ.js → chunk-YMSVBWBY.js} +9 -11
  64. package/dist/cli/chat.js +25 -25
  65. package/dist/cli/check.js +6 -7
  66. package/dist/cli/plugins.js +12 -13
  67. package/dist/cli/snapshot-create.js +9 -10
  68. package/dist/cli/upgrade.js +7 -8
  69. package/dist/db/schema/conversations.d.ts +20 -0
  70. package/dist/db/schema.d.ts +19 -0
  71. package/dist/{db-4SU2HJSV.js → db-AZB6AGJL.js} +7 -8
  72. package/dist/instrumentation.js +4 -5
  73. package/dist/nitro.js +2 -2
  74. package/dist/{oauth-callback-server-MMCH5QV6.js → oauth-callback-server-XK4QJLPZ.js} +18 -19
  75. package/dist/reporting-schema.d.ts +2 -0
  76. package/dist/{runner-ZDSNVGYA.js → runner-DSGDSATN.js} +13 -15
  77. package/dist/{skills-7G7LBHLK.js → skills-CO6E3BQJ.js} +6 -7
  78. package/dist/{validation-2ETDADPB.js → validation-IHLISKM5.js} +6 -7
  79. package/dist/version.js +1 -1
  80. package/migrations/0013_conversation_session_source.sql +38 -0
  81. package/migrations/0014_source_visibility.sql +8 -0
  82. package/migrations/meta/0013_snapshot.json +1250 -0
  83. package/migrations/meta/0014_snapshot.json +1201 -0
  84. package/migrations/meta/_journal.json +14 -0
  85. package/package.json +6 -6
  86. package/dist/chunk-BA5KHLPQ.js +0 -55
  87. package/dist/chunk-OB42YVAE.js +0 -16
package/dist/app.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  startConversationWork,
51
51
  startSlackProcessingReaction,
52
52
  stripLeadingBotMention
53
- } from "./chunk-NNKVDYXN.js";
53
+ } from "./chunk-KISG7E24.js";
54
54
  import "./chunk-FA6POGLH.js";
55
55
  import {
56
56
  ConversationTurnLifecycleService,
@@ -65,16 +65,15 @@ import {
65
65
  processPluginTask,
66
66
  requireTurnFailureEventId,
67
67
  scheduleSessionCompletedPluginTasks
68
- } from "./chunk-4JW3YNQZ.js";
68
+ } from "./chunk-YMSVBWBY.js";
69
69
  import {
70
70
  GET,
71
71
  conversationVisibilityFromSlackChannelType,
72
72
  resolveSlackChannelTypeFromMessage,
73
73
  resolveSlackConversationContext
74
- } from "./chunk-7P7YVJKH.js";
74
+ } from "./chunk-XVKJJXHF.js";
75
75
  import "./chunk-4CODA7P5.js";
76
- import "./chunk-BA5KHLPQ.js";
77
- import "./chunk-PE44LDDQ.js";
76
+ import "./chunk-UTL3MHPC.js";
78
77
  import {
79
78
  ConversationQueueMessageRejectedError,
80
79
  conversationQueueMessageSchema,
@@ -91,7 +90,7 @@ import {
91
90
  import {
92
91
  validatePluginEgressCredentialHooks,
93
92
  validatePluginRegistrations
94
- } from "./chunk-WKBPFZ25.js";
93
+ } from "./chunk-GK55KLEH.js";
95
94
  import {
96
95
  defineJuniorPlugins,
97
96
  pluginCatalogConfigFromEnv,
@@ -120,11 +119,12 @@ import {
120
119
  normalizeSandboxEgressTracePropagationDomains,
121
120
  parseSandboxEgressCredentialToken,
122
121
  renderSlackLegacyAttachmentText,
122
+ resolveDestinationVisibility,
123
123
  resolveSandboxEgressProviderForHost,
124
124
  setConfigDefaults,
125
125
  shouldEmitDevAgentTrace,
126
126
  shouldPropagateSandboxEgressTrace
127
- } from "./chunk-SS7MAJF5.js";
127
+ } from "./chunk-TUHUIBDX.js";
128
128
  import "./chunk-DIB4GX3G.js";
129
129
  import {
130
130
  RetryableDeliveryError,
@@ -135,7 +135,7 @@ import {
135
135
  formatProviderLabel,
136
136
  postSlackMessage,
137
137
  startOAuthFlow
138
- } from "./chunk-L7EZRQ2J.js";
138
+ } from "./chunk-4PV73JHH.js";
139
139
  import {
140
140
  ConversationTurnBoundaryError,
141
141
  CooperativeTurnYieldError,
@@ -191,11 +191,14 @@ import {
191
191
  trimTrailingAssistantMessages,
192
192
  updateConversationStats,
193
193
  upsertConversationMessage
194
- } from "./chunk-CMYDYVOD.js";
194
+ } from "./chunk-WRH7DWFO.js";
195
195
  import "./chunk-HDSDCEPK.js";
196
- import "./chunk-AQKVWIPR.js";
197
- import "./chunk-IMLJE2NY.js";
198
- import "./chunk-PR3M62LK.js";
196
+ import "./chunk-LIDEU7QS.js";
197
+ import "./chunk-EQMSKORN.js";
198
+ import {
199
+ parseSlackThreadId
200
+ } from "./chunk-72SDEHFP.js";
201
+ import "./chunk-HX236W2U.js";
199
202
  import "./chunk-PDO5BLNM.js";
200
203
  import "./chunk-UIE3R5XU.js";
201
204
  import {
@@ -219,7 +222,7 @@ import {
219
222
  validatePlugins,
220
223
  verifyScheduledTaskCredentialSubject,
221
224
  verifySlackDirectCredentialSubject
222
- } from "./chunk-IXTIJQ7Z.js";
225
+ } from "./chunk-6KWO5DU3.js";
223
226
  import {
224
227
  contextProvenance,
225
228
  createSlackDestination,
@@ -230,16 +233,16 @@ import {
230
233
  instructionProvenanceFor,
231
234
  requireSlackDestination,
232
235
  withConversationEventLock
233
- } from "./chunk-DW6SLS5F.js";
236
+ } from "./chunk-KP7E267S.js";
234
237
  import {
235
238
  juniorConversationEvents,
236
239
  juniorConversations
237
- } from "./chunk-GCGJGSQL.js";
240
+ } from "./chunk-S4PUICSB.js";
238
241
  import {
239
242
  acquireActiveLock,
240
243
  getStateAdapter,
241
244
  sleep
242
- } from "./chunk-KYKLQYSU.js";
245
+ } from "./chunk-APYVVX2Y.js";
243
246
  import {
244
247
  STANDARD_MODEL_PROFILE,
245
248
  botConfig,
@@ -257,18 +260,16 @@ import {
257
260
  modelIdForProfile,
258
261
  setSlackReactionConfig,
259
262
  standardModelId
260
- } from "./chunk-574YK7QW.js";
263
+ } from "./chunk-XLIAQRDI.js";
261
264
  import {
262
265
  juniorDestinations
263
266
  } from "./chunk-VFUK3X5B.js";
264
- import {
265
- parseSlackThreadId
266
- } from "./chunk-S7G34U75.js";
267
- import "./chunk-SMTAXLX4.js";
267
+ import "./chunk-VUBUFT66.js";
268
+ import "./chunk-ACJZZY5W.js";
268
269
  import {
269
270
  pluginCatalogRuntime
270
- } from "./chunk-ZO6E537B.js";
271
- import "./chunk-EOSC6JOC.js";
271
+ } from "./chunk-GHNO2WUH.js";
272
+ import "./chunk-EFQX6XBW.js";
272
273
  import {
273
274
  credentialSubjectSchema
274
275
  } from "./chunk-W3U3YQYI.js";
@@ -279,6 +280,10 @@ import {
279
280
  isActorUserId,
280
281
  parseActorUserId
281
282
  } from "./chunk-HZF5P5UN.js";
283
+ import {
284
+ parseSlackChannelId,
285
+ parseSlackMessageTs
286
+ } from "./chunk-F3B2YJ76.js";
282
287
  import {
283
288
  buildTurnFailureResponse,
284
289
  createChatSdkLogger,
@@ -292,17 +297,11 @@ import {
292
297
  setSpanAttributes,
293
298
  setSpanStatus,
294
299
  setTags,
300
+ toOptionalString,
295
301
  withContext,
296
302
  withLogContext,
297
303
  withSpan
298
- } from "./chunk-ASK74NM6.js";
299
- import {
300
- toOptionalString
301
- } from "./chunk-OB42YVAE.js";
302
- import {
303
- parseSlackChannelId,
304
- parseSlackMessageTs
305
- } from "./chunk-F3B2YJ76.js";
304
+ } from "./chunk-JP2ZOSQK.js";
306
305
  import {
307
306
  continueTrace
308
307
  } from "./chunk-6GWA276C.js";
@@ -310,10 +309,10 @@ import "./chunk-OOUNJNMR.js";
310
309
  import "./chunk-H4HBKISO.js";
311
310
  import {
312
311
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
313
- } from "./chunk-VMRKIKGO.js";
312
+ } from "./chunk-LCRWDMCH.js";
314
313
  import {
315
314
  JUNIOR_VERSION
316
- } from "./chunk-7LDOW4QA.js";
315
+ } from "./chunk-JFW62B3Y.js";
317
316
  import "./chunk-MLKGABMK.js";
318
317
 
319
318
  // src/app.ts
@@ -381,6 +380,7 @@ import {
381
380
  destinationSchema,
382
381
  destinationVisibilitySchema,
383
382
  isSlackDestination,
383
+ replyAttributionSchema,
384
384
  sourceSchema
385
385
  } from "@sentry/junior-plugin-api";
386
386
  import { z as z2 } from "zod";
@@ -418,6 +418,7 @@ var dispatchRecordSchema = z2.object({
418
418
  input: z2.string().min(1),
419
419
  metadata: z2.record(z2.string(), z2.string()).optional(),
420
420
  plugin: nonEmptyExactStringSchema,
421
+ replyAttribution: replyAttributionSchema.optional(),
421
422
  resultMessageTs: z2.string().optional(),
422
423
  source: sourceSchema,
423
424
  status: dispatchStatusSchema,
@@ -626,6 +627,7 @@ async function createOrGetDispatch(args) {
626
627
  input: args.options.input,
627
628
  ...metadata ? { metadata } : {},
628
629
  plugin: args.plugin,
630
+ ...args.options.replyAttribution ? { replyAttribution: args.options.replyAttribution } : {},
629
631
  status: "pending",
630
632
  source: args.options.source,
631
633
  updatedAtMs: args.nowMs
@@ -759,7 +761,8 @@ function buildDispatchRoutingContext(dispatch) {
759
761
  actor: dispatch.actor,
760
762
  id: dispatch.id,
761
763
  metadata: dispatch.metadata,
762
- plugin: dispatch.plugin
764
+ plugin: dispatch.plugin,
765
+ replyAttribution: dispatch.replyAttribution
763
766
  },
764
767
  surface: "api"
765
768
  };
@@ -1314,6 +1317,9 @@ function dispatchOptionsErrorMessage(issues) {
1314
1317
  if (hasIssueUnderPath(issues, ["metadata"])) {
1315
1318
  return "Dispatch metadata values must be strings";
1316
1319
  }
1320
+ if (hasIssueUnderPath(issues, ["replyAttribution"])) {
1321
+ return "Dispatch reply attribution is invalid";
1322
+ }
1317
1323
  return "Dispatch options are invalid";
1318
1324
  }
1319
1325
  function validateDispatchOptions(options) {
@@ -6487,27 +6493,30 @@ function createReplyToThread(deps) {
6487
6493
  const threadId = getThreadId(thread, message);
6488
6494
  const channelId = getChannelId(thread, message);
6489
6495
  const channelName = !options.execution && channelId ? await resolveChannelName(thread) : void 0;
6496
+ const destination = requireSlackDestination(
6497
+ options.destination,
6498
+ "Slack reply execution"
6499
+ );
6490
6500
  const slackChannelType = resolveSlackChannelTypeFromMessage(message);
6491
6501
  const slackConversation = resolveSlackConversationContext({
6492
6502
  channelId,
6493
6503
  channelName,
6494
6504
  channelType: slackChannelType
6495
6505
  });
6496
- const destinationVisibility = options.execution?.destinationVisibility ?? conversationVisibilityFromSlackChannelType(slackChannelType);
6506
+ const destinationVisibility = await resolveDestinationVisibility({
6507
+ destination,
6508
+ visibility: options.execution?.destinationVisibility ?? conversationVisibilityFromSlackChannelType(slackChannelType)
6509
+ });
6497
6510
  const threadTs = getThreadTs(threadId);
6498
6511
  const assistantThreadContext = getAssistantThreadContext(message);
6499
6512
  const messageTs = getMessageTs(message);
6500
- const destination = requireSlackDestination(
6501
- options.destination,
6502
- "Slack reply execution"
6503
- );
6504
6513
  const teamId = destination.teamId;
6505
6514
  const source = options.execution?.source ?? createSlackSource({
6506
6515
  channelId: channelId ?? destination.channelId,
6507
6516
  messageTs,
6508
6517
  teamId,
6509
6518
  threadTs,
6510
- type: destinationVisibility === "public" ? "pub" : "priv"
6519
+ visibility: destinationVisibility ?? "private"
6511
6520
  });
6512
6521
  const slackActionToken = readSlackActionToken(message);
6513
6522
  const runId = options.execution?.dispatch?.id ?? getRunId(thread, message);
@@ -6604,6 +6613,7 @@ function createReplyToThread(deps) {
6604
6613
  await sendSlackReply({
6605
6614
  channelId,
6606
6615
  conversationId,
6616
+ replyAttribution: options.execution?.dispatch?.replyAttribution,
6607
6617
  text,
6608
6618
  threadTs
6609
6619
  });
@@ -6969,6 +6979,7 @@ function createReplyToThread(deps) {
6969
6979
  slackTs = await sendSlackReply({
6970
6980
  channelId,
6971
6981
  conversationId,
6982
+ replyAttribution: options.execution?.dispatch?.replyAttribution,
6972
6983
  text,
6973
6984
  ...threadTs ? { threadTs } : {}
6974
6985
  });
@@ -7198,7 +7209,7 @@ function createReplyToThread(deps) {
7198
7209
  slackConversation,
7199
7210
  source,
7200
7211
  destination,
7201
- destinationVisibility,
7212
+ ...destinationVisibility ? { destinationVisibility } : {},
7202
7213
  surface: options.execution?.surface ?? "slack",
7203
7214
  dispatch: options.execution?.dispatch,
7204
7215
  toolChannelId,
@@ -1,17 +1,16 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-ZO6E537B.js";
4
- import "./chunk-EOSC6JOC.js";
3
+ } from "./chunk-GHNO2WUH.js";
4
+ import "./chunk-EFQX6XBW.js";
5
5
  import "./chunk-W3U3YQYI.js";
6
6
  import "./chunk-HZF5P5UN.js";
7
- import "./chunk-ASK74NM6.js";
8
- import "./chunk-OB42YVAE.js";
9
7
  import "./chunk-F3B2YJ76.js";
8
+ import "./chunk-JP2ZOSQK.js";
10
9
  import "./chunk-6GWA276C.js";
11
10
  import "./chunk-OOUNJNMR.js";
12
11
  import "./chunk-H4HBKISO.js";
13
- import "./chunk-VMRKIKGO.js";
14
- import "./chunk-7LDOW4QA.js";
12
+ import "./chunk-LCRWDMCH.js";
13
+ import "./chunk-JFW62B3Y.js";
15
14
  import "./chunk-MLKGABMK.js";
16
15
  export {
17
16
  pluginCatalogRuntime
@@ -72,6 +72,7 @@ export declare function assemblePrompt(args: {
72
72
  resumedFromSessionRecord: boolean;
73
73
  routing: AgentRunRouting;
74
74
  spanContext: LogContext;
75
+ turnId: string;
75
76
  toolGuidance: Array<{
76
77
  name: string;
77
78
  promptGuidelines: AnyToolDefinition["promptGuidelines"];
@@ -7,7 +7,7 @@
7
7
  * phases consume these groups directly; callers build them at runtime
8
8
  * boundaries.
9
9
  */
10
- import type { Destination, Source, SystemActor } from "@sentry/junior-plugin-api";
10
+ import type { Destination, ReplyAttribution, Source, SystemActor } from "@sentry/junior-plugin-api";
11
11
  import type { ChannelConfigurationService } from "@/chat/configuration/types";
12
12
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
13
13
  import type { CredentialContext } from "@/chat/credentials/context";
@@ -81,6 +81,7 @@ export interface AgentRunRouting {
81
81
  id: string;
82
82
  metadata?: Record<string, string>;
83
83
  plugin?: string;
84
+ replyAttribution?: ReplyAttribution;
84
85
  };
85
86
  toolChannelId?: string;
86
87
  }
@@ -19,10 +19,12 @@ import { type AuthorizationPauseError } from "@/chat/services/auth-pause";
19
19
  import { type AgentTurnUsage } from "@/chat/usage";
20
20
  import { type AgentRunDurability } from "@/chat/agent/request";
21
21
  import type { PluginTurnContext } from "@/chat/plugins/prompt";
22
+ import type { ConversationPrivacy } from "@/chat/conversation-privacy";
22
23
  type LoadedSessionRecordState = Awaited<ReturnType<typeof loadTurnSessionRecord>>;
23
24
  interface ResumeStateArgs {
24
25
  channelName?: string;
25
26
  destination: Destination;
27
+ destinationVisibility?: ConversationPrivacy;
26
28
  dispatchId?: string;
27
29
  durability: AgentRunDurability;
28
30
  getLoadedSkillNames: () => string[];
@@ -1,4 +1,4 @@
1
- import type { DispatchOptions, DestinationVisibility, Source, SlackDestination } from "@sentry/junior-plugin-api";
1
+ import type { DispatchOptions, DestinationVisibility, ReplyAttribution, Source, SlackDestination } from "@sentry/junior-plugin-api";
2
2
  import type { CredentialContext, CredentialSubject, CredentialSystemActor } from "@/chat/credentials/context";
3
3
  import type { AgentRunRouting } from "@/chat/agent/request";
4
4
  import type { AgentTurnSurface } from "@/chat/state/turn-session";
@@ -22,6 +22,7 @@ export interface DispatchRecord {
22
22
  input: string;
23
23
  metadata?: Record<string, string>;
24
24
  plugin: string;
25
+ replyAttribution?: ReplyAttribution;
25
26
  resultMessageTs?: string;
26
27
  source: Source;
27
28
  status: DispatchStatus;
@@ -4,22 +4,17 @@ type TraceAttributeValue = string | number | boolean | string[];
4
4
  /**
5
5
  * Resolve whether a conversation may expose raw payloads.
6
6
  *
7
- * Only a live source signal or persisted destination visibility can classify
8
- * a conversation public. Identifier prefixes may only narrow classification
9
- * toward private. Unknown stays undefined so callers fail closed to private.
7
+ * Explicit destination visibility is authoritative. Missing visibility is
8
+ * observable and fails closed without inferring from identifiers.
10
9
  */
11
10
  export declare function resolveConversationPrivacy(input: {
12
- channelId?: string;
13
- conversationId?: string;
14
- /** Live source or persisted visibility, when the caller has one. */
15
- visibility?: ConversationPrivacy;
16
- }): ConversationPrivacy | undefined;
11
+ /** Live or persisted destination visibility, when the caller has one. */
12
+ visibility?: ConversationPrivacy | "direct" | "unknown";
13
+ }): ConversationPrivacy;
17
14
  /** Gate raw transcript/tool payload exposure to public conversations. */
18
15
  export declare function canExposeConversationPayload(input: {
19
- channelId?: string;
20
- conversationId?: string;
21
- /** Live source or persisted visibility, when the caller has one. */
22
- visibility?: ConversationPrivacy;
16
+ /** Live or persisted destination visibility, when the caller has one. */
17
+ visibility?: ConversationPrivacy | "direct" | "unknown";
23
18
  }): boolean;
24
19
  /** Return the privacy mode bound to the current agent turn. */
25
20
  export declare function getCurrentConversationPrivacy(): ConversationPrivacy | undefined;
@@ -0,0 +1,7 @@
1
+ import type { Destination } from "@sentry/junior-plugin-api";
2
+ import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
+ /** Read confirmed visibility from the current signal or persisted destination. */
4
+ export declare function resolveDestinationVisibility(args: {
5
+ destination: Destination;
6
+ visibility?: ConversationPrivacy;
7
+ }): Promise<ConversationPrivacy | undefined>;
@@ -944,8 +944,10 @@ export interface ConversationEventPage {
944
944
  }
945
945
  /** Persist and read the canonical per-conversation event log. */
946
946
  export interface ConversationEventStore {
947
- /** Append events atomically, assigning `seq = max+1` under the lease. */
948
- append(conversationId: string, events: NewConversationEvent[]): Promise<void>;
947
+ /** Append events atomically, optionally preserving conversation activity. */
948
+ append(conversationId: string, events: NewConversationEvent[], options?: {
949
+ activity?: "preserve";
950
+ }): Promise<void>;
949
951
  /** Replace active model history with a compaction or handoff event. */
950
952
  replaceHistory(conversationId: string, replacement: HistoryReplacement): Promise<void>;
951
953
  /** One event selected by its retry-stable key across history versions. */
@@ -6,9 +6,12 @@ import type { JuniorSqlDatabase } from "@/db/db";
6
6
  *
7
7
  * First contact creates the row; every later content write advances the
8
8
  * activity clock so retention mirrors append-refresh semantics (each content
9
- * append refreshes the retention window). The timestamp is content-intrinsic
10
- * (the first item's `createdAtMs`), and `greatest(...)` guarantees a backfilled
11
- * or imported historical write — which carries an old timestamp — can never
9
+ * append refreshes the retention window). Background observations may opt out
10
+ * and leave an existing row unchanged. The timestamp is content-intrinsic (the
11
+ * first item's `createdAtMs`), and `greatest(...)` guarantees a backfilled or
12
+ * imported historical write — which carries an old timestamp — can never
12
13
  * regress `last_activity_at`.
13
14
  */
14
- export declare function ensureConversationRow(executor: JuniorSqlDatabase, conversationId: string, atMs: number): Promise<void>;
15
+ export declare function ensureConversationRow(executor: JuniorSqlDatabase, conversationId: string, atMs: number, options?: {
16
+ activity?: "preserve";
17
+ }): Promise<void>;
@@ -1,4 +1,4 @@
1
- import type { Destination } from "@sentry/junior-plugin-api";
1
+ import type { Destination, Source } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
3
  import type { StoredSlackActor } from "@/chat/actor";
4
4
  import type { JuniorSqlDatabase } from "@/db/db";
@@ -18,6 +18,7 @@ export declare class SqlStore implements ConversationStore {
18
18
  nowMs?: number;
19
19
  actor?: StoredSlackActor;
20
20
  source?: ConversationSource;
21
+ sessionSource?: Source;
21
22
  title?: string;
22
23
  visibility?: ConversationPrivacy;
23
24
  }): Promise<void>;
@@ -1,6 +1,7 @@
1
- import type { Destination } from "@sentry/junior-plugin-api";
1
+ import type { Destination, Source } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
3
  import type { StoredSlackActor } from "@/chat/actor";
4
+ import type { SessionSource } from "@/chat/source";
4
5
  import type { AgentTurnUsage } from "@/chat/usage";
5
6
  export type ConversationSource = "api" | "internal" | "local" | "plugin" | "resource_event" | "scheduler" | "slack";
6
7
  export type ConversationStatus = "awaiting_resume" | "failed" | "idle" | "pending" | "running";
@@ -27,6 +28,11 @@ export interface Conversation {
27
28
  actor?: StoredSlackActor;
28
29
  schemaVersion: 1;
29
30
  source?: ConversationSource;
31
+ /**
32
+ * Structured inbound Source locator for this conversation session.
33
+ * Session-stable (Slack thread anchor, not per-message ts). Set-once.
34
+ */
35
+ sessionSource?: SessionSource;
30
36
  title?: string;
31
37
  updatedAtMs: number;
32
38
  /**
@@ -43,7 +49,7 @@ export interface ConversationStore {
43
49
  get(args: {
44
50
  conversationId: string;
45
51
  }): Promise<Conversation | undefined>;
46
- /** Read persisted visibility for one destination. Missing rows fail closed. */
52
+ /** Read confirmed public/private visibility for one destination. */
47
53
  getDestinationVisibility(args: {
48
54
  provider: string;
49
55
  providerDestinationId: string;
@@ -57,8 +63,10 @@ export interface ConversationStore {
57
63
  nowMs?: number;
58
64
  actor?: StoredSlackActor;
59
65
  source?: ConversationSource;
66
+ /** Source normalized to a stable session locator; set-once when absent. */
67
+ sessionSource?: Source;
60
68
  title?: string;
61
- /** Source-confirmed visibility from the current event's signal only. */
69
+ /** Confirmed destination visibility; omit when unavailable. */
62
70
  visibility?: ConversationPrivacy;
63
71
  }): Promise<void>;
64
72
  /**
@@ -80,7 +88,7 @@ export interface ConversationStore {
80
88
  source?: ConversationSource;
81
89
  title?: string;
82
90
  updatedAtMs: number;
83
- /** Source-confirmed visibility from the current event's signal only. */
91
+ /** Confirmed destination visibility; omit when unavailable. */
84
92
  visibility?: ConversationPrivacy;
85
93
  }): Promise<void>;
86
94
  listByActivity(args?: {
@@ -59,6 +59,7 @@ export declare function embedTexts(params: {
59
59
  signal?: AbortSignal;
60
60
  metadata?: Record<string, unknown>;
61
61
  }): Promise<{
62
+ costUsd?: number;
62
63
  dimensions: number;
63
64
  model: string;
64
65
  provider: string;
@@ -48,6 +48,7 @@ export declare function getPluginSystemPromptContributions(source: ToolRuntimeCo
48
48
  /** Collect request-scoped plugin prompt contributions. */
49
49
  export declare function getPluginUserPromptContributions(args: {
50
50
  context: Pick<ToolRuntimeContext, "conversationId" | "destination" | "actor" | "source" | "userText">;
51
+ turnId?: string;
51
52
  }): Promise<PluginPromptContributionContext[]>;
52
53
  /** Collect turn-scoped tools exposed by plugins. */
53
54
  export declare function getPluginTools(context: ToolRuntimeContext): Record<string, AnyToolDefinition>;
@@ -0,0 +1,3 @@
1
+ import type { PluginConversationEventStats, PluginRegistration } from "@sentry/junior-plugin-api";
2
+ /** Create aggregate event-cost reads bound to one plugin's registered namespace. */
3
+ export declare function createPluginConversationEventStats(plugin: PluginRegistration, now?: () => number): PluginConversationEventStats;
@@ -1,5 +1,5 @@
1
1
  import type { ConversationEventPresentation, PluginConversationEvents, PluginRegistration } from "@sentry/junior-plugin-api";
2
- /** Create a conversation-bound writer for one plugin task operation. */
2
+ /** Create a conversation-bound writer for one plugin operation. */
3
3
  export declare function createPluginConversationEvents(args: {
4
4
  conversationId: string;
5
5
  operationId: string;
@@ -21,6 +21,7 @@ export declare function persistRunningSessionRecord(args: {
21
21
  channelName?: string;
22
22
  conversationId: string;
23
23
  destination?: Destination;
24
+ destinationVisibility?: ConversationPrivacy;
24
25
  dispatchId?: string;
25
26
  source?: Source;
26
27
  sessionId: string;
@@ -54,7 +55,7 @@ export declare function persistCompletedSessionRecord(args: {
54
55
  dispatchId?: string;
55
56
  dispatchOutcome?: AgentDispatchOutcome;
56
57
  errorMessage?: string;
57
- /** Source-confirmed destination visibility from the current event's signal. */
58
+ /** Confirmed visibility; omit when unavailable to preserve canonical metadata. */
58
59
  destinationVisibility?: ConversationPrivacy;
59
60
  /** Provider-owned identifier returned after visible delivery is accepted. */
60
61
  resultMessageId?: string;
@@ -105,6 +106,7 @@ export declare function persistAuthPauseSessionRecord(args: {
105
106
  currentDurationMs?: number;
106
107
  currentUsage?: AgentTurnUsage;
107
108
  destination?: Destination;
109
+ destinationVisibility?: ConversationPrivacy;
108
110
  dispatchId?: string;
109
111
  source?: Source;
110
112
  messages: PiMessage[];
@@ -123,6 +125,7 @@ interface ContinuationRecordInput {
123
125
  currentDurationMs?: number;
124
126
  currentUsage?: AgentTurnUsage;
125
127
  destination?: Destination;
128
+ destinationVisibility?: ConversationPrivacy;
126
129
  dispatchId?: string;
127
130
  source?: Source;
128
131
  messages: PiMessage[];
@@ -8,18 +8,14 @@ export type SlackConversationVisibility = "public" | "private";
8
8
  export interface SlackConversationContext {
9
9
  type: SlackConversationType;
10
10
  name?: string;
11
- /**
12
- * Visibility proven by a source signal (`channel_type`) or narrowed toward
13
- * private by a `D`/`G` id prefix. Undefined for `C`-prefixed conversations
14
- * without a signal, which may be public or private.
15
- */
11
+ /** Visibility proven by source or persisted metadata. */
16
12
  visibility?: SlackConversationVisibility;
17
13
  }
18
14
  /**
19
15
  * Map Slack's Events API channel_type to a source-confirmed visibility.
20
16
  *
21
- * This is the only mapping allowed to classify a Slack conversation public;
22
- * channel-id prefixes may only narrow classification toward private.
17
+ * Slack's event metadata is the only visibility authority; channel IDs never
18
+ * classify visibility.
23
19
  */
24
20
  export declare function conversationVisibilityFromSlackChannelType(channelType: SlackEventChannelType | undefined): SlackConversationVisibility | undefined;
25
21
  /** Resolve Slack's raw event channel type from a Chat SDK message-like object. */
@@ -34,6 +30,7 @@ export declare function resolveSlackConversationContext(input: {
34
30
  export declare function resolveSlackConversationContextFromThreadId(input: {
35
31
  threadId?: string;
36
32
  channelName?: string;
33
+ visibility?: SlackConversationVisibility;
37
34
  }): SlackConversationContext | undefined;
38
35
  /** Render a human label for a privacy-preserving Slack conversation type. */
39
36
  export declare function formatSlackConversationTypeLabel(type: SlackConversationType): string;
@@ -1,7 +1,12 @@
1
+ import type { ReplyAttribution } from "@sentry/junior-plugin-api";
1
2
  interface SlackMrkdwnTextObject {
2
3
  text: string;
3
4
  type: "mrkdwn";
4
5
  }
6
+ interface SlackPlainTextObject {
7
+ text: string;
8
+ type: "plain_text";
9
+ }
5
10
  /** Slack-flavored Markdown block — accepts a standard Markdown subset and Slack renders it natively. */
6
11
  interface SlackMarkdownBlock {
7
12
  text: string;
@@ -12,7 +17,7 @@ interface SlackSectionBlock {
12
17
  type: "section";
13
18
  }
14
19
  interface SlackContextBlock {
15
- elements: SlackMrkdwnTextObject[];
20
+ elements: Array<SlackMrkdwnTextObject | SlackPlainTextObject>;
16
21
  type: "context";
17
22
  }
18
23
  export type SlackMessageBlock = SlackMarkdownBlock | SlackSectionBlock | SlackContextBlock;
@@ -22,8 +27,11 @@ interface SlackReplyFooterItem {
22
27
  value: string;
23
28
  }
24
29
  export interface SlackReplyFooter {
30
+ attribution?: ReplyAttribution;
25
31
  items: SlackReplyFooterItem[];
26
32
  }
33
+ /** Render compact reply attribution for the Slack footer. */
34
+ export declare function formatReplyAttribution(attribution: ReplyAttribution): string;
27
35
  /**
28
36
  * Build the compact conversation footer for visible Slack reply surfaces.
29
37
  *
@@ -31,6 +39,7 @@ export interface SlackReplyFooter {
31
39
  */
32
40
  export declare function buildSlackReplyFooter(args: {
33
41
  conversationId?: string;
42
+ replyAttribution?: ReplyAttribution;
34
43
  }): SlackReplyFooter | undefined;
35
44
  /** Build Slack blocks for a reply chunk using the Slack-flavored markdown block for the body. */
36
45
  export declare function buildSlackReplyBlocks(text: string, footer: SlackReplyFooter | undefined): SlackMessageBlock[] | undefined;
@@ -1,12 +1,19 @@
1
+ /**
2
+ * Destination-visible Slack reply delivery.
3
+ *
4
+ * Owns chunking, conversation footer attachment, and outbound posting.
5
+ */
6
+ import type { ReplyAttribution } from "@sentry/junior-plugin-api";
1
7
  /**
2
8
  * Send one destination-visible Slack reply.
3
9
  *
4
- * Chunks oversized text, builds the conversation footer from
5
- * `conversationId`, and posts through the shared Slack outbound boundary.
10
+ * Chunks oversized text, builds compact attribution and conversation footer
11
+ * context, and posts through the shared Slack outbound boundary.
6
12
  */
7
13
  export declare function sendSlackReply(args: {
8
14
  channelId: string;
9
15
  conversationId: string;
16
+ replyAttribution?: ReplyAttribution;
10
17
  text: string;
11
18
  threadTs?: string;
12
19
  }): Promise<string | undefined>;
@@ -0,0 +1,5 @@
1
+ /** Build Slack's browser-safe redirect to a conversation when its IDs are valid. */
2
+ export declare function buildSlackSourceUrl(args: {
3
+ channelId: string;
4
+ teamId: string;
5
+ }): string | undefined;