@sentry/junior 0.74.1 → 0.76.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 (121) hide show
  1. package/README.md +1 -1
  2. package/bin/junior.mjs +4 -66
  3. package/dist/agent-hooks-ZOE7RIED.js +37 -0
  4. package/dist/api-reference.d.ts +3 -1
  5. package/dist/app.js +5516 -5422
  6. package/dist/build/copy-build-content.d.ts +1 -1
  7. package/dist/build/virtual-config.d.ts +2 -2
  8. package/dist/chat/agent-dispatch/context.d.ts +2 -3
  9. package/dist/chat/agent-dispatch/runner.d.ts +2 -0
  10. package/dist/chat/agent-dispatch/types.d.ts +2 -1
  11. package/dist/chat/config.d.ts +3 -0
  12. package/dist/chat/credentials/state-adapter-token-store.d.ts +2 -0
  13. package/dist/chat/credentials/subject.d.ts +3 -3
  14. package/dist/chat/credentials/user-token-store.d.ts +17 -12
  15. package/dist/chat/db.d.ts +8 -0
  16. package/dist/chat/mcp/auth-store.d.ts +2 -1
  17. package/dist/chat/mcp/oauth.d.ts +2 -1
  18. package/dist/chat/oauth-flow.d.ts +3 -1
  19. package/dist/chat/pi/client.d.ts +15 -7
  20. package/dist/chat/plugins/agent-hooks.d.ts +20 -13
  21. package/dist/chat/plugins/auth/oauth-request.d.ts +11 -7
  22. package/dist/chat/plugins/credential-hooks.d.ts +6 -6
  23. package/dist/chat/plugins/logging.d.ts +2 -2
  24. package/dist/chat/plugins/model.d.ts +9 -0
  25. package/dist/chat/plugins/package-discovery.d.ts +2 -1
  26. package/dist/chat/plugins/prompt.d.ts +5 -0
  27. package/dist/chat/plugins/registry.d.ts +4 -0
  28. package/dist/chat/plugins/state.d.ts +3 -5
  29. package/dist/chat/plugins/task-callback.d.ts +5 -0
  30. package/dist/chat/plugins/task-message.d.ts +23 -0
  31. package/dist/chat/plugins/task-queue.d.ts +5 -0
  32. package/dist/chat/plugins/task-runner.d.ts +12 -0
  33. package/dist/chat/plugins/task-signing.d.ts +31 -0
  34. package/dist/chat/plugins/types.d.ts +1 -0
  35. package/dist/chat/plugins/validation.d.ts +5 -0
  36. package/dist/chat/prompt.d.ts +15 -1
  37. package/dist/chat/requester.d.ts +6 -5
  38. package/dist/chat/respond-helpers.d.ts +2 -0
  39. package/dist/chat/respond.d.ts +13 -2
  40. package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
  41. package/dist/chat/runtime/reply-executor.d.ts +5 -1
  42. package/dist/chat/runtime/slack-resume.d.ts +10 -2
  43. package/dist/chat/runtime/slack-runtime.d.ts +6 -1
  44. package/dist/chat/sandbox/egress-credentials.d.ts +8 -8
  45. package/dist/chat/sandbox/sandbox.d.ts +2 -2
  46. package/dist/chat/sentry.d.ts +1 -0
  47. package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -1
  48. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
  49. package/dist/chat/services/subscribed-decision.d.ts +2 -2
  50. package/dist/chat/services/turn-session-record.d.ts +11 -7
  51. package/dist/chat/sql/db.d.ts +3 -0
  52. package/dist/chat/sql/executor.d.ts +7 -0
  53. package/dist/chat/sql/neon.d.ts +2 -4
  54. package/dist/chat/sql/postgres.d.ts +6 -0
  55. package/dist/chat/state/turn-session.d.ts +8 -5
  56. package/dist/chat/task-execution/state.d.ts +7 -2
  57. package/dist/chat/task-execution/worker.d.ts +1 -1
  58. package/dist/chat/tools/agent-tools.d.ts +9 -2
  59. package/dist/chat/tools/slack/context.d.ts +2 -2
  60. package/dist/chat/tools/types.d.ts +7 -4
  61. package/dist/chat/vercel-queue-client.d.ts +3 -0
  62. package/dist/{chunk-YOHFWWBV.js → chunk-2ECJXSVQ.js} +5 -107
  63. package/dist/{chunk-OR6NQJ5E.js → chunk-4SCWV7TJ.js} +3 -3
  64. package/dist/chunk-4UO6FK4G.js +64 -0
  65. package/dist/chunk-56TBVRJG.js +115 -0
  66. package/dist/{chunk-3BYAPS6B.js → chunk-EJN6G5A2.js} +17 -11
  67. package/dist/{chunk-SQGMG7OD.js → chunk-HHDUKWVG.js} +508 -149
  68. package/dist/{chunk-6UP2Z2RZ.js → chunk-JBASI5VV.js} +7 -7
  69. package/dist/chunk-KNFROR7R.js +127 -0
  70. package/dist/{chunk-HYHKTFG2.js → chunk-KOIMO7S3.js} +186 -910
  71. package/dist/chunk-MLKGABMK.js +9 -0
  72. package/dist/chunk-NFTMTIP3.js +964 -0
  73. package/dist/chunk-NYKJ3KON.js +1082 -0
  74. package/dist/{chunk-SJHUF3DP.js → chunk-OJ53FYVG.js} +2 -10
  75. package/dist/{chunk-KVZL5NZS.js → chunk-Q3XNY442.js} +17 -7
  76. package/dist/{chunk-YRDS7VKO.js → chunk-Q6XFTRV5.js} +2 -2
  77. package/dist/chunk-R6Z5XWY3.js +1076 -0
  78. package/dist/chunk-RV5RYIJW.js +56 -0
  79. package/dist/chunk-SG5WAA7H.js +132 -0
  80. package/dist/chunk-ST6YNAXG.js +54 -0
  81. package/dist/{chunk-GM7HTXYC.js → chunk-T77LUIX3.js} +148 -151
  82. package/dist/{chunk-CYUI7JU5.js → chunk-VALUBQ7R.js} +22 -30
  83. package/dist/chunk-XBBC6W45.js +71 -0
  84. package/dist/chunk-Y2CM7HXH.js +111 -0
  85. package/dist/{chunk-F6HWCPOC.js → chunk-Y5OFBCBZ.js} +1 -1
  86. package/dist/{chunk-M4FLLXXD.js → chunk-Z4CIQ3EB.js} +5 -1
  87. package/dist/{chunk-7Q5YOUUT.js → chunk-ZLMBNBUG.js} +146 -52
  88. package/dist/{chunk-2LUZA3LY.js → chunk-ZQB37HUX.js} +11 -11
  89. package/dist/cli/chat.js +87 -8
  90. package/dist/cli/check.js +8 -7
  91. package/dist/cli/env.js +4 -53
  92. package/dist/cli/init.js +6 -1
  93. package/dist/cli/main.js +84 -0
  94. package/dist/cli/plugins.js +244 -0
  95. package/dist/cli/run.js +5 -52
  96. package/dist/cli/snapshot-warmup.js +12 -11
  97. package/dist/cli/upgrade.js +385 -26
  98. package/dist/db-7A7PFRGL.js +17 -0
  99. package/dist/deployment.d.ts +1 -0
  100. package/dist/handlers/sandbox-egress-route.d.ts +4 -0
  101. package/dist/handlers/slack-webhook.d.ts +4 -0
  102. package/dist/handlers/webhooks.d.ts +6 -13
  103. package/dist/instrumentation.js +14 -18
  104. package/dist/nitro.d.ts +1 -1
  105. package/dist/nitro.js +67 -101
  106. package/dist/plugin-module.d.ts +21 -0
  107. package/dist/plugins-PZMDS7AT.js +15 -0
  108. package/dist/plugins.d.ts +9 -5
  109. package/dist/registry-OIPAJU2O.js +46 -0
  110. package/dist/reporting/conversations.d.ts +3 -3
  111. package/dist/reporting.d.ts +6 -5
  112. package/dist/reporting.js +42 -28
  113. package/dist/{runner-27NP2TEO.js → runner-KPLNHDCV.js} +77 -19
  114. package/dist/sentry-4CP5NNQ5.js +31 -0
  115. package/dist/validation-SLA6IGF7.js +15 -0
  116. package/dist/vercel.js +1 -1
  117. package/package.json +14 -11
  118. package/dist/chat/conversations/configured.d.ts +0 -5
  119. package/dist/chat/conversations/state.d.ts +0 -4
  120. package/dist/chunk-2KG3PWR4.js +0 -17
  121. package/dist/chunk-JL2SLRAT.js +0 -1970
@@ -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 { ChannelConfigurationService } from "@/chat/configuration/types";
3
3
  import type { ThreadArtifactsState } from "@/chat/state/artifacts";
4
4
  import type { ConversationPendingAuthState } from "@/chat/state/conversation";
@@ -8,6 +8,7 @@ import { type SandboxAcquiredState } from "@/chat/sandbox/sandbox";
8
8
  import type { SandboxEgressTracePropagationConfig } from "@/chat/sandbox/egress-tracing";
9
9
  import type { AssistantStatusSpec } from "@/chat/slack/assistant-thread/status";
10
10
  import type { SlackConversationContext } from "@/chat/slack/conversation-context";
11
+ import { type ToolExecutionReport } from "@/chat/tools/agent-tools";
11
12
  import { type AssistantReply, type AgentTurnDiagnostics } from "@/chat/services/turn-result";
12
13
  import type { AgentTurnSurface } from "@/chat/state/turn-session";
13
14
  import type { CredentialContext } from "@/chat/credentials/context";
@@ -18,9 +19,18 @@ export interface ReplyRequestContext {
18
19
  skillDirs?: string[];
19
20
  credentialContext?: CredentialContext;
20
21
  requester?: Requester;
22
+ source: Source;
21
23
  slackConversation?: SlackConversationContext;
22
24
  destination: Destination;
23
25
  surface?: AgentTurnSurface;
26
+ dispatch?: {
27
+ actor?: {
28
+ id: string;
29
+ type: string;
30
+ };
31
+ metadata?: Record<string, string>;
32
+ plugin?: string;
33
+ };
24
34
  correlation?: {
25
35
  conversationId?: string;
26
36
  threadId?: string;
@@ -71,7 +81,8 @@ export interface ReplyRequestContext {
71
81
  onToolInvocation?: (invocation: {
72
82
  toolName: string;
73
83
  params: Record<string, unknown>;
74
- }) => void;
84
+ }) => void | Promise<void>;
85
+ onToolResult?: (result: ToolExecutionReport) => void | Promise<void>;
75
86
  }
76
87
  export type AssistantReplyRequestContext = ReplyRequestContext;
77
88
  export interface ReplyRequestAttachment {
@@ -6,6 +6,10 @@ export interface AgentContinueRunnerOptions {
6
6
  generateReply?: typeof generateAssistantReply;
7
7
  resumeTurn?: typeof resumeSlackTurn;
8
8
  scheduleAgentContinue?: (request: AgentContinueRequest) => Promise<void>;
9
+ scheduleSessionCompletedPluginTasks?: (params: {
10
+ conversationId: string;
11
+ sessionId: string;
12
+ }) => Promise<void>;
9
13
  }
10
14
  /**
11
15
  * Continue one paused Slack agent run from durable conversation state.
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { Message, Thread } from "chat";
10
10
  import type { SlackAdapter } from "@chat-adapter/slack";
11
- import type { Destination } from "@sentry/junior-plugin-api";
11
+ import { type Destination } from "@sentry/junior-plugin-api";
12
12
  import { generateAssistantReply as generateAssistantReplyImpl } from "@/chat/respond";
13
13
  import type { PreparedTurnState } from "@/chat/runtime/turn-preparation";
14
14
  import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnToolInvocation } from "@/chat/runtime/turn-input";
@@ -26,6 +26,10 @@ export interface ReplyExecutorServices {
26
26
  }) => Promise<AgentContinueRequest | undefined>;
27
27
  lookupSlackUser: typeof lookupSlackUser;
28
28
  scheduleAgentContinue: (request: AgentContinueRequest) => Promise<void>;
29
+ scheduleSessionCompletedPluginTasks: (params: {
30
+ conversationId: string;
31
+ sessionId: string;
32
+ }) => Promise<void>;
29
33
  }
30
34
  interface ReplyExecutorDeps {
31
35
  getSlackAdapter: () => SlackAdapter;
@@ -1,4 +1,5 @@
1
1
  import { generateAssistantReply, type AssistantReply, type AssistantReplyRequestContext } from "@/chat/respond";
2
+ import type { Source } from "@sentry/junior-plugin-api";
2
3
  /** Error raised when another worker already owns the resume lock. */
3
4
  export declare class ResumeTurnBusyError extends Error {
4
5
  constructor(lockKey: string);
@@ -8,10 +9,14 @@ interface ResumeSlackTurnArgs {
8
9
  channelId: string;
9
10
  threadTs: string;
10
11
  messageTs?: string;
11
- replyContext?: AssistantReplyRequestContext;
12
+ replyContext?: ResumeReplyContext;
12
13
  lockKey?: string;
13
14
  initialText?: string;
14
15
  generateReply?: typeof generateAssistantReply;
16
+ scheduleSessionCompletedPluginTasks?: (params: {
17
+ conversationId: string;
18
+ sessionId: string;
19
+ }) => Promise<void>;
15
20
  onSuccess?: (reply: AssistantReply) => Promise<void>;
16
21
  onFailure?: (error: unknown) => Promise<void>;
17
22
  onAuthPause?: (error: unknown) => Promise<void>;
@@ -20,6 +25,9 @@ interface ResumeSlackTurnArgs {
20
25
  beforeStart?: () => Promise<Partial<ResumeSlackTurnArgs> | false | void>;
21
26
  replyTimeoutMs?: number;
22
27
  }
28
+ type ResumeReplyContext = AssistantReplyRequestContext & {
29
+ source: Source;
30
+ };
23
31
  /**
24
32
  * Resume a paused Slack turn under the normal thread lock.
25
33
  *
@@ -35,7 +43,7 @@ export declare function resumeAuthorizedRequest(args: {
35
43
  threadTs: string;
36
44
  messageTs?: string;
37
45
  connectedText: string;
38
- replyContext?: AssistantReplyRequestContext;
46
+ replyContext?: ResumeReplyContext;
39
47
  lockKey?: string;
40
48
  generateReply?: typeof generateAssistantReply;
41
49
  onSuccess?: (reply: AssistantReply) => Promise<void>;
@@ -19,9 +19,14 @@ export interface AssistantLifecycleEvent {
19
19
  threadTs: string;
20
20
  userId?: string;
21
21
  }
22
+ export interface SteeringCandidateMessage {
23
+ activeRequest: boolean;
24
+ inboundMessageId: string;
25
+ message: Message;
26
+ }
22
27
  export interface ReplyHooks {
23
28
  beforeFirstResponsePost?: () => Promise<void>;
24
- drainSteeringMessages?: (inject: (messages: Message[]) => Promise<void>) => Promise<Message[]>;
29
+ drainSteeringMessages?: (inject: (messages: SteeringCandidateMessage[]) => Promise<readonly string[] | void>) => Promise<void>;
25
30
  messageContext?: MessageContext;
26
31
  onInputCommitted?: () => Promise<void>;
27
32
  onToolInvocation?: (invocation: TurnToolInvocation) => void;
@@ -1,22 +1,22 @@
1
- import type { AgentPluginAuthorization, AgentPluginGrant } from "@sentry/junior-plugin-api";
1
+ import type { PluginAuthorization, PluginGrant } from "@sentry/junior-plugin-api";
2
2
  import { type SandboxEgressCredentialContext, type SandboxEgressCredentialLease } from "@/chat/sandbox/egress-session";
3
3
  export type SandboxEgressGrantSelection = {
4
- grant: AgentPluginGrant;
4
+ grant: PluginGrant;
5
5
  source: "plugin";
6
6
  } | {
7
- grant: AgentPluginGrant;
7
+ grant: PluginGrant;
8
8
  source: "broker";
9
9
  };
10
10
  export type SandboxEgressCredentialErrorKind = "auth_required" | "unavailable";
11
11
  /** Signals that egress selected a grant but could not issue credential headers. */
12
12
  export declare class SandboxEgressCredentialError extends Error {
13
- readonly authorization?: AgentPluginAuthorization;
14
- readonly grant: AgentPluginGrant;
13
+ readonly authorization?: PluginAuthorization;
14
+ readonly grant: PluginGrant;
15
15
  readonly kind: SandboxEgressCredentialErrorKind;
16
16
  readonly provider: string;
17
17
  constructor(input: {
18
- authorization?: AgentPluginAuthorization;
19
- grant: AgentPluginGrant;
18
+ authorization?: PluginAuthorization;
19
+ grant: PluginGrant;
20
20
  kind: SandboxEgressCredentialErrorKind;
21
21
  message: string;
22
22
  provider: string;
@@ -30,7 +30,7 @@ export declare function selectSandboxEgressGrant(input: {
30
30
  upstreamUrl: URL;
31
31
  }): Promise<SandboxEgressGrantSelection>;
32
32
  /** Resolve the authorization flow attached to a broker-selected egress grant. */
33
- export declare function authorizationForSandboxEgressGrant(provider: string, selection: SandboxEgressGrantSelection): AgentPluginAuthorization | undefined;
33
+ export declare function authorizationForSandboxEgressGrant(provider: string, selection: SandboxEgressGrantSelection): PluginAuthorization | undefined;
34
34
  /** Return a cached or newly issued credential lease for a selected grant. */
35
35
  export declare function sandboxEgressCredentialLease(provider: string, selection: SandboxEgressGrantSelection, context: SandboxEgressCredentialContext): Promise<SandboxEgressCredentialLease>;
36
36
  /** Return whether a credential lease can modify requests to the target host. */
@@ -2,7 +2,7 @@ import { type LogContext } from "@/chat/logging";
2
2
  import { type SandboxEgressAuthRequiredSignal, type SandboxEgressPermissionDeniedSignal } from "@/chat/sandbox/egress-session";
3
3
  import type { SandboxEgressTracePropagationConfig } from "@/chat/sandbox/egress-tracing";
4
4
  import type { CredentialContext } from "@/chat/credentials/context";
5
- import type { AgentPluginHookRunner } from "@/chat/plugins/agent-hooks";
5
+ import type { PluginHookRunner } from "@/chat/plugins/agent-hooks";
6
6
  import type { SandboxInstance } from "@/chat/sandbox/workspace";
7
7
  import type { SkillMetadata } from "@/chat/skills";
8
8
  interface SandboxExecutionInput {
@@ -49,7 +49,7 @@ export declare function createSandboxExecutor(options?: {
49
49
  traceContext?: LogContext;
50
50
  tracePropagation?: SandboxEgressTracePropagationConfig;
51
51
  credentialEgress?: CredentialContext;
52
- agentHooks?: AgentPluginHookRunner;
52
+ agentHooks?: PluginHookRunner;
53
53
  onSandboxAcquired?: (sandbox: SandboxAcquiredState) => void | Promise<void>;
54
54
  runBashCustomCommand?: (command: string) => Promise<{
55
55
  handled: boolean;
@@ -1,2 +1,3 @@
1
1
  /** Sentry SDK re-export. Isolates the concrete package to a single file. */
2
+ export { captureException, continueTrace, flush, getClient, getGlobalScope, init, setTag, setUser, startInactiveSpan, startSpan, vercelAIIntegration, withActiveSpan, withScope, } from "@sentry/node";
2
3
  export * from "@sentry/node";
@@ -1,5 +1,5 @@
1
1
  import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
2
- import type { Destination } from "@sentry/junior-plugin-api";
2
+ import type { Destination, Source } from "@sentry/junior-plugin-api";
3
3
  import { AuthorizationPauseError, type AuthorizationFlowMode } from "@/chat/services/auth-pause";
4
4
  import type { ThreadArtifactsState } from "@/chat/state/artifacts";
5
5
  import type { ConversationPendingAuthState } from "@/chat/state/conversation";
@@ -14,6 +14,7 @@ export interface McpAuthOrchestrationInput {
14
14
  requesterId?: string;
15
15
  channelId?: string;
16
16
  destination?: Destination;
17
+ source?: Source;
17
18
  threadTs?: string;
18
19
  toolChannelId?: string;
19
20
  userMessage: string;
@@ -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 { ChannelConfigurationService } from "@/chat/configuration/types";
3
3
  import type { UserTokenStore } from "@/chat/credentials/user-token-store";
4
4
  import { AuthorizationPauseError, type AuthorizationFlowMode } from "@/chat/services/auth-pause";
@@ -17,6 +17,7 @@ export interface PluginAuthOrchestrationInput {
17
17
  requesterId?: string;
18
18
  channelId?: string;
19
19
  destination?: Destination;
20
+ source?: Source;
20
21
  threadTs?: string;
21
22
  userMessage: string;
22
23
  channelConfiguration?: ChannelConfigurationService;
@@ -31,10 +31,10 @@ export interface SubscribedDecisionResult {
31
31
  }
32
32
  declare const replyDecisionSchema: z.ZodObject<{
33
33
  should_reply: z.ZodBoolean;
34
- should_unsubscribe: z.ZodOptional<z.ZodBoolean>;
34
+ should_unsubscribe: z.ZodBoolean;
35
35
  confidence: z.ZodNumber;
36
36
  reason: z.ZodOptional<z.ZodString>;
37
- }, z.core.$strip>;
37
+ }, z.core.$strict>;
38
38
  /** Fast heuristic check before the LLM classifier — skips messages directed at another party. */
39
39
  export declare function getSubscribedReplyPreflightDecision(args: {
40
40
  botUserName: string;
@@ -1,6 +1,5 @@
1
1
  import { type AgentTurnSessionRecord, type AgentTurnSurface } from "@/chat/state/turn-session";
2
- import type { StoredSlackRequester } from "@/chat/requester";
3
- import type { Destination } from "@sentry/junior-plugin-api";
2
+ import type { Destination, Requester, Source } from "@sentry/junior-plugin-api";
4
3
  import type { PiMessage } from "@/chat/pi/messages";
5
4
  import { type AgentTurnUsage } from "@/chat/usage";
6
5
  export declare const AGENT_CONTINUE_MAX_SLICES = 48;
@@ -29,12 +28,13 @@ export declare function persistRunningSessionRecord(args: {
29
28
  channelName?: string;
30
29
  conversationId: string;
31
30
  destination?: Destination;
31
+ source?: Source;
32
32
  sessionId: string;
33
33
  sliceId: number;
34
34
  messages: PiMessage[];
35
35
  loadedSkillNames?: string[];
36
36
  logContext: SessionRecordLogContext;
37
- requester?: StoredSlackRequester;
37
+ requester?: Requester;
38
38
  surface?: AgentTurnSurface;
39
39
  turnStartMessageIndex?: number;
40
40
  }): Promise<boolean>;
@@ -45,12 +45,13 @@ export declare function persistCompletedSessionRecord(args: {
45
45
  currentDurationMs?: number;
46
46
  currentUsage?: AgentTurnUsage;
47
47
  destination?: Destination;
48
+ source?: Source;
48
49
  sessionId: string;
49
50
  sliceId: number;
50
51
  allMessages: PiMessage[];
51
52
  loadedSkillNames?: string[];
52
53
  logContext: SessionRecordLogContext;
53
- requester?: StoredSlackRequester;
54
+ requester?: Requester;
54
55
  surface?: AgentTurnSurface;
55
56
  turnStartMessageIndex?: number;
56
57
  }): Promise<void>;
@@ -66,11 +67,12 @@ export declare function persistAuthPauseSessionRecord(args: {
66
67
  currentDurationMs?: number;
67
68
  currentUsage?: AgentTurnUsage;
68
69
  destination?: Destination;
70
+ source?: Source;
69
71
  messages: PiMessage[];
70
72
  loadedSkillNames?: string[];
71
73
  errorMessage: string;
72
74
  logContext: SessionRecordLogContext;
73
- requester?: StoredSlackRequester;
75
+ requester?: Requester;
74
76
  surface?: AgentTurnSurface;
75
77
  }): Promise<AgentTurnSessionRecord | undefined>;
76
78
  /**
@@ -85,11 +87,12 @@ export declare function persistTimeoutSessionRecord(args: {
85
87
  currentDurationMs?: number;
86
88
  currentUsage?: AgentTurnUsage;
87
89
  destination?: Destination;
90
+ source?: Source;
88
91
  messages: PiMessage[];
89
92
  loadedSkillNames?: string[];
90
93
  errorMessage: string;
91
94
  logContext: SessionRecordLogContext;
92
- requester?: StoredSlackRequester;
95
+ requester?: Requester;
93
96
  surface?: AgentTurnSurface;
94
97
  }): Promise<AgentTurnSessionRecord | undefined>;
95
98
  /**
@@ -103,11 +106,12 @@ export declare function persistYieldSessionRecord(args: {
103
106
  currentDurationMs?: number;
104
107
  currentUsage?: AgentTurnUsage;
105
108
  destination?: Destination;
109
+ source?: Source;
106
110
  messages: PiMessage[];
107
111
  loadedSkillNames?: string[];
108
112
  errorMessage: string;
109
113
  logContext: SessionRecordLogContext;
110
- requester?: StoredSlackRequester;
114
+ requester?: Requester;
111
115
  surface?: AgentTurnSurface;
112
116
  }): Promise<AgentTurnSessionRecord | undefined>;
113
117
  export {};
@@ -18,3 +18,6 @@ export interface JuniorSqlMigrationExecutor extends JuniorSqlDatabase {
18
18
  execute(statement: string, params?: readonly unknown[]): Promise<void>;
19
19
  query<T = unknown>(statement: string, params?: readonly unknown[]): Promise<T[]>;
20
20
  }
21
+ export interface JuniorSqlExecutor extends JuniorSqlMigrationExecutor {
22
+ close(): Promise<void>;
23
+ }
@@ -0,0 +1,7 @@
1
+ import type { JuniorSqlExecutor } from "./db";
2
+ import type { SqlDriver } from "@/chat/config";
3
+ /** Create the SQL executor appropriate for the configured database URL. */
4
+ export declare function createJuniorSqlExecutor(args: {
5
+ connectionString: string;
6
+ driver: SqlDriver;
7
+ }): JuniorSqlExecutor;
@@ -1,8 +1,6 @@
1
- import type { JuniorSqlMigrationExecutor } from "./db";
1
+ import type { JuniorSqlExecutor } from "./db";
2
2
  /** Neon-backed SQL executor with an owned connection pool lifecycle. */
3
- export interface NeonJuniorSqlExecutor extends JuniorSqlMigrationExecutor {
4
- close(): Promise<void>;
5
- }
3
+ export type NeonJuniorSqlExecutor = JuniorSqlExecutor;
6
4
  /** Create the shared Neon-backed Junior SQL executor. */
7
5
  export declare function createNeonJuniorSqlExecutor(args: {
8
6
  connectionString: string;
@@ -0,0 +1,6 @@
1
+ import type { JuniorSqlExecutor } from "./db";
2
+ /** Create the shared Node Postgres-backed Junior SQL executor. */
3
+ export declare function createPostgresJuniorSqlExecutor(args: {
4
+ applicationName?: string;
5
+ connectionString: string;
6
+ }): JuniorSqlExecutor;
@@ -1,6 +1,6 @@
1
- import type { Destination } from "@sentry/junior-plugin-api";
1
+ import { type Destination, type Source } from "@sentry/junior-plugin-api";
2
2
  import type { PiMessage } from "@/chat/pi/messages";
3
- import { type StoredSlackRequester } from "@/chat/requester";
3
+ import { type Requester } from "@/chat/requester";
4
4
  import type { AgentTurnUsage } from "@/chat/usage";
5
5
  import type { ConversationStore } from "@/chat/conversations/store";
6
6
  export type AgentTurnSessionStatus = "running" | "awaiting_resume" | "completed" | "failed" | "abandoned";
@@ -13,11 +13,12 @@ export interface AgentTurnSessionRecord {
13
13
  cumulativeDurationMs: number;
14
14
  cumulativeUsage?: AgentTurnUsage;
15
15
  destination?: Destination;
16
+ source?: Source;
16
17
  errorMessage?: string;
17
18
  lastProgressAtMs: number;
18
19
  loadedSkillNames?: string[];
19
20
  piMessages: PiMessage[];
20
- requester?: StoredSlackRequester;
21
+ requester?: Requester;
21
22
  resumeReason?: AgentTurnResumeReason;
22
23
  resumedFromSliceId?: number;
23
24
  sessionId: string;
@@ -39,6 +40,7 @@ export declare function upsertAgentTurnSessionRecord(args: {
39
40
  cumulativeDurationMs?: number;
40
41
  cumulativeUsage?: AgentTurnUsage;
41
42
  destination?: Destination;
43
+ source?: Source;
42
44
  lastProgressAtMs?: number;
43
45
  loadedSkillNames?: string[];
44
46
  conversationStore?: ConversationStore;
@@ -47,7 +49,7 @@ export declare function upsertAgentTurnSessionRecord(args: {
47
49
  state: AgentTurnSessionStatus;
48
50
  surface?: AgentTurnSurface;
49
51
  piMessages: PiMessage[];
50
- requester?: StoredSlackRequester;
52
+ requester?: Requester;
51
53
  resumeReason?: AgentTurnResumeReason;
52
54
  errorMessage?: string;
53
55
  resumedFromSliceId?: number;
@@ -62,10 +64,11 @@ export declare function recordAgentTurnSessionSummary(args: {
62
64
  cumulativeDurationMs?: number;
63
65
  cumulativeUsage?: AgentTurnUsage;
64
66
  destination?: Destination;
67
+ source?: Source;
65
68
  lastProgressAtMs?: number;
66
69
  loadedSkillNames?: string[];
67
70
  conversationStore?: ConversationStore;
68
- requester?: StoredSlackRequester;
71
+ requester?: Requester;
69
72
  resumeReason?: AgentTurnResumeReason;
70
73
  sessionId: string;
71
74
  sliceId: number;
@@ -146,10 +146,15 @@ export declare function checkInConversationWork(args: {
146
146
  nowMs?: number;
147
147
  state?: StateAdapter;
148
148
  }): Promise<boolean>;
149
- /** Drain pending mailbox entries after the caller has durably injected them. */
149
+ /**
150
+ * Drain pending mailbox entries after the caller acknowledges durable handling.
151
+ *
152
+ * Returning ids acknowledges only that subset; returning nothing acknowledges
153
+ * every offered pending entry.
154
+ */
150
155
  export declare function drainConversationMailbox(args: {
151
156
  conversationId: string;
152
- inject: (messages: InboundMessage[]) => Promise<void>;
157
+ inject: (messages: InboundMessage[]) => Promise<readonly string[] | void>;
153
158
  leaseToken: string;
154
159
  nowMs?: number;
155
160
  state?: StateAdapter;
@@ -9,7 +9,7 @@ export interface ConversationWorkerContext {
9
9
  checkIn(): Promise<boolean>;
10
10
  conversationId: string;
11
11
  destination: Destination;
12
- drainMailbox(inject: (messages: InboundMessage[]) => Promise<void>): Promise<InboundMessage[]>;
12
+ drainMailbox(inject: (messages: InboundMessage[]) => Promise<readonly string[] | void>): Promise<InboundMessage[]>;
13
13
  leaseToken: string;
14
14
  shouldYield(): boolean;
15
15
  }
@@ -6,6 +6,13 @@ import type { AssistantStatusSpec } from "@/chat/slack/assistant-thread/status";
6
6
  import type { SandboxExecutor } from "@/chat/sandbox/sandbox";
7
7
  import type { SkillSandbox } from "@/chat/sandbox/skill-sandbox";
8
8
  import type { ToolDefinition } from "@/chat/tools/definition";
9
- import type { AgentPluginHookRunner } from "@/chat/plugins/agent-hooks";
9
+ import type { PluginHookRunner } from "@/chat/plugins/agent-hooks";
10
+ export interface ToolExecutionReport {
11
+ error?: string;
12
+ ok: boolean;
13
+ params: Record<string, unknown>;
14
+ result?: unknown;
15
+ toolName: string;
16
+ }
10
17
  /** Wrap tool definitions into Pi Agent tool objects with logging, validation, and sandbox execution. */
11
- export declare function createAgentTools(tools: Record<string, ToolDefinition<any>>, sandbox: SkillSandbox, spanContext: LogContext, onStatus?: (status: AssistantStatusSpec) => void | Promise<void>, sandboxExecutor?: SandboxExecutor, pluginAuthOrchestration?: PluginAuthOrchestration, onToolCall?: (toolName: string, params: Record<string, unknown>) => void, agentHooks?: AgentPluginHookRunner, conversationPrivacy?: ConversationPrivacy): AgentTool[];
18
+ export declare function createAgentTools(tools: Record<string, ToolDefinition<any>>, sandbox: SkillSandbox, spanContext: LogContext, onStatus?: (status: AssistantStatusSpec) => void | Promise<void>, sandboxExecutor?: SandboxExecutor, pluginAuthOrchestration?: PluginAuthOrchestration, onToolCall?: (toolName: string, params: Record<string, unknown>) => void | Promise<void>, agentHooks?: PluginHookRunner, conversationPrivacy?: ConversationPrivacy, onToolResult?: (report: ToolExecutionReport) => void | Promise<void>): AgentTool[];
@@ -3,10 +3,10 @@ import type { SlackDestination } from "@sentry/junior-plugin-api";
3
3
  import type { SlackSource } from "@sentry/junior-plugin-api";
4
4
  import type { SlackRequester } from "@/chat/requester";
5
5
  export interface SlackToolContext {
6
- destination?: SlackDestination;
6
+ destination: SlackDestination;
7
7
  source: SlackSource;
8
8
  requester?: SlackRequester;
9
- destinationChannelId?: string;
9
+ destinationChannelId: string;
10
10
  messageTs?: string;
11
11
  sourceChannelId: string;
12
12
  teamId: string;
@@ -2,6 +2,7 @@ import type { FileUpload } from "chat";
2
2
  import type { Destination, LocalDestination, LocalSource, SlackDestination, SlackSource, Source } from "@sentry/junior-plugin-api";
3
3
  import type { McpToolManager } from "@/chat/mcp/tool-manager";
4
4
  import type { SandboxWorkspace } from "@/chat/sandbox/workspace";
5
+ import type { AgentTurnSurface } from "@/chat/state/turn-session";
5
6
  import type { ThreadArtifactsState } from "@/chat/state/artifacts";
6
7
  import type { Skill } from "@/chat/skills";
7
8
  import type { LoadSkillMetadata } from "@/chat/tools/skill/load-skill";
@@ -43,11 +44,13 @@ interface BaseToolRuntimeContext {
43
44
  * Do not parse as Slack unless the value starts with `slack:`.
44
45
  */
45
46
  conversationId?: string;
46
- /** Runtime-owned default outbound destination, if this invocation has one. */
47
- destination?: Destination;
47
+ /** Runtime-owned default outbound destination for this invocation. */
48
+ destination: Destination;
48
49
  requester?: Requester;
49
50
  /** Runtime-owned source where this invocation came from. */
50
51
  source: Source;
52
+ /** Runtime surface that owns final delivery semantics for this turn. */
53
+ surface?: AgentTurnSurface;
51
54
  userText?: string;
52
55
  artifactState?: ThreadArtifactsState;
53
56
  configuration?: Record<string, unknown>;
@@ -55,12 +58,12 @@ interface BaseToolRuntimeContext {
55
58
  sandbox: SandboxWorkspace;
56
59
  }
57
60
  interface SlackToolRuntimeContext extends BaseToolRuntimeContext {
58
- destination?: SlackDestination;
61
+ destination: SlackDestination;
59
62
  requester?: SlackRequester;
60
63
  source: SlackSource;
61
64
  }
62
65
  interface LocalToolRuntimeContext extends BaseToolRuntimeContext {
63
- destination?: LocalDestination;
66
+ destination: LocalDestination;
64
67
  requester?: LocalRequester;
65
68
  source: LocalSource;
66
69
  slack?: never;
@@ -0,0 +1,3 @@
1
+ import { QueueClient } from "@vercel/queue";
2
+ /** Create a Vercel Queue client that also works in local and eval runtimes. */
3
+ export declare function createVercelQueueClient(): QueueClient;
@@ -1,109 +1,10 @@
1
+ import {
2
+ createVercelQueueClient
3
+ } from "./chunk-KNFROR7R.js";
1
4
  import {
2
5
  destinationKey,
3
6
  parseDestination
4
- } from "./chunk-YRDS7VKO.js";
5
-
6
- // src/plugins.ts
7
- function cloneManifests(manifests) {
8
- return manifests ? structuredClone(manifests) : void 0;
9
- }
10
- function cloneInlineManifests(registrations) {
11
- const inlineManifests = registrations.flatMap(
12
- (plugin) => plugin.manifest ? [
13
- {
14
- manifest: {
15
- ...structuredClone(plugin.manifest),
16
- capabilities: plugin.manifest.capabilities?.map(
17
- (capability) => capability.includes(".") ? capability : `${plugin.manifest.name}.${capability}`
18
- ) ?? [],
19
- configKeys: plugin.manifest.configKeys?.map(
20
- (key) => key.includes(".") ? key : `${plugin.manifest.name}.${key}`
21
- ) ?? [],
22
- ...plugin.manifest.target ? {
23
- target: {
24
- ...plugin.manifest.target,
25
- configKey: plugin.manifest.target.configKey.includes(".") ? plugin.manifest.target.configKey : `${plugin.manifest.name}.${plugin.manifest.target.configKey}`
26
- }
27
- } : {}
28
- },
29
- ...plugin.packageName ? { packageName: plugin.packageName } : {}
30
- }
31
- ] : []
32
- );
33
- return inlineManifests.length > 0 ? inlineManifests : void 0;
34
- }
35
- function assertUniquePluginNames(registrations) {
36
- const seen = /* @__PURE__ */ new Set();
37
- for (const plugin of registrations) {
38
- if (seen.has(plugin.name)) {
39
- throw new Error(`Duplicate plugin registration name "${plugin.name}"`);
40
- }
41
- seen.add(plugin.name);
42
- }
43
- }
44
- function assertUniquePackageNames(packageNames) {
45
- const seen = /* @__PURE__ */ new Set();
46
- for (const packageName of packageNames) {
47
- if (seen.has(packageName)) {
48
- throw new Error(`Duplicate plugin package name "${packageName}"`);
49
- }
50
- seen.add(packageName);
51
- }
52
- }
53
- function normalizePluginInput(input) {
54
- if (typeof input === "string") {
55
- return { packageName: input };
56
- }
57
- return { registration: input };
58
- }
59
- function defineJuniorPlugins(inputs, options = {}) {
60
- const normalized = inputs.map(normalizePluginInput);
61
- const packageNames = normalized.flatMap(
62
- (input) => input.packageName ? [input.packageName] : []
63
- );
64
- const registrations = normalized.flatMap(
65
- (input) => input.registration ? [input.registration] : []
66
- );
67
- assertUniquePackageNames(packageNames);
68
- assertUniquePluginNames(registrations);
69
- const manifests = cloneManifests(options.manifests);
70
- return {
71
- packageNames,
72
- registrations: registrations.map((plugin) => ({ ...plugin })),
73
- ...manifests ? { manifests } : {}
74
- };
75
- }
76
- function pluginCatalogConfigFromPluginSet(pluginSet) {
77
- if (!pluginSet) {
78
- return void 0;
79
- }
80
- const packages = [
81
- .../* @__PURE__ */ new Set([
82
- ...pluginSet.packageNames,
83
- ...pluginSet.registrations.flatMap(
84
- (plugin) => plugin.packageName ? [plugin.packageName] : []
85
- )
86
- ])
87
- ];
88
- const manifests = cloneManifests(pluginSet.manifests);
89
- const inlineManifests = cloneInlineManifests(pluginSet.registrations);
90
- if (packages.length === 0 && !manifests && !inlineManifests) {
91
- return void 0;
92
- }
93
- return {
94
- ...inlineManifests ? { inlineManifests } : {},
95
- ...packages.length > 0 ? { packages } : {},
96
- ...manifests ? { manifests } : {}
97
- };
98
- }
99
- function pluginHookRegistrationsFromPluginSet(pluginSet) {
100
- return pluginSet?.registrations.filter(
101
- (plugin) => plugin.hooks || plugin.legacyStatePrefixes
102
- ) ?? [];
103
- }
104
-
105
- // src/chat/task-execution/vercel-queue.ts
106
- import { QueueClient } from "@vercel/queue";
7
+ } from "./chunk-Q6XFTRV5.js";
107
8
 
108
9
  // src/chat/task-execution/queue-signing.ts
109
10
  import { createHmac, timingSafeEqual } from "crypto";
@@ -207,7 +108,7 @@ function toDelaySeconds(options) {
207
108
  }
208
109
  function createVercelConversationWorkQueue(options = {}) {
209
110
  const topic = resolveConversationWorkQueueTopic(options);
210
- const client = options.client ?? new QueueClient();
111
+ const client = options.client ?? createVercelQueueClient();
211
112
  return {
212
113
  async send(message, sendOptions) {
213
114
  const result = await client.send(
@@ -229,9 +130,6 @@ function getVercelConversationWorkQueue() {
229
130
  }
230
131
 
231
132
  export {
232
- defineJuniorPlugins,
233
- pluginCatalogConfigFromPluginSet,
234
- pluginHookRegistrationsFromPluginSet,
235
133
  verifyConversationQueueMessage,
236
134
  resolveConversationWorkQueueTopic,
237
135
  getVercelConversationWorkQueue