@sentry/junior 0.144.0 → 0.146.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 (104) hide show
  1. package/dist/{agent-hooks-GCUTGKY3.js → agent-hooks-SLJADYE5.js} +10 -10
  2. package/dist/api/conversations/detail.d.ts +1 -0
  3. package/dist/api/schema/conversation.d.ts +2 -0
  4. package/dist/api/schema.js +1 -1
  5. package/dist/api.js +40 -22
  6. package/dist/app.js +400 -461
  7. package/dist/{catalog-runtime-DWVYKDC6.js → catalog-runtime-RQIMSDPR.js} +5 -5
  8. package/dist/chat/agent/request.d.ts +1 -1
  9. package/dist/chat/agent/resume.d.ts +6 -18
  10. package/dist/chat/agent/skills.d.ts +0 -1
  11. package/dist/chat/agent/tools.d.ts +1 -2
  12. package/dist/chat/agent-dispatch/types.d.ts +1 -1
  13. package/dist/chat/app/conversation-work.d.ts +24 -0
  14. package/dist/chat/conversations/message-search.d.ts +32 -0
  15. package/dist/chat/conversations/projection.d.ts +11 -3
  16. package/dist/chat/conversations/sql/message-search.d.ts +4 -0
  17. package/dist/chat/conversations/store.d.ts +1 -1
  18. package/dist/chat/conversations/tool-source.d.ts +5 -0
  19. package/dist/chat/db.d.ts +2 -2
  20. package/dist/chat/runtime/agent-run-outcome.d.ts +1 -1
  21. package/dist/chat/runtime/reply-executor.d.ts +5 -5
  22. package/dist/chat/runtime/slack-resume.d.ts +12 -4
  23. package/dist/chat/slack/message/attachments.d.ts +2 -0
  24. package/dist/chat/slack/message/blocks.d.ts +2 -0
  25. package/dist/chat/slack/message/content.d.ts +18 -0
  26. package/dist/chat/slack/message/identity.d.ts +7 -0
  27. package/dist/chat/slack/tools/{conversation-search.d.ts → conversation-message-search.d.ts} +21 -14
  28. package/dist/chat/slack/tools/user-lookup.d.ts +2 -1
  29. package/dist/chat/state/locks.d.ts +28 -0
  30. package/dist/chat/task-execution/checkpoint.d.ts +84 -0
  31. package/dist/chat/task-execution/paused-turn.d.ts +29 -0
  32. package/dist/chat/task-execution/queue-signing.d.ts +1 -0
  33. package/dist/chat/task-execution/queue.d.ts +7 -1
  34. package/dist/chat/task-execution/slack-work.d.ts +1 -1
  35. package/dist/chat/task-execution/state.d.ts +4 -4
  36. package/dist/chat/task-execution/store.d.ts +2 -2
  37. package/dist/chat/task-execution/turn-cursor-keys.d.ts +6 -0
  38. package/dist/chat/{state/turn-session.d.ts → task-execution/turn-cursor.d.ts} +52 -51
  39. package/dist/chat/task-execution/turn-wake.d.ts +29 -0
  40. package/dist/chat/tools/{query-conversation-events.d.ts → search-conversation-events.d.ts} +3 -3
  41. package/dist/chat/tools/types.d.ts +1 -1
  42. package/dist/{chunk-SBZP2J5Q.js → chunk-37EVZP66.js} +48 -35
  43. package/dist/{chunk-A67GZN73.js → chunk-37JJDS4H.js} +1 -1
  44. package/dist/{chunk-BBCWYXHB.js → chunk-47OSH2ZO.js} +7 -7
  45. package/dist/{chunk-4X5KM7Z6.js → chunk-AISNSNDV.js} +14 -14
  46. package/dist/{chunk-RIFJUJSI.js → chunk-B63BF443.js} +1 -1
  47. package/dist/{chunk-SSDTQDYQ.js → chunk-BLETMLRX.js} +566 -268
  48. package/dist/{chunk-I44JB7HQ.js → chunk-F7REGDKO.js} +1 -1
  49. package/dist/{chunk-DVO5VKYQ.js → chunk-FEKQHPVA.js} +5 -5
  50. package/dist/{chunk-SUK7NC5A.js → chunk-FGHADGIC.js} +2 -2
  51. package/dist/{chunk-7KAW7UF4.js → chunk-FXDDDSPL.js} +4 -4
  52. package/dist/{chunk-BEGGFVFR.js → chunk-GDQEU4I7.js} +414 -542
  53. package/dist/{chunk-UDQMY6RS.js → chunk-GYEKOX7N.js} +43 -1
  54. package/dist/{chunk-W7JFV5SB.js → chunk-H6U2U3EP.js} +14 -17
  55. package/dist/{chunk-WTX2RFJG.js → chunk-HQE6EJS5.js} +1 -1
  56. package/dist/{chunk-IUFM5JWV.js → chunk-JAL3CH4G.js} +3 -0
  57. package/dist/{chunk-E7HCWOHG.js → chunk-JLMVCNXL.js} +2 -1
  58. package/dist/{chunk-PELZ2ZSY.js → chunk-JUA6VU2Z.js} +33 -63
  59. package/dist/{chunk-SHEEZSLY.js → chunk-LVW7BLLT.js} +2 -2
  60. package/dist/{chunk-GKA74DRA.js → chunk-M6ZWP4RI.js} +1 -1
  61. package/dist/{chunk-HNO2E5WB.js → chunk-MCFIXAV5.js} +1 -1
  62. package/dist/{chunk-3GU4PWA3.js → chunk-MKRIZ4VG.js} +29 -30
  63. package/dist/{chunk-QUZJDAQQ.js → chunk-OFPYOC3M.js} +93 -90
  64. package/dist/{chunk-ZF3N3JD6.js → chunk-PB222GIA.js} +1 -1
  65. package/dist/{chunk-PKH6762I.js → chunk-PH4Q3A6W.js} +1 -1
  66. package/dist/{chunk-STFCL3K4.js → chunk-QG7OOKIN.js} +1 -1
  67. package/dist/{chunk-WSOLZJJS.js → chunk-QSXZ42KX.js} +3 -3
  68. package/dist/{chunk-44RJWAND.js → chunk-SCGVWUZX.js} +6 -6
  69. package/dist/{chunk-CNTWB2SM.js → chunk-T5GXFFLA.js} +1 -1
  70. package/dist/{chunk-LDWNYCZ6.js → chunk-TCEJ7XXM.js} +1 -1
  71. package/dist/{chunk-QE3TICD4.js → chunk-V6SRLKUB.js} +2 -2
  72. package/dist/{chunk-54JMYQYS.js → chunk-W65V465O.js} +2 -2
  73. package/dist/{chunk-KCBZSJRU.js → chunk-WR76IVA5.js} +5 -2
  74. package/dist/{chunk-ZZCTGAIT.js → chunk-X22KCSCO.js} +4 -4
  75. package/dist/{chunk-HD6BHR25.js → chunk-X2WMBTS3.js} +32 -34
  76. package/dist/{chunk-KQBXT5B7.js → chunk-ZDGHGY74.js} +6 -6
  77. package/dist/cli/chat.js +32 -32
  78. package/dist/cli/check.js +6 -6
  79. package/dist/cli/plugins.js +13 -13
  80. package/dist/cli/snapshot-create.js +9 -9
  81. package/dist/cli/upgrade.js +7 -7
  82. package/dist/{db-EFLHTBU6.js → db-WWOMXWTT.js} +9 -9
  83. package/dist/instrumentation.js +4 -4
  84. package/dist/nitro.js +4 -4
  85. package/dist/{oauth-callback-server-RO3IQKWM.js → oauth-callback-server-A6ZZX74U.js} +25 -25
  86. package/dist/{runner-LOWW7JKA.js → runner-KSGB2UAV.js} +19 -20
  87. package/dist/{skills-ZLMUG7AE.js → skills-26QPWKVS.js} +6 -6
  88. package/dist/spawn-5LAJXZ2P.js +39 -0
  89. package/dist/{validation-MAKEZNTS.js → validation-OPSRGFGH.js} +6 -6
  90. package/dist/version.js +1 -1
  91. package/dist/{work-5OAGC3I4.js → work-VMSW7STJ.js} +17 -16
  92. package/dist/worker-2JNFB7C7.js +24 -0
  93. package/package.json +5 -5
  94. package/dist/chat/agent/session.d.ts +0 -19
  95. package/dist/chat/conversations/search.d.ts +0 -24
  96. package/dist/chat/conversations/sql/search.d.ts +0 -4
  97. package/dist/chat/runtime/agent-continue-runner.d.ts +0 -37
  98. package/dist/chat/services/agent-continue.d.ts +0 -29
  99. package/dist/chat/services/turn-session-record.d.ts +0 -164
  100. package/dist/chat/slack/legacy-attachments.d.ts +0 -4
  101. package/dist/chat/slack/message.d.ts +0 -12
  102. package/dist/chat/state/turn-session-keys.d.ts +0 -6
  103. package/dist/spawn-R3LUV6RF.js +0 -38
  104. package/dist/worker-KTGGRTTP.js +0 -24
@@ -1,6 +1,8 @@
1
1
  import { z } from "zod";
2
- /** Validate the conversation work hint sent through Vercel Queue. */
2
+ export declare const CONVERSATION_QUEUE_SCHEMA_VERSION = 2;
3
+ /** Validate the v2 conversation work hint sent through Vercel Queue. */
3
4
  export declare const conversationQueueMessageSchema: z.ZodObject<{
5
+ schemaVersion: z.ZodLiteral<2>;
4
6
  conversationId: z.ZodString;
5
7
  }, z.core.$strict>;
6
8
  /** Conversation work hint accepted by the queue callback and worker. */
@@ -22,6 +24,10 @@ export interface ConversationQueueSendOptions {
22
24
  export interface ConversationQueueSendResult {
23
25
  messageId?: string;
24
26
  }
27
+ /**
28
+ * External transport for wake-up hints. Durable work stays in the mailbox;
29
+ * transports only need to accept one hint and may return a provider message id.
30
+ */
25
31
  export interface ConversationWorkQueue {
26
32
  send(message: ConversationQueueMessage, options?: ConversationQueueSendOptions): Promise<ConversationQueueSendResult | void>;
27
33
  }
@@ -274,7 +274,7 @@ export interface CreateSlackConversationWorkerOptions {
274
274
  crossActorMidRunMode?: CrossActorMidRunMode;
275
275
  getSlackAdapter: () => SlackAdapter;
276
276
  lookupSlackUser?: (teamId: string, userId: string) => Promise<SlackActorProfile | null | undefined>;
277
- resumeAwaitingContinuation: (conversationId: string, options: {
277
+ runNextPausedTurn: (conversationId: string, options: {
278
278
  shouldYield: () => boolean;
279
279
  }) => Promise<boolean>;
280
280
  conversationStore?: ConversationStore;
@@ -7,8 +7,8 @@ declare class InvalidConversationRecordError extends Error {
7
7
  }
8
8
  /** Return whether an error means a stored conversation record failed validation. */
9
9
  export declare function isInvalidConversationRecordError(error: unknown): error is InvalidConversationRecordError;
10
- export declare const CONVERSATION_BY_ACTIVITY_INDEX_KEY = "junior:conversation:by-activity";
11
- export declare const CONVERSATION_ACTIVE_INDEX_KEY = "junior:conversation:active";
10
+ export declare const CONVERSATION_BY_ACTIVITY_INDEX_KEY = "junior:conversation:v2:by-activity";
11
+ export declare const CONVERSATION_ACTIVE_INDEX_KEY = "junior:conversation:v2:active";
12
12
  export declare const CONVERSATION_WORK_LEASE_TTL_MS = 90000;
13
13
  export declare const CONVERSATION_WORK_CHECK_IN_INTERVAL_MS = 15000;
14
14
  export declare const CONVERSATION_WORK_STALE_ENQUEUE_MS = 60000;
@@ -24,7 +24,7 @@ declare const inboundMessageSourceSchema: z.ZodEnum<{
24
24
  scheduler: "scheduler";
25
25
  }>;
26
26
  export type Source = z.output<typeof inboundMessageSourceSchema>;
27
- export type ExecutionStatus = "awaiting_resume" | "failed" | "idle" | "pending" | "running";
27
+ export type ExecutionStatus = "paused" | "failed" | "idle" | "pending" | "running";
28
28
  declare const agentInputSchema: z.ZodObject<{
29
29
  attachments: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
30
30
  authorId: z.ZodOptional<z.ZodString>;
@@ -252,7 +252,7 @@ export declare function ackMessages(args: {
252
252
  state?: StateAdapter;
253
253
  }): Promise<boolean>;
254
254
  /** Mark the leased conversation as needing another queue-delivered slice. */
255
- export declare function requestConversationContinuation(args: {
255
+ export declare function requestAnotherSlice(args: {
256
256
  conversationId: string;
257
257
  destination?: Destination;
258
258
  leaseToken: string;
@@ -1,6 +1,6 @@
1
1
  import type { StateAdapter } from "chat";
2
2
  import type { ConversationStore } from "@/chat/conversations/store";
3
- import type { ConversationWorkQueue } from "./queue";
3
+ import { type ConversationWorkQueue } from "./queue";
4
4
  import * as workState from "./state";
5
5
  export { CONVERSATION_ACTIVE_INDEX_KEY, CONVERSATION_BY_ACTIVITY_INDEX_KEY, CONVERSATION_WORK_CHECK_IN_INTERVAL_MS, CONVERSATION_WORK_LEASE_TTL_MS, CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS, CONVERSATION_WORK_MAX_RETRIES, CONVERSATION_WORK_STALE_ENQUEUE_MS, isFinalAttempt, isInvalidConversationRecordError, type AgentInput, type AttemptFailure, type AppendAndEnqueueInboundMessageResult, type AppendInboundMessageResult, type Conversation, type ConversationExecution, type ConversationWorkLease, type ConversationWorkState, type ExecutionStatus, type InboundMessage, type InboundMessageDelivery, type Lease, type RequestConversationWorkResult, type Source, type StartConversationWorkAcquired, type StartConversationWorkActive, type StartConversationWorkNoWork, type StartConversationWorkResult, } from "@/chat/task-execution/state";
6
6
  import type { AppendAndEnqueueInboundMessageResult, Conversation, InboundMessage } from "@/chat/task-execution/state";
@@ -136,7 +136,7 @@ export declare function ackMessages(args: {
136
136
  state?: StateAdapter;
137
137
  }): Promise<boolean>;
138
138
  /** Mark the leased conversation as needing another queue-delivered slice. */
139
- export declare function requestConversationContinuation(args: {
139
+ export declare function requestAnotherSlice(args: {
140
140
  conversationId: string;
141
141
  destination: InboundMessage["destination"];
142
142
  leaseToken: string;
@@ -0,0 +1,6 @@
1
+ /** Return the Redis key for one turn cursor. */
2
+ export declare function turnCursorKey(conversationId: string, turnId: string): string;
3
+ /** Return the Redis index key for one conversation's turns. */
4
+ export declare function turnCursorIndexKey(conversationId: string): string;
5
+ /** Return the lock key that serializes writes to one turn cursor. */
6
+ export declare function turnCursorMutationKey(conversationId: string, turnId: string): string;
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Turn session records.
2
+ * Internal turn cursor storage for `checkpoint.ts`.
3
3
  *
4
- * These records track one user request across auth pauses, timeout slices, and
5
- * completion. Full Pi messages live in the durable conversation event store; this
6
- * record stores resumability metadata and a committed `seq` cursor into
7
- * `junior_conversation_events` so resumes can materialize the exact continuable
8
- * boundary without duplicating the event history.
4
+ * Callers outside `task-execution/` should use `checkpoint.ts` only.
5
+ * These records track one turn across auth pauses, timeout slices, and
6
+ * completion. Full Pi messages live in SQL conversation events; this store
7
+ * keeps resume metadata and a committed `seq` cursor into
8
+ * `junior_conversation_events`.
9
9
  */
10
10
  import type { Destination, Source } from "@sentry/junior-plugin-api";
11
11
  import { type PiMessage } from "@/chat/pi/messages";
@@ -15,12 +15,13 @@ import type { PluginTurnContext } from "@/chat/plugins/prompt";
15
15
  import type { AgentTurnUsage } from "@/chat/usage";
16
16
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
17
17
  import type { ConversationStore } from "@/chat/conversations/store";
18
- export type AgentTurnSessionStatus = "running" | "awaiting_resume" | "completed" | "failed" | "abandoned";
18
+ type TurnStatus = "running" | "paused" | "completed" | "failed" | "abandoned";
19
19
  export type AgentTurnSurface = "slack" | "api" | "scheduler" | "internal";
20
- export type AgentTurnResumeReason = "timeout" | "auth" | "yield" | "retry";
20
+ export type TurnPauseReason = "timeout" | "auth" | "yield" | "retry";
21
21
  export type AgentDispatchOutcome = "blocked" | "completed" | "failed";
22
- export interface AgentTurnSessionRecord {
22
+ export interface TurnRecord {
23
23
  channelName?: string;
24
+ schemaVersion: 2;
24
25
  version: number;
25
26
  conversationId: string;
26
27
  cumulativeDurationMs: number;
@@ -31,9 +32,6 @@ export interface AgentTurnSessionRecord {
31
32
  resultMessageId?: string;
32
33
  errorMessage?: string;
33
34
  lastProgressAtMs: number;
34
- loadedSkillNames?: string[];
35
- modelId?: string;
36
- reasoningLevel?: string;
37
35
  piMessages: PiMessage[];
38
36
  /** Per-message provenance aligned one-to-one with `piMessages`. */
39
37
  piMessageProvenance: ConversationMessageProvenance[];
@@ -44,37 +42,38 @@ export interface AgentTurnSessionRecord {
44
42
  * replaces the singular execution actor, which is rebuilt at resume.
45
43
  */
46
44
  actors: Actor[];
47
- resumeReason?: AgentTurnResumeReason;
45
+ resumeReason?: TurnPauseReason;
48
46
  resumedFromSliceId?: number;
49
- sessionId: string;
47
+ turnId: string;
50
48
  sliceId: number;
51
49
  startedAtMs: number;
52
- state: AgentTurnSessionStatus;
50
+ state: TurnStatus;
53
51
  surface?: AgentTurnSurface;
54
52
  traceId?: string;
55
53
  turnStartMessageIndex?: number;
56
54
  updatedAtMs: number;
57
55
  }
58
- export interface AgentTurnSessionSummary {
56
+ export interface TurnSummary {
57
+ schemaVersion: 2;
59
58
  conversationId: string;
60
59
  dispatchId?: string;
61
60
  dispatchOutcome?: AgentDispatchOutcome;
62
61
  /** Provider-owned identifier returned after visible delivery is accepted. */
63
62
  resultMessageId?: string;
64
- resumeReason?: AgentTurnResumeReason;
65
- sessionId: string;
63
+ resumeReason?: TurnPauseReason;
64
+ turnId: string;
66
65
  sliceId: number;
67
- state: AgentTurnSessionStatus;
66
+ state: TurnStatus;
68
67
  surface?: AgentTurnSurface;
69
68
  updatedAtMs: number;
70
69
  version: number;
71
70
  }
72
71
  /** Read a turn record pinned to the history version containing its checkpoint. */
73
- export declare function getAgentTurnSessionRecord(conversationId: string, sessionId: string): Promise<AgentTurnSessionRecord | undefined>;
74
- /** Read a turn session for resume, following a newer committed replacement while unfinished. */
75
- export declare function getAgentTurnSessionRecordForResume(conversationId: string, sessionId: string): Promise<AgentTurnSessionRecord | undefined>;
76
- /** Commit stable Pi session state and advance the turn session record. */
77
- export declare function upsertAgentTurnSessionRecord(args: {
72
+ export declare function getTurnRecord(conversationId: string, turnId: string): Promise<TurnRecord | undefined>;
73
+ /** Read a turn cursor for resume, following a newer committed replacement while unfinished. */
74
+ export declare function getTurnRecordForResume(conversationId: string, turnId: string): Promise<TurnRecord | undefined>;
75
+ /** Commit stable Pi state and advance the turn cursor. */
76
+ export declare function upsertTurnRecord(args: {
78
77
  channelName?: string;
79
78
  conversationId: string;
80
79
  cumulativeDurationMs?: number;
@@ -87,28 +86,24 @@ export declare function upsertAgentTurnSessionRecord(args: {
87
86
  destinationVisibility?: ConversationPrivacy;
88
87
  source?: Source;
89
88
  lastProgressAtMs?: number;
90
- loadedSkillNames?: string[];
91
- modelId: string;
92
89
  conversationStore?: ConversationStore;
93
- sessionId: string;
90
+ turnId: string;
94
91
  sliceId: number;
95
- state: AgentTurnSessionStatus;
92
+ state: TurnStatus;
96
93
  surface?: AgentTurnSurface;
97
94
  piMessages: PiMessage[];
98
95
  /** Provenance for trailing newly committed messages, such as steering. */
99
96
  trailingMessageProvenance?: ConversationMessageProvenance[];
100
97
  actor?: Actor;
101
- resumeReason?: AgentTurnResumeReason;
102
- reasoningLevel?: string;
98
+ resumeReason?: TurnPauseReason;
103
99
  errorMessage?: string;
104
100
  resumedFromSliceId?: number;
105
101
  traceId?: string;
106
102
  turnContexts?: PluginTurnContext[];
107
103
  turnStartMessageIndex?: number;
108
104
  ttlMs?: number;
109
- }): Promise<AgentTurnSessionRecord>;
110
- /** Record turn-session metadata without storing conversation messages. */
111
- export declare function recordAgentTurnSessionSummary(args: {
105
+ }): Promise<TurnRecord>;
106
+ type TurnSummaryWrite = {
112
107
  channelName?: string;
113
108
  conversationId: string;
114
109
  cumulativeDurationMs?: number;
@@ -117,36 +112,42 @@ export declare function recordAgentTurnSessionSummary(args: {
117
112
  dispatchId?: string;
118
113
  dispatchOutcome?: AgentDispatchOutcome;
119
114
  resultMessageId?: string;
120
- /** Confirmed destination visibility; omit when unavailable. */
121
115
  destinationVisibility?: ConversationPrivacy;
122
116
  source?: Source;
123
117
  lastProgressAtMs?: number;
124
- loadedSkillNames?: string[];
125
- modelId?: string;
126
118
  conversationStore?: ConversationStore;
127
119
  actor?: Actor;
128
- resumeReason?: AgentTurnResumeReason;
129
- reasoningLevel?: string;
130
- sessionId: string;
120
+ resumeReason?: TurnPauseReason;
121
+ turnId: string;
131
122
  sliceId: number;
132
123
  startedAtMs?: number;
133
- state: AgentTurnSessionStatus;
124
+ state: TurnStatus;
134
125
  surface?: AgentTurnSurface;
135
126
  traceId?: string;
136
127
  ttlMs?: number;
137
- }): Promise<void>;
138
- /** List retained turn-session recovery projections for one conversation. */
139
- export declare function listAgentTurnSessionSummariesForConversation(conversationId: string): Promise<AgentTurnSessionSummary[]>;
140
- /** Mark an unfinished turn session record as abandoned when a newer turn wins. */
141
- export declare function abandonAgentTurnSessionRecord(args: {
128
+ };
129
+ /** Record turn metadata without storing conversation messages. */
130
+ export declare function recordTurnSummary(args: TurnSummaryWrite): Promise<void>;
131
+ /** List retained turn recovery projections for one conversation. */
132
+ export declare function listTurnSummaries(conversationId: string): Promise<TurnSummary[]>;
133
+ /** Mark an unfinished turn cursor as abandoned when a newer turn wins. */
134
+ export declare function abandonTurnRecord(args: {
142
135
  conversationId: string;
143
- sessionId: string;
136
+ turnId: string;
144
137
  errorMessage?: string;
145
- }): Promise<AgentTurnSessionRecord | undefined>;
146
- /** Mark an unfinished turn session record as failed so it cannot resume. */
147
- export declare function failAgentTurnSessionRecord(args: {
138
+ }): Promise<TurnRecord | undefined>;
139
+ /** Mark an unfinished turn cursor as completed after delivery was accepted. */
140
+ export declare function completeTurnRecord(args: {
141
+ conversationId: string;
142
+ expectedVersion: number;
143
+ resultMessageId?: string;
144
+ turnId: string;
145
+ }): Promise<TurnRecord | undefined>;
146
+ /** Mark an unfinished turn cursor as failed so it cannot resume. */
147
+ export declare function failTurnRecord(args: {
148
148
  conversationId: string;
149
149
  expectedVersion: number;
150
- sessionId: string;
150
+ turnId: string;
151
151
  errorMessage?: string;
152
- }): Promise<AgentTurnSessionRecord | undefined>;
152
+ }): Promise<TurnRecord | undefined>;
153
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Continue a paused turn via the conversation work queue.
3
+ *
4
+ * Wake-only: mailbox/lease own liveness; this just nudges the worker.
5
+ */
6
+ import type { StateAdapter } from "chat";
7
+ import type { Destination } from "@sentry/junior-plugin-api";
8
+ import type { ConversationStore } from "@/chat/conversations/store";
9
+ import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
10
+ export interface PausedTurnRequest {
11
+ conversationId: string;
12
+ destination: Destination;
13
+ expectedVersion: number;
14
+ turnId: string;
15
+ }
16
+ interface TurnWakeOptions {
17
+ nowMs?: number;
18
+ queue?: ConversationWorkQueue;
19
+ state?: StateAdapter;
20
+ }
21
+ /** Build the worker input for a paused turn. */
22
+ export declare function getPausedTurnRequest(args: {
23
+ conversationId: string;
24
+ conversationStore?: ConversationStore;
25
+ turnId: string;
26
+ }): Promise<PausedTurnRequest | undefined>;
27
+ /** Wake the conversation worker for a paused turn. */
28
+ export declare function wakePausedTurn(request: PausedTurnRequest, options?: TurnWakeOptions): Promise<void>;
29
+ export {};
@@ -1,11 +1,11 @@
1
1
  import { type KnownConversationEventType } from "@/chat/conversations/history";
2
2
  import type { ToolRuntimeContext } from "@/chat/tools/types";
3
- /** Create a deferred tool that returns a bounded conversation event page. */
4
- export declare function createQueryConversationEventsTool(context: ToolRuntimeContext): Omit<import("./definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
3
+ /** Create a deferred tool that searches one conversation's durable event log. */
4
+ export declare function createSearchConversationEventsTool(context: ToolRuntimeContext): Omit<import("./definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
5
5
  inputSchema: import("./definition").JsonSchemaObject;
6
6
  outputSchema: import("./definition").JsonSchemaObject;
7
7
  prepareArguments(args: unknown): {
8
- conversation_id: string;
8
+ conversation_id?: string | null | undefined;
9
9
  after_seq?: number | null | undefined;
10
10
  before_seq?: number | null | undefined;
11
11
  limit?: number | null | undefined;
@@ -2,7 +2,7 @@ import type { FileUpload } from "chat";
2
2
  import type { Destination, Identity, LocalDestination, LocalSource, PluginEgress, SlackDestination, SlackSource, Source, User } 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
+ import type { AgentTurnSurface } from "@/chat/task-execution/checkpoint";
6
6
  import type { ThreadArtifactsState } from "@/chat/state/artifacts";
7
7
  import type { Skill } from "@/chat/skills";
8
8
  import type { LoadSkillMetadata } from "@/chat/tools/skill/load-skill";
@@ -5,12 +5,12 @@ import {
5
5
  juniorConversations,
6
6
  juniorIdentities,
7
7
  juniorUsers
8
- } from "./chunk-HNO2E5WB.js";
8
+ } from "./chunk-MCFIXAV5.js";
9
9
  import {
10
10
  TURN_REASONING_LEVELS,
11
11
  getChatConfig,
12
12
  modelProfileSchema
13
- } from "./chunk-3GU4PWA3.js";
13
+ } from "./chunk-MKRIZ4VG.js";
14
14
  import {
15
15
  juniorDestinations
16
16
  } from "./chunk-VFUK3X5B.js";
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-F3B2YJ76.js";
21
21
  import {
22
22
  normalizeIdentityEmail
23
- } from "./chunk-RIFJUJSI.js";
23
+ } from "./chunk-B63BF443.js";
24
24
 
25
25
  // src/chat/conversations/sql/store.ts
26
26
  import { randomUUID as randomUUID2 } from "crypto";
@@ -376,16 +376,17 @@ function destinationUpsertFromDestination(args) {
376
376
  };
377
377
  }
378
378
  function executionStatusFromValue(value) {
379
- if (value === "awaiting_resume" || value === "failed" || value === "idle" || value === "pending" || value === "running") {
379
+ if (value === "awaiting_resume" || value === "paused") return "paused";
380
+ if (value === "failed" || value === "idle" || value === "pending" || value === "running") {
380
381
  return value;
381
382
  }
382
383
  throw new Error("Conversation record execution status is invalid");
383
384
  }
385
+ function executionStatusToSql(status) {
386
+ return status === "paused" ? "awaiting_resume" : status;
387
+ }
384
388
  function actorFromIdentityRow(identity, userDisplayName) {
385
- if (!identity) {
386
- return void 0;
387
- }
388
- if (identity.provider !== "slack") {
389
+ if (!identity || identity.provider !== "slack") {
389
390
  return void 0;
390
391
  }
391
392
  const fullName = userDisplayName?.trim() ? userDisplayName : identity.displayName;
@@ -816,7 +817,7 @@ var SqlStore = class {
816
817
  lastActivityAt: dateFromMs2(conversation.lastActivityAtMs),
817
818
  updatedAt: dateFromMs2(conversation.updatedAtMs),
818
819
  executionUpdatedAt: conversation.execution.updatedAtMs === void 0 ? null : dateFromMs2(conversation.execution.updatedAtMs),
819
- executionStatus: conversation.execution.status,
820
+ executionStatus: executionStatusToSql(conversation.execution.status),
820
821
  runId: conversation.execution.runId ?? null,
821
822
  lastCheckpointAt: conversation.execution.lastCheckpointAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastCheckpointAtMs),
822
823
  lastEnqueuedAt: conversation.execution.lastEnqueuedAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastEnqueuedAtMs),
@@ -1600,22 +1601,44 @@ function createSqlConversationEventStore(executor) {
1600
1601
  return new SqlConversationEventStore(executor);
1601
1602
  }
1602
1603
 
1603
- // src/chat/conversations/sql/search.ts
1604
+ // src/chat/conversations/sql/message-search.ts
1604
1605
  import { and as and5, desc as desc3, eq as eq5, isNull as isNull2, ne, sql as sql5 } from "drizzle-orm";
1605
- var SqlConversationSearchStore = class {
1606
+ var EXCERPT_WITHOUT_QUERY_CHARS = 240;
1607
+ var SqlConversationMessageSearchStore = class {
1606
1608
  constructor(executor) {
1607
1609
  this.executor = executor;
1608
1610
  }
1609
1611
  executor;
1610
1612
  async search(args) {
1611
1613
  const db = this.executor.db();
1612
- const tsquery = sql5`websearch_to_tsquery('english', ${args.query})`;
1614
+ const query = args.filters.query?.trim() || void 0;
1613
1615
  const text = sql5`${juniorConversationEvents.payload}->>'text'`;
1614
- const rank = sql5`ts_rank_cd(to_tsvector('english', ${text}), ${tsquery})`;
1615
- const excerpt = sql5`ts_headline('english', ${text}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')`;
1616
1616
  const role = sql5`${juniorConversationEvents.payload}->>'role'`;
1617
1617
  const messageId = sql5`${juniorConversationEvents.payload}->>'messageId'`;
1618
+ const tsquery = query ? sql5`websearch_to_tsquery('english', ${query})` : void 0;
1619
+ const rank = tsquery ? sql5`ts_rank_cd(to_tsvector('english', ${text}), ${tsquery})` : sql5`1`;
1620
+ const excerpt = tsquery ? sql5`ts_headline('english', ${text}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')` : sql5`left(${text}, ${EXCERPT_WITHOUT_QUERY_CHARS})`;
1621
+ const conditions = [
1622
+ eq5(juniorConversations.source, "slack"),
1623
+ isNull2(juniorConversations.parentConversationId),
1624
+ isNull2(juniorConversations.transcriptPurgedAt),
1625
+ ne(juniorConversations.conversationId, args.currentConversationId),
1626
+ eq5(juniorDestinations.provider, args.scope.provider),
1627
+ eq5(juniorDestinations.providerTenantId, args.scope.providerTenantId),
1628
+ eq5(juniorDestinations.visibility, "public"),
1629
+ eq5(juniorConversationEvents.type, "message"),
1630
+ sql5`${role} in ('user', 'assistant')`
1631
+ ];
1632
+ if (tsquery) {
1633
+ conditions.push(sql5`to_tsvector('english', ${text}) @@ ${tsquery}`);
1634
+ }
1635
+ if (args.filters.channelId) {
1636
+ conditions.push(
1637
+ eq5(juniorDestinations.providerDestinationId, args.filters.channelId)
1638
+ );
1639
+ }
1618
1640
  const bestPerConversation = db.selectDistinctOn([juniorConversations.conversationId], {
1641
+ channelName: juniorDestinations.displayName,
1619
1642
  conversationId: juniorConversations.conversationId,
1620
1643
  excerpt: excerpt.as("excerpt"),
1621
1644
  lastActivityAt: juniorConversations.lastActivityAt,
@@ -1633,27 +1656,15 @@ var SqlConversationSearchStore = class {
1633
1656
  ).innerJoin(
1634
1657
  juniorDestinations,
1635
1658
  eq5(juniorDestinations.id, juniorConversations.destinationId)
1636
- ).where(
1637
- and5(
1638
- eq5(juniorConversations.source, "slack"),
1639
- isNull2(juniorConversations.parentConversationId),
1640
- isNull2(juniorConversations.transcriptPurgedAt),
1641
- ne(juniorConversations.conversationId, args.currentConversationId),
1642
- eq5(juniorDestinations.provider, args.scope.provider),
1643
- eq5(juniorDestinations.providerTenantId, args.scope.providerTenantId),
1644
- eq5(juniorDestinations.visibility, "public"),
1645
- eq5(juniorConversationEvents.type, "message"),
1646
- sql5`${role} in ('user', 'assistant')`,
1647
- sql5`to_tsvector('english', ${text}) @@ ${tsquery}`
1648
- )
1649
- ).orderBy(
1659
+ ).where(and5(...conditions)).orderBy(
1650
1660
  juniorConversations.conversationId,
1651
1661
  desc3(rank),
1652
1662
  desc3(juniorConversationEvents.createdAt)
1653
1663
  ).as("best_conversation_matches");
1654
1664
  const rows = await db.select().from(bestPerConversation).orderBy(
1655
1665
  desc3(bestPerConversation.rank),
1656
- desc3(bestPerConversation.lastActivityAt)
1666
+ desc3(bestPerConversation.lastActivityAt),
1667
+ desc3(bestPerConversation.messageCreatedAt)
1657
1668
  ).limit(args.limit);
1658
1669
  return rows.map((row) => ({
1659
1670
  conversationId: row.conversationId,
@@ -1661,12 +1672,13 @@ var SqlConversationSearchStore = class {
1661
1672
  messageCreatedAtMs: row.messageCreatedAt.getTime(),
1662
1673
  messageId: row.messageId,
1663
1674
  providerDestinationId: row.providerDestinationId,
1664
- role: row.role
1675
+ role: row.role,
1676
+ ...row.channelName ? { channelName: row.channelName } : {}
1665
1677
  }));
1666
1678
  }
1667
1679
  };
1668
- function createSqlConversationSearchStore(executor) {
1669
- return new SqlConversationSearchStore(executor);
1680
+ function createSqlConversationMessageSearchStore(executor) {
1681
+ return new SqlConversationMessageSearchStore(executor);
1670
1682
  }
1671
1683
 
1672
1684
  // src/chat/db.ts
@@ -1698,7 +1710,7 @@ function getSqlExecutor() {
1698
1710
  db,
1699
1711
  store: createSqlStore(db),
1700
1712
  eventStore: createSqlConversationEventStore(db),
1701
- searchStore: createSqlConversationSearchStore(db)
1713
+ searchStore: createSqlConversationMessageSearchStore(db)
1702
1714
  };
1703
1715
  }
1704
1716
  return current.db;
@@ -1714,7 +1726,7 @@ function getConversationEventStore() {
1714
1726
  getSqlExecutor();
1715
1727
  return current.eventStore;
1716
1728
  }
1717
- function getConversationSearchStore() {
1729
+ function getConversationMessageSearchStore() {
1718
1730
  getSqlExecutor();
1719
1731
  return current.searchStore;
1720
1732
  }
@@ -1729,6 +1741,7 @@ export {
1729
1741
  parseDestination,
1730
1742
  requireSlackDestination,
1731
1743
  sameDestination,
1744
+ upsertIdentity,
1732
1745
  parseSessionSource,
1733
1746
  bindProviderConversation,
1734
1747
  locationFromRow,
@@ -1747,6 +1760,6 @@ export {
1747
1760
  getDb,
1748
1761
  getConversationStore,
1749
1762
  getConversationEventStore,
1750
- getConversationSearchStore,
1763
+ getConversationMessageSearchStore,
1751
1764
  closeDb
1752
1765
  };
@@ -5,7 +5,7 @@ import {
5
5
  logInfo,
6
6
  logWarn,
7
7
  setSpanAttributes
8
- } from "./chunk-RIFJUJSI.js";
8
+ } from "./chunk-B63BF443.js";
9
9
  import {
10
10
  discoverInstalledPluginPackageContent,
11
11
  normalizePluginPackageNames
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  resolveBaseUrl
3
- } from "./chunk-KQBXT5B7.js";
3
+ } from "./chunk-ZDGHGY74.js";
4
4
  import {
5
5
  createPluginLogger,
6
6
  getPlugins
7
- } from "./chunk-44RJWAND.js";
7
+ } from "./chunk-SCGVWUZX.js";
8
8
  import {
9
9
  getDb,
10
10
  parseDestination
11
- } from "./chunk-SBZP2J5Q.js";
11
+ } from "./chunk-37EVZP66.js";
12
12
  import {
13
13
  sleep
14
14
  } from "./chunk-EM225ITJ.js";
15
15
  import {
16
16
  acquireActiveLock,
17
17
  getStateAdapter
18
- } from "./chunk-UDQMY6RS.js";
18
+ } from "./chunk-GYEKOX7N.js";
19
19
  import {
20
20
  pluginCatalogRuntime
21
- } from "./chunk-ZF3N3JD6.js";
21
+ } from "./chunk-PB222GIA.js";
22
22
  import {
23
23
  fetchWithBoundedOAuthErrorBodies
24
- } from "./chunk-A67GZN73.js";
24
+ } from "./chunk-37JJDS4H.js";
25
25
  import {
26
26
  isRecord
27
- } from "./chunk-RIFJUJSI.js";
27
+ } from "./chunk-B63BF443.js";
28
28
 
29
29
  // src/chat/capabilities/router.ts
30
30
  var ProviderCredentialRouter = class {