@sentry/junior 0.185.0 → 0.187.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 (96) hide show
  1. package/dist/{agent-hooks-NGZQLL5O.js → agent-hooks-XVAE2554.js} +11 -11
  2. package/dist/api/schema/conversation.d.ts +8 -0
  3. package/dist/api/schema.js +1 -1
  4. package/dist/api.js +44 -36
  5. package/dist/app.js +1079 -264
  6. package/dist/{catalog-runtime-AAEAO2RL.js → catalog-runtime-DWFAC562.js} +4 -4
  7. package/dist/chat/agent/types.d.ts +16 -13
  8. package/dist/chat/api-turns/{accepted-reply.d.ts → assistant-message.d.ts} +3 -2
  9. package/dist/chat/api-turns/cancellation.d.ts +0 -1
  10. package/dist/chat/api-turns/mailbox-input.d.ts +4 -0
  11. package/dist/chat/api-turns/routing.d.ts +23 -7
  12. package/dist/chat/api-turns/work.d.ts +2 -2
  13. package/dist/chat/conversations/location.d.ts +2 -2
  14. package/dist/chat/conversations/store.d.ts +13 -0
  15. package/dist/chat/conversations/turn-lifecycle.d.ts +2 -0
  16. package/dist/chat/providers/slack/runtime.d.ts +0 -2
  17. package/dist/chat/providers/slack/turn.d.ts +0 -2
  18. package/dist/chat/resource-events/actor.d.ts +14 -2
  19. package/dist/chat/resource-events/app-publisher.d.ts +18 -0
  20. package/dist/chat/resource-events/catalog.d.ts +19 -0
  21. package/dist/chat/resource-events/ingest.d.ts +0 -1
  22. package/dist/chat/resource-events/notification.d.ts +28 -3
  23. package/dist/chat/resource-events/runtime-catalog.d.ts +7 -2
  24. package/dist/chat/resource-events/store.d.ts +1 -13
  25. package/dist/chat/resource-events/workspace.d.ts +7 -3
  26. package/dist/chat/sandbox/egress/credentials.d.ts +5 -4
  27. package/dist/chat/sandbox/egress/session.d.ts +9 -9
  28. package/dist/chat/sandbox/errors.d.ts +1 -1
  29. package/dist/chat/sandbox/ref.d.ts +1 -1
  30. package/dist/chat/sandbox/snapshot/events.d.ts +8 -1
  31. package/dist/chat/sandbox/snapshot/not-ready-error.d.ts +6 -1
  32. package/dist/chat/sentry-links.d.ts +2 -0
  33. package/dist/chat/services/turn-session-routing.d.ts +23 -7
  34. package/dist/chat/task-execution/slack-resource-event.d.ts +47 -0
  35. package/dist/chat/task-execution/slack-work.d.ts +0 -21
  36. package/dist/chat/task-input.d.ts +22 -0
  37. package/dist/chat/tools/event-tasks.d.ts +1 -1
  38. package/dist/chat/tools/resource-events.d.ts +1 -1
  39. package/dist/{chunk-Y5G23T2D.js → chunk-27T5HZHO.js} +91 -7
  40. package/dist/{chunk-TVVAMOLS.js → chunk-2VUDJGB6.js} +2 -2
  41. package/dist/{chunk-X7NCJQAA.js → chunk-4A2R3AQB.js} +1 -1
  42. package/dist/{chunk-MWOH6CIK.js → chunk-4YD3DET6.js} +278 -116
  43. package/dist/{chunk-INQHUE72.js → chunk-6FGN7ZEG.js} +6 -2
  44. package/dist/{chunk-ZKKGFUWM.js → chunk-6FKNNUSN.js} +6 -6
  45. package/dist/{chunk-OMQ2J6F6.js → chunk-6YCIYOVA.js} +1 -1
  46. package/dist/{chunk-7GAP2XG4.js → chunk-7LRRVMPH.js} +1 -1
  47. package/dist/{chunk-4HA36IWS.js → chunk-BITZUBPJ.js} +8 -8
  48. package/dist/{chunk-QCT4226Q.js → chunk-D3GDGREI.js} +3 -3
  49. package/dist/{chunk-WLKWN4CD.js → chunk-D5BWM37G.js} +8 -5
  50. package/dist/{chunk-VH4IU3UC.js → chunk-DUE4EUNL.js} +19 -45
  51. package/dist/{chunk-DAPC2HTM.js → chunk-EIWYZXSM.js} +5 -5
  52. package/dist/{chunk-LVK4WJKM.js → chunk-HXR3FHTE.js} +13 -3
  53. package/dist/{chunk-UUULGCKK.js → chunk-ITLYUKGZ.js} +14 -4
  54. package/dist/{chunk-FTVMXDNN.js → chunk-JCRXXEMC.js} +1 -1
  55. package/dist/{chunk-EJYP3NQ4.js → chunk-JZPDYKRG.js} +37 -3
  56. package/dist/{chunk-HJPC32TQ.js → chunk-KRYJ5VOD.js} +20 -14
  57. package/dist/{chunk-QZKHHG3B.js → chunk-MUPPP7A7.js} +436 -283
  58. package/dist/{chunk-D63IUQQE.js → chunk-NIKLTFBP.js} +12 -9
  59. package/dist/{chunk-U4CTAVWN.js → chunk-NU775DLU.js} +2 -2
  60. package/dist/{chunk-W7GCLNIV.js → chunk-OM4SFFJK.js} +3 -3
  61. package/dist/{chunk-X2SS6BF7.js → chunk-P2VU5JNH.js} +32 -36
  62. package/dist/{chunk-4K25ODAO.js → chunk-PFAZSRGR.js} +3 -1
  63. package/dist/{chunk-EIJCPJOY.js → chunk-Q6OCUQ7W.js} +1 -1
  64. package/dist/{chunk-GJTIZQGJ.js → chunk-QH3I7ZOK.js} +1 -1
  65. package/dist/{chunk-4S47VHJR.js → chunk-STF4GSK4.js} +3 -3
  66. package/dist/{chunk-C6TS47CQ.js → chunk-TQHCZXN7.js} +11 -5
  67. package/dist/{chunk-ZIF2S464.js → chunk-U3KMII5Y.js} +1 -1
  68. package/dist/{chunk-6DOAUXLD.js → chunk-U5POFCKM.js} +753 -1718
  69. package/dist/{chunk-PNYJOEVV.js → chunk-U6ZQHRIP.js} +1 -1
  70. package/dist/{chunk-LRI5IRGY.js → chunk-URZ7UD4P.js} +2 -2
  71. package/dist/{chunk-6Q7YZLCL.js → chunk-VC343WHM.js} +9 -1
  72. package/dist/{chunk-ABAX75GG.js → chunk-WKIS4VRK.js} +17 -3
  73. package/dist/{chunk-FFHXG2FX.js → chunk-WL3R2KTS.js} +11 -29
  74. package/dist/{chunk-EWEH2PJW.js → chunk-WRDW3A3D.js} +5 -5
  75. package/dist/{chunk-7MHNIGHP.js → chunk-X5SXFVZT.js} +1 -1
  76. package/dist/{chunk-ATUWN6Z3.js → chunk-Z6OHCDXP.js} +2 -2
  77. package/dist/cli/chat.js +33 -33
  78. package/dist/cli/check.js +5 -5
  79. package/dist/cli/plugins.js +12 -12
  80. package/dist/cli/snapshot-create.js +9 -9
  81. package/dist/cli/upgrade.js +6 -6
  82. package/dist/{db-TRJ77FAU.js → db-FBHAWVXU.js} +6 -6
  83. package/dist/instrumentation.js +3 -3
  84. package/dist/nitro.js +6 -6
  85. package/dist/{oauth-callback-server-XD5SV3MS.js → oauth-callback-server-5HS5ULC6.js} +28 -28
  86. package/dist/{runner-KFX7NG6D.js → runner-46W6NV6B.js} +19 -19
  87. package/dist/{skills-J2AH26CW.js → skills-TG3QC4B6.js} +5 -5
  88. package/dist/spawn-Y6YWBIJS.js +41 -0
  89. package/dist/task-runner-YSGBPN4U.js +34 -0
  90. package/dist/{validation-O5J4VOPF.js → validation-GMRIDBC5.js} +5 -5
  91. package/dist/version.js +1 -1
  92. package/dist/{work-ECPQTG3U.js → work-W4ULBJTU.js} +21 -21
  93. package/dist/{worker-RS3DXUDO.js → worker-M6NVACS2.js} +10 -10
  94. package/package.json +4 -4
  95. package/dist/spawn-VU3CSRI6.js +0 -41
  96. package/dist/task-runner-5JG3VIIY.js +0 -34
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-GJTIZQGJ.js";
4
- import "./chunk-7MHNIGHP.js";
3
+ } from "./chunk-QH3I7ZOK.js";
4
+ import "./chunk-X5SXFVZT.js";
5
5
  import "./chunk-CEMMLV5L.js";
6
6
  import "./chunk-N7TMSOZH.js";
7
7
  import "./chunk-DWPN6SCH.js";
8
8
  import "./chunk-TXKUKMVO.js";
9
- import "./chunk-OMQ2J6F6.js";
9
+ import "./chunk-6YCIYOVA.js";
10
10
  import "./chunk-PEQXYSSE.js";
11
- import "./chunk-7GAP2XG4.js";
11
+ import "./chunk-7LRRVMPH.js";
12
12
  export {
13
13
  pluginCatalogRuntime
14
14
  };
@@ -1,13 +1,8 @@
1
- /**
2
- * Public agent-run launch contract.
3
- *
4
- * Providers build one flat `AgentRun` and call `AgentRunner.run`. Delivery and
5
- * durability are capabilities that affect the run. `onEvent` is best-effort UI
6
- * only. Stable composition binds stream, spawn, and tracing outside this type.
7
- */
1
+ /** Input for one Run through Junior's agent. */
8
2
  import type { Destination, ReplyAttribution, Source, SystemActor } from "@sentry/junior-plugin-api";
9
3
  import type { LocationConfigurationService } from "@/chat/configuration/types";
10
4
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
5
+ import type { Location } from "@/chat/conversations/location";
11
6
  import type { CredentialContext } from "@/chat/credentials/context";
12
7
  import type { PiMessage } from "@/chat/pi/messages";
13
8
  import type { Actor } from "@/chat/actor";
@@ -38,7 +33,8 @@ export type AgentInstructionActor = {
38
33
  authorName?: string;
39
34
  /**
40
35
  * Slack message ts for the instruction when known.
41
- * TODO: generalize to a provider-neutral message id once prompt attrs are neutral.
36
+ * TODO(dcramer): Use a provider-neutral message id after prompt attributes no
37
+ * longer require the Slack timestamp.
42
38
  */
43
39
  slackTs?: string;
44
40
  };
@@ -153,7 +149,7 @@ export type AgentEnvironment = {
153
149
  };
154
150
  };
155
151
  /**
156
- * One provider-launched agent-run slice.
152
+ * One bounded attempt to advance a Turn.
157
153
  *
158
154
  * Build identity, instruction, history, delivery, and durability here. Bind
159
155
  * stable model/stream composition when creating the runner, not on each run.
@@ -177,6 +173,13 @@ export type AgentRun = {
177
173
  /** Credential authority projected from actor (plus optional subject). */
178
174
  credentialContext?: CredentialContext;
179
175
  source: Source;
176
+ /**
177
+ * Transitional Conversation Location for this Run.
178
+ * TODO(dcramer): Remove top-level Location, Destination, and
179
+ * publishExternally after Source and Delivery contain Location across new,
180
+ * resumed, and child Runs.
181
+ */
182
+ location?: Location;
180
183
  destination: Destination;
181
184
  /** When true, also publish assistant output to the conversation destination. */
182
185
  publishExternally?: boolean;
@@ -185,7 +188,7 @@ export type AgentRun = {
185
188
  surface?: AgentTurnSurface;
186
189
  dispatch?: AgentDispatch;
187
190
  /**
188
- * TODO: Move ephemeral Slack credentials and conversation labels into
191
+ * TODO(dcramer): Move ephemeral Slack credentials and conversation labels into
189
192
  * provider-owned tool/prompt context so the shared run edge stays neutral.
190
193
  */
191
194
  slackConversation?: SlackConversationContext;
@@ -197,9 +200,9 @@ export type AgentRun = {
197
200
  * Optional agent capabilities disabled for this run slice.
198
201
  * `interactive-auth` blocks pausing to send an OAuth link; missing credentials
199
202
  * hard-fail instead. Default is enabled when omitted.
200
- * TODO(#881, #883): child invocations currently disable interactive-auth, but
201
- * may later need a path to force the auth flow when a delegated tool requires
202
- * credentials the parent can already request.
203
+ * TODO(dcramer): Issues #881 and #883 track a path for child invocations to
204
+ * force interactive auth when a delegated tool requires credentials the
205
+ * parent can already request. Children currently disable it.
203
206
  */
204
207
  disabledFeatures?: readonly AgentFeature[];
205
208
  /** Absolute wall-clock deadline for this host request, in milliseconds. */
@@ -1,11 +1,12 @@
1
1
  import type { AssistantMessage } from "@earendil-works/pi-ai";
2
2
  import type { ThreadConversationState } from "@/chat/state/conversation";
3
- /** Record a web-accepted assistant reply with agent history before the visible message. */
4
- export declare function commitWebAcceptedReply(args: {
3
+ /** Store one assistant Message and its Agent history. */
4
+ export declare function commitAssistantMessage(args: {
5
5
  agentMessage?: AssistantMessage;
6
6
  conversation: ThreadConversationState;
7
7
  conversationId: string;
8
8
  sessionId: string;
9
+ source?: "web";
9
10
  text: string;
10
11
  userMessageId: string;
11
12
  }): Promise<void>;
@@ -12,7 +12,6 @@ export declare function createApiTurnCancellation(): ApiTurnCancellation;
12
12
  /** Close one cancelled Turn without a failure reply or retry. */
13
13
  export declare function completeCancelledApiTurn(args: {
14
14
  acknowledge(): Promise<void>;
15
- actorId: string;
16
15
  cancellation?: ApiTurnCancellation;
17
16
  conversation: ThreadConversationState;
18
17
  conversationId: string;
@@ -0,0 +1,4 @@
1
+ /** Shared mailbox helpers for conversation-only turns. */
2
+ import type { InboundMessage } from "@/chat/task-execution/store";
3
+ /** Join non-empty mailbox texts for one conversation-only turn. */
4
+ export declare function joinMailboxText(messages: readonly InboundMessage[]): string;
@@ -1,4 +1,8 @@
1
1
  import { z } from "zod";
2
+ import { type Source } from "@sentry/junior-plugin-api";
3
+ import { type Actor } from "@/chat/actor";
4
+ import type { ConversationPrivacy } from "@/chat/conversation-privacy";
5
+ import type { ConversationAuthor, ConversationMessage } from "@/chat/state/conversation";
2
6
  import type { InboundMessage } from "@/chat/task-execution/store";
3
7
  import type { ConversationWorkerContext } from "@/chat/task-execution/worker";
4
8
  declare const apiTurnMailboxMetadataSchema: z.ZodObject<{
@@ -10,22 +14,34 @@ declare const apiTurnMailboxMetadataSchema: z.ZodObject<{
10
14
  messageId: z.ZodString;
11
15
  }, z.core.$strict>;
12
16
  export type ApiTurnMailboxMetadata = z.output<typeof apiTurnMailboxMetadataSchema>;
17
+ export interface TurnInput {
18
+ actor: Actor;
19
+ author: ConversationAuthor;
20
+ message: InboundMessage;
21
+ source: "resource_event" | "web";
22
+ }
23
+ export type TurnIdentity = Pick<TurnInput, "actor" | "author" | "source">;
24
+ /** Restore normalized Turn identity from one saved Message. */
25
+ export declare function turnIdentityFromConversationMessage(message: ConversationMessage): TurnIdentity | undefined;
26
+ /** Build the AgentRun Source for one Turn input. */
27
+ export declare function sourceFromTurnInput(args: {
28
+ conversationId: string;
29
+ source: TurnInput["source"];
30
+ visibility?: ConversationPrivacy;
31
+ }): Source;
13
32
  /** Return the active root API Turn for one Conversation, if it has one. */
14
33
  export declare function getActiveApiTurnId(conversationId: string): Promise<string | undefined>;
15
34
  /** Return the idle auth-paused root API Turn for one Conversation. */
16
35
  export declare function getAuthPausedApiTurnId(conversationId: string): Promise<string | undefined>;
17
36
  /**
18
- * Resolve API Turn work from mailbox metadata or an active checkpoint.
37
+ * Resolve conversation-only work from new input or a saved Turn.
19
38
  *
20
- * Empty resume wakes after yield carry no mailbox rows. Use durable active
21
- * Turn state so these wakes do not fall through to Slack.
39
+ * User messages from the Conversation API run here. Resource events with a
40
+ * local Destination run here too. Saved state identifies a resumed Turn.
22
41
  */
23
42
  export declare function resolveApiTurnWork(context: ConversationWorkerContext): Promise<{
24
43
  kind: "mailbox";
25
- batch: Array<{
26
- message: InboundMessage;
27
- metadata: ApiTurnMailboxMetadata;
28
- }>;
44
+ batch: TurnInput[];
29
45
  } | {
30
46
  kind: "resume";
31
47
  turnId: string;
@@ -1,7 +1,7 @@
1
1
  import type { StateAdapter } from "chat";
2
2
  import { type Destination } from "@sentry/junior-plugin-api";
3
3
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
4
- import type { WebActor } from "@/chat/actor";
4
+ import { type WebActor } from "@/chat/actor";
5
5
  import type { ConversationStore } from "@/chat/conversations/store";
6
6
  import type { AgentRunner } from "@/chat/runtime/agent-runner";
7
7
  import { type InboundMessage } from "@/chat/task-execution/store";
@@ -90,7 +90,7 @@ export declare function appendAndEnqueueApiConversationMessage(input: AppendApiC
90
90
  exclusive: true;
91
91
  }): Promise<ApiConversationMessageAdmission>;
92
92
  export declare function appendAndEnqueueApiConversationMessage(input: AppendApiConversationMessageInput, options: EnqueueOptions): Promise<ApiConversationMessageAccepted>;
93
- /** Create the worker for messages from the Conversation API. */
93
+ /** Create the worker for Turns that need no provider delivery. */
94
94
  export declare function createApiTurnWorker(agentRunner: AgentRunner, cancellation?: ApiTurnCancellation): (context: ConversationWorkerContext) => Promise<ConversationWorkerResult>;
95
95
  /** Route Conversation API work before other work. */
96
96
  export declare function routeApiTurnWork(options: {
@@ -1,10 +1,10 @@
1
1
  import { z } from "zod";
2
- /** Provider-neutral container associated with a conversation. */
2
+ /** One place outside Junior where a Conversation can be delivered. */
3
3
  export declare const locationSchema: z.ZodObject<{
4
4
  id: z.ZodString;
5
5
  provider: z.ZodString;
6
6
  tenantId: z.ZodOptional<z.ZodString>;
7
7
  providerId: z.ZodString;
8
8
  }, z.core.$strict>;
9
- /** Validated provider location associated with a conversation. */
9
+ /** Validated Location associated with a Conversation. */
10
10
  export type Location = z.output<typeof locationSchema>;
@@ -17,6 +17,18 @@ export interface ConversationExecution {
17
17
  export interface ConversationLineage {
18
18
  parentConversationId: string;
19
19
  }
20
+ /**
21
+ * Durable Conversation owned by Junior.
22
+ *
23
+ * The final interface stores zero or one complete Location here. No Location
24
+ * means the Conversation stays in Junior's API and UI. A Location names the
25
+ * outside place where a provider can deliver the Conversation. Source may also
26
+ * contain this Location so the agent can use it. Delivery contains it when
27
+ * output may be sent there. Only Delivery allows output to be sent.
28
+ *
29
+ * `destination` and `sessionSource` temporarily duplicate parts of that model.
30
+ * Their field TODOs state when each legacy copy can be removed.
31
+ */
20
32
  export interface Conversation {
21
33
  channelName?: string;
22
34
  conversationId: string;
@@ -30,6 +42,7 @@ export interface Conversation {
30
42
  };
31
43
  lastActivityAtMs: number;
32
44
  lineage?: ConversationLineage;
45
+ /** Optional provider coordinates associated with this Conversation. */
33
46
  location?: Location;
34
47
  actor?: StoredSlackActor;
35
48
  schemaVersion: 1;
@@ -40,3 +40,5 @@ export declare class ConversationTurnLifecycleService implements ConversationTur
40
40
  /** Record a classified failure once. Do not store raw error text. */
41
41
  fail(input: FailConversationTurnInput): Promise<void>;
42
42
  }
43
+ /** Return the Turn lifecycle that records Conversation events. */
44
+ export declare function getTurnLifecycle(): ConversationTurnLifecycle;
@@ -10,7 +10,6 @@ import type { Message, MessageContext, Thread } from "chat";
10
10
  import type { Destination } from "@sentry/junior-plugin-api";
11
11
  import type { SubscribedReplyDecision, SubscribedReplyPolicy } from "@/chat/services/subscribed-reply-policy";
12
12
  import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnMessageText, type TurnToolInvocation } from "@/chat/runtime/turn-input";
13
- import type { FailConversationTurnInput } from "@/chat/conversations/turn-lifecycle";
14
13
  export interface AssistantLifecycleEvent {
15
14
  channelId: string;
16
15
  context?: {
@@ -55,7 +54,6 @@ export interface SlackTurnRuntimeDependencies<TPreparedState> {
55
54
  threadId: string;
56
55
  threadTs: string;
57
56
  }) => Promise<void>;
58
- failConversationTurn: (input: FailConversationTurnInput) => Promise<void>;
59
57
  refreshAssistantThreadContext: (event: {
60
58
  channelId: string;
61
59
  sourceChannelId?: string;
@@ -12,7 +12,6 @@ import type { PreparedTurnState } from "@/chat/runtime/turn-preparation";
12
12
  import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnToolInvocation } from "@/chat/runtime/turn-input";
13
13
  import type { ContextCompactor } from "@/chat/services/context-compaction";
14
14
  import type { PausedTurns } from "@/chat/task-execution/turn-wake";
15
- import type { ConversationTurnLifecycle } from "@/chat/conversations/turn-lifecycle";
16
15
  import { type ScheduleSessionCompletedPluginTasksOptions } from "@/chat/plugins/task-runner";
17
16
  import type { DispatchTurnContext, DispatchTurnResult } from "@/chat/agent-dispatch/types";
18
17
  interface SlackTurnDeps {
@@ -35,7 +34,6 @@ interface SlackTurnDeps {
35
34
  }>>;
36
35
  prepareTurnState: (args: PrepareTurnStateInput) => Promise<PreparedTurnState>;
37
36
  sendPluginTask?: ScheduleSessionCompletedPluginTasksOptions["send"];
38
- turnLifecycle: Pick<ConversationTurnLifecycle, "fail" | "start">;
39
37
  }
40
38
  /** Build the Slack caller that prepares input and delivers output for a Turn. */
41
39
  export declare function createSlackTurn(deps: SlackTurnDeps): (thread: Thread, message: Message, options: {
@@ -1,5 +1,17 @@
1
- /** Synthetic Slack author id stamped on resource-event mailbox messages. */
2
- export declare const RESOURCE_EVENT_SLACK_AUTHOR_ID = "UJRNEVENT";
1
+ /**
2
+ * Synthetic author id stamped on resource-event mailbox messages.
3
+ *
4
+ * Kept stable so provider adapters and conversation history can recognize the
5
+ * same system input for resource-event turns.
6
+ */
7
+ export declare const RESOURCE_EVENT_AUTHOR_ID = "UJRNEVENT";
8
+ /** Synthetic Message author for resource-event input. */
9
+ export declare const RESOURCE_EVENT_MESSAGE_AUTHOR: {
10
+ readonly fullName: "Junior event";
11
+ readonly isBot: true;
12
+ readonly userId: "UJRNEVENT";
13
+ readonly userName: "junior-event";
14
+ };
3
15
  /** System execution actor for every resource-event turn. */
4
16
  export declare const RESOURCE_EVENT_SYSTEM_ACTOR: {
5
17
  readonly platform: "system";
@@ -0,0 +1,18 @@
1
+ import type { ResourceEvent } from "@sentry/junior-plugin-api";
2
+ import type { StateAdapter } from "chat";
3
+ import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
4
+ export type ResourceEventAppPublisher = {
5
+ neededMatchKeys(input: {
6
+ eventTypes: string[];
7
+ identifiers: string[];
8
+ namespace: string;
9
+ }): Promise<string[]>;
10
+ publish(event: ResourceEvent): Promise<void>;
11
+ };
12
+ /** Build the core resource-event publisher used by plugin routes. */
13
+ export declare function createResourceEventAppPublisher(args: {
14
+ conversationWork: () => {
15
+ queue?: ConversationWorkQueue;
16
+ state?: StateAdapter;
17
+ };
18
+ }): ResourceEventAppPublisher;
@@ -2,6 +2,25 @@ import { type PluginResourceEvents, type ResourceEventMatch, type ResourceEventM
2
2
  import { z } from "zod";
3
3
  type ResourceEventRegistration = Pick<PluginResourceEvents, "resourceTypes" | "normalizeIdentifier">;
4
4
  export type ResourceEventCatalog = Readonly<Record<string, ResourceEventRegistration>>;
5
+ /** Core-owned resource-event namespace. Not a plugin publisher. */
6
+ export declare const CORE_RESOURCE_EVENT_NAMESPACE = "junior";
7
+ /** True when the catalog has any enabled registration. */
8
+ export declare function hasResourceEventCatalogEntries(catalog: ResourceEventCatalog): boolean;
9
+ /**
10
+ * True when at least one plugin namespace is enabled.
11
+ *
12
+ * Core Workspace snapshot events stay in the catalog for search and temporary
13
+ * watches. Durable event tasks still require a plugin publisher.
14
+ */
15
+ export declare function hasPluginResourceEventCatalogEntries(catalog: ResourceEventCatalog): boolean;
16
+ /**
17
+ * Catalog entries that durable event tasks may select.
18
+ *
19
+ * Core Workspace snapshot events only wake temporary watches. Snapshot finish
20
+ * does not run event-task ingest, so those namespaces stay out of create/update
21
+ * schemas and trigger availability.
22
+ */
23
+ export declare function pluginResourceEventCatalog(catalog: ResourceEventCatalog): ResourceEventCatalog;
5
24
  /** Build the model-facing namespace enum from enabled resource event plugins. */
6
25
  export declare function eventNamespaceSchema(catalog: ResourceEventCatalog): z.ZodString | z.ZodEnum<{
7
26
  [x: string]: string;
@@ -5,7 +5,6 @@ export declare function ingestResourceEvent(input: unknown, options: {
5
5
  nowMs?: number;
6
6
  queue: ConversationWorkQueue;
7
7
  state?: StateAdapter;
8
- teamId: string;
9
8
  }): Promise<{
10
9
  enqueued: number;
11
10
  }>;
@@ -1,5 +1,5 @@
1
1
  import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
2
- import { appendAndEnqueueInboundMessage } from "@/chat/task-execution/store";
2
+ import { appendAndEnqueueInboundMessage, type AppendAndEnqueueInboundMessageResult, type InboundMessage } from "@/chat/task-execution/store";
3
3
  import type { ResourceEventSubscription } from "@/chat/resource-events/store";
4
4
  export interface ResourceEventNotification {
5
5
  eventKey: string;
@@ -19,10 +19,35 @@ export interface ResourceEventNotification {
19
19
  * contract. Stable delivery rules live in runtime and docs, not this prompt.
20
20
  */
21
21
  export declare function renderResourceEventNotificationText(subscription: Pick<ResourceEventSubscription, "intent" | "label" | "resourceType">, event: Pick<ResourceEventNotification, "namespace" | "eventType" | "trustedSummary" | "data" | "untrustedText">): string;
22
- /** Enqueue a resource event as normal conversation mailbox input. */
22
+ /** Resource-event identity stamped on plain mailbox input. */
23
+ export type ResourceEventMailboxMetadata = {
24
+ kind: "resource_event";
25
+ resourceEvent: {
26
+ eventKey: string;
27
+ eventType: string;
28
+ namespace: string;
29
+ identifier: string;
30
+ subscriptionId: string;
31
+ };
32
+ } & Record<string, unknown>;
33
+ /** Whether mailbox metadata is a plain resource-event wake. */
34
+ export declare function isResourceEventMailboxMetadata(value: unknown): value is ResourceEventMailboxMetadata;
35
+ /** Build plain conversation mailbox input for one matched watch. */
36
+ export declare function createResourceEventInboundMessage(input: {
37
+ event: ResourceEventNotification;
38
+ subscription: Pick<ResourceEventSubscription, "conversationId" | "id">;
39
+ text: string;
40
+ receivedAtMs?: number;
41
+ }): InboundMessage;
42
+ /**
43
+ * Enqueue a resource event as normal conversation mailbox input.
44
+ *
45
+ * The watch only names the conversation. Destination stays on the conversation
46
+ * and is applied when the worker runs.
47
+ */
23
48
  export declare function enqueueResourceEventNotification(args: {
24
49
  event: ResourceEventNotification;
25
50
  queue: ConversationWorkQueue;
26
51
  subscription: ResourceEventSubscription;
27
52
  state?: Parameters<typeof appendAndEnqueueInboundMessage>[0]["state"];
28
- }): Promise<Awaited<ReturnType<typeof appendAndEnqueueInboundMessage>>>;
53
+ }): Promise<AppendAndEnqueueInboundMessageResult>;
@@ -1,3 +1,8 @@
1
- import type { ResourceEventCatalog } from "@/chat/resource-events/catalog";
2
- /** Read enabled plugin resource-event registrations as one core catalog. */
1
+ import { type ResourceEventCatalog } from "@/chat/resource-events/catalog";
2
+ /**
3
+ * Enabled resource-event registrations for search, guidance, and tool schemas.
4
+ *
5
+ * Includes core Workspace snapshot events under the `junior` namespace, plus
6
+ * every enabled plugin registration. Plugins may not use the `junior` namespace.
7
+ */
3
8
  export declare function getResourceEventCatalog(): ResourceEventCatalog;
@@ -1,17 +1,9 @@
1
1
  import type { StateAdapter } from "chat";
2
- import { type Destination, type ResourceEventData, type ResourceEventMatch } from "@sentry/junior-plugin-api";
2
+ import { type ResourceEventData, type ResourceEventMatch } from "@sentry/junior-plugin-api";
3
3
  import { z } from "zod";
4
4
  declare const subscriptionSchema: z.ZodObject<{
5
5
  conversationId: z.ZodString;
6
6
  createdAtMs: z.ZodNumber;
7
- destination: z.ZodDiscriminatedUnion<[z.ZodObject<{
8
- platform: z.ZodLiteral<"slack">;
9
- teamId: z.ZodString;
10
- channelId: z.ZodString;
11
- }, z.core.$strict>, z.ZodObject<{
12
- platform: z.ZodLiteral<"local">;
13
- conversationId: z.ZodString;
14
- }, z.core.$strict>], "platform">;
15
7
  events: z.ZodArray<z.ZodString>;
16
8
  expiresAtMs: z.ZodNumber;
17
9
  id: z.ZodString;
@@ -31,7 +23,6 @@ declare const subscriptionSchema: z.ZodObject<{
31
23
  export type ResourceEventSubscription = z.output<typeof subscriptionSchema>;
32
24
  export interface CreateResourceEventSubscriptionInput {
33
25
  conversationId: string;
34
- destination: Destination;
35
26
  events: string[];
36
27
  expiresAtMs: number;
37
28
  intent: string;
@@ -75,7 +66,6 @@ export declare function collectResourceEventMatchKeys(input: {
75
66
  namespace: string;
76
67
  nowMs?: number;
77
68
  state?: StateAdapter;
78
- teamId: string;
79
69
  }): Promise<string[]>;
80
70
  /** Find active subscriptions interested in a normalized resource event. */
81
71
  export declare function findMatchingResourceEventSubscriptions(input: {
@@ -85,7 +75,6 @@ export declare function findMatchingResourceEventSubscriptions(input: {
85
75
  namespace: string;
86
76
  identifier: string;
87
77
  state?: StateAdapter;
88
- teamId: string;
89
78
  }): Promise<ResourceEventSubscription[]>;
90
79
  /** Recheck and deliver a matched subscription while holding its status lock. */
91
80
  export declare function deliverResourceEventSubscription(input: {
@@ -97,7 +86,6 @@ export declare function deliverResourceEventSubscription(input: {
97
86
  identifier: string;
98
87
  state?: StateAdapter;
99
88
  subscription: ResourceEventSubscription;
100
- teamId: string;
101
89
  terminal?: boolean;
102
90
  waitDeadlineMs?: number;
103
91
  }): Promise<boolean>;
@@ -1,4 +1,8 @@
1
- /** Return whether provider events can be bound to one Slack workspace. */
2
- export declare function canRouteResourceEvents(): boolean;
3
- /** Resolve and cache the Slack workspace owned by this app instance. */
1
+ /**
2
+ * Resolve the single-bot Slack team id for event-task indexing.
3
+ *
4
+ * Resource watches do not use this. Event tasks still key by destination team
5
+ * until that store is conversation-owned. Resource-event delivery itself is
6
+ * not gated on Slack.
7
+ */
4
8
  export declare function createResourceEventTeamIdResolver(): () => Promise<string | undefined>;
@@ -49,11 +49,12 @@ export declare function selectSandboxEgressGrant(input: {
49
49
  */
50
50
  export declare function authorizationForSandboxEgressGrant(provider: string, selection: SandboxEgressGrantSelection): PluginAuthorization | undefined;
51
51
  /**
52
- * Return cached or newly issued credential header transforms for a selected grant.
52
+ * Return credential header transforms for a selected grant.
53
53
  *
54
- * Leases are cached on the host by provider grant, validated against
55
- * provider-owned domains, and reused until the provider lease is near expiry.
56
- * Sandbox context only authorizes the hop.
54
+ * Only shared installation grants are remembered on the host. User and other
55
+ * grants always issue from the live credential source so a saved login change
56
+ * cannot leave stale auth headers in place. The sandbox context only authorizes
57
+ * the request.
57
58
  */
58
59
  export declare function sandboxEgressCredentialLease(provider: string, selection: SandboxEgressGrantSelection, context: SandboxEgressCredentialContext): Promise<SandboxEgressCredentialLease>;
59
60
  /** Return whether a credential lease can modify requests to the target host. */
@@ -22,17 +22,17 @@ export declare function createSandboxEgressCredentialToken(input: {
22
22
  */
23
23
  export declare function parseSandboxEgressCredentialToken(token: string | undefined): SandboxEgressCredentialContext | undefined;
24
24
  /**
25
- * Cache credential header transforms for one provider grant.
25
+ * Remember auth headers for a shared installation grant.
26
26
  *
27
- * TTL follows the provider lease expiry. Sandbox context expiry still decides
28
- * whether a hop may use the cache; it does not shorten a shared installation
29
- * lease for other sandboxes.
27
+ * User and other grants are ignored here. TTL follows the provider expiry.
28
+ * Sandbox context expiry still decides whether a request may use the headers;
29
+ * it does not shorten a shared installation grant for other sandboxes.
30
30
  */
31
- export declare function setSandboxEgressCredentialLease(context: SandboxEgressCredentialContext, lease: SandboxEgressCredentialLease): Promise<void>;
32
- /** Load cached credential header transforms for one provider grant. */
33
- export declare function getSandboxEgressCredentialLease(provider: string, grant: SandboxEgressCredentialLease["grant"], context: SandboxEgressCredentialContext): Promise<SandboxEgressCredentialLease | undefined>;
34
- /** Clear a cached lease after the upstream provider rejects its auth headers. */
35
- export declare function clearSandboxEgressCredentialLease(provider: string, grant: SandboxEgressCredentialLease["grant"], context: SandboxEgressCredentialContext): Promise<void>;
31
+ export declare function setSandboxEgressCredentialLease(_context: SandboxEgressCredentialContext, lease: SandboxEgressCredentialLease): Promise<void>;
32
+ /** Load remembered auth headers for a shared installation grant. */
33
+ export declare function getSandboxEgressCredentialLease(provider: string, grant: SandboxEgressCredentialLease["grant"], _context: SandboxEgressCredentialContext): Promise<SandboxEgressCredentialLease | undefined>;
34
+ /** Drop remembered installation headers after the upstream rejects them. */
35
+ export declare function clearSandboxEgressCredentialLease(provider: string, grant: SandboxEgressCredentialLease["grant"], _context: SandboxEgressCredentialContext): Promise<void>;
36
36
  /**
37
37
  * Record that credential issuance needs user authorization for this command.
38
38
  *
@@ -12,7 +12,7 @@ export declare function isAbortError(error: unknown): boolean;
12
12
  export declare function isSandboxApiTransientError(error: unknown): boolean;
13
13
  /** Detect interrupted command streams where no reliable exit status is available. */
14
14
  export declare function isSandboxCommandStreamInterruptedError(error: unknown): boolean;
15
- /** Wrap raw sandbox setup failures into one stable user-facing error contract. */
15
+ /** Wrap setup failures. Keep WorkspaceSnapshotNotReadyError as-is. */
16
16
  export declare function wrapSandboxSetupError(error: unknown): Error;
17
17
  /** Record span data and throw one stable sandbox operation error. */
18
18
  export declare function throwSandboxOperationError(action: string, error: unknown, includeMissingPath?: boolean): never;
@@ -1,4 +1,4 @@
1
- /** Durable opaque handle used to reopen a conversation's sandbox. */
1
+ /** Sandbox this conversation is using. Reopen by `id`; only switchWorkspace replaces it. */
2
2
  export interface SandboxRef {
3
3
  id: string;
4
4
  profileHash?: string;
@@ -1,8 +1,15 @@
1
- import type { ResourceEvent, SubscribableResource } from "@sentry/junior-plugin-api";
1
+ import type { PluginResourceEvents, ResourceEvent, SubscribableResource } from "@sentry/junior-plugin-api";
2
2
  export declare const WORKSPACE_SNAPSHOT_NAMESPACE = "junior";
3
3
  export declare const WORKSPACE_SNAPSHOT_RESOURCE_TYPE = "workspace_snapshot";
4
4
  export declare const WORKSPACE_SNAPSHOT_READY_EVENT = "workspace_snapshot.ready";
5
5
  export declare const WORKSPACE_SNAPSHOT_FAILED_EVENT = "workspace_snapshot.failed";
6
+ /**
7
+ * Core catalog entry for Workspace snapshot ready and failed events.
8
+ *
9
+ * Uses the same registration shape as plugins so search, guidance, and tool
10
+ * schemas treat these events like any other resource type.
11
+ */
12
+ export declare function workspaceSnapshotResourceEvents(): PluginResourceEvents;
6
13
  /** Describe the events that report when a snapshot build ends. */
7
14
  export declare function workspaceSnapshotWatch(input: {
8
15
  workspaceId: string;
@@ -1,6 +1,11 @@
1
1
  /** Report that a Workspace snapshot is not ready to use. */
2
2
  export declare class WorkspaceSnapshotNotReadyError extends Error {
3
+ readonly workspaceName: string;
3
4
  constructor(workspaceName: string);
4
5
  }
5
- /** Check an error and its causes for a snapshot that is not ready. */
6
+ /** Return WorkspaceSnapshotNotReadyError from this error or its causes. */
7
+ export declare function getWorkspaceSnapshotNotReadyError(error: unknown): WorkspaceSnapshotNotReadyError | undefined;
8
+ /** True when this error or a cause is WorkspaceSnapshotNotReadyError. */
6
9
  export declare function isWorkspaceSnapshotNotReadyError(error: unknown): boolean;
10
+ /** User message when a Workspace sandbox is still preparing. */
11
+ export declare function workspaceSnapshotNotReadyUserMessage(error: WorkspaceSnapshotNotReadyError): string;
@@ -1,4 +1,6 @@
1
1
  /** Build a Sentry conversation URL only when the runtime has enough Sentry config. */
2
2
  export declare function buildSentryConversationUrl(conversationId: string): string | undefined;
3
+ /** Build a Sentry event URL only when the runtime has enough Sentry config. */
4
+ export declare function buildSentryEventUrl(eventId: string): string | undefined;
3
5
  /** Build a Sentry trace URL only when the runtime has enough Sentry config. */
4
6
  export declare function buildSentryTraceUrl(traceId: string): string | undefined;
@@ -1,18 +1,34 @@
1
1
  /**
2
- * Load turn-session routing from durable conversation metadata.
2
+ * Load Location, Destination, and session Source from the Conversation record.
3
3
  *
4
- * SQL owns destination and session source. Resume paths query those columns
5
- * directly — no redis fallback and no derived rebuild of missing fields.
4
+ * Destination is set once on the root conversation. Child conversations
5
+ * inherit through parent lineage. Later turns and mailbox wakes use that
6
+ * same destination so tools stay consistent for the whole conversation.
6
7
  */
7
8
  import type { Destination, Source } from "@sentry/junior-plugin-api";
8
9
  import type { ConversationStore } from "@/chat/conversations/store";
10
+ import type { Location } from "@/chat/conversations/location";
9
11
  export interface TurnSessionRouting {
10
12
  destination: Destination;
11
- locationId?: string;
12
- source: Source;
13
+ location?: Location;
14
+ /** Present when the conversation already stores a session source. */
15
+ source?: Source;
13
16
  }
14
- /** Require conversation destination and session source from SQL. */
17
+ /** Conversation data with a required Destination and Source. */
18
+ export type RequiredTurnSessionRouting = TurnSessionRouting & {
19
+ source: Source;
20
+ };
21
+ /**
22
+ * Resolve the Conversation's Location, Destination, and session Source.
23
+ *
24
+ * Walks parent lineage when the conversation has no destination of its own.
25
+ */
26
+ export declare function resolveConversationRouting(args: {
27
+ conversationId: string;
28
+ conversationStore?: ConversationStore;
29
+ }): Promise<TurnSessionRouting | undefined>;
30
+ /** Require the Conversation Destination and Source from SQL. */
15
31
  export declare function resolveTurnSessionRouting(args: {
16
32
  conversationId: string;
17
33
  conversationStore?: ConversationStore;
18
- }): Promise<TurnSessionRouting>;
34
+ }): Promise<RequiredTurnSessionRouting>;