@sentry/junior 0.112.0 → 0.114.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 (59) hide show
  1. package/dist/{agent-hooks-6MVTPKP4.js → agent-hooks-WNBUY4OB.js} +8 -8
  2. package/dist/api/conversations/cursor.d.ts +17 -0
  3. package/dist/api/conversations/detail.d.ts +40 -18
  4. package/dist/api/conversations/event-list.d.ts +115 -0
  5. package/dist/api/conversations/event-page.d.ts +18 -0
  6. package/dist/api/conversations/events.d.ts +6 -2
  7. package/dist/api/conversations/projection.d.ts +6 -1
  8. package/dist/api/schema/conversation.d.ts +228 -51
  9. package/dist/api/schema.d.ts +2 -2
  10. package/dist/api/schema.js +7 -1
  11. package/dist/api.js +461 -139
  12. package/dist/app.d.ts +2 -0
  13. package/dist/app.js +33 -24
  14. package/dist/{catalog-runtime-UEO25P2J.js → catalog-runtime-6O4M6JGA.js} +5 -5
  15. package/dist/chat/config.d.ts +1 -1
  16. package/dist/chat/conversations/history.d.ts +86 -0
  17. package/dist/chat/conversations/projection.d.ts +20 -1
  18. package/dist/chat/pi/transcript.d.ts +2 -0
  19. package/dist/chat/services/context-budget.d.ts +7 -2
  20. package/dist/chat/services/context-compaction.d.ts +28 -1
  21. package/dist/chat/services/conversation-memory.d.ts +1 -0
  22. package/dist/chat/services/provider-error.d.ts +40 -0
  23. package/dist/chat/services/provider-retry.d.ts +3 -6
  24. package/dist/chat/services/turn-router.d.ts +1 -0
  25. package/dist/chat/task-execution/state.d.ts +2 -2
  26. package/dist/chat/task-execution/store.d.ts +1 -1
  27. package/dist/chat/tools/sandbox/edit-file.d.ts +1 -1
  28. package/dist/chat/tools/sandbox/text-edits.d.ts +1 -0
  29. package/dist/{chunk-CSS7JHEM.js → chunk-4FUEG3QY.js} +1 -1
  30. package/dist/{chunk-AU2JVUDF.js → chunk-5CZ7RETL.js} +1 -1
  31. package/dist/{chunk-SKEMI4IF.js → chunk-6QWPVTMO.js} +200 -52
  32. package/dist/{chunk-AWNDKI5K.js → chunk-ABPSDO6M.js} +20 -15
  33. package/dist/{chunk-QIALGHRN.js → chunk-FIGAF6KL.js} +34 -2
  34. package/dist/{chunk-TZU3R5OC.js → chunk-K2W4CK7K.js} +1 -1
  35. package/dist/{chunk-2FJ6WEYV.js → chunk-O4GT7LYB.js} +1 -1
  36. package/dist/{chunk-ZHP4KNF7.js → chunk-OSKEC4XU.js} +1 -1
  37. package/dist/{chunk-IV2O4HQJ.js → chunk-PM3PX42K.js} +1 -1
  38. package/dist/{chunk-NDQL4ESR.js → chunk-RD7EJI7H.js} +2 -2
  39. package/dist/{chunk-JE23YR3X.js → chunk-S4QDH23A.js} +75 -43
  40. package/dist/{chunk-GJG67YFS.js → chunk-TLGM5X2M.js} +2 -2
  41. package/dist/{chunk-VBSVNOLA.js → chunk-VNNBSKCO.js} +5 -5
  42. package/dist/{chunk-4EJO4HIC.js → chunk-W6RDUAO3.js} +1 -1
  43. package/dist/{chunk-GR4IB6OQ.js → chunk-WV4UJBAS.js} +431 -96
  44. package/dist/{chunk-66IP6WED.js → chunk-XLFBQJUO.js} +4 -4
  45. package/dist/{chunk-X3SP5RDW.js → chunk-YU6PO42Q.js} +1 -1
  46. package/dist/{chunk-PK4ETCUQ.js → chunk-ZGXH3REA.js} +226 -215
  47. package/dist/cli/chat.js +19 -19
  48. package/dist/cli/check.js +6 -6
  49. package/dist/cli/plugins.js +11 -11
  50. package/dist/cli/snapshot-warmup.js +8 -8
  51. package/dist/cli/upgrade.js +5 -5
  52. package/dist/{db-P5H5RVQV.js → db-4VLP7KBF.js} +5 -5
  53. package/dist/instrumentation.js +2 -2
  54. package/dist/nitro.js +2 -2
  55. package/dist/{runner-B4ZDUO3R.js → runner-IPXLWQOF.js} +12 -13
  56. package/dist/{skills-GWTOZ3XV.js → skills-QCNZISNF.js} +6 -6
  57. package/dist/{validation-QFIC6XH6.js → validation-I2BW3UHD.js} +6 -6
  58. package/dist/version.js +1 -1
  59. package/package.json +6 -6
package/dist/app.d.ts CHANGED
@@ -45,6 +45,8 @@ export interface JuniorDashboardOptions {
45
45
  basePath?: string;
46
46
  /** Public deployment origin used for auth callbacks and external links. */
47
47
  baseURL?: string;
48
+ /** Expose the config-gated component gallery for local visual QA. */
49
+ componentGallery?: boolean;
48
50
  /** Disable dashboard route mounting while preserving serializable config shape. */
49
51
  disabled?: boolean;
50
52
  /** Replace conversation API responses with dashboard visual-QA fixtures. */
package/dist/app.js CHANGED
@@ -6,14 +6,14 @@ import {
6
6
  processPluginTask,
7
7
  requireTurnFailureEventId,
8
8
  scheduleSessionCompletedPluginTasks
9
- } from "./chunk-AWNDKI5K.js";
9
+ } from "./chunk-ABPSDO6M.js";
10
10
  import {
11
11
  GET,
12
12
  buildSentryConversationUrl,
13
13
  conversationVisibilityFromSlackChannelType,
14
14
  resolveSlackChannelTypeFromMessage,
15
15
  resolveSlackConversationContext
16
- } from "./chunk-2FJ6WEYV.js";
16
+ } from "./chunk-O4GT7LYB.js";
17
17
  import "./chunk-2ZTTXTSZ.js";
18
18
  import {
19
19
  ConversationQueueMessageRejectedError,
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  validatePluginEgressCredentialHooks,
33
33
  validatePluginRegistrations
34
- } from "./chunk-4EJO4HIC.js";
34
+ } from "./chunk-W6RDUAO3.js";
35
35
  import {
36
36
  defineJuniorPlugins,
37
37
  pluginCatalogConfigFromEnv,
@@ -84,7 +84,7 @@ import {
84
84
  splitSlackReplyText,
85
85
  startOAuthFlow,
86
86
  truncateStatusText
87
- } from "./chunk-GR4IB6OQ.js";
87
+ } from "./chunk-WV4UJBAS.js";
88
88
  import {
89
89
  ConversationTurnBoundaryError,
90
90
  CooperativeTurnYieldError,
@@ -140,11 +140,13 @@ import {
140
140
  recordAuthorizationCompleted,
141
141
  recordDeliveredAssistantMessage,
142
142
  startActiveTurn,
143
+ stripRuntimeTurnContext,
144
+ trimTrailingAssistantMessages,
143
145
  turnHasReply,
144
146
  updateConversationStats,
145
147
  upsertConversationMessage
146
- } from "./chunk-SKEMI4IF.js";
147
- import "./chunk-66IP6WED.js";
148
+ } from "./chunk-6QWPVTMO.js";
149
+ import "./chunk-XLFBQJUO.js";
148
150
  import "./chunk-MU6HHZEN.js";
149
151
  import "./chunk-PDO5BLNM.js";
150
152
  import "./chunk-UIE3R5XU.js";
@@ -163,12 +165,12 @@ import {
163
165
  validatePlugins,
164
166
  verifyScheduledTaskCredentialSubject,
165
167
  verifySlackDirectCredentialSubject
166
- } from "./chunk-VBSVNOLA.js";
168
+ } from "./chunk-VNNBSKCO.js";
167
169
  import {
168
170
  acquireActiveLock,
169
171
  getDefaultRedisStateAdapterFor,
170
172
  getStateAdapter
171
- } from "./chunk-X3SP5RDW.js";
173
+ } from "./chunk-YU6PO42Q.js";
172
174
  import {
173
175
  SlackActionError,
174
176
  downloadPrivateSlackFile,
@@ -179,7 +181,7 @@ import {
179
181
  normalizeSlackConversationId,
180
182
  runWithSlackInstallationToken,
181
183
  runWithWorkspaceTeamId
182
- } from "./chunk-NDQL4ESR.js";
184
+ } from "./chunk-RD7EJI7H.js";
183
185
  import {
184
186
  contextProvenance,
185
187
  createSlackDestination,
@@ -193,7 +195,7 @@ import {
193
195
  requireSlackDestination,
194
196
  sameDestination,
195
197
  withConversationEventLock
196
- } from "./chunk-QIALGHRN.js";
198
+ } from "./chunk-FIGAF6KL.js";
197
199
  import {
198
200
  juniorConversationEvents,
199
201
  juniorConversations
@@ -203,6 +205,7 @@ import {
203
205
  } from "./chunk-4ZNGQH7C.js";
204
206
  import {
205
207
  FUNCTION_TIMEOUT_BUFFER_SECONDS,
208
+ STANDARD_MODEL_PROFILE,
206
209
  botConfig,
207
210
  completeObject,
208
211
  completeText,
@@ -219,10 +222,8 @@ import {
219
222
  modelIdForProfile,
220
223
  normalizeSlackEmojiName,
221
224
  setSlackReactionConfig,
222
- standardModelId,
223
- stripRuntimeTurnContext,
224
- trimTrailingAssistantMessages
225
- } from "./chunk-PK4ETCUQ.js";
225
+ standardModelId
226
+ } from "./chunk-ZGXH3REA.js";
226
227
  import {
227
228
  juniorDestinations
228
229
  } from "./chunk-VFUK3X5B.js";
@@ -234,16 +235,16 @@ import {
234
235
  } from "./chunk-6Y5L4BOM.js";
235
236
  import {
236
237
  discoverSkills
237
- } from "./chunk-GJG67YFS.js";
238
+ } from "./chunk-TLGM5X2M.js";
238
239
  import {
239
240
  pluginCatalogRuntime
240
- } from "./chunk-ZHP4KNF7.js";
241
+ } from "./chunk-OSKEC4XU.js";
241
242
  import {
242
243
  buildOAuthTokenRequest,
243
244
  credentialSubjectSchema,
244
245
  hasRequiredOAuthScope,
245
246
  parseOAuthTokenResponse
246
- } from "./chunk-TZU3R5OC.js";
247
+ } from "./chunk-K2W4CK7K.js";
247
248
  import {
248
249
  createActor,
249
250
  createSlackActor,
@@ -268,7 +269,7 @@ import {
268
269
  setTags,
269
270
  withContext,
270
271
  withSpan
271
- } from "./chunk-CSS7JHEM.js";
272
+ } from "./chunk-4FUEG3QY.js";
272
273
  import {
273
274
  isRecord,
274
275
  parseSlackChannelId,
@@ -285,10 +286,10 @@ import {
285
286
  } from "./chunk-3V7OFJZC.js";
286
287
  import {
287
288
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
288
- } from "./chunk-AU2JVUDF.js";
289
+ } from "./chunk-5CZ7RETL.js";
289
290
  import {
290
291
  JUNIOR_VERSION
291
- } from "./chunk-IV2O4HQJ.js";
292
+ } from "./chunk-PM3PX42K.js";
292
293
  import "./chunk-MLKGABMK.js";
293
294
 
294
295
  // src/app.ts
@@ -10764,13 +10765,14 @@ async function loadPiMessagesForTurn(args) {
10764
10765
  };
10765
10766
  }
10766
10767
  }
10767
- const projection = await loadProjection({
10768
+ const projection = await loadConversationProjection({
10768
10769
  conversationId: args.conversationId
10769
10770
  });
10770
- if (projection.length > 0) {
10771
+ if (projection.messages.length > 0) {
10771
10772
  return {
10772
10773
  canCompact: true,
10773
- piMessages: projection
10774
+ modelProfile: projection.modelProfile,
10775
+ piMessages: projection.messages
10774
10776
  };
10775
10777
  }
10776
10778
  return {};
@@ -11340,7 +11342,11 @@ function createReplyToThread(deps) {
11340
11342
  runId
11341
11343
  },
11342
11344
  onCompactionStart: () => status.update(compactingStatus),
11343
- piMessages
11345
+ piMessages,
11346
+ modelId: modelIdForProfile(
11347
+ botConfig,
11348
+ loadedPiMessages.modelProfile ?? STANDARD_MODEL_PROFILE
11349
+ )
11344
11350
  });
11345
11351
  if (compaction.compacted) {
11346
11352
  piMessages = compaction.piMessages;
@@ -13166,6 +13172,9 @@ function dashboardHostRoutePaths(dashboard) {
13166
13172
  `${peoplePath}/*`,
13167
13173
  pagePath("system")
13168
13174
  ];
13175
+ if (dashboard.componentGallery) {
13176
+ pagePaths.push(pagePath("dev"), `${pagePath("dev")}/*`);
13177
+ }
13169
13178
  const loginPath = basePath === "/" ? "/auth/login" : `${basePath}/auth/login`;
13170
13179
  return [
13171
13180
  ...pagePaths,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-ZHP4KNF7.js";
4
- import "./chunk-TZU3R5OC.js";
3
+ } from "./chunk-OSKEC4XU.js";
4
+ import "./chunk-K2W4CK7K.js";
5
5
  import "./chunk-C4MZ3GP5.js";
6
- import "./chunk-CSS7JHEM.js";
6
+ import "./chunk-4FUEG3QY.js";
7
7
  import "./chunk-42WRQLJ6.js";
8
8
  import "./chunk-6GWA276C.js";
9
9
  import "./chunk-B3IT5END.js";
10
10
  import "./chunk-3V7OFJZC.js";
11
- import "./chunk-AU2JVUDF.js";
12
- import "./chunk-IV2O4HQJ.js";
11
+ import "./chunk-5CZ7RETL.js";
12
+ import "./chunk-PM3PX42K.js";
13
13
  import "./chunk-MLKGABMK.js";
14
14
  export {
15
15
  pluginCatalogRuntime
@@ -8,13 +8,13 @@ export declare const FUNCTION_TIMEOUT_BUFFER_SECONDS = 20;
8
8
  /** Additional buffer that makes conversation work yield before the hard request deadline. */
9
9
  export declare const CONVERSATION_WORK_SOFT_YIELD_BUFFER_SECONDS = 40;
10
10
  export interface BotConfig {
11
+ contextWindowTokens: number;
11
12
  embeddingModelId: string;
12
13
  fastModelId: string;
13
14
  imageGenerationModelId: string;
14
15
  loadingMessages: string[];
15
16
  profiles: Readonly<Record<string, ExecutionProfileConfig>>;
16
17
  reasoningLevel?: TurnReasoningLevel;
17
- modelContextWindowTokens?: number;
18
18
  visionModelId?: string;
19
19
  maxSlicesPerTurn: number;
20
20
  turnTimeoutMs: number;
@@ -62,6 +62,16 @@ export declare const historyReplacementSchema: z.ZodObject<{
62
62
  type: z.ZodLiteral<"compaction">;
63
63
  modelProfile: z.ZodString;
64
64
  modelId: z.ZodString;
65
+ details: z.ZodOptional<z.ZodObject<{
66
+ reason: z.ZodLiteral<"capacity">;
67
+ estimatedInputTokens: z.ZodNumber;
68
+ replacementInputTokens: z.ZodOptional<z.ZodNumber>;
69
+ triggerTokens: z.ZodNumber;
70
+ inputLimitTokens: z.ZodNumber;
71
+ inputMessageCount: z.ZodNumber;
72
+ retainedMessageCount: z.ZodNumber;
73
+ summaryChars: z.ZodNumber;
74
+ }, z.core.$strict>>;
65
75
  replacementHistory: z.ZodArray<z.ZodObject<{
66
76
  message: z.ZodPipe<z.ZodObject<{
67
77
  role: z.ZodString;
@@ -204,6 +214,24 @@ export declare const conversationEventDataSchema: z.ZodUnion<readonly [z.ZodUnio
204
214
  internal: "internal";
205
215
  scheduler: "scheduler";
206
216
  }>;
217
+ }, z.core.$strict>, z.ZodObject<{
218
+ type: z.ZodLiteral<"turn_routed">;
219
+ turnId: z.ZodString;
220
+ modelProfile: z.ZodString;
221
+ modelId: z.ZodString;
222
+ reasoningLevel: z.ZodEnum<{
223
+ low: "low";
224
+ medium: "medium";
225
+ high: "high";
226
+ xhigh: "xhigh";
227
+ none: "none";
228
+ }>;
229
+ confidence: z.ZodOptional<z.ZodNumber>;
230
+ source: z.ZodEnum<{
231
+ configured: "configured";
232
+ inherited: "inherited";
233
+ router: "router";
234
+ }>;
207
235
  }, z.core.$strict>, z.ZodObject<{
208
236
  type: z.ZodLiteral<"turn_completed">;
209
237
  turnId: z.ZodString;
@@ -275,6 +303,16 @@ export declare const conversationEventDataSchema: z.ZodUnion<readonly [z.ZodUnio
275
303
  type: z.ZodLiteral<"compaction">;
276
304
  modelProfile: z.ZodString;
277
305
  modelId: z.ZodString;
306
+ details: z.ZodOptional<z.ZodObject<{
307
+ reason: z.ZodLiteral<"capacity">;
308
+ estimatedInputTokens: z.ZodNumber;
309
+ replacementInputTokens: z.ZodOptional<z.ZodNumber>;
310
+ triggerTokens: z.ZodNumber;
311
+ inputLimitTokens: z.ZodNumber;
312
+ inputMessageCount: z.ZodNumber;
313
+ retainedMessageCount: z.ZodNumber;
314
+ summaryChars: z.ZodNumber;
315
+ }, z.core.$strict>>;
278
316
  replacementHistory: z.ZodArray<z.ZodObject<{
279
317
  message: z.ZodPipe<z.ZodObject<{
280
318
  role: z.ZodString;
@@ -447,6 +485,24 @@ export declare const conversationEventSchema: z.ZodUnion<readonly [z.ZodObject<{
447
485
  internal: "internal";
448
486
  scheduler: "scheduler";
449
487
  }>;
488
+ }, z.core.$strict>, z.ZodObject<{
489
+ type: z.ZodLiteral<"turn_routed">;
490
+ turnId: z.ZodString;
491
+ modelProfile: z.ZodString;
492
+ modelId: z.ZodString;
493
+ reasoningLevel: z.ZodEnum<{
494
+ low: "low";
495
+ medium: "medium";
496
+ high: "high";
497
+ xhigh: "xhigh";
498
+ none: "none";
499
+ }>;
500
+ confidence: z.ZodOptional<z.ZodNumber>;
501
+ source: z.ZodEnum<{
502
+ configured: "configured";
503
+ inherited: "inherited";
504
+ router: "router";
505
+ }>;
450
506
  }, z.core.$strict>, z.ZodObject<{
451
507
  type: z.ZodLiteral<"turn_completed">;
452
508
  turnId: z.ZodString;
@@ -518,6 +574,16 @@ export declare const conversationEventSchema: z.ZodUnion<readonly [z.ZodObject<{
518
574
  type: z.ZodLiteral<"compaction">;
519
575
  modelProfile: z.ZodString;
520
576
  modelId: z.ZodString;
577
+ details: z.ZodOptional<z.ZodObject<{
578
+ reason: z.ZodLiteral<"capacity">;
579
+ estimatedInputTokens: z.ZodNumber;
580
+ replacementInputTokens: z.ZodOptional<z.ZodNumber>;
581
+ triggerTokens: z.ZodNumber;
582
+ inputLimitTokens: z.ZodNumber;
583
+ inputMessageCount: z.ZodNumber;
584
+ retainedMessageCount: z.ZodNumber;
585
+ summaryChars: z.ZodNumber;
586
+ }, z.core.$strict>>;
521
587
  replacementHistory: z.ZodArray<z.ZodObject<{
522
588
  message: z.ZodPipe<z.ZodObject<{
523
589
  role: z.ZodString;
@@ -717,6 +783,24 @@ export declare const newConversationEventSchema: z.ZodObject<{
717
783
  internal: "internal";
718
784
  scheduler: "scheduler";
719
785
  }>;
786
+ }, z.core.$strict>, z.ZodObject<{
787
+ type: z.ZodLiteral<"turn_routed">;
788
+ turnId: z.ZodString;
789
+ modelProfile: z.ZodString;
790
+ modelId: z.ZodString;
791
+ reasoningLevel: z.ZodEnum<{
792
+ low: "low";
793
+ medium: "medium";
794
+ high: "high";
795
+ xhigh: "xhigh";
796
+ none: "none";
797
+ }>;
798
+ confidence: z.ZodOptional<z.ZodNumber>;
799
+ source: z.ZodEnum<{
800
+ configured: "configured";
801
+ inherited: "inherited";
802
+ router: "router";
803
+ }>;
720
804
  }, z.core.$strict>, z.ZodObject<{
721
805
  type: z.ZodLiteral<"turn_completed">;
722
806
  turnId: z.ZodString;
@@ -759,6 +843,8 @@ export interface ConversationEventStore {
759
843
  append(conversationId: string, events: NewConversationEvent[]): Promise<void>;
760
844
  /** Replace active model history with a compaction or handoff event. */
761
845
  replaceHistory(conversationId: string, replacement: HistoryReplacement): Promise<void>;
846
+ /** One event selected by its retry-stable key across history versions. */
847
+ loadByIdempotencyKey(conversationId: string, idempotencyKey: string): Promise<ConversationEvent | undefined>;
762
848
  /** Events of the current history version in `seq` order. */
763
849
  loadCurrentHistory(conversationId: string): Promise<ConversationEvent[]>;
764
850
  /** Events in the history version containing `seq`, when it exists. */
@@ -1,8 +1,10 @@
1
1
  import { type PiMessage } from "@/chat/pi/messages";
2
2
  import { type ConversationMessageProvenance } from "@/chat/conversations/provenance";
3
- import type { AuthorizationKind } from "@/chat/conversations/history";
3
+ import type { AuthorizationKind, ConversationEvent } from "@/chat/conversations/history";
4
4
  import type { JuniorSqlDatabase } from "@/db/db";
5
5
  import { type PiConversationEventProjection, type PiConversationProjection } from "@/chat/pi/conversation-events";
6
+ import type { ModelProfile } from "@/chat/model-profile";
7
+ import type { TurnReasoningLevel } from "@/chat/reasoning-level";
6
8
  interface ScopedConversation {
7
9
  conversationId: string;
8
10
  }
@@ -77,6 +79,23 @@ export declare function recordAuthorizationCompleted(args: {
77
79
  actorId: string;
78
80
  authorizationId: string;
79
81
  }): Promise<void>;
82
+ /** Load a previously selected execution profile for a resumed turn. */
83
+ export declare function loadTurnRoute(args: {
84
+ conversationId: string;
85
+ turnId: string;
86
+ }): Promise<Extract<ConversationEvent["data"], {
87
+ type: "turn_routed";
88
+ }> | undefined>;
89
+ /** Record the execution profile selected for one turn without changing agent history. */
90
+ export declare function recordTurnRoute(args: {
91
+ conversationId: string;
92
+ turnId: string;
93
+ modelProfile: ModelProfile;
94
+ modelId: string;
95
+ reasoningLevel: TurnReasoningLevel;
96
+ confidence?: number;
97
+ source: "configured" | "inherited" | "router";
98
+ }): Promise<void>;
80
99
  /** Record a host-observed parent tool start without adding it to Pi replay. */
81
100
  export declare function recordToolExecutionStarted(args: {
82
101
  conversationId: string;
@@ -19,6 +19,8 @@ export declare function isToolResultError(result: unknown): boolean;
19
19
  export declare function normalizeToolNameFromResult(result: unknown): string | undefined;
20
20
  /** Extract role string from a raw Pi message. */
21
21
  export declare function getPiMessageRole(value: unknown): string | undefined;
22
+ /** Return whether Pi can continue directly from the current history tail. */
23
+ export declare function isContinuablePiBoundary(messages: readonly PiMessage[]): boolean;
22
24
  /** Concatenate text content parts from an assistant message. */
23
25
  export declare function extractAssistantText(message: AssistantMessage): string;
24
26
  /** Return assistant messages that belong to the terminal post-tool reply phase. */
@@ -1,14 +1,19 @@
1
1
  export interface ModelContextBudget {
2
2
  contextWindow: number;
3
- maxTokens: number;
4
3
  }
5
4
  /** Estimate text tokens with the shared coarse heuristic used for local budgets. */
6
5
  export declare function estimateTextTokens(text: string): number;
7
6
  /** Derive the automatic compaction threshold from model context capacity. */
8
7
  export declare function calculateContextCompactionTriggerTokens(model: ModelContextBudget): number;
8
+ /** Derive the maximum estimated input size with room for uncounted request overhead. */
9
+ export declare function calculateContextInputLimitTokens(model: ModelContextBudget): number;
9
10
  /** Derive the post-compaction target from the automatic trigger threshold. */
10
11
  export declare function calculateContextCompactionTargetTokens(triggerTokens: number): number;
12
+ /** Cap one model's advertised context capacity with the host bot configuration. */
13
+ export declare function getModelContextBudget(modelId: string): ModelContextBudget;
11
14
  /** Resolve the automatic compaction threshold for the active agent model. */
12
- export declare function getAgentContextCompactionTriggerTokens(): number;
15
+ export declare function getAgentContextCompactionTriggerTokens(modelId: string): number;
16
+ /** Resolve the hard input ceiling for the active agent model. */
17
+ export declare function getAgentContextInputLimitTokens(modelId: string): number;
13
18
  /** Resolve the visible conversation compaction threshold for the auxiliary model. */
14
19
  export declare function getConversationContextCompactionTriggerTokens(): number;
@@ -1,5 +1,6 @@
1
1
  import type { completeText } from "@/chat/pi/client";
2
2
  import type { PiMessage } from "@/chat/pi/messages";
3
+ import { type ConversationMessageProvenance } from "@/chat/conversations/provenance";
3
4
  import type { ThreadConversationState } from "@/chat/state/conversation";
4
5
  import { type ModelProfile } from "@/chat/model-profile";
5
6
  export interface ContextCompactorDeps {
@@ -13,7 +14,7 @@ export interface CompactContextArgs {
13
14
  conversation: ThreadConversationState;
14
15
  conversationContext?: string;
15
16
  conversationId: string;
16
- onCompactionStart?: () => void;
17
+ onCompactionStart?: () => void | Promise<void>;
17
18
  piMessages: PiMessage[];
18
19
  metadata?: {
19
20
  channelId?: string;
@@ -21,6 +22,7 @@ export interface CompactContextArgs {
21
22
  runId?: string;
22
23
  threadId?: string;
23
24
  };
25
+ modelId: string;
24
26
  }
25
27
  export interface CompactContextResult {
26
28
  compacted: boolean;
@@ -41,10 +43,35 @@ interface HandoffContextArgs {
41
43
  reasoningLevel?: string;
42
44
  };
43
45
  }
46
+ interface ActiveContextCompactionArgs {
47
+ conversationContext?: string;
48
+ conversationId: string;
49
+ metadata?: CompactContextArgs["metadata"];
50
+ modelId: string;
51
+ modelProfile: ModelProfile;
52
+ onCompactionStart?: () => void | Promise<void>;
53
+ pendingMessages?: Array<{
54
+ message: PiMessage;
55
+ provenance: ConversationMessageProvenance;
56
+ }>;
57
+ piMessages: PiMessage[];
58
+ signal?: AbortSignal;
59
+ }
60
+ /** Raised when Junior cannot compact history below the active model's hard ceiling. */
61
+ export declare class ContextInputLimitExceededError extends Error {
62
+ readonly estimatedTokens: number;
63
+ readonly inputLimitTokens: number;
64
+ constructor(estimatedTokens: number, inputLimitTokens: number);
65
+ }
44
66
  /** Build retained user messages for a compacted Pi replacement history. */
45
67
  export declare function selectRetainedUserMessages(messages: PiMessage[], maxTokens?: number): PiMessage[];
46
68
  /** Build the service that owns local context compaction. */
47
69
  export declare function createContextCompactor(deps: ContextCompactorDeps): ContextCompactor;
48
70
  /** Compact the active conversation and durably bind its selected handoff profile. */
49
71
  export declare function compactContextForHandoff(args: HandoffContextArgs, deps: Pick<ContextCompactorDeps, "completeText">): Promise<PiMessage[]>;
72
+ /**
73
+ * Replace oversized active history at Pi's next-turn boundary before another
74
+ * provider request can observe it.
75
+ */
76
+ export declare function compactActiveContextIfNeeded(args: ActiveContextCompactionArgs, deps: Pick<ContextCompactorDeps, "completeText">): Promise<CompactContextResult>;
50
77
  export {};
@@ -14,6 +14,7 @@ export interface ConversationMemoryService {
14
14
  generateThreadTitle: (sourceText: string) => Promise<string>;
15
15
  }
16
16
  export declare function generateConversationId(prefix: "assistant" | "backfill" | "compaction" | "turn"): string;
17
+ /** Normalize message boundaries without changing transcript formatting. */
17
18
  export declare function normalizeConversationText(text: string): string;
18
19
  export declare function updateConversationStats(conversation: ThreadConversationState): void;
19
20
  export declare function upsertConversationMessage(conversation: ThreadConversationState, message: ConversationMessage): string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Normalize failures at the model-provider boundary.
3
+ *
4
+ * Junior owns stable failure kinds, safe user copy, and telemetry fields. Pi
5
+ * remains the source of truth for retrying assistant error messages.
6
+ */
7
+ export type ProviderErrorKind = "auth" | "permission" | "rate_limit" | "capacity" | "timeout" | "network" | "server" | "invalid_request" | "invalid_response" | "quota" | "content_policy" | "unknown";
8
+ interface ProviderErrorOptions {
9
+ kind?: ProviderErrorKind;
10
+ modelId?: string;
11
+ /** Pi's decision for an assistant error; explicit terminal kinds still win. */
12
+ retryable?: boolean;
13
+ }
14
+ interface ProviderErrorDetails {
15
+ cause?: unknown;
16
+ kind: ProviderErrorKind;
17
+ modelId?: string;
18
+ retryable: boolean;
19
+ retryAfterMs?: number;
20
+ status?: number;
21
+ }
22
+ /** Structured failure produced at an AI provider boundary. */
23
+ export declare class ProviderError extends Error {
24
+ readonly code = "provider_error";
25
+ readonly kind: ProviderErrorKind;
26
+ readonly modelId?: string;
27
+ readonly retryable: boolean;
28
+ readonly retryAfterMs?: number;
29
+ readonly status?: number;
30
+ constructor(details: ProviderErrorDetails);
31
+ }
32
+ /** Normalize SDK, Gateway, and Pi failures into one provider error contract. */
33
+ export declare function createProviderError(error: unknown, options?: ProviderErrorOptions): ProviderError;
34
+ /** Return whether a provider-boundary error should be retried. */
35
+ export declare function isProviderRetryError(error: unknown): error is ProviderError;
36
+ /** Return stable, sanitized copy suitable for a terminal user response. */
37
+ export declare function getProviderErrorUserMessage(error: ProviderError): string;
38
+ /** Return safe structured fields for terminal failure telemetry. */
39
+ export declare function getProviderErrorAttributes(error: ProviderError): Record<string, unknown>;
40
+ export {};
@@ -1,13 +1,10 @@
1
+ import { type AssistantMessage } from "@earendil-works/pi-ai";
1
2
  import type { PiMessage } from "@/chat/pi/messages";
2
- /** Mark failures that cross the AI provider boundary for shared retry handling. */
3
- export declare function createProviderError(error: unknown): Error;
4
- /** Return whether a provider-boundary error should be retried by the worker. */
5
- export declare function isProviderRetryError(error: unknown): boolean;
6
- /** Build the next provider retry step from Pi history, if the turn can resume. */
3
+ /** Apply Junior's retry budget to a retryable Pi assistant failure. */
7
4
  export declare function nextProviderRetry(args: {
8
5
  attempt: number;
6
+ failure?: AssistantMessage;
9
7
  messages: PiMessage[];
10
- retryableFailure: boolean;
11
8
  }): {
12
9
  delayMs: number;
13
10
  messages: PiMessage[];
@@ -20,6 +20,7 @@ export interface TurnRoute {
20
20
  profile: ModelProfile;
21
21
  reasoningLevel: TurnReasoningLevel;
22
22
  reason: string;
23
+ source?: "configured" | "inherited" | "router";
23
24
  }
24
25
  /** Preserve an explicitly configured reasoning level without invoking the router. */
25
26
  export declare function configuredTurnRoute(profile: ModelProfile, reasoningLevel: TurnReasoningLevel, source: "agent_config" | "default" | "profile"): TurnRoute;
@@ -16,8 +16,8 @@ export declare const CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS = 5;
16
16
  declare const inboundMessageSourceSchema: z.ZodEnum<{
17
17
  slack: "slack";
18
18
  plugin: "plugin";
19
- api: "api";
20
19
  local: "local";
20
+ api: "api";
21
21
  internal: "internal";
22
22
  resource_event: "resource_event";
23
23
  scheduler: "scheduler";
@@ -66,8 +66,8 @@ export declare const inboundMessageSchema: z.ZodObject<{
66
66
  source: z.ZodEnum<{
67
67
  slack: "slack";
68
68
  plugin: "plugin";
69
- api: "api";
70
69
  local: "local";
70
+ api: "api";
71
71
  internal: "internal";
72
72
  resource_event: "resource_event";
73
73
  scheduler: "scheduler";
@@ -114,7 +114,7 @@ export declare function drainConversationMailbox(args: Parameters<typeof workSta
114
114
  metadata?: Record<string, unknown> | undefined;
115
115
  };
116
116
  receivedAtMs: number;
117
- source: "slack" | "plugin" | "api" | "local" | "internal" | "resource_event" | "scheduler";
117
+ source: "slack" | "plugin" | "local" | "api" | "internal" | "resource_event" | "scheduler";
118
118
  attemptCount?: number | undefined;
119
119
  injectedAtMs?: number | undefined;
120
120
  }[]>;
@@ -9,7 +9,6 @@ interface EditFileResult {
9
9
  }];
10
10
  details: {
11
11
  data: {
12
- diff: string;
13
12
  first_changed_line?: number;
14
13
  path: string;
15
14
  replacements: number;
@@ -21,6 +20,7 @@ interface EditFileResult {
21
20
  replacements: number;
22
21
  status: "success";
23
22
  target: string;
23
+ truncated: boolean;
24
24
  } | {
25
25
  data: {
26
26
  path: string;
@@ -20,6 +20,7 @@ export declare function prepareTextReplacementArguments<T extends TextReplacemen
20
20
  export declare function buildCompactDiff(oldContent: string, newContent: string): {
21
21
  diff: string;
22
22
  firstChangedLine?: number;
23
+ truncated: boolean;
23
24
  };
24
25
  /** Apply exact replacements to normalized text after validating uniqueness and overlap. */
25
26
  export declare function validateAndApplyTextEdits(content: string, edits: TextReplacement[], targetName: string): {
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-6GWA276C.js";
14
14
  import {
15
15
  getDeploymentTelemetryAttributes
16
- } from "./chunk-AU2JVUDF.js";
16
+ } from "./chunk-5CZ7RETL.js";
17
17
 
18
18
  // src/chat/logging.ts
19
19
  import path from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  JUNIOR_VERSION
3
- } from "./chunk-IV2O4HQJ.js";
3
+ } from "./chunk-PM3PX42K.js";
4
4
 
5
5
  // src/deployment.ts
6
6
  var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";