@sentry/junior 0.143.0 → 0.145.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 (100) hide show
  1. package/dist/{agent-hooks-2EP3QS47.js → agent-hooks-L7D2BDVV.js} +10 -10
  2. package/dist/api/conversations/detail.d.ts +9 -0
  3. package/dist/api/schema/conversation.d.ts +20 -0
  4. package/dist/api/schema/task.d.ts +40 -1
  5. package/dist/api/schema.d.ts +3 -3
  6. package/dist/api/schema.js +5 -1
  7. package/dist/api.js +2250 -2172
  8. package/dist/app.js +335 -409
  9. package/dist/{catalog-runtime-IAVW4W3B.js → catalog-runtime-QLAC4Q3W.js} +5 -5
  10. package/dist/chat/agent/request.d.ts +1 -1
  11. package/dist/chat/agent/resume.d.ts +6 -15
  12. package/dist/chat/agent/tools.d.ts +1 -1
  13. package/dist/chat/agent-dispatch/types.d.ts +1 -1
  14. package/dist/chat/app/conversation-work.d.ts +24 -0
  15. package/dist/chat/conversations/projection.d.ts +11 -3
  16. package/dist/chat/conversations/store.d.ts +1 -1
  17. package/dist/chat/runtime/agent-run-outcome.d.ts +1 -1
  18. package/dist/chat/runtime/reply-executor.d.ts +5 -5
  19. package/dist/chat/runtime/slack-resume.d.ts +12 -4
  20. package/dist/chat/scheduled-tasks/store.d.ts +1 -0
  21. package/dist/chat/scheduled-tasks/tool-support.d.ts +26 -1
  22. package/dist/chat/scheduled-tasks/tools/create.d.ts +10 -0
  23. package/dist/chat/scheduled-tasks/tools/delete.d.ts +10 -0
  24. package/dist/chat/scheduled-tasks/tools/list.d.ts +15 -2
  25. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +10 -0
  26. package/dist/chat/scheduled-tasks/tools/update.d.ts +12 -1
  27. package/dist/chat/services/guardian-action-policy.d.ts +1 -1
  28. package/dist/chat/state/locks.d.ts +28 -0
  29. package/dist/chat/task-execution/checkpoint.d.ts +86 -0
  30. package/dist/chat/task-execution/paused-turn.d.ts +29 -0
  31. package/dist/chat/task-execution/queue-signing.d.ts +1 -0
  32. package/dist/chat/task-execution/queue.d.ts +7 -1
  33. package/dist/chat/task-execution/slack-work.d.ts +1 -1
  34. package/dist/chat/task-execution/state.d.ts +4 -4
  35. package/dist/chat/task-execution/store.d.ts +2 -2
  36. package/dist/chat/task-execution/turn-cursor-keys.d.ts +6 -0
  37. package/dist/chat/{state/turn-session.d.ts → task-execution/turn-cursor.d.ts} +52 -42
  38. package/dist/chat/task-execution/turn-wake.d.ts +29 -0
  39. package/dist/chat/tasks/execution-stats.d.ts +21 -0
  40. package/dist/chat/tasks/read.d.ts +9 -1
  41. package/dist/chat/tools/types.d.ts +1 -1
  42. package/dist/{chunk-2KLMGRRQ.js → chunk-27TEJTZO.js} +1 -1
  43. package/dist/{chunk-GZRWULXF.js → chunk-2LWPFSB4.js} +1 -1
  44. package/dist/{chunk-NAINBOZQ.js → chunk-2UH3JI64.js} +10 -9
  45. package/dist/{chunk-QFWXGUAH.js → chunk-2XET6PKP.js} +93 -89
  46. package/dist/{chunk-U5ATCOHE.js → chunk-5PNPQYTO.js} +2 -2
  47. package/dist/{chunk-XYJNNZYR.js → chunk-64SBYW2O.js} +397 -288
  48. package/dist/{chunk-F6RWNJBK.js → chunk-B46ZMVOV.js} +5 -5
  49. package/dist/{chunk-BJ6ISBOA.js → chunk-CD2XFGYQ.js} +1 -1
  50. package/dist/{chunk-WSWVWP2V.js → chunk-DS3J6WGY.js} +1 -1
  51. package/dist/{chunk-OG5JQHKR.js → chunk-DXEQAIUV.js} +1 -1
  52. package/dist/{chunk-A3XPSABC.js → chunk-EIX2LQ6L.js} +82 -4
  53. package/dist/{chunk-ANG7IWAI.js → chunk-FUBRJA5F.js} +6 -6
  54. package/dist/{chunk-OB7ZJK7Y.js → chunk-GDV5LXRA.js} +1 -1
  55. package/dist/{chunk-AEFJN7OK.js → chunk-GUWLDMGF.js} +4 -4
  56. package/dist/{chunk-I4NQNZVW.js → chunk-HISR3DTV.js} +33 -61
  57. package/dist/{chunk-WM4PRM7W.js → chunk-HLOUZC5C.js} +32 -34
  58. package/dist/{chunk-RABHACKG.js → chunk-I47UGQPJ.js} +7 -7
  59. package/dist/{chunk-IUFM5JWV.js → chunk-JAL3CH4G.js} +3 -0
  60. package/dist/{chunk-OGQGJAD7.js → chunk-JLMVCNXL.js} +26 -1
  61. package/dist/{chunk-5YJBS4I5.js → chunk-JTGS3ZZE.js} +1 -1
  62. package/dist/{chunk-LSBQHDI2.js → chunk-LVVSIMBB.js} +1 -1
  63. package/dist/{chunk-2T5CHXRZ.js → chunk-PJ4NMVQB.js} +2 -2
  64. package/dist/{chunk-I5PIM72M.js → chunk-QJBDABQA.js} +14 -17
  65. package/dist/{chunk-M2T7MHQJ.js → chunk-QUG4JSZK.js} +43 -1
  66. package/dist/{chunk-X5SC2UGE.js → chunk-RUSS62EN.js} +14 -14
  67. package/dist/{chunk-NVFVM67W.js → chunk-SIN3MXH6.js} +1 -1
  68. package/dist/{chunk-I25V3XRN.js → chunk-TZRXYWRE.js} +2 -2
  69. package/dist/{chunk-WJHWOAVZ.js → chunk-VTDMB7XX.js} +1 -1
  70. package/dist/{chunk-TPJK6AVJ.js → chunk-WF5HVH3M.js} +1 -1
  71. package/dist/{chunk-KCBZSJRU.js → chunk-WR76IVA5.js} +5 -2
  72. package/dist/{chunk-7GVX5SOG.js → chunk-XFKIRN3Q.js} +29 -29
  73. package/dist/{chunk-UFCA4EZB.js → chunk-YD54Q45G.js} +4 -4
  74. package/dist/{chunk-PBV7VXUA.js → chunk-ZIAMN2UW.js} +407 -523
  75. package/dist/{chunk-SNBTWIQO.js → chunk-ZIMRGFYL.js} +6 -6
  76. package/dist/{chunk-STX5WIH6.js → chunk-ZYAJMESY.js} +2 -2
  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-RBXBVEVO.js → db-62PW6LM3.js} +7 -7
  83. package/dist/instrumentation.js +4 -4
  84. package/dist/nitro.js +4 -4
  85. package/dist/{oauth-callback-server-LRB6BX6C.js → oauth-callback-server-6NZNHJAM.js} +25 -25
  86. package/dist/{runner-WK5VUOW6.js → runner-GCRPG3GQ.js} +19 -18
  87. package/dist/{skills-MJWRME3A.js → skills-2S3MDFIQ.js} +6 -6
  88. package/dist/spawn-7WK37BTD.js +39 -0
  89. package/dist/{validation-556WSWVU.js → validation-HAOLCJ5A.js} +6 -6
  90. package/dist/version.js +1 -1
  91. package/dist/{work-W6IXSPY3.js → work-R4XYKMUW.js} +17 -16
  92. package/dist/worker-U2UCVR7M.js +24 -0
  93. package/package.json +5 -5
  94. package/dist/chat/agent/session.d.ts +0 -19
  95. package/dist/chat/runtime/agent-continue-runner.d.ts +0 -37
  96. package/dist/chat/services/agent-continue.d.ts +0 -29
  97. package/dist/chat/services/turn-session-record.d.ts +0 -164
  98. package/dist/chat/state/turn-session-keys.d.ts +0 -6
  99. package/dist/spawn-ZCW6UOAA.js +0 -38
  100. package/dist/worker-5KM346HH.js +0 -24
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Turn checkpoint — public resume cursor for one turn.
3
+ *
4
+ * Part of conversation execution with mailbox + lease + worker.
5
+ * History is SQL (`commitMessages`). This module is the only external gate
6
+ * for turn cursor storage (`turn-cursor.ts` is internal).
7
+ *
8
+ * Public API:
9
+ * - `loadTurnCheckpoint({ conversationId, turnId })`
10
+ * - `saveTurnCheckpoint({ mode, conversationId, turnId, messages, ... })`
11
+ * - fail / abandon / summary helpers for terminal and recovery edges
12
+ */
13
+ import type { ConversationPrivacy } from "@/chat/conversation-privacy";
14
+ import type { Destination, Actor, Source } from "@sentry/junior-plugin-api";
15
+ import type { PiMessage } from "@/chat/pi/messages";
16
+ import type { ConversationMessageProvenance } from "@/chat/conversations/provenance";
17
+ import { type AgentTurnUsage } from "@/chat/usage";
18
+ import type { PluginTurnContext } from "@/chat/plugins/prompt";
19
+ import { abandonTurnRecord, failTurnRecord, getTurnRecord, listTurnSummaries, recordTurnSummary, type AgentDispatchOutcome, type TurnPauseReason, type TurnRecord, type TurnSummary, type AgentTurnSurface } from "./turn-cursor";
20
+ export type { AgentDispatchOutcome, TurnRecord, TurnSummary, AgentTurnSurface };
21
+ export { abandonTurnRecord, failTurnRecord, getTurnRecord, listTurnSummaries, recordTurnSummary, };
22
+ /** Loaded resume cursor. A resumed checkpoint always has its record. */
23
+ export type TurnCheckpoint = {
24
+ resumed: true;
25
+ sliceId: number;
26
+ record: TurnRecord;
27
+ } | {
28
+ resumed: false;
29
+ sliceId: 1;
30
+ record?: TurnRecord;
31
+ };
32
+ /**
33
+ * Lifecycle fields for a checkpoint write.
34
+ * Routing/metrics/provenance are only for SQL dual-write / resume restore.
35
+ */
36
+ interface TurnCheckpointWrite {
37
+ conversationId: string;
38
+ turnId: string;
39
+ messages: PiMessage[];
40
+ modelId: string;
41
+ /** Required for running/paused; optional for completed/failed (falls back to stored). */
42
+ sliceId?: number;
43
+ actor?: Actor;
44
+ channelName?: string;
45
+ destination?: Destination;
46
+ destinationVisibility?: ConversationPrivacy;
47
+ dispatchId?: string;
48
+ dispatchOutcome?: AgentDispatchOutcome;
49
+ source?: Source;
50
+ surface?: AgentTurnSurface;
51
+ loadedSkillNames?: string[];
52
+ reasoningLevel?: string;
53
+ turnStartMessageIndex?: number;
54
+ trailingMessageProvenance?: ConversationMessageProvenance[];
55
+ turnContexts?: PluginTurnContext[];
56
+ durationMs?: number;
57
+ usage?: AgentTurnUsage;
58
+ errorMessage?: string;
59
+ resultMessageId?: string;
60
+ }
61
+ type ProgressCheckpointArgs = (TurnCheckpointWrite & {
62
+ mode: "running";
63
+ sliceId: number;
64
+ }) | (TurnCheckpointWrite & {
65
+ mode: "paused";
66
+ reason: TurnPauseReason;
67
+ sliceId: number;
68
+ });
69
+ type TerminalCheckpointArgs = TurnCheckpointWrite & {
70
+ mode: "completed" | "failed";
71
+ };
72
+ /** Boundary safe to continue after auth/timeout (trim mid-assistant). */
73
+ export declare function continuableMessages(messages: PiMessage[], fallback?: PiMessage[]): PiMessage[];
74
+ /** Load resume cursor for one turn. */
75
+ export declare function loadTurnCheckpoint(args: {
76
+ conversationId: string;
77
+ turnId: string;
78
+ }): Promise<TurnCheckpoint>;
79
+ /**
80
+ * Save turn progress.
81
+ *
82
+ * - `running` / `paused`: best-effort; returns the stored record or undefined
83
+ * - `completed` / `failed`: retries until write accepts; throws on hard failure
84
+ */
85
+ export declare function saveTurnCheckpoint(args: ProgressCheckpointArgs): Promise<TurnRecord | undefined>;
86
+ export declare function saveTurnCheckpoint(args: TerminalCheckpointArgs): Promise<void>;
@@ -0,0 +1,29 @@
1
+ import { resumeSlackTurn } from "@/chat/runtime/slack-resume";
2
+ import { type PausedTurnRequest } from "@/chat/task-execution/turn-wake";
3
+ import type { AgentRunner } from "@/chat/runtime/agent-runner";
4
+ import type { AgentRunRouting } from "@/chat/agent/request";
5
+ /** Runtime ports for paused turn scheduling. */
6
+ export interface PausedTurnOptions {
7
+ agentRunner: AgentRunner;
8
+ /** Exact persisted input ids accepted while running the paused turn. */
9
+ inputMessageIds?: readonly string[];
10
+ routingContext?: Pick<AgentRunRouting, "actor" | "credentialContext" | "destinationVisibility" | "dispatch" | "surface">;
11
+ resumeTurn?: typeof resumeSlackTurn;
12
+ wakePausedTurn?: (request: PausedTurnRequest) => Promise<void>;
13
+ scheduleSessionCompletedPluginTasks?: (params: {
14
+ conversationId: string;
15
+ sessionId: string;
16
+ }) => Promise<void>;
17
+ }
18
+ /** Per-worker controls for one paused turn. */
19
+ export interface PausedTurnRunOptions {
20
+ shouldYield?: () => boolean;
21
+ }
22
+ /**
23
+ * Continue one paused Slack agent run from durable conversation state.
24
+ *
25
+ * Returns false when the session became stale before generation began.
26
+ */
27
+ export declare function runPausedTurn(payload: PausedTurnRequest, options: PausedTurnOptions, runOptions?: PausedTurnRunOptions): Promise<boolean>;
28
+ /** Resume the first valid paused Slack session for an idle conversation. */
29
+ export declare function runNextPausedTurn(conversationId: string, options: PausedTurnOptions, runOptions?: PausedTurnRunOptions): Promise<boolean>;
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { type ConversationQueueMessage } from "./queue";
3
3
  export declare const CONVERSATION_WORK_QUEUE_SIGNATURE_MAX_SKEW_MS: number;
4
4
  declare const signedConversationQueueMessageSchema: z.ZodObject<{
5
+ schemaVersion: z.ZodLiteral<2>;
5
6
  conversationId: z.ZodString;
6
7
  signature: z.ZodString;
7
8
  signatureVersion: z.ZodLiteral<"v2">;
@@ -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;
@@ -44,37 +45,38 @@ export interface AgentTurnSessionRecord {
44
45
  * replaces the singular execution actor, which is rebuilt at resume.
45
46
  */
46
47
  actors: Actor[];
47
- resumeReason?: AgentTurnResumeReason;
48
+ resumeReason?: TurnPauseReason;
48
49
  resumedFromSliceId?: number;
49
- sessionId: string;
50
+ turnId: string;
50
51
  sliceId: number;
51
52
  startedAtMs: number;
52
- state: AgentTurnSessionStatus;
53
+ state: TurnStatus;
53
54
  surface?: AgentTurnSurface;
54
55
  traceId?: string;
55
56
  turnStartMessageIndex?: number;
56
57
  updatedAtMs: number;
57
58
  }
58
- export interface AgentTurnSessionSummary {
59
+ export interface TurnSummary {
60
+ schemaVersion: 2;
59
61
  conversationId: string;
60
62
  dispatchId?: string;
61
63
  dispatchOutcome?: AgentDispatchOutcome;
62
64
  /** Provider-owned identifier returned after visible delivery is accepted. */
63
65
  resultMessageId?: string;
64
- resumeReason?: AgentTurnResumeReason;
65
- sessionId: string;
66
+ resumeReason?: TurnPauseReason;
67
+ turnId: string;
66
68
  sliceId: number;
67
- state: AgentTurnSessionStatus;
69
+ state: TurnStatus;
68
70
  surface?: AgentTurnSurface;
69
71
  updatedAtMs: number;
70
72
  version: number;
71
73
  }
72
74
  /** 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: {
75
+ export declare function getTurnRecord(conversationId: string, turnId: string): Promise<TurnRecord | undefined>;
76
+ /** Read a turn cursor for resume, following a newer committed replacement while unfinished. */
77
+ export declare function getTurnRecordForResume(conversationId: string, turnId: string): Promise<TurnRecord | undefined>;
78
+ /** Commit stable Pi state and advance the turn cursor. */
79
+ export declare function upsertTurnRecord(args: {
78
80
  channelName?: string;
79
81
  conversationId: string;
80
82
  cumulativeDurationMs?: number;
@@ -90,15 +92,15 @@ export declare function upsertAgentTurnSessionRecord(args: {
90
92
  loadedSkillNames?: string[];
91
93
  modelId: string;
92
94
  conversationStore?: ConversationStore;
93
- sessionId: string;
95
+ turnId: string;
94
96
  sliceId: number;
95
- state: AgentTurnSessionStatus;
97
+ state: TurnStatus;
96
98
  surface?: AgentTurnSurface;
97
99
  piMessages: PiMessage[];
98
100
  /** Provenance for trailing newly committed messages, such as steering. */
99
101
  trailingMessageProvenance?: ConversationMessageProvenance[];
100
102
  actor?: Actor;
101
- resumeReason?: AgentTurnResumeReason;
103
+ resumeReason?: TurnPauseReason;
102
104
  reasoningLevel?: string;
103
105
  errorMessage?: string;
104
106
  resumedFromSliceId?: number;
@@ -106,9 +108,8 @@ export declare function upsertAgentTurnSessionRecord(args: {
106
108
  turnContexts?: PluginTurnContext[];
107
109
  turnStartMessageIndex?: number;
108
110
  ttlMs?: number;
109
- }): Promise<AgentTurnSessionRecord>;
110
- /** Record turn-session metadata without storing conversation messages. */
111
- export declare function recordAgentTurnSessionSummary(args: {
111
+ }): Promise<TurnRecord>;
112
+ type TurnSummaryWrite = {
112
113
  channelName?: string;
113
114
  conversationId: string;
114
115
  cumulativeDurationMs?: number;
@@ -117,7 +118,6 @@ export declare function recordAgentTurnSessionSummary(args: {
117
118
  dispatchId?: string;
118
119
  dispatchOutcome?: AgentDispatchOutcome;
119
120
  resultMessageId?: string;
120
- /** Confirmed destination visibility; omit when unavailable. */
121
121
  destinationVisibility?: ConversationPrivacy;
122
122
  source?: Source;
123
123
  lastProgressAtMs?: number;
@@ -125,28 +125,38 @@ export declare function recordAgentTurnSessionSummary(args: {
125
125
  modelId?: string;
126
126
  conversationStore?: ConversationStore;
127
127
  actor?: Actor;
128
- resumeReason?: AgentTurnResumeReason;
128
+ resumeReason?: TurnPauseReason;
129
129
  reasoningLevel?: string;
130
- sessionId: string;
130
+ turnId: string;
131
131
  sliceId: number;
132
132
  startedAtMs?: number;
133
- state: AgentTurnSessionStatus;
133
+ state: TurnStatus;
134
134
  surface?: AgentTurnSurface;
135
135
  traceId?: string;
136
136
  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: {
137
+ };
138
+ /** Record turn metadata without storing conversation messages. */
139
+ export declare function recordTurnSummary(args: TurnSummaryWrite): Promise<void>;
140
+ /** List retained turn recovery projections for one conversation. */
141
+ export declare function listTurnSummaries(conversationId: string): Promise<TurnSummary[]>;
142
+ /** Mark an unfinished turn cursor as abandoned when a newer turn wins. */
143
+ export declare function abandonTurnRecord(args: {
142
144
  conversationId: string;
143
- sessionId: string;
145
+ turnId: string;
144
146
  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: {
147
+ }): Promise<TurnRecord | undefined>;
148
+ /** Mark an unfinished turn cursor as completed after delivery was accepted. */
149
+ export declare function completeTurnRecord(args: {
150
+ conversationId: string;
151
+ expectedVersion: number;
152
+ resultMessageId?: string;
153
+ turnId: string;
154
+ }): Promise<TurnRecord | undefined>;
155
+ /** Mark an unfinished turn cursor as failed so it cannot resume. */
156
+ export declare function failTurnRecord(args: {
148
157
  conversationId: string;
149
158
  expectedVersion: number;
150
- sessionId: string;
159
+ turnId: string;
151
160
  errorMessage?: string;
152
- }): Promise<AgentTurnSessionRecord | undefined>;
161
+ }): Promise<TurnRecord | undefined>;
162
+ 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 {};
@@ -20,6 +20,10 @@ export type TaskExecutionRecord = {
20
20
  status: TaskExecutionStatus;
21
21
  title?: string;
22
22
  };
23
+ export type TaskRunRecord = TaskExecutionRecord & {
24
+ kind: TaskExecutionType;
25
+ taskId: string;
26
+ };
23
27
  export type TaskExecutionStatusDay = {
24
28
  blocked: number;
25
29
  completed: number;
@@ -42,6 +46,14 @@ export declare function readTaskExecutionSummaries(type: TaskExecutionType, name
42
46
  export declare function readTaskExecutionDays(dayCount?: number, options?: {
43
47
  nowMs?: number;
44
48
  }): Promise<TaskExecutionDay[]>;
49
+ /** Load the newest terminal task execution linked to one conversation, if any. */
50
+ export declare function readTaskExecutionByConversationId(args: {
51
+ conversationId: string;
52
+ namespace?: string;
53
+ }): Promise<{
54
+ kind: TaskExecutionType;
55
+ taskId: string;
56
+ } | undefined>;
45
57
  /** Load newest-first executions for one task, with conversation titles when present. */
46
58
  export declare function readTaskExecutions(args: {
47
59
  kind: TaskExecutionType;
@@ -49,6 +61,15 @@ export declare function readTaskExecutions(args: {
49
61
  namespace?: string;
50
62
  taskId: string;
51
63
  }): Promise<TaskExecutionRecord[]>;
64
+ /** Load newest-first executions for the supplied viewer-visible tasks. */
65
+ export declare function readTaskRuns(args: {
66
+ limit: number;
67
+ namespace?: string;
68
+ tasks: Array<{
69
+ kind: TaskExecutionType;
70
+ taskId: string;
71
+ }>;
72
+ }): Promise<TaskRunRecord[]>;
52
73
  /** Load a fixed trailing window of terminal executions for one task by status. */
53
74
  export declare function readTaskExecutionStatusDays(args: {
54
75
  dayCount?: number;
@@ -1,11 +1,19 @@
1
1
  import type { User } from "@sentry/junior-plugin-api";
2
- import type { TaskExecutionList, TaskList } from "@/api/schema/task";
2
+ import type { ConversationSourceTask } from "@/api/schema/conversation";
3
+ import type { TaskExecutionList, TaskList, TaskRunList } from "@/api/schema/task";
3
4
  /** Read viewer-owned and public-workspace tasks as one bounded newest-first projection. */
4
5
  export declare function readViewerTasks(user: User): Promise<TaskList>;
6
+ /** Read newest runs across the viewer-visible scheduled and event tasks. */
7
+ export declare function readViewerTaskRuns(user: User): Promise<TaskRunList>;
5
8
  export declare class ViewerTaskNotFoundError extends Error {
6
9
  constructor();
7
10
  }
8
11
  /** Read one viewer-visible task and its newest terminal executions. */
9
12
  export declare function readViewerTaskExecutions(user: User, kind: "scheduled" | "event", id: string): Promise<TaskExecutionList>;
13
+ /** Resolve the source task for one conversation when a terminal execution links it. */
14
+ export declare function readConversationSourceTask(args: {
15
+ conversationId: string;
16
+ verifiedViewerEmail?: string;
17
+ }): Promise<ConversationSourceTask | undefined>;
10
18
  /** Delete one viewer-owned scheduled or event task. */
11
19
  export declare function deleteViewerTask(user: User, kind: "scheduled" | "event", id: string): Promise<void>;
@@ -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";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DEFAULT_SQL_STATEMENT_TIMEOUT_MS
3
- } from "./chunk-7GVX5SOG.js";
3
+ } from "./chunk-XFKIRN3Q.js";
4
4
  import {
5
5
  juniorDestinations,
6
6
  timestamptz
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-6GWA276C.js";
10
10
  import {
11
11
  getDeploymentTelemetryAttributes
12
- } from "./chunk-WSWVWP2V.js";
12
+ } from "./chunk-DS3J6WGY.js";
13
13
 
14
14
  // src/chat/logging.ts
15
15
  import path from "path";
@@ -5,12 +5,12 @@ import {
5
5
  juniorConversations,
6
6
  juniorIdentities,
7
7
  juniorUsers
8
- } from "./chunk-2KLMGRRQ.js";
8
+ } from "./chunk-27TEJTZO.js";
9
9
  import {
10
10
  TURN_REASONING_LEVELS,
11
11
  getChatConfig,
12
12
  modelProfileSchema
13
- } from "./chunk-7GVX5SOG.js";
13
+ } from "./chunk-XFKIRN3Q.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-GZRWULXF.js";
23
+ } from "./chunk-2LWPFSB4.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),