@sentry/junior 0.186.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 (72) hide show
  1. package/dist/{agent-hooks-4B3Z4WRK.js → agent-hooks-XVAE2554.js} +11 -11
  2. package/dist/api.js +32 -32
  3. package/dist/app.js +59 -89
  4. package/dist/{catalog-runtime-AFJCAOHC.js → catalog-runtime-DWFAC562.js} +4 -4
  5. package/dist/chat/agent/types.d.ts +16 -13
  6. package/dist/chat/api-turns/{accepted-reply.d.ts → assistant-message.d.ts} +3 -2
  7. package/dist/chat/api-turns/cancellation.d.ts +0 -1
  8. package/dist/chat/api-turns/mailbox-input.d.ts +0 -3
  9. package/dist/chat/api-turns/routing.d.ts +22 -21
  10. package/dist/chat/api-turns/work.d.ts +2 -2
  11. package/dist/chat/conversations/location.d.ts +2 -2
  12. package/dist/chat/conversations/store.d.ts +13 -0
  13. package/dist/chat/resource-events/actor.d.ts +7 -0
  14. package/dist/chat/services/turn-session-routing.d.ts +6 -5
  15. package/dist/chat/task-input.d.ts +22 -0
  16. package/dist/{chunk-CM6RTYSO.js → chunk-27T5HZHO.js} +91 -7
  17. package/dist/{chunk-QBL2AVFF.js → chunk-2VUDJGB6.js} +2 -2
  18. package/dist/{chunk-7EOWT62G.js → chunk-4A2R3AQB.js} +1 -1
  19. package/dist/{chunk-7EU4YSZ4.js → chunk-4YD3DET6.js} +139 -121
  20. package/dist/{chunk-INQHUE72.js → chunk-6FGN7ZEG.js} +6 -2
  21. package/dist/{chunk-VQZYIVYN.js → chunk-6FKNNUSN.js} +6 -6
  22. package/dist/{chunk-3CVEE6LA.js → chunk-6YCIYOVA.js} +1 -1
  23. package/dist/{chunk-YXSBZRP7.js → chunk-7LRRVMPH.js} +1 -1
  24. package/dist/{chunk-QU3URVWG.js → chunk-BITZUBPJ.js} +8 -8
  25. package/dist/{chunk-CV5CPRVG.js → chunk-D3GDGREI.js} +3 -3
  26. package/dist/{chunk-H7X2G2KS.js → chunk-D5BWM37G.js} +5 -5
  27. package/dist/{chunk-JFPY6XFF.js → chunk-DUE4EUNL.js} +6 -6
  28. package/dist/{chunk-OZG7E22Y.js → chunk-EIWYZXSM.js} +5 -5
  29. package/dist/{chunk-VXL2LBPK.js → chunk-HXR3FHTE.js} +13 -3
  30. package/dist/{chunk-PZZOGHVR.js → chunk-ITLYUKGZ.js} +1 -1
  31. package/dist/{chunk-BRKB5R7P.js → chunk-JCRXXEMC.js} +1 -1
  32. package/dist/{chunk-HWXP6RHG.js → chunk-JZPDYKRG.js} +3 -3
  33. package/dist/{chunk-EWRPUXE3.js → chunk-KRYJ5VOD.js} +20 -14
  34. package/dist/{chunk-DHYZ4VKG.js → chunk-MUPPP7A7.js} +97 -47
  35. package/dist/{chunk-2IBDVE62.js → chunk-NIKLTFBP.js} +4 -4
  36. package/dist/{chunk-VOGOTEW7.js → chunk-NU775DLU.js} +2 -2
  37. package/dist/{chunk-GQMQCY7H.js → chunk-OM4SFFJK.js} +3 -3
  38. package/dist/{chunk-O6GQO7VP.js → chunk-P2VU5JNH.js} +26 -24
  39. package/dist/{chunk-FFYDRLXW.js → chunk-Q6OCUQ7W.js} +1 -1
  40. package/dist/{chunk-NRMAOGRS.js → chunk-QH3I7ZOK.js} +1 -1
  41. package/dist/{chunk-ACGWTJ74.js → chunk-STF4GSK4.js} +3 -3
  42. package/dist/{chunk-2U7EPTRZ.js → chunk-TQHCZXN7.js} +4 -4
  43. package/dist/{chunk-VQIWBJOP.js → chunk-U3KMII5Y.js} +1 -1
  44. package/dist/{chunk-GSB3NTNS.js → chunk-U5POFCKM.js} +29 -31
  45. package/dist/{chunk-DOP3FIQC.js → chunk-U6ZQHRIP.js} +1 -1
  46. package/dist/{chunk-AD64YMEC.js → chunk-URZ7UD4P.js} +2 -2
  47. package/dist/{chunk-STOCCPWH.js → chunk-VC343WHM.js} +1 -1
  48. package/dist/{chunk-43LODHJM.js → chunk-WKIS4VRK.js} +3 -3
  49. package/dist/{chunk-MCLWOBPN.js → chunk-WL3R2KTS.js} +11 -89
  50. package/dist/{chunk-TXLBLGNQ.js → chunk-WRDW3A3D.js} +5 -5
  51. package/dist/{chunk-64WF2GQ3.js → chunk-X5SXFVZT.js} +1 -1
  52. package/dist/{chunk-HKFLRIBD.js → chunk-Z6OHCDXP.js} +2 -2
  53. package/dist/cli/chat.js +33 -33
  54. package/dist/cli/check.js +5 -5
  55. package/dist/cli/plugins.js +12 -12
  56. package/dist/cli/snapshot-create.js +9 -9
  57. package/dist/cli/upgrade.js +6 -6
  58. package/dist/{db-7XL4UPAE.js → db-FBHAWVXU.js} +6 -6
  59. package/dist/instrumentation.js +3 -3
  60. package/dist/nitro.js +6 -6
  61. package/dist/{oauth-callback-server-RAOYHWDI.js → oauth-callback-server-5HS5ULC6.js} +28 -28
  62. package/dist/{runner-KMPBWRPM.js → runner-46W6NV6B.js} +19 -19
  63. package/dist/{skills-IPCALGLQ.js → skills-TG3QC4B6.js} +5 -5
  64. package/dist/spawn-Y6YWBIJS.js +41 -0
  65. package/dist/task-runner-YSGBPN4U.js +34 -0
  66. package/dist/{validation-BSRCCX6N.js → validation-GMRIDBC5.js} +5 -5
  67. package/dist/version.js +1 -1
  68. package/dist/{work-T6UFTOJY.js → work-W4ULBJTU.js} +21 -21
  69. package/dist/{worker-L35OG7VA.js → worker-M6NVACS2.js} +10 -10
  70. package/package.json +5 -5
  71. package/dist/spawn-OSOWTMBG.js +0 -41
  72. package/dist/task-runner-IQNBA3RY.js +0 -34
@@ -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;
@@ -1,7 +1,4 @@
1
1
  /** Shared mailbox helpers for conversation-only turns. */
2
- import type { LocalActor } from "@/chat/actor";
3
2
  import type { InboundMessage } from "@/chat/task-execution/store";
4
3
  /** Join non-empty mailbox texts for one conversation-only turn. */
5
4
  export declare function joinMailboxText(messages: readonly InboundMessage[]): string;
6
- /** Local actor stamped on resource-event conversation-only turns. */
7
- export declare function localResourceEventActor(): LocalActor;
@@ -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,37 +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>;
13
- /**
14
- * Local destination resource-event mailbox rows share the conversation-only runner.
15
- *
16
- * TODO(resource-events): Remove the dedicated `resource_event` work kind once
17
- * local/web destinations run plain mailbox system wakes the same way as any
18
- * other deferred conversation turn (no special batch/actor fork).
19
- */
20
- export type LocalResourceEventMailboxEntry = {
17
+ export interface TurnInput {
18
+ actor: Actor;
19
+ author: ConversationAuthor;
21
20
  message: InboundMessage;
22
- kind: "resource_event";
23
- };
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;
24
32
  /** Return the active root API Turn for one Conversation, if it has one. */
25
33
  export declare function getActiveApiTurnId(conversationId: string): Promise<string | undefined>;
26
34
  /** Return the idle auth-paused root API Turn for one Conversation. */
27
35
  export declare function getAuthPausedApiTurnId(conversationId: string): Promise<string | undefined>;
28
36
  /**
29
- * Resolve conversation-only work from mailbox metadata or an active checkpoint.
37
+ * Resolve conversation-only work from new input or a saved Turn.
30
38
  *
31
- * Covers dashboard API turns and local destination resource-event wakes. Empty
32
- * resume wakes after yield carry no mailbox rows; durable active Turn state keeps
33
- * those wakes on this runner instead of falling 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.
34
41
  */
35
42
  export declare function resolveApiTurnWork(context: ConversationWorkerContext): Promise<{
36
43
  kind: "mailbox";
37
- batch: Array<{
38
- message: InboundMessage;
39
- metadata: ApiTurnMailboxMetadata;
40
- }>;
41
- } | {
42
- kind: "resource_event";
43
- batch: LocalResourceEventMailboxEntry[];
44
+ batch: TurnInput[];
44
45
  } | {
45
46
  kind: "resume";
46
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;
@@ -5,6 +5,13 @@
5
5
  * same system input for resource-event turns.
6
6
  */
7
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
+ };
8
15
  /** System execution actor for every resource-event turn. */
9
16
  export declare const RESOURCE_EVENT_SYSTEM_ACTOR: {
10
17
  readonly platform: "system";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Load destination and session source from the conversation record.
2
+ * Load Location, Destination, and session Source from the Conversation record.
3
3
  *
4
4
  * Destination is set once on the root conversation. Child conversations
5
5
  * inherit through parent lineage. Later turns and mailbox wakes use that
@@ -7,18 +7,19 @@
7
7
  */
8
8
  import type { Destination, Source } from "@sentry/junior-plugin-api";
9
9
  import type { ConversationStore } from "@/chat/conversations/store";
10
+ import type { Location } from "@/chat/conversations/location";
10
11
  export interface TurnSessionRouting {
11
12
  destination: Destination;
12
- locationId?: string;
13
+ location?: Location;
13
14
  /** Present when the conversation already stores a session source. */
14
15
  source?: Source;
15
16
  }
16
- /** Full turn routing: destination plus a completed session source. */
17
+ /** Conversation data with a required Destination and Source. */
17
18
  export type RequiredTurnSessionRouting = TurnSessionRouting & {
18
19
  source: Source;
19
20
  };
20
21
  /**
21
- * Resolve the conversation's destination and session source.
22
+ * Resolve the Conversation's Location, Destination, and session Source.
22
23
  *
23
24
  * Walks parent lineage when the conversation has no destination of its own.
24
25
  */
@@ -26,7 +27,7 @@ export declare function resolveConversationRouting(args: {
26
27
  conversationId: string;
27
28
  conversationStore?: ConversationStore;
28
29
  }): Promise<TurnSessionRouting | undefined>;
29
- /** Require conversation destination and session source from SQL. */
30
+ /** Require the Conversation Destination and Source from SQL. */
30
31
  export declare function resolveTurnSessionRouting(args: {
31
32
  conversationId: string;
32
33
  conversationStore?: ConversationStore;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Render agent input for a task run.
3
+ *
4
+ * Section order and required prose live in `chat/README.md` under Task agent
5
+ * input. Empty optional fields are omitted.
6
+ */
7
+ export declare function renderTaskInput(args: {
8
+ /** Stored task instruction, or subscription intent. */
9
+ instructions: string;
10
+ /** Human label for the matched resource, when present. */
11
+ about?: string;
12
+ /** Plugin guidance scoped under the instructions. */
13
+ guidance?: string;
14
+ /** Trusted one-line summary, when available. */
15
+ trustedSummary?: string;
16
+ /** Structured verified fields, when available. */
17
+ verifiedDetails?: Record<string, unknown>;
18
+ /** Untrusted provider text; never treated as instructions. */
19
+ externalText?: string;
20
+ externalTextMaxLength?: number;
21
+ trustedSummaryMaxLength?: number;
22
+ }): string;
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  persistConversationMessages
3
- } from "./chunk-H7X2G2KS.js";
3
+ } from "./chunk-D5BWM37G.js";
4
4
  import {
5
5
  JUNIOR_THREAD_STATE_TTL_MS
6
6
  } from "./chunk-3Y47VMHV.js";
7
7
  import {
8
8
  getDb
9
- } from "./chunk-43LODHJM.js";
9
+ } from "./chunk-WKIS4VRK.js";
10
10
  import {
11
11
  juniorLocationConfigurations
12
- } from "./chunk-VXL2LBPK.js";
12
+ } from "./chunk-HXR3FHTE.js";
13
13
  import {
14
14
  getStateAdapter
15
- } from "./chunk-DOP3FIQC.js";
15
+ } from "./chunk-U6ZQHRIP.js";
16
16
  import {
17
17
  juniorDestinations
18
18
  } from "./chunk-VFUK3X5B.js";
@@ -20,7 +20,7 @@ import {
20
20
  isRecord,
21
21
  toOptionalNumber,
22
22
  toOptionalString
23
- } from "./chunk-3CVEE6LA.js";
23
+ } from "./chunk-6YCIYOVA.js";
24
24
 
25
25
  // src/chat/state/conversation.ts
26
26
  function defaultConversationState() {
@@ -372,7 +372,10 @@ function createSqlLocationConfigurationStorage(db, destination) {
372
372
  };
373
373
  }
374
374
  function createDurableLocationConfigurationService(args) {
375
- const storage = createSqlLocationConfigurationStorage(args.db, args.destination);
375
+ const storage = createSqlLocationConfigurationStorage(
376
+ args.db,
377
+ args.destination
378
+ );
376
379
  let cutover;
377
380
  const ensureCutover = () => cutover ??= (async () => {
378
381
  if ((await storage.list()).length > 0) {
@@ -504,6 +507,85 @@ function getLocationConfigurationService(destination) {
504
507
  });
505
508
  }
506
509
 
510
+ // src/chat/services/turn-session-routing.ts
511
+ async function loadConversationChain(conversationId, conversationStore) {
512
+ const chain = [];
513
+ const seen = /* @__PURE__ */ new Set();
514
+ let cursor = conversationId;
515
+ while (cursor && !seen.has(cursor)) {
516
+ seen.add(cursor);
517
+ const conversation = await conversationStore.get({
518
+ conversationId: cursor
519
+ });
520
+ if (!conversation) {
521
+ break;
522
+ }
523
+ chain.push(conversation);
524
+ cursor = conversation.lineage?.parentConversationId;
525
+ }
526
+ return chain;
527
+ }
528
+ function slackSourceForDestination(args) {
529
+ if (args.source?.platform !== "slack" || args.source.channelId !== args.destination.channelId) {
530
+ return void 0;
531
+ }
532
+ const threadTs = args.source.threadTs?.trim();
533
+ return {
534
+ platform: "slack",
535
+ visibility: args.source.visibility ?? "public",
536
+ teamId: args.source.teamId?.trim() || args.destination.teamId,
537
+ channelId: args.source.channelId,
538
+ ...threadTs ? { threadTs } : void 0
539
+ };
540
+ }
541
+ async function resolveConversationRouting(args) {
542
+ const conversationStore = args.conversationStore ?? (await import("./db-FBHAWVXU.js")).getConversationStore();
543
+ const chain = await loadConversationChain(
544
+ args.conversationId,
545
+ conversationStore
546
+ );
547
+ let destination;
548
+ let source;
549
+ let location;
550
+ for (const conversation of chain) {
551
+ destination ??= conversation.destination;
552
+ source ??= conversation.sessionSource;
553
+ location ??= conversation.location;
554
+ if (destination && source) {
555
+ break;
556
+ }
557
+ }
558
+ if (!destination) {
559
+ return void 0;
560
+ }
561
+ if (destination.platform === "slack") {
562
+ const slackSource = slackSourceForDestination({ destination, source });
563
+ return {
564
+ destination,
565
+ ...location ? { location } : void 0,
566
+ ...slackSource ? { source: slackSource } : void 0
567
+ };
568
+ }
569
+ return {
570
+ destination,
571
+ ...location ? { location } : void 0,
572
+ ...source ? { source } : void 0
573
+ };
574
+ }
575
+ async function resolveTurnSessionRouting(args) {
576
+ const routing = await resolveConversationRouting(args);
577
+ if (!routing?.destination || !routing.source) {
578
+ throw new Error(
579
+ `Conversation ${args.conversationId} is missing durable routing metadata`
580
+ );
581
+ }
582
+ return {
583
+ destination: routing.destination,
584
+ source: routing.source,
585
+ ...routing.location ? { location: routing.location } : void 0
586
+ };
587
+ }
588
+
507
589
  export {
508
590
  configValueSchema,
509
591
  coerceThreadConversationState,
@@ -512,5 +594,7 @@ export {
512
594
  persistThreadRuntimeState,
513
595
  getPersistedThreadState,
514
596
  persistThreadStateById,
515
- getLocationConfigurationService
597
+ getLocationConfigurationService,
598
+ resolveConversationRouting,
599
+ resolveTurnSessionRouting
516
600
  };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createAndEnqueueAgentInvocation
3
- } from "./chunk-EWRPUXE3.js";
3
+ } from "./chunk-KRYJ5VOD.js";
4
4
  import {
5
5
  actorFromRun,
6
6
  toolInvocationDestination
7
- } from "./chunk-INQHUE72.js";
7
+ } from "./chunk-6FGN7ZEG.js";
8
8
 
9
9
  // src/chat/agent-invocations/spawn.ts
10
10
  function bindSpawnAgent(run, options) {
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-N7TMSOZH.js";
6
6
  import {
7
7
  toOptionalString
8
- } from "./chunk-3CVEE6LA.js";
8
+ } from "./chunk-6YCIYOVA.js";
9
9
 
10
10
  // src/chat/slack/context.ts
11
11
  import { z } from "zod";