@sentry/junior 0.96.0 → 0.97.1

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 (135) hide show
  1. package/dist/{agent-hooks-5URSMY3O.js → agent-hooks-XSUIVRQS.js} +8 -6
  2. package/dist/{reporting → api}/conversations/activity.d.ts +1 -1
  3. package/dist/api/conversations/detail-projection.d.ts +10 -0
  4. package/dist/api/conversations/detail.d.ts +3 -0
  5. package/dist/api/conversations/detail.query.d.ts +3 -0
  6. package/dist/api/conversations/list.d.ts +3 -0
  7. package/dist/api/conversations/list.query.d.ts +94 -0
  8. package/dist/api/conversations/projection.d.ts +14 -0
  9. package/dist/api/conversations/schema.d.ts +683 -0
  10. package/dist/{reporting → api}/conversations/shared.d.ts +1 -5
  11. package/dist/api/conversations/stats.d.ts +3 -0
  12. package/dist/api/conversations/stats.query.d.ts +3 -0
  13. package/dist/api/conversations/subagent.d.ts +3 -0
  14. package/dist/{reporting → api}/conversations/transcript.d.ts +4 -4
  15. package/dist/api/people/list.d.ts +1 -2
  16. package/dist/api/people/list.query.d.ts +3 -4
  17. package/dist/api/people/profile.d.ts +1 -2
  18. package/dist/api/people/profile.query.d.ts +3 -4
  19. package/dist/api/people/schema.d.ts +193 -0
  20. package/dist/api/people/shared.d.ts +31 -9
  21. package/dist/api/schema.d.ts +20 -0
  22. package/dist/api/schema.js +50 -0
  23. package/dist/api-reference.d.ts +4 -3
  24. package/dist/api.d.ts +3 -0
  25. package/dist/api.js +156 -0
  26. package/dist/app.d.ts +1 -4
  27. package/dist/app.js +101 -367
  28. package/dist/build/virtual-config.d.ts +2 -2
  29. package/dist/{catalog-runtime-MSMAYYIK.js → catalog-runtime-PFHVMHDR.js} +3 -2
  30. package/dist/chat/agent/resume.d.ts +3 -1
  31. package/dist/chat/agent/tools.d.ts +2 -1
  32. package/dist/chat/config.d.ts +1 -8
  33. package/dist/chat/conversations/history.d.ts +241 -27
  34. package/dist/chat/conversations/legacy-advisor-session.d.ts +7 -0
  35. package/dist/chat/conversations/legacy-import.d.ts +2 -2
  36. package/dist/chat/conversations/projection.d.ts +19 -3
  37. package/dist/chat/conversations/sql/legacy-history-import.d.ts +1 -1
  38. package/dist/chat/conversations/sql/store.d.ts +15 -9
  39. package/dist/chat/conversations/store.d.ts +9 -4
  40. package/dist/chat/model-profile.d.ts +14 -0
  41. package/dist/chat/pi/transcript.d.ts +5 -3
  42. package/dist/chat/resource-events/store.d.ts +2 -2
  43. package/dist/chat/services/context-compaction.d.ts +15 -0
  44. package/dist/chat/services/turn-result.d.ts +1 -0
  45. package/dist/chat/services/turn-session-record.d.ts +6 -6
  46. package/dist/chat/state/turn-session.d.ts +16 -5
  47. package/dist/chat/task-execution/store.d.ts +2 -2
  48. package/dist/chat/tools/handoff/tool.d.ts +45 -0
  49. package/dist/chat/tools/types.d.ts +7 -2
  50. package/dist/chat/usage.d.ts +25 -25
  51. package/dist/{chunk-RITD7E5L.js → chunk-35BNLDOJ.js} +338 -577
  52. package/dist/{chunk-PMNN6ST4.js → chunk-3ECW2K2O.js} +7 -2
  53. package/dist/{chunk-5C6XTTFI.js → chunk-3F4OPKGF.js} +89 -55
  54. package/dist/chunk-3V7OFJZC.js +264 -0
  55. package/dist/chunk-4ZNGQH7C.js +25 -0
  56. package/dist/{chunk-S5KZ5LPG.js → chunk-5HLDPVYS.js} +14 -447
  57. package/dist/{chunk-DZENG5ML.js → chunk-6U26PYI5.js} +24 -14
  58. package/dist/chunk-AUUCAFDE.js +546 -0
  59. package/dist/{chunk-6APU57E6.js → chunk-B3IT5END.js} +41 -260
  60. package/dist/chunk-CEA3A3UA.js +86 -0
  61. package/dist/{chunk-YDT7SNCN.js → chunk-D5KZYS4T.js} +1 -1
  62. package/dist/{chunk-YDVEH3SB.js → chunk-EEZCY5WX.js} +78 -28
  63. package/dist/{chunk-2NAZZPPS.js → chunk-EOWXRY5E.js} +1 -1
  64. package/dist/{chunk-GQ3GK22G.js → chunk-FBHZJFHI.js} +2 -2
  65. package/dist/{chunk-CZEX6KIQ.js → chunk-G3E7SCME.js} +0 -23
  66. package/dist/chunk-GUAP3H7O.js +319 -0
  67. package/dist/{chunk-BYZWPRJA.js → chunk-H66UCBPW.js} +6 -4
  68. package/dist/{chunk-L7CDEIVJ.js → chunk-LMJPRYHP.js} +4 -2
  69. package/dist/chunk-LUAE4MGW.js +199 -0
  70. package/dist/{chunk-GY34VGP5.js → chunk-LVA4I4H7.js} +3 -1
  71. package/dist/chunk-LVUKF5CE.js +63 -0
  72. package/dist/{chunk-AAZXTVJT.js → chunk-NG2AV7IB.js} +2 -72
  73. package/dist/chunk-ON6YKIQ7.js +260 -0
  74. package/dist/chunk-PDO5BLNM.js +22 -0
  75. package/dist/chunk-QNVHH5PU.js +20 -0
  76. package/dist/{chunk-P3YFQLEN.js → chunk-T533JLM3.js} +8 -10
  77. package/dist/chunk-UAMKJPDF.js +11 -0
  78. package/dist/chunk-VFH4ZKZT.js +66 -0
  79. package/dist/{chunk-UKHVMPX5.js → chunk-WGXMTFNU.js} +15 -17
  80. package/dist/{chunk-MNTINMWR.js → chunk-WJOSZOON.js} +184 -300
  81. package/dist/chunk-WTYEKPXU.js +451 -0
  82. package/dist/{chunk-IYM2SIVG.js → chunk-XIRPQQVE.js} +605 -363
  83. package/dist/cli/chat.js +24 -21
  84. package/dist/cli/check.js +4 -3
  85. package/dist/cli/init.js +12 -0
  86. package/dist/cli/plugins.js +12 -9
  87. package/dist/cli/snapshot-warmup.js +8 -6
  88. package/dist/cli/upgrade.js +265 -137
  89. package/dist/db/db.d.ts +4 -0
  90. package/dist/db/schema/conversations.d.ts +128 -0
  91. package/dist/db/schema.d.ts +129 -60
  92. package/dist/{db-2D6RMG67.js → db-BWXYIKFQ.js} +3 -3
  93. package/dist/detail-GA6NXWQJ.js +43 -0
  94. package/dist/discovery-RMHYSRL7.js +43 -0
  95. package/dist/handlers/health.d.ts +3 -0
  96. package/dist/instrumentation.js +1 -1
  97. package/dist/{legacy-import-VZ2MEGP7.js → legacy-import-3NQJVGQL.js} +4 -4
  98. package/dist/{api/people/list.js → list-A3WFRIYX.js} +26 -16
  99. package/dist/list-UXJI5Q5X.js +27 -0
  100. package/dist/nitro.d.ts +1 -1
  101. package/dist/nitro.js +2 -1
  102. package/dist/plugin-conversations-DDNGC35A.js +36 -0
  103. package/dist/{api/people/profile.js → profile-4RYDXWTF.js} +33 -18
  104. package/dist/reporting/plugin-conversations.d.ts +3 -0
  105. package/dist/reporting-schema.d.ts +140 -0
  106. package/dist/reporting.d.ts +12 -81
  107. package/dist/{runner-JZBRQP4F.js → runner-JALSYH2P.js} +17 -12
  108. package/dist/skills-MAZXZ2KE.js +26 -0
  109. package/dist/stats-XKXH3PTY.js +217 -0
  110. package/dist/subagent-TZ55XY37.js +48 -0
  111. package/dist/usage-schema.d.ts +25 -0
  112. package/dist/{validation-6XOOQGME.js → validation-FMEAEKCY.js} +4 -3
  113. package/migrations/0000_initial.sql +115 -0
  114. package/migrations/0001_conversation_metrics.sql +4 -0
  115. package/migrations/README.md +12 -30
  116. package/migrations/meta/0000_snapshot.json +1 -33
  117. package/migrations/meta/0001_snapshot.json +972 -0
  118. package/migrations/meta/_journal.json +9 -2
  119. package/package.json +13 -17
  120. package/dist/api/people/types.d.ts +0 -85
  121. package/dist/chat/advisor-request.d.ts +0 -4
  122. package/dist/chat/conversations/sql/migrations.d.ts +0 -22
  123. package/dist/chat/tools/advisor/session-store.d.ts +0 -9
  124. package/dist/chat/tools/advisor/tool.d.ts +0 -72
  125. package/dist/chunk-RAIB6WSG.js +0 -142
  126. package/dist/chunk-WM6KHPBQ.js +0 -48
  127. package/dist/db/schema/migrations.d.ts +0 -58
  128. package/dist/reporting/conversations/context.d.ts +0 -8
  129. package/dist/reporting/conversations/details.d.ts +0 -6
  130. package/dist/reporting/conversations/index.d.ts +0 -4
  131. package/dist/reporting/conversations/statistics.d.ts +0 -4
  132. package/dist/reporting/conversations/summaries.d.ts +0 -20
  133. package/dist/reporting/conversations/types.d.ts +0 -191
  134. package/dist/reporting/conversations.d.ts +0 -1
  135. package/dist/reporting.js +0 -1155
@@ -8,7 +8,7 @@ export interface RuntimePluginModule {
8
8
  }
9
9
  /** Render the virtual config module consumed by createApp(). */
10
10
  export declare function renderVirtualConfig(options: {
11
- dashboard?: Omit<JuniorDashboardOptions, "reporting">;
11
+ dashboard?: JuniorDashboardOptions;
12
12
  plugins?: PluginCatalogConfig;
13
13
  pluginModule?: RuntimePluginModule;
14
14
  pluginRuntimeRegistrations?: string[];
@@ -19,5 +19,5 @@ export declare function injectVirtualConfig(nitro: Nitro, options?: {
19
19
  pluginModule?: RuntimePluginModule;
20
20
  plugins?: PluginCatalogConfig;
21
21
  pluginRuntimeRegistrations?: string[];
22
- dashboard?: Omit<JuniorDashboardOptions, "reporting">;
22
+ dashboard?: JuniorDashboardOptions;
23
23
  }): void;
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-L7CDEIVJ.js";
3
+ } from "./chunk-LMJPRYHP.js";
4
4
  import "./chunk-I35CTGPO.js";
5
5
  import "./chunk-OB42YVAE.js";
6
6
  import "./chunk-6GWA276C.js";
7
- import "./chunk-6APU57E6.js";
7
+ import "./chunk-B3IT5END.js";
8
8
  import "./chunk-7FBGKXPE.js";
9
+ import "./chunk-3V7OFJZC.js";
9
10
  import "./chunk-MLKGABMK.js";
10
11
  export {
11
12
  pluginCatalogRuntime
@@ -24,8 +24,8 @@ interface ResumeStateArgs {
24
24
  destination: Destination;
25
25
  durability: AgentRunDurability;
26
26
  getLoadedSkillNames: () => string[];
27
+ getModelId: () => string;
27
28
  logContext: SessionRecordLogContext;
28
- modelId: string;
29
29
  getReasoningLevel: () => string | undefined;
30
30
  recordActiveMcpProviders: () => Promise<void>;
31
31
  actor?: Actor;
@@ -47,6 +47,8 @@ export declare function createResumeState(args: ResumeStateArgs): {
47
47
  readonly cooperativeYieldError: CooperativeTurnYieldError | undefined;
48
48
  setTurnStartMessageIndex(index: number | undefined): void;
49
49
  setBeforeMessageCount(count: number): void;
50
+ /** Adopt an already committed epoch replacement as every resume baseline. */
51
+ adoptCommittedBoundary(messages: PiMessage[]): void;
50
52
  captureResumeSnapshot(messages: PiMessage[]): void;
51
53
  getResumeSnapshot(currentMessages: PiMessage[]): PiMessage[];
52
54
  markTimedOut(): void;
@@ -4,7 +4,7 @@
4
4
  * Builds everything the agent can act through for one run slice: the sandbox
5
5
  * executor and lazy workspace, MCP and plugin auth orchestration, MCP
6
6
  * provider restoration from durable history, and the Pi-facing tool surfaces
7
- * (agent tools plus the advisor's tool view). Auth pauses raised while
7
+ * (main-agent tools plus runtime control tools). Auth pauses raised while
8
8
  * restoring providers are thrown here so the run parks before prompting.
9
9
  */
10
10
  import type { AgentTool } from "@earendil-works/pi-agent-core";
@@ -49,6 +49,7 @@ interface ToolWiringArgs {
49
49
  preAgentPromptMessages: () => PiMessage[];
50
50
  priorPiMessages: PiMessage[] | undefined;
51
51
  recordConnectedMcpProvider: (provider: string) => Promise<void>;
52
+ requestHandoff?: ToolRuntimeContext["handoff"];
52
53
  resume: ResumeState;
53
54
  routing: AgentRunRouting;
54
55
  sessionConversationId?: string;
@@ -1,25 +1,19 @@
1
- declare const ADVISOR_THINKING_LEVELS: readonly ["minimal", "low", "medium", "high", "xhigh"];
2
- export type AdvisorThinkingLevel = (typeof ADVISOR_THINKING_LEVELS)[number];
3
1
  /**
4
2
  * Buffer between the Vercel function timeout and the agent turn timeout so
5
3
  * Junior can abort, persist, and schedule continuation before host teardown.
6
4
  */
7
5
  export declare const FUNCTION_TIMEOUT_BUFFER_SECONDS = 20;
8
6
  export interface BotConfig {
9
- advisor: AdvisorConfig;
10
7
  embeddingModelId: string;
11
8
  fastModelId: string;
12
9
  loadingMessages: string[];
13
10
  modelId: string;
11
+ modelProfiles: Readonly<Record<string, string>>;
14
12
  modelContextWindowTokens?: number;
15
13
  visionModelId?: string;
16
14
  turnTimeoutMs: number;
17
15
  userName: string;
18
16
  }
19
- export interface AdvisorConfig {
20
- modelId: string;
21
- thinkingLevel: AdvisorThinkingLevel;
22
- }
23
17
  export type SqlDriver = "neon" | "postgres";
24
18
  export interface ChatConfig {
25
19
  bot: BotConfig;
@@ -67,4 +61,3 @@ export interface SlackReactionConfig {
67
61
  export declare function getSlackReactionConfig(): SlackReactionConfig;
68
62
  /** Apply Slack reaction emoji overrides from createApp() options, validating names. */
69
63
  export declare function setSlackReactionConfig(overrides: Partial<SlackReactionConfig>): void;
70
- export {};
@@ -2,18 +2,148 @@
2
2
  * Durable agent execution history port.
3
3
  *
4
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.
5
+ * rebuilds (compaction, handoff, rollback) open a new context epoch instead of
6
+ * rewriting history. Each new epoch binds the model profile that owns it and
7
+ * records the exact resolved model id for audit.
6
8
  * The step envelope is strictly validated — an unknown type or malformed shape
7
9
  * is corrupt state and fails loudly — while `pi_message` content stays
8
10
  * permissive because the Pi SDK owns the message shape.
9
11
  */
10
12
  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";
13
+ declare const piMessageStepSchema: z.ZodObject<{
14
+ message: z.ZodPipe<z.ZodObject<{
15
+ role: z.ZodString;
16
+ }, 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, {
17
+ [x: string]: unknown;
18
+ role: string;
19
+ }>>;
20
+ createdAtMs: z.ZodNumber;
21
+ provenance: z.ZodOptional<z.ZodObject<{
22
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
23
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
24
+ platform: z.ZodLiteral<"slack">;
25
+ teamId: z.ZodString;
26
+ email: z.ZodOptional<z.ZodString>;
27
+ fullName: z.ZodOptional<z.ZodString>;
28
+ userId: z.ZodString;
29
+ userName: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strict>, z.ZodObject<{
31
+ platform: z.ZodLiteral<"local">;
32
+ email: z.ZodOptional<z.ZodString>;
33
+ fullName: z.ZodOptional<z.ZodString>;
34
+ userId: z.ZodString;
35
+ userName: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strict>, z.ZodObject<{
37
+ platform: z.ZodLiteral<"system">;
38
+ name: z.ZodString;
39
+ }, z.core.$strict>], "platform">>;
40
+ }, z.core.$strict>>;
41
+ }, z.core.$strict>;
42
+ /** Validate one atomically persisted context epoch. */
43
+ export declare const contextEpochStartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
44
+ reason: z.ZodLiteral<"initial">;
45
+ modelProfile: z.ZodLiteral<"standard">;
46
+ modelId: z.ZodString;
47
+ messages: z.ZodArray<z.ZodObject<{
48
+ message: z.ZodPipe<z.ZodObject<{
49
+ role: z.ZodString;
50
+ }, 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, {
51
+ [x: string]: unknown;
52
+ role: string;
53
+ }>>;
54
+ createdAtMs: z.ZodNumber;
55
+ provenance: z.ZodOptional<z.ZodObject<{
56
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
57
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
58
+ platform: z.ZodLiteral<"slack">;
59
+ teamId: z.ZodString;
60
+ email: z.ZodOptional<z.ZodString>;
61
+ fullName: z.ZodOptional<z.ZodString>;
62
+ userId: z.ZodString;
63
+ userName: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strict>, z.ZodObject<{
65
+ platform: z.ZodLiteral<"local">;
66
+ email: z.ZodOptional<z.ZodString>;
67
+ fullName: z.ZodOptional<z.ZodString>;
68
+ userId: z.ZodString;
69
+ userName: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ platform: z.ZodLiteral<"system">;
72
+ name: z.ZodString;
73
+ }, z.core.$strict>], "platform">>;
74
+ }, z.core.$strict>>;
75
+ }, z.core.$strict>>;
76
+ }, z.core.$strict>, z.ZodObject<{
77
+ reason: z.ZodLiteral<"handoff">;
78
+ modelProfile: z.ZodString;
79
+ modelId: z.ZodString;
80
+ messages: z.ZodArray<z.ZodObject<{
81
+ message: z.ZodPipe<z.ZodObject<{
82
+ role: z.ZodString;
83
+ }, 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, {
84
+ [x: string]: unknown;
85
+ role: string;
86
+ }>>;
87
+ createdAtMs: z.ZodNumber;
88
+ provenance: z.ZodOptional<z.ZodObject<{
89
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
90
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
91
+ platform: z.ZodLiteral<"slack">;
92
+ teamId: z.ZodString;
93
+ email: z.ZodOptional<z.ZodString>;
94
+ fullName: z.ZodOptional<z.ZodString>;
95
+ userId: z.ZodString;
96
+ userName: z.ZodOptional<z.ZodString>;
97
+ }, z.core.$strict>, z.ZodObject<{
98
+ platform: z.ZodLiteral<"local">;
99
+ email: z.ZodOptional<z.ZodString>;
100
+ fullName: z.ZodOptional<z.ZodString>;
101
+ userId: z.ZodString;
102
+ userName: z.ZodOptional<z.ZodString>;
103
+ }, z.core.$strict>, z.ZodObject<{
104
+ platform: z.ZodLiteral<"system">;
105
+ name: z.ZodString;
106
+ }, z.core.$strict>], "platform">>;
107
+ }, z.core.$strict>>;
108
+ }, z.core.$strict>>;
109
+ }, z.core.$strict>, z.ZodObject<{
110
+ reason: z.ZodUnion<readonly [z.ZodLiteral<"compaction">, z.ZodLiteral<"rollback">]>;
111
+ modelProfile: z.ZodString;
112
+ modelId: z.ZodString;
113
+ messages: z.ZodArray<z.ZodObject<{
114
+ message: z.ZodPipe<z.ZodObject<{
115
+ role: z.ZodString;
116
+ }, 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, {
117
+ [x: string]: unknown;
118
+ role: string;
119
+ }>>;
120
+ createdAtMs: z.ZodNumber;
121
+ provenance: z.ZodOptional<z.ZodObject<{
122
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
123
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
124
+ platform: z.ZodLiteral<"slack">;
125
+ teamId: z.ZodString;
126
+ email: z.ZodOptional<z.ZodString>;
127
+ fullName: z.ZodOptional<z.ZodString>;
128
+ userId: z.ZodString;
129
+ userName: z.ZodOptional<z.ZodString>;
130
+ }, z.core.$strict>, z.ZodObject<{
131
+ platform: z.ZodLiteral<"local">;
132
+ email: z.ZodOptional<z.ZodString>;
133
+ fullName: z.ZodOptional<z.ZodString>;
134
+ userId: z.ZodString;
135
+ userName: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$strict>, z.ZodObject<{
137
+ platform: z.ZodLiteral<"system">;
138
+ name: z.ZodString;
139
+ }, z.core.$strict>], "platform">>;
140
+ }, z.core.$strict>>;
141
+ }, z.core.$strict>>;
142
+ }, z.core.$strict>], "reason">;
143
+ /** One atomically persisted context epoch and its model binding. */
144
+ export type ContextEpochStart = z.output<typeof contextEpochStartSchema>;
15
145
  /** Strict step envelope reused by the SQL row codec; unknown types fail loudly. */
16
- export declare const agentStepEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
146
+ export declare const agentStepEntrySchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
17
147
  type: z.ZodLiteral<"pi_message">;
18
148
  schemaVersion: z.ZodOptional<z.ZodNumber>;
19
149
  message: z.ZodPipe<z.ZodObject<{
@@ -42,9 +172,6 @@ export declare const agentStepEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<
42
172
  name: z.ZodString;
43
173
  }, z.core.$strict>], "platform">>;
44
174
  }, 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
175
  }, z.core.$strip>, z.ZodObject<{
49
176
  type: z.ZodLiteral<"mcp_provider_connected">;
50
177
  provider: z.ZodString;
@@ -82,13 +209,33 @@ export declare const agentStepEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<
82
209
  parentToolCallId: z.ZodOptional<z.ZodString>;
83
210
  reasoningLevel: z.ZodOptional<z.ZodString>;
84
211
  childConversationId: z.ZodString;
85
- historyMode: z.ZodLiteral<"shared">;
86
- }, z.core.$strip>, z.ZodObject<{
212
+ historyMode: z.ZodUnion<readonly [z.ZodLiteral<"isolated">, z.ZodLiteral<"shared">]>;
213
+ }, z.core.$strict>, z.ZodObject<{
87
214
  type: z.ZodLiteral<"subagent_ended">;
88
215
  subagentInvocationId: z.ZodString;
89
216
  outcome: z.ZodUnion<readonly [z.ZodLiteral<"success">, z.ZodLiteral<"error">, z.ZodLiteral<"aborted">]>;
90
217
  errorCode: z.ZodOptional<z.ZodString>;
91
- }, z.core.$strip>], "type">;
218
+ }, z.core.$strip>]>, z.ZodUnion<readonly [z.ZodObject<{
219
+ type: z.ZodLiteral<"context_epoch_started">;
220
+ reason: z.ZodLiteral<"initial">;
221
+ modelProfile: z.ZodLiteral<"standard">;
222
+ modelId: z.ZodString;
223
+ }, z.core.$strict>, z.ZodObject<{
224
+ type: z.ZodLiteral<"context_epoch_started">;
225
+ reason: z.ZodLiteral<"handoff">;
226
+ modelProfile: z.ZodString;
227
+ modelId: z.ZodString;
228
+ }, z.core.$strict>, z.ZodObject<{
229
+ type: z.ZodLiteral<"context_epoch_started">;
230
+ reason: z.ZodUnion<readonly [z.ZodLiteral<"compaction">, z.ZodLiteral<"rollback">]>;
231
+ modelProfile: z.ZodOptional<z.ZodUndefined>;
232
+ modelId: z.ZodOptional<z.ZodUndefined>;
233
+ }, z.core.$strict>, z.ZodObject<{
234
+ type: z.ZodLiteral<"context_epoch_started">;
235
+ reason: z.ZodUnion<readonly [z.ZodLiteral<"compaction">, z.ZodLiteral<"rollback">]>;
236
+ modelProfile: z.ZodString;
237
+ modelId: z.ZodString;
238
+ }, z.core.$strict>]>]>;
92
239
  /** One durable execution step's validated payload (sessionId lifted to epoch). */
93
240
  export type AgentStepEntry = z.infer<typeof agentStepEntrySchema>;
94
241
  /** A step read back from storage with its assigned order and epoch. */
@@ -98,31 +245,98 @@ export interface StoredAgentStep {
98
245
  createdAtMs: number;
99
246
  entry: AgentStepEntry;
100
247
  }
248
+ /** Validate a current-epoch append without permitting epoch markers. */
249
+ export declare const newAgentStepSchema: z.ZodObject<{
250
+ entry: z.ZodUnion<readonly [z.ZodObject<{
251
+ type: z.ZodLiteral<"pi_message">;
252
+ schemaVersion: z.ZodOptional<z.ZodNumber>;
253
+ message: z.ZodPipe<z.ZodObject<{
254
+ role: z.ZodString;
255
+ }, 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, {
256
+ [x: string]: unknown;
257
+ role: string;
258
+ }>>;
259
+ provenance: z.ZodOptional<z.ZodObject<{
260
+ authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
261
+ actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
262
+ platform: z.ZodLiteral<"slack">;
263
+ teamId: z.ZodString;
264
+ email: z.ZodOptional<z.ZodString>;
265
+ fullName: z.ZodOptional<z.ZodString>;
266
+ userId: z.ZodString;
267
+ userName: z.ZodOptional<z.ZodString>;
268
+ }, z.core.$strict>, z.ZodObject<{
269
+ platform: z.ZodLiteral<"local">;
270
+ email: z.ZodOptional<z.ZodString>;
271
+ fullName: z.ZodOptional<z.ZodString>;
272
+ userId: z.ZodString;
273
+ userName: z.ZodOptional<z.ZodString>;
274
+ }, z.core.$strict>, z.ZodObject<{
275
+ platform: z.ZodLiteral<"system">;
276
+ name: z.ZodString;
277
+ }, z.core.$strict>], "platform">>;
278
+ }, z.core.$strict>>;
279
+ }, z.core.$strip>, z.ZodObject<{
280
+ type: z.ZodLiteral<"mcp_provider_connected">;
281
+ provider: z.ZodString;
282
+ }, z.core.$strip>, z.ZodObject<{
283
+ type: z.ZodLiteral<"authorization_requested">;
284
+ kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
285
+ provider: z.ZodString;
286
+ actorId: z.ZodString;
287
+ authorizationId: z.ZodString;
288
+ delivery: z.ZodUnion<readonly [z.ZodLiteral<"private_link_sent">, z.ZodLiteral<"private_link_reused">]>;
289
+ }, z.core.$strip>, z.ZodObject<{
290
+ type: z.ZodLiteral<"authorization_completed">;
291
+ kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
292
+ provider: z.ZodString;
293
+ actorId: z.ZodString;
294
+ authorizationId: z.ZodString;
295
+ }, z.core.$strip>, z.ZodObject<{
296
+ type: z.ZodLiteral<"tool_execution_started">;
297
+ toolCallId: z.ZodString;
298
+ toolName: z.ZodString;
299
+ args: z.ZodOptional<z.ZodUnknown>;
300
+ }, z.core.$strip>, z.ZodObject<{
301
+ type: z.ZodLiteral<"visible_context_compacted">;
302
+ compactions: z.ZodArray<z.ZodObject<{
303
+ coveredMessageIds: z.ZodArray<z.ZodString>;
304
+ createdAtMs: z.ZodNumber;
305
+ id: z.ZodString;
306
+ summary: z.ZodString;
307
+ }, z.core.$strip>>;
308
+ }, z.core.$strip>, z.ZodObject<{
309
+ type: z.ZodLiteral<"subagent_started">;
310
+ subagentInvocationId: z.ZodString;
311
+ subagentKind: z.ZodString;
312
+ modelId: z.ZodOptional<z.ZodString>;
313
+ parentToolCallId: z.ZodOptional<z.ZodString>;
314
+ reasoningLevel: z.ZodOptional<z.ZodString>;
315
+ childConversationId: z.ZodString;
316
+ historyMode: z.ZodUnion<readonly [z.ZodLiteral<"isolated">, z.ZodLiteral<"shared">]>;
317
+ }, z.core.$strict>, z.ZodObject<{
318
+ type: z.ZodLiteral<"subagent_ended">;
319
+ subagentInvocationId: z.ZodString;
320
+ outcome: z.ZodUnion<readonly [z.ZodLiteral<"success">, z.ZodLiteral<"error">, z.ZodLiteral<"aborted">]>;
321
+ errorCode: z.ZodOptional<z.ZodString>;
322
+ }, z.core.$strip>]>;
323
+ createdAtMs: z.ZodNumber;
324
+ }, z.core.$strict>;
101
325
  /** A step to append; the store assigns `seq` and the current `context_epoch`. */
102
- export interface NewAgentStep {
103
- entry: AgentStepEntry;
104
- createdAtMs: number;
105
- }
326
+ export type NewAgentStep = z.output<typeof newAgentStepSchema>;
106
327
  /** A replacement Pi message written into a freshly opened epoch. */
107
- export interface PiMessageStep {
108
- message: PiMessage;
109
- createdAtMs: number;
110
- provenance?: PiMessageProvenance;
111
- }
328
+ export type PiMessageStep = z.output<typeof piMessageStepSchema>;
112
329
  /** Persist and read the durable per-conversation agent execution history. */
113
330
  export interface AgentStepStore {
114
331
  /** Append steps in one transaction, assigning `seq = max+1` under the lease. */
115
332
  append(conversationId: string, steps: NewAgentStep[]): Promise<void>;
116
333
  /**
117
- * Open the next epoch in one transaction: a `context_epoch_started` marker
118
- * followed by the replacement messages as ordinary `pi_message` rows.
334
+ * Open initial epoch 0 or the next replacement epoch in one transaction.
119
335
  */
120
- startEpoch(conversationId: string, opts: {
121
- reason: EpochReason;
122
- messages: PiMessageStep[];
123
- }): Promise<void>;
336
+ startEpoch(conversationId: string, opts: ContextEpochStart): Promise<void>;
124
337
  /** Steps of the highest epoch in `seq` order (all types; caller filters). */
125
338
  loadCurrentEpoch(conversationId: string): Promise<StoredAgentStep[]>;
126
339
  /** All steps across all epochs in `seq` order, for audit and reporting. */
127
340
  loadHistory(conversationId: string): Promise<StoredAgentStep[]>;
128
341
  }
342
+ export {};
@@ -0,0 +1,7 @@
1
+ import { type PiMessage } from "@/chat/pi/messages";
2
+ /** Read historical advisor messages during the bounded Redis-to-SQL import. */
3
+ export interface LegacyAdvisorSessionReader {
4
+ load: (conversationId: string) => Promise<PiMessage[]>;
5
+ }
6
+ /** Create the load-only reader for historical advisor session blobs. */
7
+ export declare function createLegacyAdvisorSessionReader(): LegacyAdvisorSessionReader;
@@ -1,6 +1,6 @@
1
1
  import { type ConversationCompaction, type ConversationMessage as ThreadConversationMessage } from "@/chat/state/conversation";
2
2
  import { type SessionLogStore } from "@/chat/state/session-log";
3
- import { type AdvisorSessionStore } from "@/chat/tools/advisor/session-store";
3
+ import { type LegacyAdvisorSessionReader } from "@/chat/conversations/legacy-advisor-session";
4
4
  import type { JuniorSqlDatabase } from "@/db/db";
5
5
  import type { ConversationMessageStore } from "./messages";
6
6
  import type { Conversation } from "./store";
@@ -9,7 +9,7 @@ export interface LegacyImportDeps {
9
9
  executor: JuniorSqlDatabase;
10
10
  messageStore: ConversationMessageStore;
11
11
  sessionLogStore?: SessionLogStore;
12
- advisorSessionStore?: AdvisorSessionStore;
12
+ advisorSessionStore?: LegacyAdvisorSessionReader;
13
13
  loadVisibleMessages?: (conversationId: string) => Promise<ThreadConversationMessage[]>;
14
14
  legacyCompactions?: ConversationCompaction[];
15
15
  /** Conversation metadata used for imported creation and activity clocks. */
@@ -1,8 +1,16 @@
1
1
  import type { PiMessage } from "@/chat/pi/messages";
2
2
  import { type AuthorizationKind, type PiMessageProvenance, type SessionProjection } from "@/chat/state/session-log";
3
3
  import type { StoredAgentStep } from "@/chat/conversations/history";
4
+ import type { ModelProfile } from "@/chat/model-profile";
5
+ /** Current conversation context with its authoritative model binding. */
6
+ export interface ConversationProjection extends SessionProjection {
7
+ /** Model profile bound to this projection. */
8
+ modelProfile: ModelProfile;
9
+ /** Audit snapshot; runtime model selection remains profile-driven. */
10
+ modelId: string | undefined;
11
+ }
4
12
  /** Aligned step projection: `provenance[i]` and `seqs[i]` describe `messages[i]`. */
5
- export interface StepProjection extends SessionProjection {
13
+ export interface StepProjection extends ConversationProjection {
6
14
  /** The `seq` of the step each projected message came from. */
7
15
  seqs: number[];
8
16
  }
@@ -20,7 +28,11 @@ interface ScopedConversation {
20
28
  /** Load the current-epoch Pi projection for a conversation. */
21
29
  export declare function loadProjection(args: ScopedConversation): Promise<PiMessage[]>;
22
30
  /** Load the current-epoch Pi projection with aligned per-message provenance. */
23
- export declare function loadProjectionWithProvenance(args: ScopedConversation): Promise<SessionProjection>;
31
+ export declare function loadConversationProjection(args: ScopedConversation): Promise<ConversationProjection>;
32
+ /** Open a standard initial epoch before a conversation's first model request. */
33
+ export declare function openConversationProjection(args: ScopedConversation & {
34
+ modelId: string;
35
+ }): Promise<ConversationProjection>;
24
36
  /**
25
37
  * Load a turn's committed Pi projection from the durable step store.
26
38
  *
@@ -45,10 +57,14 @@ export declare function loadConnectedMcpProviders(args: ScopedConversation): Pro
45
57
  * projection normally, or open a `rollback` epoch when it diverged (a
46
58
  * provider-retry trim regenerated trailing assistant output). Returns the
47
59
  * resolved provenance, the per-message step seqs, and the `seq` boundary that
48
- * reproduces exactly the committed messages.
60
+ * reproduces exactly the committed messages. A first commit atomically opens
61
+ * the standard initial epoch; the run boundary opens it earlier when a model
62
+ * may act before any session checkpoint, such as recordless handoff.
49
63
  */
50
64
  export declare function commitMessages(args: {
51
65
  conversationId: string;
66
+ /** Exact model selected for this write; persisted for epoch audit only. */
67
+ modelId: string;
52
68
  messages: PiMessage[];
53
69
  /** Explicit per-message provenance aligned one-to-one with `messages`. */
54
70
  provenance?: PiMessageProvenance[];
@@ -28,7 +28,7 @@ export declare function convertLegacySessionLog(args: {
28
28
  entries: SessionLogEntry[];
29
29
  fallbackCreatedAtMs: number;
30
30
  }): ConvertedLegacyLog;
31
- /** Convert an advisor session blob into epoch-0 child pi_message rows. */
31
+ /** Import advisor child rows while decoding the historical request envelope. */
32
32
  export declare function convertAdvisorMessages(messages: PiMessage[], fallbackCreatedAtMs: number): ImportedStep[];
33
33
  /** One conversation's converted history plus optional advisor child history. */
34
34
  export interface LegacyImportWrite {
@@ -1,15 +1,12 @@
1
1
  import type { Destination } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
3
  import type { StoredSlackActor } from "@/chat/actor";
4
- import type { JuniorSqlDatabase, JuniorSqlMigrationExecutor } from "@/db/db";
4
+ import type { JuniorSqlDatabase } from "@/db/db";
5
5
  import type { Conversation, ConversationExecution, ConversationSource, ConversationStore } from "../store";
6
+ import type { AgentTurnUsage } from "@/chat/usage";
6
7
  export declare class SqlStore implements ConversationStore {
7
8
  private readonly executor;
8
- private readonly migrationExecutor;
9
- private schemaReady;
10
- constructor(executor: JuniorSqlDatabase, migrationExecutor: JuniorSqlMigrationExecutor);
11
- /** Apply SQL schema migrations before runtime uses this store. */
12
- migrate(): Promise<void>;
9
+ constructor(executor: JuniorSqlDatabase);
13
10
  get(args: {
14
11
  conversationId: string;
15
12
  }): Promise<Conversation | undefined>;
@@ -31,6 +28,10 @@ export declare class SqlStore implements ConversationStore {
31
28
  destination?: Destination;
32
29
  execution: ConversationExecution;
33
30
  lastActivityAtMs: number;
31
+ metrics: {
32
+ durationMs: number;
33
+ usage?: AgentTurnUsage;
34
+ } | null;
34
35
  actor?: StoredSlackActor;
35
36
  source?: ConversationSource;
36
37
  title?: string;
@@ -42,8 +43,13 @@ export declare class SqlStore implements ConversationStore {
42
43
  parentConversationId: string;
43
44
  nowMs?: number;
44
45
  }): Promise<void>;
45
- /** Copy one conversation record into SQL during backfill. */
46
- backfillConversation(sourceConversation: Conversation): Promise<void>;
46
+ /** Copy one conversation record and retained metrics into SQL during backfill. */
47
+ backfillConversation(sourceConversation: Conversation, metrics?: {
48
+ durationMs: number;
49
+ executionDurationMs: number;
50
+ executionUsage?: AgentTurnUsage;
51
+ usage?: AgentTurnUsage;
52
+ }): Promise<void>;
47
53
  listByActivity(args?: {
48
54
  limit?: number;
49
55
  offset?: number;
@@ -61,4 +67,4 @@ export declare class SqlStore implements ConversationStore {
61
67
  private upsertDestination;
62
68
  }
63
69
  /** Create a SQL-backed conversation store. */
64
- export declare function createSqlStore(executor: JuniorSqlMigrationExecutor): SqlStore;
70
+ export declare function createSqlStore(executor: JuniorSqlDatabase): SqlStore;
@@ -1,6 +1,7 @@
1
1
  import type { Destination } from "@sentry/junior-plugin-api";
2
2
  import type { ConversationPrivacy } from "@/chat/conversation-privacy";
3
3
  import type { StoredSlackActor } from "@/chat/actor";
4
+ import type { AgentTurnUsage } from "@/chat/usage";
4
5
  export type ConversationSource = "api" | "internal" | "local" | "plugin" | "resource_event" | "scheduler" | "slack";
5
6
  export type ConversationStatus = "awaiting_resume" | "failed" | "idle" | "pending" | "running";
6
7
  export interface ConversationExecution {
@@ -57,10 +58,10 @@ export interface ConversationStore {
57
58
  /**
58
59
  * Establish a subagent child conversation row linked to its parent.
59
60
  *
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.
61
+ * Subagent histories live under their own child `conversation_id` with
62
+ * `parent_conversation_id` set; the child carries no destination and is
63
+ * excluded from top-level listings. Idempotent: it links a bare row a step
64
+ * append may have created first without clobbering it.
64
65
  */
65
66
  ensureChildConversation(args: {
66
67
  conversationId: string;
@@ -75,6 +76,10 @@ export interface ConversationStore {
75
76
  destination?: Destination;
76
77
  execution: ConversationExecution;
77
78
  lastActivityAtMs: number;
79
+ metrics: {
80
+ durationMs: number;
81
+ usage?: AgentTurnUsage;
82
+ } | null;
78
83
  actor?: StoredSlackActor;
79
84
  source?: ConversationSource;
80
85
  title?: string;
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ import type { BotConfig } from "@/chat/config";
3
+ export declare const STANDARD_MODEL_PROFILE = "standard";
4
+ export declare const DEFAULT_HANDOFF_MODEL_PROFILE = "handoff";
5
+ /** Keep durable profile names stable and safe to expose in tool schemas. */
6
+ export declare const modelProfileSchema: z.ZodString;
7
+ /** A configured model role rather than a provider-specific model id. */
8
+ export type ModelProfile = z.output<typeof modelProfileSchema>;
9
+ /** Identify durable profile bindings that the current host cannot resolve. */
10
+ export declare class ModelProfileNotConfiguredError extends Error {
11
+ constructor(profile: ModelProfile);
12
+ }
13
+ /** Resolve a stable model profile through the host-owned model catalog. */
14
+ export declare function modelIdForProfile(config: BotConfig, profile: ModelProfile): string;
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * Shape predicates and durable-history manipulation for raw Pi messages,
5
5
  * shared by the agent executor and the services that persist, trim, or
6
- * summarize transcripts. Volatile runtime turn context (the
7
- * `<runtime-turn-context>` bootstrap block) is stripped here so durable
8
- * history never retains per-session runtime instructions as user text.
6
+ * summarize transcripts. The utilities here strip stale
7
+ * `<runtime-turn-context>` bootstrap blocks before history is reused or
8
+ * replaced; an active completed projection may retain its current bootstrap.
9
9
  */
10
10
  import type { AssistantMessage, ToolResultMessage } from "@earendil-works/pi-ai";
11
11
  import type { PiMessage } from "@/chat/pi/messages";
@@ -27,6 +27,8 @@ export declare function getTerminalAssistantMessages(messages: readonly unknown[
27
27
  export declare function trimTrailingAssistantMessages(messages: PiMessage[]): PiMessage[];
28
28
  /** Return whether Pi history already carries session bootstrap context. */
29
29
  export declare function hasRuntimeTurnContext(messages: PiMessage[]): boolean;
30
+ /** Keep only volatile bootstrap messages needed by an in-turn context replacement. */
31
+ export declare function retainRuntimeTurnContext(messages: PiMessage[]): PiMessage[];
30
32
  /**
31
33
  * Reduce a runtime user-turn prompt to only the current turn's instruction.
32
34
  *
@@ -21,9 +21,9 @@ declare const subscriptionSchema: z.ZodObject<{
21
21
  resourceRef: z.ZodString;
22
22
  resourceType: z.ZodString;
23
23
  status: z.ZodEnum<{
24
- cancelled: "cancelled";
25
- completed: "completed";
26
24
  active: "active";
25
+ completed: "completed";
26
+ cancelled: "cancelled";
27
27
  }>;
28
28
  updatedAtMs: z.ZodNumber;
29
29
  }, z.core.$strict>;