@sentry/junior 0.93.0 → 0.95.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 (122) hide show
  1. package/dist/{agent-hooks-ZG7IDOIN.js → agent-hooks-FTQ5EGPO.js} +9 -10
  2. package/dist/api/people/list.js +7 -7
  3. package/dist/api/people/profile.js +7 -7
  4. package/dist/api/people/shared.d.ts +2 -2
  5. package/dist/api-reference.d.ts +1 -1
  6. package/dist/app.js +474 -231
  7. package/dist/{catalog-runtime-NZHMSMYC.js → catalog-runtime-2D7IVKUT.js} +3 -3
  8. package/dist/chat/advisor-request.d.ts +4 -0
  9. package/dist/chat/agent/request.d.ts +2 -0
  10. package/dist/chat/agent/resume.d.ts +2 -0
  11. package/dist/chat/conversations/history.d.ts +128 -0
  12. package/dist/chat/conversations/legacy-import.d.ts +38 -0
  13. package/dist/chat/conversations/messages.d.ts +39 -0
  14. package/dist/chat/conversations/projection.d.ts +94 -0
  15. package/dist/chat/conversations/retention.d.ts +36 -0
  16. package/dist/chat/conversations/sql/conversation-row.d.ts +14 -0
  17. package/dist/chat/conversations/sql/history.d.ts +4 -0
  18. package/dist/chat/conversations/sql/legacy-history-import.d.ts +55 -0
  19. package/dist/chat/conversations/sql/messages.d.ts +4 -0
  20. package/dist/chat/conversations/sql/migrations.d.ts +14 -3
  21. package/dist/chat/conversations/sql/purge.d.ts +53 -0
  22. package/dist/chat/conversations/sql/store.d.ts +7 -2
  23. package/dist/chat/conversations/store.d.ts +19 -0
  24. package/dist/chat/conversations/visible-compactions.d.ts +11 -0
  25. package/dist/chat/conversations/visible-messages.d.ts +47 -0
  26. package/dist/chat/db.d.ts +12 -1
  27. package/dist/chat/egress/credentialed.d.ts +1 -1
  28. package/dist/chat/identities/sql.d.ts +1 -1
  29. package/dist/chat/logging.d.ts +2 -1
  30. package/dist/chat/resource-events/store.d.ts +2 -1
  31. package/dist/chat/runtime/reply-executor.d.ts +8 -0
  32. package/dist/chat/runtime/thread-state.d.ts +2 -0
  33. package/dist/chat/sandbox/egress/schemas.d.ts +4 -0
  34. package/dist/chat/sandbox/egress/session.d.ts +2 -2
  35. package/dist/chat/sandbox/resources.d.ts +4 -0
  36. package/dist/chat/services/mcp-auth-orchestration.d.ts +8 -0
  37. package/dist/chat/services/plugin-auth-orchestration.d.ts +12 -0
  38. package/dist/chat/services/turn-session-record.d.ts +14 -2
  39. package/dist/chat/sleep.d.ts +2 -0
  40. package/dist/chat/state/conversation.d.ts +7 -4
  41. package/dist/chat/state/session-log.d.ts +23 -1
  42. package/dist/chat/state/turn-session.d.ts +6 -0
  43. package/dist/chat/tool-support/private-trace-result.d.ts +4 -0
  44. package/dist/chat/tool-support/zod-tool.d.ts +1 -0
  45. package/dist/chat/tools/advisor/tool.d.ts +9 -4
  46. package/dist/chat/tools/definition.d.ts +2 -0
  47. package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -2
  48. package/dist/chat/tools/system-time.d.ts +8 -0
  49. package/dist/chat/xml.d.ts +2 -0
  50. package/dist/{chunk-NYWPISSO.js → chunk-2XXEKR44.js} +1 -1
  51. package/dist/{chunk-QGEWC27H.js → chunk-5XMNOD3S.js} +5 -7
  52. package/dist/{chunk-NFXSLTYG.js → chunk-6ONME5IG.js} +864 -62
  53. package/dist/{chunk-LFLTJQVR.js → chunk-7FBGKXPE.js} +4 -0
  54. package/dist/{chunk-MC4ZZE4Q.js → chunk-AYP4ERVZ.js} +1 -1
  55. package/dist/{chunk-GHGPTPBL.js → chunk-B7PUBQQM.js} +1 -1
  56. package/dist/chunk-CM5EZD5F.js +17 -0
  57. package/dist/chunk-CRRBJ3JP.js +1037 -0
  58. package/dist/{chunk-G3E7SCME.js → chunk-CZEX6KIQ.js} +23 -0
  59. package/dist/{chunk-TNUUATT7.js → chunk-E3E2XNCN.js} +2 -2
  60. package/dist/{chunk-LNCREA5Z.js → chunk-EKNJM5IG.js} +3 -127
  61. package/dist/{chunk-NAPITCZ6.js → chunk-GUE7HTNR.js} +251 -6
  62. package/dist/{chunk-BTH37NCU.js → chunk-GVOUCI2O.js} +1 -1
  63. package/dist/{chunk-YYBX2BD5.js → chunk-GY34VGP5.js} +1 -1
  64. package/dist/{chunk-JJUJ4CO2.js → chunk-HCXXB35T.js} +1489 -360
  65. package/dist/{chunk-YTNPU7I2.js → chunk-HDTO3A74.js} +2 -2
  66. package/dist/{chunk-YJ4OPVNA.js → chunk-HZNJLKKI.js} +1 -1
  67. package/dist/{chunk-HDNWZMUN.js → chunk-KDPCGVIT.js} +116 -51
  68. package/dist/chunk-N4RNJ32C.js +48 -0
  69. package/dist/{chunk-UUB3D2XI.js → chunk-NSCHU54X.js} +8 -10
  70. package/dist/{chunk-PFXC67GJ.js → chunk-RAIB6WSG.js} +6 -80
  71. package/dist/chunk-WAGQ377B.js +724 -0
  72. package/dist/{chunk-6H4PP63X.js → chunk-WCMQJE4F.js} +24 -14
  73. package/dist/{chunk-S6QKIGRM.js → chunk-WPOJ443W.js} +15 -25
  74. package/dist/{chunk-MAVOJ54A.js → chunk-XX4N4E6C.js} +25 -388
  75. package/dist/cli/chat.js +24 -23
  76. package/dist/cli/check.js +4 -4
  77. package/dist/cli/plugins.js +11 -12
  78. package/dist/cli/snapshot-warmup.js +7 -8
  79. package/dist/cli/upgrade.js +78 -17
  80. package/dist/db/schema/agent-steps.d.ts +134 -0
  81. package/dist/db/schema/conversation-messages.d.ts +153 -0
  82. package/dist/{chat/conversations/sql → db}/schema/conversations.d.ts +34 -0
  83. package/dist/{chat/conversations/sql → db}/schema.d.ts +319 -8
  84. package/dist/db-W55B74OP.js +24 -0
  85. package/dist/deployment.d.ts +2 -0
  86. package/dist/handlers/retention.d.ts +6 -0
  87. package/dist/instrumentation.js +16 -3
  88. package/dist/legacy-import-ZPLGLAFD.js +17 -0
  89. package/dist/nitro.js +14 -4
  90. package/dist/reporting/conversations/activity.d.ts +40 -0
  91. package/dist/reporting/conversations/context.d.ts +8 -0
  92. package/dist/reporting/conversations/details.d.ts +6 -0
  93. package/dist/reporting/conversations/index.d.ts +4 -0
  94. package/dist/reporting/conversations/shared.d.ts +9 -0
  95. package/dist/reporting/conversations/statistics.d.ts +4 -0
  96. package/dist/reporting/conversations/summaries.d.ts +17 -0
  97. package/dist/reporting/conversations/transcript.d.ts +28 -0
  98. package/dist/reporting/conversations/types.d.ts +178 -0
  99. package/dist/reporting/conversations.d.ts +1 -178
  100. package/dist/reporting.d.ts +4 -3
  101. package/dist/reporting.js +603 -827
  102. package/dist/{runner-XAZPJNAQ.js → runner-OOSBDYRK.js} +35 -41
  103. package/dist/{validation-KYAWETI4.js → validation-QCGRFRFZ.js} +4 -4
  104. package/migrations/README.md +32 -0
  105. package/migrations/meta/0000_snapshot.json +978 -0
  106. package/migrations/meta/_journal.json +13 -0
  107. package/package.json +9 -6
  108. package/dist/chat/sql/schema.d.ts +0 -1049
  109. package/dist/chat/state/conversation-details.d.ts +0 -47
  110. package/dist/chunk-7STN2ZSK.js +0 -250
  111. package/dist/chunk-LE5ANBUZ.js +0 -1040
  112. package/dist/chunk-QL66APYJ.js +0 -1377
  113. package/dist/db-YDN6AFJH.js +0 -18
  114. /package/dist/{chat/sql → db}/db.d.ts +0 -0
  115. /package/dist/{chat/sql → db}/executor.d.ts +0 -0
  116. /package/dist/{chat/sql → db}/neon.d.ts +0 -0
  117. /package/dist/{chat/sql → db}/postgres.d.ts +0 -0
  118. /package/dist/{chat/conversations/sql → db}/schema/destinations.d.ts +0 -0
  119. /package/dist/{chat/conversations/sql → db}/schema/identities.d.ts +0 -0
  120. /package/dist/{chat/conversations/sql → db}/schema/migrations.d.ts +0 -0
  121. /package/dist/{chat/conversations/sql → db}/schema/timestamps.d.ts +0 -0
  122. /package/dist/{chat/conversations/sql → db}/schema/users.d.ts +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-BTH37NCU.js";
4
- import "./chunk-S6QKIGRM.js";
3
+ } from "./chunk-GVOUCI2O.js";
4
+ import "./chunk-WPOJ443W.js";
5
5
  import "./chunk-OB42YVAE.js";
6
6
  import "./chunk-3DA7X2U3.js";
7
7
  import "./chunk-6APU57E6.js";
8
- import "./chunk-LFLTJQVR.js";
8
+ import "./chunk-7FBGKXPE.js";
9
9
  import "./chunk-MLKGABMK.js";
10
10
  export {
11
11
  pluginCatalogRuntime
@@ -0,0 +1,4 @@
1
+ /** Render the executor's advisor request in stable model-facing boundaries. */
2
+ export declare function renderAdvisorRequest(question: string, context: string): string;
3
+ /** Recover readable task and context text from an advisor request message. */
4
+ export declare function unwrapAdvisorRequest(text: string): string | undefined;
@@ -86,6 +86,8 @@ export interface AgentRunRouting {
86
86
  export interface AgentRunPolicy {
87
87
  /** Absolute wall-clock deadline for this host request, in milliseconds. */
88
88
  turnDeadlineAtMs?: number;
89
+ /** Cancels provider work when the owning host request is abandoned. */
90
+ signal?: AbortSignal;
89
91
  authorizationFlowMode?: AuthorizationFlowMode;
90
92
  configuration?: Record<string, unknown>;
91
93
  channelConfiguration?: ChannelConfigurationService;
@@ -25,6 +25,8 @@ interface ResumeStateArgs {
25
25
  durability: AgentRunDurability;
26
26
  getLoadedSkillNames: () => string[];
27
27
  logContext: SessionRecordLogContext;
28
+ modelId: string;
29
+ getReasoningLevel: () => string | undefined;
28
30
  recordActiveMcpProviders: () => Promise<void>;
29
31
  actor?: Actor;
30
32
  runSource: Source;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Durable agent execution history port.
3
+ *
4
+ * Steps are appended one row at a time under the conversation lease; context
5
+ * rebuilds (compaction/rollback) open a new epoch instead of rewriting history.
6
+ * The step envelope is strictly validated — an unknown type or malformed shape
7
+ * is corrupt state and fails loudly — while `pi_message` content stays
8
+ * permissive because the Pi SDK owns the message shape.
9
+ */
10
+ import { z } from "zod";
11
+ import { type PiMessage } from "@/chat/pi/messages";
12
+ import { type PiMessageProvenance } from "@/chat/state/session-log";
13
+ /** Reason a new context epoch was opened. */
14
+ export type EpochReason = "compaction" | "rollback";
15
+ /** Strict step envelope reused by the SQL row codec; unknown types fail loudly. */
16
+ export declare const agentStepEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
17
+ type: z.ZodLiteral<"pi_message">;
18
+ schemaVersion: z.ZodOptional<z.ZodNumber>;
19
+ message: z.ZodPipe<z.ZodObject<{
20
+ role: z.ZodString;
21
+ }, z.core.$loose>, z.ZodTransform<import("@earendil-works/pi-ai").AssistantMessage | import("@earendil-works/pi-ai").UserMessage | import("@earendil-works/pi-ai").ToolResultMessage<any> | import("@earendil-works/pi-agent-core").CustomMessage<unknown> | import("@earendil-works/pi-agent-core").BashExecutionMessage | import("@earendil-works/pi-agent-core").BranchSummaryMessage | import("@earendil-works/pi-agent-core").CompactionSummaryMessage, {
22
+ [x: string]: unknown;
23
+ role: string;
24
+ }>>;
25
+ provenance: z.ZodOptional<z.ZodObject<{
26
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
27
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
28
+ platform: z.ZodLiteral<"slack">;
29
+ teamId: z.ZodString;
30
+ email: z.ZodOptional<z.ZodString>;
31
+ fullName: z.ZodOptional<z.ZodString>;
32
+ userId: z.ZodString;
33
+ userName: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ platform: z.ZodLiteral<"local">;
36
+ email: z.ZodOptional<z.ZodString>;
37
+ fullName: z.ZodOptional<z.ZodString>;
38
+ userId: z.ZodString;
39
+ userName: z.ZodOptional<z.ZodString>;
40
+ }, z.core.$strict>, z.ZodObject<{
41
+ platform: z.ZodLiteral<"system">;
42
+ name: z.ZodString;
43
+ }, z.core.$strict>], "platform">>;
44
+ }, z.core.$strict>>;
45
+ }, z.core.$strip>, z.ZodObject<{
46
+ type: z.ZodLiteral<"context_epoch_started">;
47
+ reason: z.ZodUnion<readonly [z.ZodLiteral<"compaction">, z.ZodLiteral<"rollback">]>;
48
+ }, z.core.$strip>, z.ZodObject<{
49
+ type: z.ZodLiteral<"mcp_provider_connected">;
50
+ provider: z.ZodString;
51
+ }, z.core.$strip>, z.ZodObject<{
52
+ type: z.ZodLiteral<"authorization_requested">;
53
+ kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
54
+ provider: z.ZodString;
55
+ actorId: z.ZodString;
56
+ authorizationId: z.ZodString;
57
+ delivery: z.ZodUnion<readonly [z.ZodLiteral<"private_link_sent">, z.ZodLiteral<"private_link_reused">]>;
58
+ }, z.core.$strip>, z.ZodObject<{
59
+ type: z.ZodLiteral<"authorization_completed">;
60
+ kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
61
+ provider: z.ZodString;
62
+ actorId: z.ZodString;
63
+ authorizationId: z.ZodString;
64
+ }, z.core.$strip>, z.ZodObject<{
65
+ type: z.ZodLiteral<"tool_execution_started">;
66
+ toolCallId: z.ZodString;
67
+ toolName: z.ZodString;
68
+ args: z.ZodOptional<z.ZodUnknown>;
69
+ }, z.core.$strip>, z.ZodObject<{
70
+ type: z.ZodLiteral<"visible_context_compacted">;
71
+ compactions: z.ZodArray<z.ZodObject<{
72
+ coveredMessageIds: z.ZodArray<z.ZodString>;
73
+ createdAtMs: z.ZodNumber;
74
+ id: z.ZodString;
75
+ summary: z.ZodString;
76
+ }, z.core.$strip>>;
77
+ }, z.core.$strip>, z.ZodObject<{
78
+ type: z.ZodLiteral<"subagent_started">;
79
+ subagentInvocationId: z.ZodString;
80
+ subagentKind: z.ZodString;
81
+ modelId: z.ZodOptional<z.ZodString>;
82
+ parentToolCallId: z.ZodOptional<z.ZodString>;
83
+ reasoningLevel: z.ZodOptional<z.ZodString>;
84
+ childConversationId: z.ZodString;
85
+ historyMode: z.ZodLiteral<"shared">;
86
+ }, z.core.$strip>, z.ZodObject<{
87
+ type: z.ZodLiteral<"subagent_ended">;
88
+ subagentInvocationId: z.ZodString;
89
+ outcome: z.ZodUnion<readonly [z.ZodLiteral<"success">, z.ZodLiteral<"error">, z.ZodLiteral<"aborted">]>;
90
+ errorCode: z.ZodOptional<z.ZodString>;
91
+ }, z.core.$strip>], "type">;
92
+ /** One durable execution step's validated payload (sessionId lifted to epoch). */
93
+ export type AgentStepEntry = z.infer<typeof agentStepEntrySchema>;
94
+ /** A step read back from storage with its assigned order and epoch. */
95
+ export interface StoredAgentStep {
96
+ seq: number;
97
+ contextEpoch: number;
98
+ createdAtMs: number;
99
+ entry: AgentStepEntry;
100
+ }
101
+ /** A step to append; the store assigns `seq` and the current `context_epoch`. */
102
+ export interface NewAgentStep {
103
+ entry: AgentStepEntry;
104
+ createdAtMs: number;
105
+ }
106
+ /** A replacement Pi message written into a freshly opened epoch. */
107
+ export interface PiMessageStep {
108
+ message: PiMessage;
109
+ createdAtMs: number;
110
+ provenance?: PiMessageProvenance;
111
+ }
112
+ /** Persist and read the durable per-conversation agent execution history. */
113
+ export interface AgentStepStore {
114
+ /** Append steps in one transaction, assigning `seq = max+1` under the lease. */
115
+ append(conversationId: string, steps: NewAgentStep[]): Promise<void>;
116
+ /**
117
+ * Open the next epoch in one transaction: a `context_epoch_started` marker
118
+ * followed by the replacement messages as ordinary `pi_message` rows.
119
+ */
120
+ startEpoch(conversationId: string, opts: {
121
+ reason: EpochReason;
122
+ messages: PiMessageStep[];
123
+ }): Promise<void>;
124
+ /** Steps of the highest epoch in `seq` order (all types; caller filters). */
125
+ loadCurrentEpoch(conversationId: string): Promise<StoredAgentStep[]>;
126
+ /** All steps across all epochs in `seq` order, for audit and reporting. */
127
+ loadHistory(conversationId: string): Promise<StoredAgentStep[]>;
128
+ }
@@ -0,0 +1,38 @@
1
+ import { type ConversationCompaction, type ConversationMessage as ThreadConversationMessage } from "@/chat/state/conversation";
2
+ import { type SessionLogStore } from "@/chat/state/session-log";
3
+ import { type AdvisorSessionStore } from "@/chat/tools/advisor/session-store";
4
+ import type { JuniorSqlDatabase } from "@/db/db";
5
+ import type { ConversationMessageStore } from "./messages";
6
+ import type { Conversation } from "./store";
7
+ /** Legacy source seams used by the one-time migration. */
8
+ export interface LegacyImportDeps {
9
+ executor: JuniorSqlDatabase;
10
+ messageStore: ConversationMessageStore;
11
+ sessionLogStore?: SessionLogStore;
12
+ advisorSessionStore?: AdvisorSessionStore;
13
+ loadVisibleMessages?: (conversationId: string) => Promise<ThreadConversationMessage[]>;
14
+ legacyCompactions?: ConversationCompaction[];
15
+ /** Conversation metadata used for imported creation and activity clocks. */
16
+ conversationRecord?: Conversation;
17
+ /** Latest activity recovered from the legacy thread-state payload. */
18
+ legacyLastActivityAtMs?: number;
19
+ }
20
+ /**
21
+ * Import one conversation's legacy Redis history into SQL, idempotently.
22
+ *
23
+ * Returns whether an import ran (false when step rows already exist or there is
24
+ * nothing legacy to import).
25
+ */
26
+ export declare function importConversationFromLegacy(conversationId: string, deps: LegacyImportDeps): Promise<{
27
+ imported: boolean;
28
+ }>;
29
+ /**
30
+ * Lazy first-read import for a straggler the old deployment touched during
31
+ * promotion. Runs under the conversation lease the worker already holds before
32
+ * any turn/resume projection read; idempotent skip-if-rows-exist makes re-entry
33
+ * safe. Missing legacy keys produce empty reads for genuinely new conversations;
34
+ * actual Redis read failures surface through normal worker recovery.
35
+ */
36
+ export declare function ensureLegacyConversationImport(args: {
37
+ conversationId: string;
38
+ }): Promise<void>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Visible conversation message port.
3
+ *
4
+ * Messages are immutable source facts recorded idempotently by source identity;
5
+ * the only mutable bookkeeping is the `replied_at` delivery mark.
6
+ */
7
+ /** Author role of a visible conversation message. */
8
+ export type ConversationMessageRole = "user" | "assistant" | "system";
9
+ /** A source message to record; identity is `(conversationId, messageId)`. */
10
+ export interface NewConversationMessage {
11
+ messageId: string;
12
+ role: ConversationMessageRole;
13
+ text: string;
14
+ authorIdentityId?: string;
15
+ meta?: Record<string, unknown>;
16
+ createdAtMs: number;
17
+ }
18
+ /** A visible message read back from storage. */
19
+ export interface ConversationMessage {
20
+ conversationId: string;
21
+ messageId: string;
22
+ role: ConversationMessageRole;
23
+ text: string;
24
+ authorIdentityId?: string;
25
+ meta?: Record<string, unknown>;
26
+ repliedAtMs?: number;
27
+ createdAtMs: number;
28
+ }
29
+ /** Persist and read the visible per-conversation message transcript. */
30
+ export interface ConversationMessageStore {
31
+ /** Record source messages idempotently by `(conversation_id, message_id)`. */
32
+ record(conversationId: string, messages: NewConversationMessage[]): Promise<void>;
33
+ /** Set the mutable `replied_at` mark; content columns are never touched. */
34
+ markReplied(conversationId: string, messageId: string, repliedAtMs: number): Promise<void>;
35
+ /** List messages in `created_at` order. */
36
+ list(conversationId: string, opts?: {
37
+ limit?: number;
38
+ }): Promise<ConversationMessage[]>;
39
+ }
@@ -0,0 +1,94 @@
1
+ import type { PiMessage } from "@/chat/pi/messages";
2
+ import { type AuthorizationKind, type PiMessageProvenance, type SessionProjection } from "@/chat/state/session-log";
3
+ import type { StoredAgentStep } from "@/chat/conversations/history";
4
+ /** Aligned step projection: `provenance[i]` and `seqs[i]` describe `messages[i]`. */
5
+ export interface StepProjection extends SessionProjection {
6
+ /** The `seq` of the step each projected message came from. */
7
+ seqs: number[];
8
+ }
9
+ /**
10
+ * Materialize Pi messages with aligned provenance and source seqs from one
11
+ * epoch's steps. Steps above `maxSeq` (when given) are excluded so a terminal
12
+ * turn record reproduces exactly the boundary it committed.
13
+ */
14
+ export declare function projectSteps(steps: StoredAgentStep[], opts?: {
15
+ maxSeq?: number;
16
+ }): StepProjection;
17
+ interface ScopedConversation {
18
+ conversationId: string;
19
+ }
20
+ /** Load the current-epoch Pi projection for a conversation. */
21
+ export declare function loadProjection(args: ScopedConversation): Promise<PiMessage[]>;
22
+ /** Load the current-epoch Pi projection with aligned per-message provenance. */
23
+ export declare function loadProjectionWithProvenance(args: ScopedConversation): Promise<SessionProjection>;
24
+ /**
25
+ * Load a turn's committed Pi projection from the durable step store.
26
+ *
27
+ * The record stays pinned to the epoch containing its committed boundary, so a
28
+ * later rollback or compaction cannot silently rewrite what a stale record
29
+ * resumes from. Unfinished records (`includeTail`) also see that epoch's tail
30
+ * so parked input appended after the last safe boundary is model-visible; for
31
+ * a live run the committed epoch is the current epoch. Terminal records
32
+ * reproduce exactly the boundary they committed by cutting at `committedSeq`.
33
+ * Returns undefined when the committed boundary no longer exists (purged
34
+ * history) so callers fail closed.
35
+ */
36
+ export declare function loadTurnProjection(args: {
37
+ conversationId: string;
38
+ committedSeq: number;
39
+ includeTail: boolean;
40
+ }): Promise<StepProjection | undefined>;
41
+ /** Load MCP providers durably connected in this conversation's current epoch. */
42
+ export declare function loadConnectedMcpProviders(args: ScopedConversation): Promise<string[]>;
43
+ /**
44
+ * Commit the turn's Pi history: append when it advanced the committed
45
+ * projection normally, or open a `rollback` epoch when it diverged (a
46
+ * provider-retry trim regenerated trailing assistant output). Returns the
47
+ * resolved provenance, the per-message step seqs, and the `seq` boundary that
48
+ * reproduces exactly the committed messages.
49
+ */
50
+ export declare function commitMessages(args: {
51
+ conversationId: string;
52
+ messages: PiMessage[];
53
+ /** Explicit per-message provenance aligned one-to-one with `messages`. */
54
+ provenance?: PiMessageProvenance[];
55
+ /** Explicit provenance for the trailing newly committed messages. */
56
+ trailingMessageProvenance?: PiMessageProvenance[];
57
+ /** Default applied to the last new user message when no explicit array. */
58
+ newMessageProvenance?: PiMessageProvenance;
59
+ }): Promise<{
60
+ committedSeq: number;
61
+ messageSeqs: number[];
62
+ provenance: PiMessageProvenance[];
63
+ }>;
64
+ /** Record a successful MCP provider connection without duplicating the fact. */
65
+ export declare function recordMcpProviderConnected(args: {
66
+ conversationId: string;
67
+ provider: string;
68
+ }): Promise<void>;
69
+ /** Record that an OAuth/MCP authorization link was delivered or reused. */
70
+ export declare function recordAuthorizationRequested(args: {
71
+ conversationId: string;
72
+ kind: AuthorizationKind;
73
+ provider: string;
74
+ actorId: string;
75
+ authorizationId: string;
76
+ delivery: "private_link_sent" | "private_link_reused";
77
+ }): Promise<void>;
78
+ /** Record completed authorization as a chronological host observation for Pi. */
79
+ export declare function recordAuthorizationCompleted(args: {
80
+ conversationId: string;
81
+ kind: AuthorizationKind;
82
+ provider: string;
83
+ actorId: string;
84
+ authorizationId: string;
85
+ }): Promise<void>;
86
+ /** Record a host-observed parent tool start without adding it to Pi replay. */
87
+ export declare function recordToolExecutionStarted(args: {
88
+ conversationId: string;
89
+ args?: unknown;
90
+ createdAtMs?: number;
91
+ toolCallId: string;
92
+ toolName: string;
93
+ }): Promise<void>;
94
+ export {};
@@ -0,0 +1,36 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ /** Content retention windows keyed by resolved conversation visibility. */
3
+ export declare const CONTENT_RETENTION_MS: {
4
+ readonly public: number;
5
+ readonly private: number;
6
+ };
7
+ /** Aggregate outcome of one bounded retention purge batch. */
8
+ export interface RetentionPurgeResult {
9
+ /** Root conversations examined and attempted this run. */
10
+ scanned: number;
11
+ /** Root trees successfully purged. */
12
+ purged: number;
13
+ /** Root trees whose purge failed and were skipped. */
14
+ failed: number;
15
+ /** Total conversation rows (roots plus descendants) stamped by the purge. */
16
+ conversations: number;
17
+ }
18
+ /**
19
+ * Run one bounded retention purge batch: delete expired root conversation trees
20
+ * oldest-activity-first. Each tree is purged transactionally in isolation, so a
21
+ * single failing tree is logged and skipped without aborting the batch, and the
22
+ * remainder of an over-limit backlog is left for the next run.
23
+ */
24
+ export declare function runRetentionPurge(executor: JuniorSqlDatabase, args: {
25
+ nowMs: number;
26
+ limit?: number;
27
+ }): Promise<RetentionPurgeResult>;
28
+ /**
29
+ * Erase one conversation's content and descendants immediately, regardless of
30
+ * age, applying the same visibility-based metadata scrubbing as the purge job.
31
+ * The scrub decision uses the root's resolved visibility so erasing a child
32
+ * still fails closed to private for a private root.
33
+ */
34
+ export declare function purgeConversation(executor: JuniorSqlDatabase, conversationId: string, opts?: {
35
+ nowMs?: number;
36
+ }): Promise<void>;
@@ -0,0 +1,14 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ /**
3
+ * Establish the conversation metadata row on first contact for content writes
4
+ * (agent steps, visible transcript) that can land before activity recording has
5
+ * created the row, and whose tables FK to it.
6
+ *
7
+ * First contact creates the row; every later content write advances the
8
+ * activity clock so retention mirrors append-refresh semantics (each content
9
+ * append refreshes the retention window). The timestamp is content-intrinsic
10
+ * (the first item's `createdAtMs`), and `greatest(...)` guarantees a backfilled
11
+ * or imported historical write — which carries an old timestamp — can never
12
+ * regress `last_activity_at`.
13
+ */
14
+ export declare function ensureConversationRow(executor: JuniorSqlDatabase, conversationId: string, atMs: number): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import { type AgentStepStore } from "../history";
3
+ /** Create a SQL-backed agent step store. */
4
+ export declare function createSqlAgentStepStore(executor: JuniorSqlDatabase): AgentStepStore;
@@ -0,0 +1,55 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import type { PiMessage } from "@/chat/pi/messages";
3
+ import type { NewConversationMessage } from "../messages";
4
+ import { type SessionLogEntry } from "@/chat/state/session-log";
5
+ import { type AgentStepEntry } from "../history";
6
+ /** A converted legacy step with its explicit order and epoch pinned. */
7
+ export interface ImportedStep {
8
+ seq: number;
9
+ contextEpoch: number;
10
+ entry: AgentStepEntry;
11
+ createdAtMs: number;
12
+ }
13
+ /** Result of converting one conversation's legacy log. */
14
+ export interface ConvertedLegacyLog {
15
+ steps: ImportedStep[];
16
+ /** Deterministic advisor child conversation id, when a subagent was recorded. */
17
+ advisorChildConversationId?: string;
18
+ }
19
+ /**
20
+ * Convert a legacy session log into ordered step rows with explicit epochs.
21
+ *
22
+ * `fallbackCreatedAtMs` supplies `created_at` for rows without an intrinsic
23
+ * timestamp (epoch markers, provider facts, timestamp-less messages); a real
24
+ * conversation-derived value is always passed so no import-time `now` is used.
25
+ */
26
+ export declare function convertLegacySessionLog(args: {
27
+ conversationId: string;
28
+ entries: SessionLogEntry[];
29
+ fallbackCreatedAtMs: number;
30
+ }): ConvertedLegacyLog;
31
+ /** Convert an advisor session blob into epoch-0 child pi_message rows. */
32
+ export declare function convertAdvisorMessages(messages: PiMessage[], fallbackCreatedAtMs: number): ImportedStep[];
33
+ /** One conversation's converted history plus optional advisor child history. */
34
+ export interface LegacyImportWrite {
35
+ conversationId: string;
36
+ fallbackCreatedAtMs: number;
37
+ lastActivityAtMs: number;
38
+ messages?: Array<NewConversationMessage & {
39
+ repliedAtMs?: number;
40
+ }>;
41
+ steps: ImportedStep[];
42
+ child?: {
43
+ conversationId: string;
44
+ steps: ImportedStep[];
45
+ };
46
+ }
47
+ /**
48
+ * Write a converted legacy history for one conversation, all-or-nothing.
49
+ *
50
+ * Serialized by a per-conversation advisory lock and skipped when step rows
51
+ * already exist, so a re-run (bulk or lazy) never double-imports. Parent and
52
+ * advisor-child rows land in one transaction; explicit `seq`/`context_epoch`
53
+ * are what make this need a dedicated writer rather than the narrow port.
54
+ */
55
+ export declare function writeLegacyImport(executor: JuniorSqlDatabase, args: LegacyImportWrite): Promise<boolean>;
@@ -0,0 +1,4 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import type { ConversationMessageStore } from "../messages";
3
+ /** Create a SQL-backed conversation message store. */
4
+ export declare function createSqlConversationMessageStore(executor: JuniorSqlDatabase): ConversationMessageStore;
@@ -1,11 +1,22 @@
1
- import { schema } from "./schema";
2
- import type { JuniorSqlMigrationExecutor } from "@/chat/sql/db";
1
+ import type { JuniorSqlMigrationExecutor } from "@/db/db";
2
+ import { juniorSqlSchema as schema } from "@/db/schema";
3
3
  export interface Migration {
4
4
  checksum: string;
5
5
  id: string;
6
6
  statements: readonly string[];
7
7
  }
8
- export declare const migrations: readonly [Migration, Migration, Migration, Migration];
8
+ /**
9
+ * Register a drizzle-kit-generated `.sql` file as a checksum-pinned migration.
10
+ *
11
+ * Migrations 0006 onward are authored by editing the Drizzle schema and running
12
+ * `pnpm --filter @sentry/junior db:generate`; each generated file becomes one
13
+ * line here. Statements are split on drizzle-kit's `--> statement-breakpoint`
14
+ * markers and applied by the custom `junior upgrade` runner (never
15
+ * `drizzle-kit migrate`). Migrations 0001–0005 predate kit and stay inline so
16
+ * their recorded checksums remain byte-stable.
17
+ */
18
+ export declare function defineMigrationFromFile(id: string, fileName: string): Migration;
19
+ export declare const migrations: readonly [Migration, Migration, Migration, Migration, Migration];
9
20
  export { schema };
10
21
  /** Apply pending SQL schema migrations for queryable conversation records. */
11
22
  export declare function migrateSchema(executor: JuniorSqlMigrationExecutor, migrationList?: readonly Migration[]): Promise<void>;
@@ -0,0 +1,53 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import type { JuniorDestinationVisibility } from "@/db/schema/destinations";
3
+ /** An expired root conversation selected for purge, with its resolved visibility. */
4
+ export interface ExpiredRoot {
5
+ conversationId: string;
6
+ visibility: JuniorDestinationVisibility | null;
7
+ }
8
+ /** Outcome of purging one conversation tree. */
9
+ export interface PurgeTreeResult {
10
+ /** Whether this transaction still found the root eligible for purge. */
11
+ purged: boolean;
12
+ /** Root plus descendant conversation rows stamped by the purge. */
13
+ conversations: number;
14
+ }
15
+ /**
16
+ * Select expired root conversations for purge, oldest activity first.
17
+ *
18
+ * Roots have no parent, so visibility is read directly from the root's own
19
+ * destination; the private window applies to every non-`public` case. A row is
20
+ * skipped once it is fully purged — no content rows survive and no non-public
21
+ * scrub fields remain — so a bounded batch spends its budget on real work.
22
+ */
23
+ export declare function selectExpiredRoots(executor: JuniorSqlDatabase, args: {
24
+ nowMs: number;
25
+ publicWindowMs: number;
26
+ privateWindowMs: number;
27
+ limit: number;
28
+ }): Promise<ExpiredRoot[]>;
29
+ /**
30
+ * Purge one conversation tree in a single transaction: delete all message and
31
+ * step rows for the given conversation and every descendant, stamp
32
+ * `transcript_purged_at`, and — for non-public content — null the raw-payload
33
+ * metadata (`title`, `channel_name`, legacy actor JSON) so purged private
34
+ * conversations keep only safe metadata. The metadata rows themselves survive.
35
+ */
36
+ export declare function purgeConversationTree(executor: JuniorSqlDatabase, args: {
37
+ rootConversationId: string;
38
+ scrubMetadata?: boolean;
39
+ nowMs: number;
40
+ retention?: {
41
+ privateWindowMs: number;
42
+ publicWindowMs: number;
43
+ };
44
+ }): Promise<PurgeTreeResult>;
45
+ /**
46
+ * Walk `parent_conversation_id` to the root and return the root's destination
47
+ * visibility. Retention resolves visibility at purge time rather than storing an
48
+ * expiry, so a public↔private flip takes effect on the next pass.
49
+ */
50
+ export declare function resolveRootVisibility(executor: JuniorSqlDatabase, conversationId: string): Promise<{
51
+ rootConversationId: string;
52
+ visibility: JuniorDestinationVisibility | null;
53
+ }>;
@@ -1,7 +1,7 @@
1
1
  import type { Destination } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
- import { type StoredSlackActor } from "@/chat/actor";
4
- import type { JuniorSqlDatabase, JuniorSqlMigrationExecutor } from "@/chat/sql/db";
3
+ import type { StoredSlackActor } from "@/chat/actor";
4
+ import type { JuniorSqlDatabase, JuniorSqlMigrationExecutor } from "@/db/db";
5
5
  import type { Conversation, ConversationExecution, ConversationSource, ConversationStore } from "../store";
6
6
  export declare class SqlStore implements ConversationStore {
7
7
  private readonly executor;
@@ -37,6 +37,11 @@ export declare class SqlStore implements ConversationStore {
37
37
  updatedAtMs: number;
38
38
  visibility?: ConversationPrivacy;
39
39
  }): Promise<void>;
40
+ ensureChildConversation(args: {
41
+ conversationId: string;
42
+ parentConversationId: string;
43
+ nowMs?: number;
44
+ }): Promise<void>;
40
45
  /** Copy one conversation record into SQL during backfill. */
41
46
  backfillConversation(sourceConversation: Conversation): Promise<void>;
42
47
  listByActivity(args?: {
@@ -22,6 +22,12 @@ export interface Conversation {
22
22
  source?: ConversationSource;
23
23
  title?: string;
24
24
  updatedAtMs: number;
25
+ /**
26
+ * When retention purged this conversation's content. Set means messages and
27
+ * steps were deleted wholesale; reporting presents the transcript as expired
28
+ * rather than privacy-redacted (`../../../specs/data-redaction-policy.md`).
29
+ */
30
+ transcriptPurgedAtMs?: number;
25
31
  /** Persisted destination visibility. Undefined means no destination row exists. */
26
32
  visibility?: ConversationPrivacy;
27
33
  }
@@ -48,6 +54,19 @@ export interface ConversationStore {
48
54
  /** Source-confirmed visibility from the current event's signal only. */
49
55
  visibility?: ConversationPrivacy;
50
56
  }): Promise<void>;
57
+ /**
58
+ * Establish a subagent child conversation row linked to its parent.
59
+ *
60
+ * Advisor and future subagent histories live under their own child
61
+ * `conversation_id` with `parent_conversation_id` set; the child carries no
62
+ * destination and is excluded from top-level listings. Idempotent: it links a
63
+ * bare row a step append may have created first without clobbering it.
64
+ */
65
+ ensureChildConversation(args: {
66
+ conversationId: string;
67
+ parentConversationId: string;
68
+ nowMs?: number;
69
+ }): Promise<void>;
51
70
  /** Store task-execution metadata for long-term conversation history. */
52
71
  recordExecution(args: {
53
72
  channelName?: string;
@@ -0,0 +1,11 @@
1
+ import type { ThreadConversationState } from "@/chat/state/conversation";
2
+ /** Hydrate the durable visible-context compaction snapshot from SQL. */
3
+ export declare function hydrateConversationCompactions(args: {
4
+ conversation: ThreadConversationState;
5
+ conversationId: string;
6
+ }): Promise<void>;
7
+ /** Persist a changed visible-context compaction snapshot in SQL agent history. */
8
+ export declare function persistConversationCompactions(args: {
9
+ conversation: ThreadConversationState;
10
+ conversationId: string;
11
+ }): Promise<void>;