@sentry/junior 0.73.0 → 0.74.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 (54) hide show
  1. package/dist/api-reference.d.ts +1 -1
  2. package/dist/app.js +258 -62
  3. package/dist/chat/app/production.d.ts +3 -0
  4. package/dist/chat/config.d.ts +3 -0
  5. package/dist/chat/conversations/configured.d.ts +5 -0
  6. package/dist/chat/conversations/sql/migrations.d.ts +11 -0
  7. package/dist/chat/conversations/sql/schema/conversations.d.ts +435 -0
  8. package/dist/chat/conversations/sql/schema/destinations.d.ts +200 -0
  9. package/dist/chat/conversations/sql/schema/identities.d.ts +214 -0
  10. package/dist/chat/conversations/sql/schema/migrations.d.ts +58 -0
  11. package/dist/chat/conversations/sql/schema/timestamps.d.ts +1 -0
  12. package/dist/chat/conversations/sql/schema.d.ts +910 -0
  13. package/dist/chat/conversations/sql/store.d.ts +52 -0
  14. package/dist/chat/conversations/state.d.ts +4 -0
  15. package/dist/chat/conversations/store.d.ts +57 -0
  16. package/dist/chat/ingress/slack-webhook.d.ts +2 -0
  17. package/dist/chat/plugins/agent-hooks.d.ts +2 -2
  18. package/dist/chat/respond.d.ts +1 -1
  19. package/dist/chat/services/mcp-auth-orchestration.d.ts +6 -5
  20. package/dist/chat/services/pending-auth.d.ts +2 -0
  21. package/dist/chat/services/plugin-auth-orchestration.d.ts +7 -6
  22. package/dist/chat/sql/db.d.ts +20 -0
  23. package/dist/chat/sql/neon.d.ts +9 -0
  24. package/dist/chat/sql/schema.d.ts +906 -0
  25. package/dist/chat/state/turn-session.d.ts +3 -0
  26. package/dist/chat/task-execution/slack-work.d.ts +2 -0
  27. package/dist/chat/task-execution/state.d.ts +209 -0
  28. package/dist/chat/task-execution/store.d.ts +30 -114
  29. package/dist/chat/task-execution/vercel-callback.d.ts +2 -0
  30. package/dist/chat/task-execution/worker.d.ts +2 -0
  31. package/dist/{chunk-ZDA2HYX5.js → chunk-2LUZA3LY.js} +3 -3
  32. package/dist/{chunk-RY6AL5C7.js → chunk-6UP2Z2RZ.js} +2 -2
  33. package/dist/{chunk-DIMX5F3T.js → chunk-F6HWCPOC.js} +1 -1
  34. package/dist/{chunk-WS2EG3GW.js → chunk-GM7HTXYC.js} +6 -0
  35. package/dist/{chunk-UZVHXZ7V.js → chunk-HYHKTFG2.js} +59 -15
  36. package/dist/chunk-JL2SLRAT.js +1970 -0
  37. package/dist/{chunk-OQSYYOLM.js → chunk-SQGMG7OD.js} +128 -114
  38. package/dist/{chunk-QUXPUKBH.js → chunk-Y7X25LFY.js} +1 -1
  39. package/dist/{chunk-UOTZ3EEQ.js → chunk-YOHFWWBV.js} +1 -1
  40. package/dist/{chunk-V4VYUY4A.js → chunk-YRDS7VKO.js} +1 -1
  41. package/dist/cli/chat.js +2 -2
  42. package/dist/cli/init.js +1 -1
  43. package/dist/cli/snapshot-warmup.js +3 -3
  44. package/dist/cli/upgrade.js +77 -7
  45. package/dist/instrumentation.js +0 -1
  46. package/dist/nitro.js +3 -3
  47. package/dist/reporting/conversations.d.ts +13 -3
  48. package/dist/reporting.d.ts +9 -2
  49. package/dist/reporting.js +101 -37
  50. package/dist/{runner-LMAM4OGD.js → runner-27NP2TEO.js} +7 -7
  51. package/dist/vercel.d.ts +6 -1
  52. package/dist/vercel.js +1 -1
  53. package/package.json +9 -4
  54. package/dist/chunk-AL5T52ZD.js +0 -1119
@@ -13,7 +13,7 @@ import {
13
13
  recordMcpProviderConnected,
14
14
  resolveChannelCapabilities,
15
15
  upsertAgentTurnSessionRecord
16
- } from "./chunk-UZVHXZ7V.js";
16
+ } from "./chunk-HYHKTFG2.js";
17
17
  import {
18
18
  discoverSkills,
19
19
  findSkillByName,
@@ -25,7 +25,7 @@ import {
25
25
  } from "./chunk-M4FLLXXD.js";
26
26
  import {
27
27
  JUNIOR_THREAD_STATE_TTL_MS
28
- } from "./chunk-AL5T52ZD.js";
28
+ } from "./chunk-JL2SLRAT.js";
29
29
  import {
30
30
  SlackActionError,
31
31
  downloadPrivateSlackFile,
@@ -36,7 +36,7 @@ import {
36
36
  normalizeSlackConversationId,
37
37
  parseDestination,
38
38
  withSlackRetries
39
- } from "./chunk-V4VYUY4A.js";
39
+ } from "./chunk-YRDS7VKO.js";
40
40
  import {
41
41
  buildNonInteractiveShellScript,
42
42
  createSandboxInstance,
@@ -45,7 +45,7 @@ import {
45
45
  isSnapshotMissingError,
46
46
  resolveRuntimeDependencySnapshot,
47
47
  runNonInteractiveCommand
48
- } from "./chunk-RY6AL5C7.js";
48
+ } from "./chunk-6UP2Z2RZ.js";
49
49
  import {
50
50
  SANDBOX_DATA_ROOT,
51
51
  SANDBOX_SKILLS_ROOT,
@@ -72,7 +72,7 @@ import {
72
72
  } from "./chunk-KVZL5NZS.js";
73
73
  import {
74
74
  getStateAdapter
75
- } from "./chunk-DIMX5F3T.js";
75
+ } from "./chunk-F6HWCPOC.js";
76
76
  import {
77
77
  GEN_AI_PROVIDER_NAME,
78
78
  GEN_AI_SERVER_ADDRESS,
@@ -112,7 +112,7 @@ import {
112
112
  toObservablePromptPart,
113
113
  trimTrailingAssistantMessages,
114
114
  upsertActiveSkill
115
- } from "./chunk-WS2EG3GW.js";
115
+ } from "./chunk-GM7HTXYC.js";
116
116
  import {
117
117
  createRequester,
118
118
  parseActorUserId,
@@ -9374,7 +9374,7 @@ function canReusePendingAuthLink(args) {
9374
9374
  if (!pendingAuth) {
9375
9375
  return false;
9376
9376
  }
9377
- return pendingAuth.kind === args.kind && pendingAuth.provider === args.provider && pendingAuth.requesterId === args.requesterId && pendingAuth.scope === args.scope && pendingAuth.linkSentAtMs + AUTH_LINK_REUSE_WINDOW_MS > (args.nowMs ?? Date.now());
9377
+ return pendingAuth.kind === args.kind && pendingAuth.provider === args.provider && pendingAuth.requesterId === args.requesterId && pendingAuth.scope === args.scope && pendingAuth.sessionId === args.sessionId && pendingAuth.linkSentAtMs + AUTH_LINK_REUSE_WINDOW_MS > (args.nowMs ?? Date.now());
9378
9378
  }
9379
9379
  function getConversationPendingAuth(args) {
9380
9380
  const pendingAuth = args.conversation.processing.pendingAuth;
@@ -9451,37 +9451,44 @@ function pluginAuthRequiredSignal(details) {
9451
9451
  function authorizationId(args) {
9452
9452
  return `${args.sessionId}:${args.kind}:${args.provider}`;
9453
9453
  }
9454
- function createPluginAuthOrchestration(deps, abortAgent) {
9454
+ function createPluginAuthOrchestration(input) {
9455
9455
  let pendingPause;
9456
9456
  const startAuthorizationPause = async (provider, options) => {
9457
9457
  if (pendingPause) {
9458
9458
  throw pendingPause;
9459
9459
  }
9460
- if (!deps.requesterId || !getPluginOAuthConfig(provider)) {
9460
+ if (!input.requesterId || !getPluginOAuthConfig(provider)) {
9461
9461
  throw new Error(`Cannot start plugin authorization for ${provider}`);
9462
9462
  }
9463
- if (deps.authorizationFlowMode === "disabled") {
9463
+ if (input.authorizationFlowMode === "disabled") {
9464
9464
  throw new AuthorizationFlowDisabledError("plugin", provider);
9465
9465
  }
9466
+ const recordPendingAuth = input.sessionId ? input.recordPendingAuth : void 0;
9467
+ if (input.sessionId && !recordPendingAuth) {
9468
+ throw new Error(
9469
+ `Missing pending auth recorder for plugin authorization pause "${provider}"`
9470
+ );
9471
+ }
9466
9472
  const providerLabel = formatProviderLabel(provider);
9467
- const reusingPendingLink = canReusePendingAuthLink({
9468
- pendingAuth: deps.currentPendingAuth,
9473
+ const reusingPendingLink = input.sessionId ? canReusePendingAuthLink({
9474
+ pendingAuth: input.pendingAuth,
9469
9475
  kind: "plugin",
9470
9476
  provider,
9471
- requesterId: deps.requesterId,
9477
+ requesterId: input.requesterId,
9478
+ sessionId: input.sessionId,
9472
9479
  ...options?.scope ? { scope: options.scope } : {}
9473
- });
9480
+ }) : false;
9474
9481
  if (!reusingPendingLink) {
9475
9482
  const oauthResult = await startOAuthFlow(provider, {
9476
- requesterId: deps.requesterId,
9477
- channelId: deps.channelId,
9478
- destination: deps.destination,
9479
- threadTs: deps.threadTs,
9480
- userMessage: deps.userMessage,
9481
- channelConfiguration: deps.channelConfiguration,
9483
+ requesterId: input.requesterId,
9484
+ channelId: input.channelId,
9485
+ destination: input.destination,
9486
+ threadTs: input.threadTs,
9487
+ userMessage: input.userMessage,
9488
+ channelConfiguration: input.channelConfiguration,
9482
9489
  ...options?.scope ? { scope: options.scope } : {},
9483
- resumeConversationId: deps.conversationId,
9484
- resumeSessionId: deps.sessionId
9490
+ resumeConversationId: input.conversationId,
9491
+ resumeSessionId: input.sessionId
9485
9492
  });
9486
9493
  if (!oauthResult.ok) {
9487
9494
  throw new Error(oauthResult.error);
@@ -9492,29 +9499,29 @@ function createPluginAuthOrchestration(deps, abortAgent) {
9492
9499
  );
9493
9500
  }
9494
9501
  }
9495
- if (options?.unlinkExistingProvider && deps.requesterId && deps.userTokenStore) {
9496
- await unlinkProvider(deps.requesterId, provider, deps.userTokenStore);
9502
+ if (options?.unlinkExistingProvider && input.requesterId && input.userTokenStore) {
9503
+ await unlinkProvider(input.requesterId, provider, input.userTokenStore);
9497
9504
  }
9498
- if (deps.sessionId) {
9499
- await deps.onPendingAuth?.({
9505
+ if (input.sessionId && recordPendingAuth) {
9506
+ await recordPendingAuth({
9500
9507
  kind: "plugin",
9501
9508
  provider,
9502
- requesterId: deps.requesterId,
9509
+ requesterId: input.requesterId,
9503
9510
  ...options?.scope ? { scope: options.scope } : {},
9504
- sessionId: deps.sessionId,
9505
- linkSentAtMs: reusingPendingLink ? deps.currentPendingAuth.linkSentAtMs : Date.now()
9511
+ sessionId: input.sessionId,
9512
+ linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
9506
9513
  });
9507
9514
  }
9508
- if (deps.conversationId && deps.sessionId) {
9515
+ if (input.conversationId && input.sessionId) {
9509
9516
  await recordAuthorizationRequested({
9510
- conversationId: deps.conversationId,
9517
+ conversationId: input.conversationId,
9511
9518
  kind: "plugin",
9512
9519
  provider,
9513
- requesterId: deps.requesterId,
9520
+ requesterId: input.requesterId,
9514
9521
  authorizationId: authorizationId({
9515
9522
  kind: "plugin",
9516
9523
  provider,
9517
- sessionId: deps.sessionId
9524
+ sessionId: input.sessionId
9518
9525
  }),
9519
9526
  delivery: reusingPendingLink ? "private_link_reused" : "private_link_sent",
9520
9527
  ttlMs: THREAD_STATE_TTL_MS
@@ -9525,7 +9532,7 @@ function createPluginAuthOrchestration(deps, abortAgent) {
9525
9532
  providerLabel,
9526
9533
  reusingPendingLink ? "link_already_sent" : "link_sent"
9527
9534
  );
9528
- abortAgent();
9535
+ input.abortAgent();
9529
9536
  throw pendingPause;
9530
9537
  };
9531
9538
  return {
@@ -9547,8 +9554,8 @@ function createPluginAuthOrchestration(deps, abortAgent) {
9547
9554
  signal.message ?? `${formatProviderLabel(provider)} credentials are required but no OAuth flow is available for this provider.`
9548
9555
  );
9549
9556
  }
9550
- if (!deps.requesterId || !deps.userTokenStore) {
9551
- if (deps.authorizationFlowMode === "disabled") {
9557
+ if (!input.requesterId || !input.userTokenStore) {
9558
+ if (input.authorizationFlowMode === "disabled") {
9552
9559
  throw new AuthorizationFlowDisabledError("plugin", provider);
9553
9560
  }
9554
9561
  throw new PluginCredentialFailureError(
@@ -10893,25 +10900,30 @@ var McpAuthorizationPauseError = class extends AuthorizationPauseError {
10893
10900
  function authorizationId2(args) {
10894
10901
  return `${args.sessionId}:${args.kind}:${args.provider}`;
10895
10902
  }
10896
- function createMcpAuthOrchestration(deps, abortAgent) {
10903
+ function createMcpAuthOrchestration(input) {
10897
10904
  let pendingPause;
10898
10905
  const authSessionIdsByProvider = /* @__PURE__ */ new Map();
10899
10906
  const authProviderFactory = async (plugin) => {
10900
- if (!deps.conversationId || !deps.sessionId || !deps.requesterId) {
10907
+ if (!input.conversationId || !input.sessionId || !input.requesterId) {
10901
10908
  return void 0;
10902
10909
  }
10910
+ if (!input.recordPendingAuth && input.authorizationFlowMode !== "disabled") {
10911
+ throw new Error(
10912
+ `Missing pending auth recorder for MCP authorization pause "${plugin.manifest.name}"`
10913
+ );
10914
+ }
10903
10915
  const provider = await createMcpOAuthClientProvider({
10904
10916
  provider: plugin.manifest.name,
10905
- conversationId: deps.conversationId,
10906
- destination: deps.destination,
10907
- sessionId: deps.sessionId,
10908
- userId: deps.requesterId,
10909
- userMessage: deps.userMessage,
10910
- ...deps.channelId ? { channelId: deps.channelId } : {},
10911
- ...deps.threadTs ? { threadTs: deps.threadTs } : {},
10912
- ...deps.toolChannelId ? { toolChannelId: deps.toolChannelId } : {},
10913
- configuration: deps.getConfiguration(),
10914
- artifactState: deps.getArtifactState()
10917
+ conversationId: input.conversationId,
10918
+ destination: input.destination,
10919
+ sessionId: input.sessionId,
10920
+ userId: input.requesterId,
10921
+ userMessage: input.userMessage,
10922
+ ...input.channelId ? { channelId: input.channelId } : {},
10923
+ ...input.threadTs ? { threadTs: input.threadTs } : {},
10924
+ ...input.toolChannelId ? { toolChannelId: input.toolChannelId } : {},
10925
+ configuration: input.getConfiguration(),
10926
+ artifactState: input.getArtifactState()
10915
10927
  });
10916
10928
  authSessionIdsByProvider.set(plugin.manifest.name, provider.authSessionId);
10917
10929
  return provider;
@@ -10921,30 +10933,40 @@ function createMcpAuthOrchestration(deps, abortAgent) {
10921
10933
  return true;
10922
10934
  }
10923
10935
  const authSessionId = authSessionIdsByProvider.get(provider);
10924
- if (!authSessionId || !deps.requesterId) {
10936
+ const conversationId = input.conversationId;
10937
+ const sessionId = input.sessionId;
10938
+ const requesterId = input.requesterId;
10939
+ if (!authSessionId || !conversationId || !sessionId || !requesterId) {
10925
10940
  throw new Error(
10926
10941
  `Missing MCP auth session context for plugin "${provider}"`
10927
10942
  );
10928
10943
  }
10929
- if (deps.authorizationFlowMode === "disabled") {
10944
+ if (input.authorizationFlowMode === "disabled") {
10930
10945
  await deleteMcpAuthSession(authSessionId);
10931
10946
  throw new AuthorizationFlowDisabledError("mcp", provider);
10932
10947
  }
10933
- const latestArtifactState = deps.getMergedArtifactState();
10948
+ const recordPendingAuth = input.recordPendingAuth;
10949
+ if (!recordPendingAuth) {
10950
+ throw new Error(
10951
+ `Missing pending auth recorder for MCP authorization pause "${provider}"`
10952
+ );
10953
+ }
10954
+ const latestArtifactState = input.getMergedArtifactState();
10934
10955
  await patchMcpAuthSession(authSessionId, {
10935
- configuration: { ...deps.getConfiguration() },
10956
+ configuration: { ...input.getConfiguration() },
10936
10957
  artifactState: latestArtifactState,
10937
- toolChannelId: deps.toolChannelId ?? latestArtifactState.assistantContextChannelId ?? deps.channelId
10958
+ toolChannelId: input.toolChannelId ?? latestArtifactState.assistantContextChannelId ?? input.channelId
10938
10959
  });
10939
10960
  const authSession = await getMcpAuthSession(authSessionId);
10940
10961
  if (!authSession?.authorizationUrl) {
10941
10962
  throw new Error(`Missing MCP authorization URL for plugin "${provider}"`);
10942
10963
  }
10943
10964
  const reusingPendingLink = canReusePendingAuthLink({
10944
- pendingAuth: deps.currentPendingAuth,
10965
+ pendingAuth: input.pendingAuth,
10945
10966
  kind: "mcp",
10946
10967
  provider,
10947
- requesterId: deps.requesterId
10968
+ requesterId,
10969
+ sessionId
10948
10970
  });
10949
10971
  const providerLabel = formatProviderLabel(provider);
10950
10972
  if (!reusingPendingLink) {
@@ -10962,36 +10984,32 @@ function createMcpAuthOrchestration(deps, abortAgent) {
10962
10984
  } else {
10963
10985
  await deleteMcpAuthSession(authSessionId);
10964
10986
  }
10965
- if (deps.sessionId && deps.requesterId) {
10966
- await deps.onPendingAuth?.({
10967
- kind: "mcp",
10968
- provider,
10969
- requesterId: deps.requesterId,
10970
- sessionId: deps.sessionId,
10971
- linkSentAtMs: reusingPendingLink ? deps.currentPendingAuth.linkSentAtMs : Date.now()
10972
- });
10973
- }
10974
- if (deps.conversationId && deps.sessionId && deps.requesterId) {
10975
- await recordAuthorizationRequested({
10976
- conversationId: deps.conversationId,
10987
+ await recordPendingAuth({
10988
+ kind: "mcp",
10989
+ provider,
10990
+ requesterId,
10991
+ sessionId,
10992
+ linkSentAtMs: reusingPendingLink ? input.pendingAuth.linkSentAtMs : Date.now()
10993
+ });
10994
+ await recordAuthorizationRequested({
10995
+ conversationId,
10996
+ kind: "mcp",
10997
+ provider,
10998
+ requesterId,
10999
+ authorizationId: authorizationId2({
10977
11000
  kind: "mcp",
10978
11001
  provider,
10979
- requesterId: deps.requesterId,
10980
- authorizationId: authorizationId2({
10981
- kind: "mcp",
10982
- provider,
10983
- sessionId: deps.sessionId
10984
- }),
10985
- delivery: reusingPendingLink ? "private_link_reused" : "private_link_sent",
10986
- ttlMs: THREAD_STATE_TTL_MS2
10987
- });
10988
- }
11002
+ sessionId
11003
+ }),
11004
+ delivery: reusingPendingLink ? "private_link_reused" : "private_link_sent",
11005
+ ttlMs: THREAD_STATE_TTL_MS2
11006
+ });
10989
11007
  pendingPause = new McpAuthorizationPauseError(
10990
11008
  provider,
10991
11009
  providerLabel,
10992
11010
  reusingPendingLink ? "link_already_sent" : "link_sent"
10993
11011
  );
10994
- abortAgent();
11012
+ input.abortAgent();
10995
11013
  return true;
10996
11014
  };
10997
11015
  return {
@@ -11539,42 +11557,38 @@ async function generateAssistantReply(messageText, context) {
11539
11557
  };
11540
11558
  const slackDestination = context.destination.platform === "slack" ? context.destination : void 0;
11541
11559
  const slackChannelId = slackDestination?.channelId;
11542
- const mcpAuth = createMcpAuthOrchestration(
11543
- {
11544
- conversationId: sessionConversationId,
11545
- sessionId,
11546
- requesterId: authRequesterId,
11547
- channelId: slackChannelId,
11548
- destination: context.destination,
11549
- threadTs: context.correlation?.threadTs,
11550
- toolChannelId: context.toolChannelId,
11551
- userMessage: userInput,
11552
- currentPendingAuth: context.pendingAuth,
11553
- getConfiguration: () => configurationValues,
11554
- getArtifactState: () => context.artifactState,
11555
- getMergedArtifactState: () => mergeArtifactsState(context.artifactState ?? {}, artifactStatePatch),
11556
- onPendingAuth: context.onAuthPending,
11557
- authorizationFlowMode: context.authorizationFlowMode
11558
- },
11559
- () => agent?.abort()
11560
- );
11561
- const pluginAuth = createPluginAuthOrchestration(
11562
- {
11563
- conversationId: sessionConversationId,
11564
- sessionId,
11565
- requesterId: authRequesterId,
11566
- channelId: slackChannelId,
11567
- destination: context.destination,
11568
- threadTs: context.correlation?.threadTs,
11569
- userMessage: userInput,
11570
- channelConfiguration: context.channelConfiguration,
11571
- currentPendingAuth: context.pendingAuth,
11572
- onPendingAuth: context.onAuthPending,
11573
- authorizationFlowMode: context.authorizationFlowMode,
11574
- userTokenStore
11575
- },
11576
- () => agent?.abort()
11577
- );
11560
+ const mcpAuth = createMcpAuthOrchestration({
11561
+ abortAgent: () => agent?.abort(),
11562
+ conversationId: sessionConversationId,
11563
+ sessionId,
11564
+ requesterId: authRequesterId,
11565
+ channelId: slackChannelId,
11566
+ destination: context.destination,
11567
+ threadTs: context.correlation?.threadTs,
11568
+ toolChannelId: context.toolChannelId,
11569
+ userMessage: userInput,
11570
+ pendingAuth: context.pendingAuth,
11571
+ getConfiguration: () => configurationValues,
11572
+ getArtifactState: () => context.artifactState,
11573
+ getMergedArtifactState: () => mergeArtifactsState(context.artifactState ?? {}, artifactStatePatch),
11574
+ recordPendingAuth: context.recordPendingAuth,
11575
+ authorizationFlowMode: context.authorizationFlowMode
11576
+ });
11577
+ const pluginAuth = createPluginAuthOrchestration({
11578
+ abortAgent: () => agent?.abort(),
11579
+ conversationId: sessionConversationId,
11580
+ sessionId,
11581
+ requesterId: authRequesterId,
11582
+ channelId: slackChannelId,
11583
+ destination: context.destination,
11584
+ threadTs: context.correlation?.threadTs,
11585
+ userMessage: userInput,
11586
+ channelConfiguration: context.channelConfiguration,
11587
+ pendingAuth: context.pendingAuth,
11588
+ recordPendingAuth: context.recordPendingAuth,
11589
+ authorizationFlowMode: context.authorizationFlowMode,
11590
+ userTokenStore
11591
+ });
11578
11592
  mcpToolManager = new McpToolManager(getPluginMcpProviders(), {
11579
11593
  authProviderFactory: mcpAuth.authProviderFactory,
11580
11594
  onAuthorizationRequired: mcpAuth.onAuthorizationRequired
@@ -1,6 +1,6 @@
1
1
  // src/vercel.ts
2
2
  function juniorVercelConfig(options = {}) {
3
- const buildCommand = options.buildCommand === void 0 ? "pnpm build" : options.buildCommand;
3
+ const buildCommand = options.buildCommand === void 0 ? "pnpm exec junior upgrade && pnpm build" : options.buildCommand;
4
4
  const config = {
5
5
  framework: "nitro"
6
6
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  destinationKey,
3
3
  parseDestination
4
- } from "./chunk-V4VYUY4A.js";
4
+ } from "./chunk-YRDS7VKO.js";
5
5
 
6
6
  // src/plugins.ts
7
7
  function cloneManifests(manifests) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSlackBotToken
3
- } from "./chunk-WS2EG3GW.js";
3
+ } from "./chunk-GM7HTXYC.js";
4
4
  import {
5
5
  isSlackConversationId,
6
6
  isSlackTeamId,
package/dist/cli/chat.js CHANGED
@@ -121,7 +121,7 @@ function newRunConversationId() {
121
121
  async function runPrompt(options, io) {
122
122
  defaultStateAdapterForLocalChat();
123
123
  const conversationId = newRunConversationId();
124
- const { runLocalAgentTurn } = await import("../runner-LMAM4OGD.js");
124
+ const { runLocalAgentTurn } = await import("../runner-27NP2TEO.js");
125
125
  const result = await runLocalAgentTurn(
126
126
  {
127
127
  conversationId,
@@ -141,7 +141,7 @@ async function runPrompt(options, io) {
141
141
  async function runInteractive(io) {
142
142
  defaultStateAdapterForLocalChat();
143
143
  const conversationId = newRunConversationId();
144
- const { runLocalAgentTurn } = await import("../runner-LMAM4OGD.js");
144
+ const { runLocalAgentTurn } = await import("../runner-27NP2TEO.js");
145
145
  const rl = readline.createInterface({
146
146
  input: io.input,
147
147
  output: io.output,
package/dist/cli/init.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  juniorVercelConfig
3
- } from "../chunk-QUXPUKBH.js";
3
+ } from "../chunk-Y7X25LFY.js";
4
4
  import "../chunk-2KG3PWR4.js";
5
5
 
6
6
  // src/cli/init.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveRuntimeDependencySnapshot
3
- } from "../chunk-RY6AL5C7.js";
3
+ } from "../chunk-6UP2Z2RZ.js";
4
4
  import "../chunk-G3E7SCME.js";
5
5
  import {
6
6
  getPluginProviders,
@@ -10,8 +10,8 @@ import {
10
10
  import "../chunk-KVZL5NZS.js";
11
11
  import {
12
12
  disconnectStateAdapter
13
- } from "../chunk-DIMX5F3T.js";
14
- import "../chunk-WS2EG3GW.js";
13
+ } from "../chunk-F6HWCPOC.js";
14
+ import "../chunk-GM7HTXYC.js";
15
15
  import "../chunk-CYUI7JU5.js";
16
16
  import "../chunk-3BYAPS6B.js";
17
17
  import "../chunk-SJHUF3DP.js";
@@ -3,20 +3,23 @@ import {
3
3
  } from "../chunk-M4FLLXXD.js";
4
4
  import {
5
5
  JUNIOR_THREAD_STATE_TTL_MS,
6
+ createNeonJuniorSqlExecutor,
7
+ createSqlStore,
8
+ createStateConversationStore,
6
9
  getConversation,
7
10
  requestConversationWork
8
- } from "../chunk-AL5T52ZD.js";
11
+ } from "../chunk-JL2SLRAT.js";
9
12
  import {
10
13
  parseDestination,
11
14
  sameDestination
12
- } from "../chunk-V4VYUY4A.js";
15
+ } from "../chunk-YRDS7VKO.js";
13
16
  import {
14
17
  disconnectStateAdapter,
15
18
  getConnectedStateContext
16
- } from "../chunk-DIMX5F3T.js";
19
+ } from "../chunk-F6HWCPOC.js";
17
20
  import {
18
21
  getChatConfig
19
- } from "../chunk-WS2EG3GW.js";
22
+ } from "../chunk-GM7HTXYC.js";
20
23
  import "../chunk-CYUI7JU5.js";
21
24
  import {
22
25
  isRecord,
@@ -26,6 +29,65 @@ import {
26
29
  import "../chunk-SJHUF3DP.js";
27
30
  import "../chunk-2KG3PWR4.js";
28
31
 
32
+ // src/chat/conversations/sql/backfill.ts
33
+ async function backfillToSql(args) {
34
+ const limit = Math.max(0, args.limit ?? 500);
35
+ const conversations = await args.source.listByActivity({
36
+ limit
37
+ });
38
+ await args.target.migrate();
39
+ for (const conversation of conversations) {
40
+ await args.target.backfillConversation(conversation);
41
+ }
42
+ return {
43
+ copiedCount: conversations.length
44
+ };
45
+ }
46
+
47
+ // src/cli/upgrade/migrations/conversations-sql.ts
48
+ var CONVERSATION_BACKFILL_LIMIT = 1e4;
49
+ var REQUIRED_SQL_DATABASE_URL_MESSAGE = "Junior SQL database URL is required for conversation metadata upgrade. Set JUNIOR_DATABASE_URL or DATABASE_URL.";
50
+ function requireConversationSqlDatabaseUrl(context) {
51
+ const databaseUrl = context.sqlDatabaseUrl ?? getChatConfig().sql.databaseUrl;
52
+ if (!databaseUrl) {
53
+ throw new Error(REQUIRED_SQL_DATABASE_URL_MESSAGE);
54
+ }
55
+ return databaseUrl;
56
+ }
57
+ async function migrateConversationsToSql(context, options = {}) {
58
+ const source = createStateConversationStore(context.stateAdapter);
59
+ let target = options.target;
60
+ let closeTarget;
61
+ if (!target) {
62
+ const databaseUrl = requireConversationSqlDatabaseUrl(context);
63
+ const executor = createNeonJuniorSqlExecutor({
64
+ connectionString: databaseUrl
65
+ });
66
+ target = createSqlStore(executor);
67
+ closeTarget = () => executor.close();
68
+ }
69
+ const limit = Math.max(1, options.batchSize ?? CONVERSATION_BACKFILL_LIMIT);
70
+ try {
71
+ const result = await backfillToSql({
72
+ limit,
73
+ source,
74
+ target
75
+ });
76
+ return {
77
+ existing: 0,
78
+ migrated: result.copiedCount,
79
+ missing: 0,
80
+ scanned: result.copiedCount
81
+ };
82
+ } finally {
83
+ await closeTarget?.();
84
+ }
85
+ }
86
+ var sqlConversationMigration = {
87
+ name: "backfill-conversations-sql",
88
+ run: migrateConversationsToSql
89
+ };
90
+
29
91
  // src/cli/upgrade/migrations/redis-conversation-state.ts
30
92
  var CONVERSATION_PREFIX = "junior:conversation";
31
93
  var CONVERSATION_SCHEMA_VERSION = 1;
@@ -562,16 +624,24 @@ var redisConversationStateMigration = {
562
624
  var DEFAULT_IO = {
563
625
  info: console.log
564
626
  };
565
- var MIGRATIONS = [redisConversationStateMigration];
627
+ var MIGRATIONS = [
628
+ redisConversationStateMigration,
629
+ sqlConversationMigration
630
+ ];
566
631
  function formatMigrationResult(result) {
567
- return [
632
+ const fields = [
568
633
  `scanned=${result.scanned}`,
569
634
  `migrated=${result.migrated}`,
570
635
  `existing=${result.existing}`,
571
636
  `missing=${result.missing}`
572
- ].join(" ");
637
+ ];
638
+ if (result.skipped !== void 0) {
639
+ fields.push(`skipped=${result.skipped}`);
640
+ }
641
+ return fields.join(" ");
573
642
  }
574
643
  async function runUpgradeMigrations(context) {
644
+ requireConversationSqlDatabaseUrl(context);
575
645
  const results = [];
576
646
  for (const migration of MIGRATIONS) {
577
647
  context.io.info(`Running migration ${migration.name}...`);
@@ -32,7 +32,6 @@ function initSentry() {
32
32
  release: serviceVersion,
33
33
  tracesSampleRate: getSampleRate(process.env.SENTRY_TRACES_SAMPLE_RATE, 1),
34
34
  sendDefaultPii: true,
35
- enabled: Boolean(dsn),
36
35
  enableLogs,
37
36
  registerEsmLoaderHooks: false,
38
37
  streamGenAiSpans: true,
package/dist/nitro.js CHANGED
@@ -2,14 +2,14 @@ import {
2
2
  pluginCatalogConfigFromPluginSet,
3
3
  pluginHookRegistrationsFromPluginSet,
4
4
  resolveConversationWorkQueueTopic
5
- } from "./chunk-UOTZ3EEQ.js";
6
- import "./chunk-V4VYUY4A.js";
5
+ } from "./chunk-YOHFWWBV.js";
6
+ import "./chunk-YRDS7VKO.js";
7
7
  import {
8
8
  discoverInstalledPluginPackageContent,
9
9
  isValidPackageName,
10
10
  resolvePackageDir
11
11
  } from "./chunk-KVZL5NZS.js";
12
- import "./chunk-WS2EG3GW.js";
12
+ import "./chunk-GM7HTXYC.js";
13
13
  import "./chunk-3BYAPS6B.js";
14
14
  import {
15
15
  JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
@@ -1,3 +1,9 @@
1
+ import type { AgentPluginConversationStatus, AgentPluginConversations, AgentPluginConversationSummary } from "@sentry/junior-plugin-api";
2
+ import type { ConversationStore } from "@/chat/conversations/store";
3
+ export type { AgentPluginConversationStatus, AgentPluginConversations, AgentPluginConversationSummary, };
4
+ interface ConversationReaderOptions {
5
+ conversationStore?: ConversationStore;
6
+ }
1
7
  export type ConversationReportStatus = "active" | "completed" | "failed" | "hung" | "superseded";
2
8
  export type ConversationSurface = "api" | "internal" | "scheduler" | "slack";
3
9
  export interface ConversationUsage {
@@ -109,8 +115,12 @@ export interface ConversationStatsReport {
109
115
  windowStart: string;
110
116
  }
111
117
  /** Read the recent conversation feed for reporting consumers. */
112
- export declare function readConversationFeed(): Promise<ConversationFeed>;
118
+ export declare function readConversationFeed(options?: ConversationReaderOptions): Promise<ConversationFeed>;
113
119
  /** Read aggregate conversation statistics for reporting consumers. */
114
- export declare function readConversationStatsReport(): Promise<ConversationStatsReport>;
120
+ export declare function readConversationStatsReport(options?: ConversationReaderOptions): Promise<ConversationStatsReport>;
121
+ /** List recent conversation summaries for plugin operational reports. */
122
+ export declare function listRecentConversationSummaries(options?: {
123
+ limit?: number;
124
+ } & ConversationReaderOptions): Promise<AgentPluginConversationSummary[]>;
115
125
  /** Read one conversation transcript for reporting consumers. */
116
- export declare function readConversationReport(conversationId: string): Promise<ConversationReport>;
126
+ export declare function readConversationReport(conversationId: string, options?: ConversationReaderOptions): Promise<ConversationReport>;