@sentry/junior 0.97.1 → 0.99.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-XSUIVRQS.js → agent-hooks-OSW6C3CJ.js} +2 -2
  2. package/dist/api/conversations/detail.d.ts +1 -1
  3. package/dist/api/conversations/detail.query.d.ts +1 -1
  4. package/dist/api/conversations/list.d.ts +7 -2
  5. package/dist/api/conversations/list.query.d.ts +9 -3
  6. package/dist/api/conversations/projection.d.ts +0 -1
  7. package/dist/api/conversations/schema.d.ts +31 -8
  8. package/dist/api/people/schema.d.ts +0 -11
  9. package/dist/api/people/shared.d.ts +2 -4
  10. package/dist/api/schema.d.ts +4 -1
  11. package/dist/api/schema.js +5 -3
  12. package/dist/api-reference.d.ts +2 -2
  13. package/dist/api.js +28 -13
  14. package/dist/app.js +50 -37
  15. package/dist/chat/conversations/search.d.ts +24 -0
  16. package/dist/chat/conversations/sql/search.d.ts +4 -0
  17. package/dist/chat/db.d.ts +3 -0
  18. package/dist/chat/runtime/report-progress.d.ts +3 -0
  19. package/dist/chat/runtime/slack-resume.d.ts +2 -0
  20. package/dist/chat/services/context-compaction.d.ts +1 -0
  21. package/dist/chat/slack/assistant-thread/status-scheduler.d.ts +4 -3
  22. package/dist/chat/slack/outbound.d.ts +6 -0
  23. package/dist/chat/slack/tools/conversation-search.d.ts +71 -0
  24. package/dist/chat/state/turn-session.d.ts +2 -0
  25. package/dist/chat/tool-support/zod-tool.d.ts +1 -1
  26. package/dist/chunk-6DTVCPLO.js +146 -0
  27. package/dist/{chunk-VFH4ZKZT.js → chunk-CRQVIHDI.js} +1 -3
  28. package/dist/{chunk-6U26PYI5.js → chunk-CV22LUIV.js} +7 -17
  29. package/dist/{chunk-GUAP3H7O.js → chunk-DHHU2WSG.js} +2 -2
  30. package/dist/{chunk-T533JLM3.js → chunk-ER45IV77.js} +8 -6
  31. package/dist/{chunk-LUAE4MGW.js → chunk-EUZ44ROE.js} +21 -4
  32. package/dist/{chunk-5HLDPVYS.js → chunk-FTTFV6DC.js} +1 -1
  33. package/dist/{chunk-3F4OPKGF.js → chunk-IO65E4ZD.js} +2 -2
  34. package/dist/{chunk-ON6YKIQ7.js → chunk-KFUSLFLL.js} +21 -15
  35. package/dist/{chunk-FBHZJFHI.js → chunk-NJEDJFK4.js} +1 -1
  36. package/dist/{chunk-35BNLDOJ.js → chunk-OGHXZ4KQ.js} +134 -57
  37. package/dist/{chunk-WJOSZOON.js → chunk-OL6XQ23W.js} +11 -150
  38. package/dist/{chunk-XIRPQQVE.js → chunk-PYK7R5A7.js} +312 -175
  39. package/dist/{chunk-UAMKJPDF.js → chunk-T55RBE4Z.js} +4 -0
  40. package/dist/{chunk-WGXMTFNU.js → chunk-WJ7STXT6.js} +5 -3
  41. package/dist/{chunk-AUUCAFDE.js → chunk-ZZUBLPXD.js} +134 -11
  42. package/dist/cli/chat.js +11 -10
  43. package/dist/cli/plugins.js +2 -2
  44. package/dist/cli/upgrade.js +9 -7
  45. package/dist/{db-BWXYIKFQ.js → db-GFSCDAHS.js} +3 -1
  46. package/dist/detail-Q4IVDNGS.js +67 -0
  47. package/dist/{legacy-import-3NQJVGQL.js → legacy-import-6WWXMALY.js} +2 -2
  48. package/dist/{list-UXJI5Q5X.js → list-A3F5JDYV.js} +7 -5
  49. package/dist/{list-A3WFRIYX.js → list-M5BRWW3D.js} +5 -6
  50. package/dist/{plugin-conversations-DDNGC35A.js → plugin-conversations-PDCQWU3O.js} +3 -3
  51. package/dist/{profile-4RYDXWTF.js → profile-UEIRSVT3.js} +5 -5
  52. package/dist/{runner-JALSYH2P.js → runner-267ZRLZD.js} +8 -7
  53. package/dist/{stats-XKXH3PTY.js → stats-L62E4O4U.js} +7 -17
  54. package/dist/{subagent-TZ55XY37.js → subagent-UN3MP6LV.js} +6 -6
  55. package/migrations/0002_conversation_message_search.sql +1 -0
  56. package/migrations/meta/0002_snapshot.json +987 -0
  57. package/migrations/meta/_journal.json +7 -0
  58. package/package.json +6 -6
  59. package/dist/detail-GA6NXWQJ.js +0 -43
package/dist/app.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  processPluginTask,
6
6
  requireTurnFailureEventId,
7
7
  scheduleSessionCompletedPluginTasks
8
- } from "./chunk-T533JLM3.js";
8
+ } from "./chunk-ER45IV77.js";
9
9
  import {
10
10
  buildSentryConversationUrl
11
11
  } from "./chunk-LVUKF5CE.js";
@@ -37,7 +37,7 @@ import {
37
37
  requestConversationContinuation,
38
38
  requestConversationWork,
39
39
  startConversationWork
40
- } from "./chunk-FBHZJFHI.js";
40
+ } from "./chunk-NJEDJFK4.js";
41
41
  import {
42
42
  GET
43
43
  } from "./chunk-QNVHH5PU.js";
@@ -87,6 +87,7 @@ import {
87
87
  formatSlackLink,
88
88
  getConfigDefaults,
89
89
  getMcpStoredOAuthCredentials,
90
+ latestReportedProgress,
90
91
  listThreadReplies,
91
92
  normalizeSandboxEgressTracePropagationDomains,
92
93
  normalizeSlackStatusText,
@@ -104,7 +105,7 @@ import {
104
105
  splitSlackReplyText,
105
106
  startOAuthFlow,
106
107
  truncateStatusText
107
- } from "./chunk-XIRPQQVE.js";
108
+ } from "./chunk-PYK7R5A7.js";
108
109
  import {
109
110
  CooperativeTurnYieldError,
110
111
  TurnInputCommitLostError,
@@ -133,22 +134,24 @@ import {
133
134
  persistWithRetry,
134
135
  persistYieldSessionRecord,
135
136
  startActiveTurn
136
- } from "./chunk-WGXMTFNU.js";
137
+ } from "./chunk-WJ7STXT6.js";
137
138
  import {
138
139
  JUNIOR_THREAD_STATE_TTL_MS,
140
+ coerceThreadConversationState
141
+ } from "./chunk-6DTVCPLO.js";
142
+ import {
139
143
  abandonAgentTurnSessionRecord,
140
- coerceThreadConversationState,
141
144
  failAgentTurnSessionRecord,
142
145
  getAgentTurnSessionRecord,
143
146
  listAgentTurnSessionSummariesForConversation,
144
147
  recordAgentTurnSessionSummary
145
- } from "./chunk-WJOSZOON.js";
148
+ } from "./chunk-OL6XQ23W.js";
146
149
  import {
147
150
  commitMessages,
148
151
  loadConversationProjection,
149
152
  loadProjection,
150
153
  recordAuthorizationCompleted
151
- } from "./chunk-GUAP3H7O.js";
154
+ } from "./chunk-DHHU2WSG.js";
152
155
  import {
153
156
  buildConversationContext,
154
157
  createConversationMemoryService,
@@ -163,7 +166,7 @@ import {
163
166
  persistConversationMessages,
164
167
  updateConversationStats,
165
168
  upsertConversationMessage
166
- } from "./chunk-3F4OPKGF.js";
169
+ } from "./chunk-IO65E4ZD.js";
167
170
  import "./chunk-H66UCBPW.js";
168
171
  import "./chunk-PDO5BLNM.js";
169
172
  import "./chunk-CM5EZD5F.js";
@@ -176,7 +179,7 @@ import {
176
179
  setPlugins,
177
180
  validatePlugins,
178
181
  verifySlackDirectCredentialSubject
179
- } from "./chunk-5HLDPVYS.js";
182
+ } from "./chunk-FTTFV6DC.js";
180
183
  import {
181
184
  SlackActionError,
182
185
  downloadPrivateSlackFile,
@@ -202,7 +205,7 @@ import {
202
205
  juniorConversationMessages,
203
206
  juniorConversations,
204
207
  juniorDestinations
205
- } from "./chunk-35BNLDOJ.js";
208
+ } from "./chunk-OGHXZ4KQ.js";
206
209
  import "./chunk-G3E7SCME.js";
207
210
  import {
208
211
  sleep
@@ -3451,17 +3454,7 @@ function createAssistantStatusScheduler(args) {
3451
3454
  }
3452
3455
  };
3453
3456
  return {
3454
- start(status) {
3455
- active = true;
3456
- clearPending();
3457
- if (status) {
3458
- void postRenderedStatus(status);
3459
- return;
3460
- }
3461
- currentKey = "initial";
3462
- void postStatus(getInitialStatusText(), loadingMessages);
3463
- },
3464
- async stop() {
3457
+ async clear() {
3465
3458
  active = false;
3466
3459
  clearPending();
3467
3460
  if (rotationTimer) {
@@ -3473,6 +3466,20 @@ function createAssistantStatusScheduler(args) {
3473
3466
  },
3474
3467
  update(status) {
3475
3468
  if (!active) {
3469
+ active = true;
3470
+ clearPending();
3471
+ if (status) {
3472
+ void postRenderedStatus(status);
3473
+ return;
3474
+ }
3475
+ currentKey = "initial";
3476
+ void postStatus(getInitialStatusText(), loadingMessages);
3477
+ return;
3478
+ }
3479
+ if (!status) {
3480
+ clearPending();
3481
+ currentKey = "initial";
3482
+ void postStatus(getInitialStatusText(), loadingMessages);
3476
3483
  return;
3477
3484
  }
3478
3485
  const presentation = renderAssistantStatus({
@@ -4168,7 +4175,7 @@ async function resumeSlackTurn(args) {
4168
4175
  runArgs.initialText
4169
4176
  );
4170
4177
  }
4171
- status.start();
4178
+ status.update(runArgs.initialStatus);
4172
4179
  const replyContext = createResumeReplyContext(runArgs, status);
4173
4180
  const replyPromise = runArgs.agentRunner.run(replyContext);
4174
4181
  const replyTimeoutMs = resolveReplyTimeoutMs(runArgs.replyTimeoutMs);
@@ -4186,7 +4193,7 @@ async function resumeSlackTurn(args) {
4186
4193
  )
4187
4194
  ]) : await replyPromise;
4188
4195
  if (outcome.status !== "completed") {
4189
- await status.stop();
4196
+ await status.clear();
4190
4197
  const onAuthPause = runArgs.onAuthPause;
4191
4198
  const onTimeoutPause = runArgs.onTimeoutPause;
4192
4199
  if (outcome.status === "awaiting_auth" && onAuthPause) {
@@ -4225,7 +4232,7 @@ async function resumeSlackTurn(args) {
4225
4232
  logException,
4226
4233
  context: getResumeLogContext(runArgs, lockKey)
4227
4234
  });
4228
- await status.stop();
4235
+ await status.clear();
4229
4236
  const footer = buildSlackReplyFooter({
4230
4237
  conversationId: getResumeConversationId(runArgs, lockKey)
4231
4238
  });
@@ -4281,7 +4288,7 @@ async function resumeSlackTurn(args) {
4281
4288
  }
4282
4289
  }
4283
4290
  } catch (error) {
4284
- await status.stop();
4291
+ await status.clear();
4285
4292
  if (finalReplyDelivered) {
4286
4293
  postDeliveryCommitError = error;
4287
4294
  try {
@@ -9908,7 +9915,7 @@ function createReplyToThread(deps) {
9908
9915
  channelId,
9909
9916
  runId
9910
9917
  },
9911
- onCompactionStart: () => status.start(compactingStatus),
9918
+ onCompactionStart: () => status.update(compactingStatus),
9912
9919
  piMessages
9913
9920
  });
9914
9921
  if (compaction.compacted) {
@@ -9943,7 +9950,7 @@ function createReplyToThread(deps) {
9943
9950
  piMessages = [...piMessages ?? [], ...newlyBatched];
9944
9951
  }
9945
9952
  }
9946
- status.start();
9953
+ status.update();
9947
9954
  const assistantTitleTask = maybeUpdateAssistantTitle({
9948
9955
  assistantThreadContext,
9949
9956
  assistantUserName: botConfig.userName,
@@ -10526,7 +10533,7 @@ function createReplyToThread(deps) {
10526
10533
  );
10527
10534
  }
10528
10535
  }
10529
- await status.stop();
10536
+ await status.clear();
10530
10537
  }
10531
10538
  }
10532
10539
  );
@@ -11150,9 +11157,13 @@ async function continueSlackAgentRun(payload, options) {
11150
11157
  });
11151
11158
  return false;
11152
11159
  }
11160
+ const turnMessages = activeSessionRecord.turnStartMessageIndex === void 0 ? [] : activeSessionRecord.piMessages.slice(
11161
+ activeSessionRecord.turnStartMessageIndex
11162
+ );
11153
11163
  return {
11154
11164
  messageText: userMessage.text,
11155
11165
  messageTs: getTurnUserSlackMessageTs(userMessage),
11166
+ initialStatus: latestReportedProgress(turnMessages),
11156
11167
  replyContext: {
11157
11168
  input: {
11158
11169
  conversationContext,
@@ -11656,15 +11667,17 @@ function normalizeDashboardPath2(path2, fallback) {
11656
11667
  function dashboardHostRoutePaths(dashboard) {
11657
11668
  const basePath = normalizeDashboardPath2(dashboard.basePath, "/");
11658
11669
  const authPath = normalizeDashboardPath2(dashboard.authPath, "/api/auth");
11659
- const pagePaths = basePath === "/" ? [
11660
- "/",
11661
- "/conversations",
11662
- "/conversations/*",
11663
- "/people",
11664
- "/people/*",
11665
- "/plugins",
11666
- "/plugins/*"
11667
- ] : [basePath, `${basePath}/*`];
11670
+ const pagePath = (suffix) => basePath === "/" ? `/${suffix}` : `${basePath}/${suffix}`;
11671
+ const conversationsPath = pagePath("conversations");
11672
+ const peoplePath = pagePath("people");
11673
+ const pagePaths = [
11674
+ basePath,
11675
+ conversationsPath,
11676
+ `${conversationsPath}/*`,
11677
+ peoplePath,
11678
+ `${peoplePath}/*`,
11679
+ pagePath("plugins")
11680
+ ];
11668
11681
  const loginPath = basePath === "/" ? "/auth/login" : `${basePath}/auth/login`;
11669
11682
  return [
11670
11683
  ...pagePaths,
@@ -0,0 +1,24 @@
1
+ /** One relevant visible-message match from a prior conversation. */
2
+ export interface ConversationSearchResult {
3
+ conversationId: string;
4
+ excerpt: string;
5
+ messageCreatedAtMs: number;
6
+ messageId: string;
7
+ providerDestinationId: string;
8
+ role: "assistant" | "user";
9
+ }
10
+ /** Runtime-derived public workspace scope for cross-conversation search. */
11
+ export interface ConversationSearchScope {
12
+ kind: "public_provider_tenant";
13
+ provider: "slack";
14
+ providerTenantId: string;
15
+ }
16
+ /** Search retained public visible messages within an authorized workspace. */
17
+ export interface ConversationSearchStore {
18
+ search(args: {
19
+ currentConversationId: string;
20
+ limit: number;
21
+ query: string;
22
+ scope: ConversationSearchScope;
23
+ }): Promise<ConversationSearchResult[]>;
24
+ }
@@ -0,0 +1,4 @@
1
+ import type { JuniorSqlDatabase } from "@/db/db";
2
+ import type { ConversationSearchStore } from "../search";
3
+ /** Create a SQL-backed public workspace conversation search store. */
4
+ export declare function createSqlConversationSearchStore(executor: JuniorSqlDatabase): ConversationSearchStore;
package/dist/chat/db.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ConversationStore } from "@/chat/conversations/store";
2
2
  import type { AgentStepStore } from "@/chat/conversations/history";
3
3
  import type { ConversationMessageStore } from "@/chat/conversations/messages";
4
+ import type { ConversationSearchStore } from "@/chat/conversations/search";
4
5
  import type { JuniorDatabase, JuniorSqlExecutor } from "@/db/db";
5
6
  /**
6
7
  * Return the process SQL executor. Exposed for the one-time legacy import
@@ -15,5 +16,7 @@ export declare function getConversationStore(): ConversationStore;
15
16
  export declare function getAgentStepStore(): AgentStepStore;
16
17
  /** Return the SQL-backed visible conversation message store. */
17
18
  export declare function getConversationMessageStore(): ConversationMessageStore;
19
+ /** Return the SQL-backed public provider-tenant conversation search store. */
20
+ export declare function getConversationSearchStore(): ConversationSearchStore;
18
21
  /** Close the process SQL database when it has been opened. */
19
22
  export declare function closeDb(): Promise<void>;
@@ -1,3 +1,6 @@
1
+ import type { PiMessage } from "@/chat/pi/messages";
1
2
  import type { AssistantStatusSpec } from "@/chat/slack/assistant-thread/status-render";
2
3
  /** Convert a `reportProgress` tool payload into assistant status text. */
3
4
  export declare function buildReportedProgressStatus(input: unknown): AssistantStatusSpec | undefined;
5
+ /** Recover the latest explicit progress update from a resumable Pi transcript. */
6
+ export declare function latestReportedProgress(messages: readonly PiMessage[]): AssistantStatusSpec | undefined;
@@ -1,6 +1,7 @@
1
1
  import type { AgentRunRequest } from "@/chat/agent/request";
2
2
  import type { AgentRunResult } from "@/chat/services/turn-result";
3
3
  import type { AgentRunner } from "@/chat/runtime/agent-runner";
4
+ import { type AssistantStatusSpec } from "@/chat/slack/assistant-thread/status";
4
5
  import type { SlackMessageTs } from "@/chat/slack/timestamp";
5
6
  /** Error raised when another worker already owns the resume lock. */
6
7
  export declare class ResumeTurnBusyError extends Error {
@@ -14,6 +15,7 @@ interface ResumeSlackTurnArgs {
14
15
  replyContext?: ResumeReplyContext;
15
16
  lockKey?: string;
16
17
  initialText?: string;
18
+ initialStatus?: AssistantStatusSpec;
17
19
  agentRunner: AgentRunner;
18
20
  scheduleSessionCompletedPluginTasks?: (params: {
19
21
  conversationId: string;
@@ -32,6 +32,7 @@ interface HandoffContextArgs {
32
32
  conversationId: string;
33
33
  metadata?: CompactContextArgs["metadata"];
34
34
  piMessages: PiMessage[];
35
+ runtimeContext: PiMessage[];
35
36
  signal?: AbortSignal;
36
37
  target: {
37
38
  modelId: string;
@@ -1,9 +1,10 @@
1
1
  import { type AssistantStatusSpec } from "@/chat/slack/assistant-thread/status-render";
2
2
  export type TimerHandle = ReturnType<typeof setTimeout>;
3
3
  export interface AssistantStatusSession {
4
- start: (status?: AssistantStatusSpec) => void;
5
- stop: () => Promise<void>;
6
- update: (status: AssistantStatusSpec) => void;
4
+ /** Activate or replace the loading state; omit status to show generic loading. */
5
+ update: (status?: AssistantStatusSpec) => void;
6
+ /** Stop refresh scheduling and clear the loading state. */
7
+ clear: () => Promise<void>;
7
8
  }
8
9
  /**
9
10
  * Pace assistant loading-state writes for a single turn.
@@ -1,5 +1,11 @@
1
1
  import type { SlackMessageBlock } from "@/chat/slack/footer";
2
+ import { type SlackChannelId } from "@/chat/slack/ids";
2
3
  import { type SlackMessageTs } from "@/chat/slack/timestamp";
4
+ /** Resolve a Slack message permalink without making read-only workflows fail on lookup errors. */
5
+ export declare function getSlackMessagePermalink(args: {
6
+ channelId: SlackChannelId;
7
+ messageTs: SlackMessageTs;
8
+ }): Promise<string | undefined>;
3
9
  /** Post Slack `mrkdwn` text to a conversation or thread via the shared outbound boundary. */
4
10
  export declare function postSlackMessage(input: {
5
11
  blocks?: SlackMessageBlock[];
@@ -0,0 +1,71 @@
1
+ import type { ConversationSearchScope, ConversationSearchStore } from "@/chat/conversations/search";
2
+ import { getSlackMessagePermalink } from "@/chat/slack/outbound";
3
+ interface ConversationSearchToolDeps {
4
+ getPermalink?: typeof getSlackMessagePermalink;
5
+ store?: ConversationSearchStore;
6
+ }
7
+ /** Create a tool that searches retained public Junior threads across an authorized Slack workspace. */
8
+ export declare function createSlackConversationSearchTool(scope: ConversationSearchScope, currentConversationId: string, deps?: ConversationSearchToolDeps): Omit<import("../../tools/definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
9
+ inputSchema: import("../../tools/definition").JsonSchemaObject;
10
+ outputSchema: import("../../tools/definition").JsonSchemaObject;
11
+ prepareArguments(args: unknown): {
12
+ query: string;
13
+ limit?: number | null | undefined;
14
+ };
15
+ execute?: ((input: unknown, options: import("../../tools/definition").ToolExecuteOptions) => {
16
+ [x: string]: unknown;
17
+ ok: boolean;
18
+ status: "error" | "success";
19
+ query: string;
20
+ count: number;
21
+ threads: {
22
+ conversation_id: string;
23
+ thread_ts: string;
24
+ message_id: string;
25
+ message_role: "assistant" | "user";
26
+ message_timestamp: string;
27
+ excerpt: string;
28
+ permalink?: string | undefined;
29
+ }[];
30
+ target?: string | undefined;
31
+ data?: unknown;
32
+ truncated?: boolean | undefined;
33
+ continuation?: {
34
+ arguments: Record<string, unknown>;
35
+ reason?: string | undefined;
36
+ } | undefined;
37
+ error?: string | {
38
+ kind: string;
39
+ message: string;
40
+ retryable?: boolean | undefined;
41
+ } | undefined;
42
+ } | Promise<{
43
+ [x: string]: unknown;
44
+ ok: boolean;
45
+ status: "error" | "success";
46
+ query: string;
47
+ count: number;
48
+ threads: {
49
+ conversation_id: string;
50
+ thread_ts: string;
51
+ message_id: string;
52
+ message_role: "assistant" | "user";
53
+ message_timestamp: string;
54
+ excerpt: string;
55
+ permalink?: string | undefined;
56
+ }[];
57
+ target?: string | undefined;
58
+ data?: unknown;
59
+ truncated?: boolean | undefined;
60
+ continuation?: {
61
+ arguments: Record<string, unknown>;
62
+ reason?: string | undefined;
63
+ } | undefined;
64
+ error?: string | {
65
+ kind: string;
66
+ message: string;
67
+ retryable?: boolean | undefined;
68
+ } | undefined;
69
+ }>) | undefined;
70
+ };
71
+ export {};
@@ -121,6 +121,8 @@ export declare function recordAgentTurnSessionSummary(args: {
121
121
  export declare function listAgentTurnSessionSummaries(limit?: number): Promise<AgentTurnSessionSummary[]>;
122
122
  /** List turn-session summaries for one conversation without the global feed cap. */
123
123
  export declare function listAgentTurnSessionSummariesForConversation(conversationId: string): Promise<AgentTurnSessionSummary[]>;
124
+ /** List retained run summaries without falling back to global history. */
125
+ export declare function listBoundedAgentTurnSessionSummariesForConversation(conversationId: string): Promise<AgentTurnSessionSummary[]>;
124
126
  /** Read complete per-conversation summary indexes with bounded backend load. */
125
127
  export declare function listAgentTurnSessionSummariesForConversations(stateAdapter: StateAdapter, conversationIds: string[]): Promise<Map<string, AgentTurnSessionSummary[]>>;
126
128
  /** Mark an unfinished turn session record as abandoned when a newer turn wins. */
@@ -2,7 +2,7 @@ import { z, type ZodType, type ZodTypeAny } from "zod";
2
2
  import { type JuniorToolResult } from "@/chat/tool-support/structured-result";
3
3
  import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
4
4
  import type { AnyToolDefinition, JsonSchemaObject, ToolExecuteOptions } from "@/chat/tools/definition";
5
- type ZodToolDefinitionBase<TInputSchema extends ZodTypeAny> = Pick<AnyToolDefinition, "identity" | "description" | "exposure" | "annotations" | "promptSnippet" | "promptGuidelines" | "executionMode"> & {
5
+ type ZodToolDefinitionBase<TInputSchema extends ZodTypeAny> = Pick<AnyToolDefinition, "identity" | "source" | "description" | "exposure" | "annotations" | "promptSnippet" | "promptGuidelines" | "executionMode"> & {
6
6
  inputSchema: TInputSchema;
7
7
  prepareArguments?: (args: unknown) => z.input<TInputSchema>;
8
8
  };
@@ -0,0 +1,146 @@
1
+ import {
2
+ isRecord,
3
+ toOptionalNumber,
4
+ toOptionalString
5
+ } from "./chunk-OB42YVAE.js";
6
+
7
+ // src/chat/state/conversation.ts
8
+ function defaultConversationState() {
9
+ const nowMs = Date.now();
10
+ return {
11
+ schemaVersion: 1,
12
+ messages: [],
13
+ compactions: [],
14
+ backfill: {},
15
+ processing: {},
16
+ stats: {
17
+ estimatedContextTokens: 0,
18
+ totalMessageCount: 0,
19
+ compactedMessageCount: 0,
20
+ updatedAtMs: nowMs
21
+ },
22
+ vision: {
23
+ byFileId: {}
24
+ }
25
+ };
26
+ }
27
+ function coercePendingAuthState(value) {
28
+ if (!isRecord(value)) {
29
+ return void 0;
30
+ }
31
+ const kind = value.kind;
32
+ const provider = toOptionalString(value.provider);
33
+ const actorId = toOptionalString(value.actorId);
34
+ const scope = toOptionalString(value.scope);
35
+ const sessionId = toOptionalString(value.sessionId);
36
+ const linkSentAtMs = toOptionalNumber(value.linkSentAtMs);
37
+ if (kind !== "mcp" && kind !== "plugin" || !provider || !actorId || !sessionId || typeof linkSentAtMs !== "number") {
38
+ return void 0;
39
+ }
40
+ return {
41
+ kind,
42
+ provider,
43
+ actorId,
44
+ ...scope ? { scope } : {},
45
+ sessionId,
46
+ linkSentAtMs
47
+ };
48
+ }
49
+ function coerceThreadConversationState(value) {
50
+ if (!isRecord(value)) {
51
+ return defaultConversationState();
52
+ }
53
+ const root = value;
54
+ const rawConversation = isRecord(root.conversation) ? root.conversation : {};
55
+ const base = defaultConversationState();
56
+ const messages = [];
57
+ const rawCompactions = Array.isArray(rawConversation.compactions) ? rawConversation.compactions : [];
58
+ const compactions = [];
59
+ for (const item of rawCompactions) {
60
+ if (!isRecord(item)) continue;
61
+ const id = toOptionalString(item.id);
62
+ const summary = toOptionalString(item.summary);
63
+ const createdAtMs = toOptionalNumber(item.createdAtMs);
64
+ if (!id || !summary || !createdAtMs) continue;
65
+ const coveredMessageIds = Array.isArray(item.coveredMessageIds) ? item.coveredMessageIds.filter(
66
+ (entry) => typeof entry === "string" && entry.length > 0
67
+ ) : [];
68
+ compactions.push({
69
+ id,
70
+ summary,
71
+ createdAtMs,
72
+ coveredMessageIds
73
+ });
74
+ }
75
+ const rawBackfill = isRecord(rawConversation.backfill) ? rawConversation.backfill : {};
76
+ const backfill = {
77
+ completedAtMs: toOptionalNumber(rawBackfill.completedAtMs),
78
+ source: rawBackfill.source === "recent_messages" || rawBackfill.source === "thread_fetch" ? rawBackfill.source : void 0
79
+ };
80
+ const rawProcessing = isRecord(rawConversation.processing) ? rawConversation.processing : {};
81
+ const processing = {
82
+ activeTurnId: toOptionalString(rawProcessing.activeTurnId),
83
+ lastCompletedAtMs: toOptionalNumber(rawProcessing.lastCompletedAtMs),
84
+ pendingAuth: coercePendingAuthState(rawProcessing.pendingAuth)
85
+ };
86
+ const rawStats = isRecord(rawConversation.stats) ? rawConversation.stats : {};
87
+ const stats = {
88
+ estimatedContextTokens: toOptionalNumber(rawStats.estimatedContextTokens) ?? base.stats.estimatedContextTokens,
89
+ totalMessageCount: toOptionalNumber(rawStats.totalMessageCount) ?? messages.length,
90
+ compactedMessageCount: toOptionalNumber(rawStats.compactedMessageCount) ?? 0,
91
+ updatedAtMs: toOptionalNumber(rawStats.updatedAtMs) ?? base.stats.updatedAtMs
92
+ };
93
+ const rawVision = isRecord(rawConversation.vision) ? rawConversation.vision : {};
94
+ const rawVisionByFileId = isRecord(rawVision.byFileId) ? rawVision.byFileId : {};
95
+ const byFileId = {};
96
+ for (const [fileId, value2] of Object.entries(rawVisionByFileId)) {
97
+ if (typeof fileId !== "string" || fileId.trim().length === 0) continue;
98
+ if (!isRecord(value2)) continue;
99
+ const summary = toOptionalString(value2.summary);
100
+ const analyzedAtMs = toOptionalNumber(value2.analyzedAtMs);
101
+ if (!summary || !analyzedAtMs) continue;
102
+ byFileId[fileId] = {
103
+ summary,
104
+ analyzedAtMs
105
+ };
106
+ }
107
+ return {
108
+ schemaVersion: 1,
109
+ messages,
110
+ compactions,
111
+ backfill,
112
+ processing,
113
+ stats,
114
+ vision: {
115
+ backfillCompletedAtMs: toOptionalNumber(rawVision.backfillCompletedAtMs),
116
+ byFileId
117
+ }
118
+ };
119
+ }
120
+ function buildConversationStatePatch(conversation) {
121
+ const {
122
+ compactions: _compactions,
123
+ messages: _messages,
124
+ ...scratch
125
+ } = conversation;
126
+ return {
127
+ conversation: {
128
+ ...scratch,
129
+ schemaVersion: 1,
130
+ stats: {
131
+ ...conversation.stats,
132
+ totalMessageCount: conversation.messages.length,
133
+ updatedAtMs: Date.now()
134
+ }
135
+ }
136
+ };
137
+ }
138
+
139
+ // src/chat/state/ttl.ts
140
+ var JUNIOR_THREAD_STATE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
141
+
142
+ export {
143
+ JUNIOR_THREAD_STATE_TTL_MS,
144
+ coerceThreadConversationState,
145
+ buildConversationStatePatch
146
+ };
@@ -2,7 +2,7 @@ import {
2
2
  actorIdentitySchema,
3
3
  conversationStatsItemSchema,
4
4
  conversationSummaryReportSchema
5
- } from "./chunk-LUAE4MGW.js";
5
+ } from "./chunk-EUZ44ROE.js";
6
6
 
7
7
  // src/api/people/schema.ts
8
8
  import { z } from "zod";
@@ -18,7 +18,6 @@ var actorActivityDayReportSchema = z.object({
18
18
  date: z.string(),
19
19
  durationMs: z.number(),
20
20
  failed: z.number(),
21
- hung: z.number(),
22
21
  tokens: z.number().optional()
23
22
  }).strict();
24
23
  var actorTotalsReportSchema = z.object({
@@ -27,7 +26,6 @@ var actorTotalsReportSchema = z.object({
27
26
  conversations: z.number(),
28
27
  durationMs: z.number(),
29
28
  failed: z.number(),
30
- hung: z.number(),
31
29
  tokens: z.number().optional()
32
30
  }).strict();
33
31
  var identifiedActorSchema = actorIdentitySchema.extend({ email: z.string().min(1) }).strict();