@sentry/junior 0.57.0 → 0.59.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 (55) hide show
  1. package/dist/app.js +1311 -1284
  2. package/dist/chat/agent-dispatch/store.d.ts +4 -2
  3. package/dist/chat/agent-dispatch/types.d.ts +0 -1
  4. package/dist/chat/conversation-privacy.d.ts +23 -0
  5. package/dist/chat/logging.d.ts +2 -0
  6. package/dist/chat/mcp/tool-manager.d.ts +18 -5
  7. package/dist/chat/mcp/tool-name.d.ts +2 -0
  8. package/dist/chat/pi/client.d.ts +2 -0
  9. package/dist/chat/pi/derived-state.d.ts +5 -0
  10. package/dist/chat/pi/traced-stream.d.ts +5 -1
  11. package/dist/chat/prompt.d.ts +3 -9
  12. package/dist/chat/respond-helpers.d.ts +5 -3
  13. package/dist/chat/respond.d.ts +1 -0
  14. package/dist/chat/runtime/conversation-message.d.ts +10 -0
  15. package/dist/chat/runtime/processing-reaction.d.ts +2 -4
  16. package/dist/chat/runtime/reply-executor.d.ts +13 -16
  17. package/dist/chat/runtime/slack-runtime.d.ts +19 -32
  18. package/dist/chat/runtime/thread-state.d.ts +1 -1
  19. package/dist/chat/runtime/turn-input.d.ts +29 -0
  20. package/dist/chat/runtime/turn-preparation.d.ts +4 -24
  21. package/dist/chat/runtime/turn.d.ts +2 -3
  22. package/dist/chat/sentry-links.d.ts +4 -0
  23. package/dist/chat/services/context-compaction.d.ts +3 -4
  24. package/dist/chat/services/pending-auth.d.ts +1 -1
  25. package/dist/chat/services/subscribed-reply-policy.d.ts +2 -13
  26. package/dist/chat/services/timeout-resume.d.ts +1 -2
  27. package/dist/chat/services/turn-session-record.d.ts +82 -0
  28. package/dist/chat/slack/assistant-thread/title.d.ts +4 -1
  29. package/dist/chat/state/artifacts.d.ts +1 -0
  30. package/dist/chat/state/conversation.d.ts +0 -1
  31. package/dist/chat/state/session-log.d.ts +117 -0
  32. package/dist/chat/state/ttl.d.ts +2 -0
  33. package/dist/chat/state/turn-session.d.ts +89 -0
  34. package/dist/chat/tools/advisor/tool.d.ts +2 -0
  35. package/dist/chat/tools/agent-tools.d.ts +2 -1
  36. package/dist/chat/tools/skill/call-mcp-tool.d.ts +7 -3
  37. package/dist/chat/tools/skill/search-mcp-tools.d.ts +15 -3
  38. package/dist/chat/tools/types.d.ts +0 -1
  39. package/dist/{chunk-AA5TIFN5.js → chunk-FKEKRBUB.js} +267 -735
  40. package/dist/{chunk-TTUY467K.js → chunk-H652GMDH.js} +30 -14
  41. package/dist/chunk-I4FDGMFI.js +950 -0
  42. package/dist/{chunk-D3G3YOU4.js → chunk-ITOW4DED.js} +1 -1
  43. package/dist/chunk-QDGD5WVN.js +708 -0
  44. package/dist/cli/check.js +2 -2
  45. package/dist/cli/init.js +0 -1
  46. package/dist/cli/snapshot-warmup.js +5 -3
  47. package/dist/instrumentation.js +3 -0
  48. package/dist/reporting.d.ts +113 -0
  49. package/dist/reporting.js +390 -0
  50. package/package.json +25 -11
  51. package/dist/chat/services/turn-checkpoint.d.ts +0 -74
  52. package/dist/chat/state/pi-session-message-store.d.ts +0 -15
  53. package/dist/chat/state/turn-session-store.d.ts +0 -49
  54. package/dist/handlers/diagnostics-dashboard.d.ts +0 -2
  55. package/dist/handlers/diagnostics.d.ts +0 -2
@@ -2,8 +2,10 @@ import type { StateAdapter } from "chat";
2
2
  import type { DispatchCreateResult, DispatchOptions, DispatchProjection, DispatchRecord, DispatchStatus } from "./types";
3
3
  /** Keep dispatch persistence keys consistent across callback and recovery paths. */
4
4
  export declare function getDispatchStorageKey(id: string): string;
5
- /** Map a dispatch destination to the conversation lock and memory key it owns. */
6
- export declare function getDispatchConversationId(destination: DispatchRecord["destination"]): string;
5
+ /** Map a dispatch destination to the lock key that serializes Slack delivery. */
6
+ export declare function getDispatchDestinationLockId(destination: DispatchRecord["destination"]): string;
7
+ /** Return the isolated persisted conversation key for one dispatch run. */
8
+ export declare function getDispatchConversationId(dispatch: Pick<DispatchRecord, "id">): string;
7
9
  /** Give dispatch slices stable turn ids for resumability and trace correlation. */
8
10
  export declare function getDispatchTurnId(dispatchId: string): string;
9
11
  /** Gate recovery to dispatches that can still make progress. */
@@ -36,7 +36,6 @@ export interface DispatchRecord {
36
36
  metadata?: Record<string, string>;
37
37
  plugin: string;
38
38
  resultMessageTs?: string;
39
- resumeCheckpointVersion?: number;
40
39
  status: DispatchStatus;
41
40
  updatedAtMs: number;
42
41
  version: number;
@@ -0,0 +1,23 @@
1
+ export type ConversationPrivacy = "public" | "private";
2
+ type TraceAttributeValue = string | number | boolean | string[];
3
+ /** Resolve whether a conversation may expose raw payloads based on known Slack identity. */
4
+ export declare function resolveConversationPrivacy(input: {
5
+ channelId?: string;
6
+ conversationId?: string;
7
+ }): ConversationPrivacy | undefined;
8
+ /** Gate raw transcript/tool payload exposure to conversations known to be public. */
9
+ export declare function canExposeConversationPayload(input: {
10
+ channelId?: string;
11
+ conversationId?: string;
12
+ }): boolean;
13
+ /** Convert a GenAI message into safe metadata for private trace contexts. */
14
+ export declare function toGenAiMessageMetadata(message: unknown): Record<string, unknown>;
15
+ /** Convert raw text into size-only metadata for private trace contexts. */
16
+ export declare function toGenAiTextMetadata(text: string): Record<string, unknown>;
17
+ /** Convert an arbitrary payload into safe structured metadata for trace data fields. */
18
+ export declare function toGenAiPayloadMetadata(payload: unknown): Record<string, unknown>;
19
+ /** Convert an arbitrary payload into safe flattened trace attributes. */
20
+ export declare function toGenAiPayloadTraceAttributes(prefix: string, payload: unknown): Record<string, TraceAttributeValue>;
21
+ /** Summarize a message list without exposing raw message content. */
22
+ export declare function toGenAiMessagesTraceAttributes(prefix: string, messages: unknown[]): Record<string, TraceAttributeValue>;
23
+ export {};
@@ -30,6 +30,8 @@ export interface LogContext {
30
30
  urlFull?: string;
31
31
  userAgent?: string;
32
32
  }
33
+ /** Normalize runtime finish reasons to the telemetry spelling we emit. */
34
+ export declare function normalizeGenAiFinishReason(reason: string): string;
33
35
  export declare const log: {
34
36
  debug(eventName: string, attrs?: Record<string, unknown>, body?: string): void;
35
37
  info(eventName: string, attrs?: Record<string, unknown>, body?: string): void;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Turn-local MCP tool manager.
3
+ *
4
+ * This manager activates plugin MCP providers for one agent turn, exposes
5
+ * discovered tools through provider-prefixed names, and converts MCP results
6
+ * into Pi tool content. MCP clients, auth challenges, and provider session
7
+ * details stay inside this layer.
8
+ */
1
9
  import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
2
10
  import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
3
11
  import type { SkillMetadata } from "@/chat/skills";
@@ -26,7 +34,6 @@ export interface ManagedMcpToolDescriptor {
26
34
  annotations?: Record<string, unknown>;
27
35
  provider: string;
28
36
  }
29
- type ActiveMcpSkillScope = Pick<SkillMetadata, "pluginProvider">;
30
37
  type ActiveMcpSkill = Pick<SkillMetadata, "name" | "pluginProvider">;
31
38
  export interface ManagedMcpTool extends ManagedMcpToolDescriptor {
32
39
  execute: (args: Record<string, unknown>) => Promise<ManagedMcpToolResult>;
@@ -40,21 +47,27 @@ export declare class McpToolManager {
40
47
  private readonly toolsByProvider;
41
48
  constructor(plugins: PluginDefinition[], options?: McpToolManagerOptions);
42
49
  getActiveProviders(): string[];
50
+ /** List configured MCP providers for discovery without connecting to them. */
51
+ getAvailableProviderCatalog(): Array<{
52
+ provider: string;
53
+ description: string;
54
+ active: boolean;
55
+ }>;
43
56
  activateForSkill(skill: ActiveMcpSkill): Promise<boolean>;
44
57
  activateProvider(provider: string): Promise<boolean>;
45
58
  close(): Promise<void>;
46
- getActiveToolCatalog(skills: ActiveMcpSkillScope[], options?: {
59
+ /** Return descriptors for all active MCP provider tools, optionally filtered by provider. */
60
+ getActiveToolCatalog(options?: {
47
61
  provider?: string;
48
62
  }): ManagedMcpToolDescriptor[];
49
63
  private filterListedTools;
50
64
  private getClient;
51
65
  private toManagedTool;
52
66
  private handleAuthorizationRequired;
53
- /** Return all active ManagedMcpTool objects for the given skill scope. */
54
- getResolvedActiveTools(skills: ActiveMcpSkillScope[], options?: {
67
+ /** Return all active ManagedMcpTool objects, optionally filtered by provider. */
68
+ getResolvedActiveTools(options?: {
55
69
  provider?: string;
56
70
  }): ManagedMcpTool[];
57
- private resolveProviderTools;
58
71
  private toToolDescriptor;
59
72
  }
60
73
  export {};
@@ -0,0 +1,2 @@
1
+ /** Extract the provider from canonical `mcp__<provider>__<tool>` names. */
2
+ export declare function parseMcpProviderFromToolName(toolName: string): string | undefined;
@@ -1,6 +1,8 @@
1
1
  import { type Message, type Model, type ThinkingLevel } from "@earendil-works/pi-ai";
2
2
  import type { ZodTypeAny, z } from "zod";
3
3
  export declare const GEN_AI_PROVIDER_NAME: "vercel-ai-gateway";
4
+ export declare const GEN_AI_SERVER_ADDRESS = "ai-gateway.vercel.sh";
5
+ export declare const GEN_AI_SERVER_PORT = 443;
4
6
  export declare const MISSING_GATEWAY_CREDENTIALS_ERROR = "Missing AI gateway credentials (AI_GATEWAY_API_KEY or VERCEL_OIDC_TOKEN)";
5
7
  /**
6
8
  * Resolve the documented AI Gateway env credentials for the paths that need
@@ -0,0 +1,5 @@
1
+ import type { PiMessage } from "@/chat/pi/messages";
2
+ /** Infer MCP providers previously used in durable Pi history. */
3
+ export declare function inferActiveMcpProvidersFromPiMessages(messages: PiMessage[] | undefined): string[];
4
+ /** Infer successfully loaded skills from durable Pi history. */
5
+ export declare function inferLoadedSkillNamesFromPiMessages(messages: PiMessage[] | undefined): string[];
@@ -1,4 +1,5 @@
1
1
  import type { StreamFn } from "@earendil-works/pi-agent-core";
2
+ import { type ConversationPrivacy } from "@/chat/conversation-privacy";
2
3
  /**
3
4
  * Wraps pi-ai's `streamSimple` so each LLM call inside a pi-agent-core agent
4
5
  * loop produces its own `gen_ai.chat` Sentry span. The returned function is
@@ -6,4 +7,7 @@ import type { StreamFn } from "@earendil-works/pi-agent-core";
6
7
  *
7
8
  * The base argument exists so tests can inject a stub stream function.
8
9
  */
9
- export declare function createTracedStreamFn(base?: StreamFn): StreamFn;
10
+ export declare function createTracedStreamFn(baseOrOptions?: StreamFn | {
11
+ conversationPrivacy?: ConversationPrivacy;
12
+ base?: StreamFn;
13
+ }): StreamFn;
@@ -1,5 +1,5 @@
1
1
  import type { ThreadArtifactsState } from "@/chat/state/artifacts";
2
- import type { Skill, SkillMetadata, SkillInvocation } from "@/chat/skills";
2
+ import type { SkillMetadata, SkillInvocation } from "@/chat/skills";
3
3
  import type { ActiveMcpCatalogSummary } from "@/chat/tools/skill/mcp-tool-summary";
4
4
  export declare const JUNIOR_PERSONALITY: string;
5
5
  export declare const JUNIOR_WORLD: string | null;
@@ -10,8 +10,8 @@ interface ToolPromptContext {
10
10
  }
11
11
  type TurnContextPromptInput = {
12
12
  availableSkills: SkillMetadata[];
13
- activeSkills: Skill[];
14
13
  activeMcpCatalogs?: ActiveMcpCatalogSummary[];
14
+ includeSessionContext?: boolean;
15
15
  toolGuidance?: ToolPromptContext[];
16
16
  runtime?: {
17
17
  conversationId?: string;
@@ -25,15 +25,9 @@ type TurnContextPromptInput = {
25
25
  };
26
26
  artifactState?: ThreadArtifactsState;
27
27
  configuration?: Record<string, unknown>;
28
- /**
29
- * Whether this turn is a fresh prompt or a resume from a prior checkpoint
30
- * (OAuth pause or timeout-resume). Surfaced in <context> so the model knows
31
- * it is continuing rather than starting fresh.
32
- */
33
- turnState?: "fresh" | "resumed";
34
28
  };
35
29
  /** Return byte-stable platform instructions shared by every conversation and turn. */
36
30
  export declare function buildSystemPrompt(): string;
37
31
  /** Build volatile runtime context that belongs in the user turn, not the system prompt. */
38
- export declare function buildTurnContextPrompt(params: TurnContextPromptInput): string;
32
+ export declare function buildTurnContextPrompt(params: TurnContextPromptInput): string | null;
39
33
  export {};
@@ -63,9 +63,11 @@ export declare function isToolResultError(result: unknown): boolean;
63
63
  export declare function isAssistantMessage(value: unknown): value is AssistantMessage;
64
64
  /** Extract role string from a raw Pi message. */
65
65
  export declare function getPiMessageRole(value: unknown): string | undefined;
66
- /** Refresh volatile runtime context in a checkpoint before continuing Pi. */
66
+ /** Refresh volatile runtime context in session history before continuing Pi. */
67
67
  export declare function refreshRuntimeTurnContext(messages: PiMessage[], turnContextPrompt: string): PiMessage[];
68
- /** Remove volatile runtime context before using checkpoint messages as history. */
68
+ /** Return whether Pi history already carries session bootstrap context. */
69
+ export declare function hasRuntimeTurnContext(messages: PiMessage[]): boolean;
70
+ /** Remove volatile runtime context before reusing messages as history. */
69
71
  export declare function stripRuntimeTurnContext(messages: PiMessage[]): PiMessage[];
70
72
  /** Concatenate text content parts from an assistant message. */
71
73
  export declare function extractAssistantText(message: AssistantMessage): string;
@@ -73,5 +75,5 @@ export declare function extractAssistantText(message: AssistantMessage): string;
73
75
  export declare function getTerminalAssistantMessages(messages: readonly unknown[]): AssistantMessage[];
74
76
  /** Upsert a skill into the active skills list by name. */
75
77
  export declare function upsertActiveSkill(activeSkills: Skill[], next: Skill): void;
76
- /** Remove trailing assistant messages before checkpointing. */
78
+ /** Remove trailing assistant messages before committing a resumable boundary. */
77
79
  export declare function trimTrailingAssistantMessages(messages: PiMessage[]): PiMessage[];
@@ -27,6 +27,7 @@ export interface ReplyRequestContext {
27
27
  turnId?: string;
28
28
  runId?: string;
29
29
  channelId?: string;
30
+ channelName?: string;
30
31
  teamId?: string;
31
32
  messageTs?: string;
32
33
  threadTs?: string;
@@ -0,0 +1,10 @@
1
+ import type { Message } from "chat";
2
+ import type { ConversationMessage } from "@/chat/state/conversation";
3
+ interface ConversationMessageInput {
4
+ entry: Message;
5
+ explicitMention?: boolean;
6
+ text: string;
7
+ }
8
+ /** Preserve an SDK message and its Slack metadata in durable conversation memory. */
9
+ export declare function toConversationMessage(args: ConversationMessageInput): ConversationMessage;
10
+ export {};
@@ -1,14 +1,12 @@
1
1
  import type { Message, Thread } from "chat";
2
+ import type { TurnToolInvocation } from "@/chat/runtime/turn-input";
2
3
  /** Controls the automatic Slack processing reaction lifecycle for one message. */
3
4
  export interface ProcessingReactionSession {
4
5
  keep: () => void;
5
6
  stop: () => Promise<void>;
6
7
  }
7
8
  /** Return true when a Slack reaction tool call should leave the processing reaction in place. */
8
- export declare function shouldKeepProcessingReactionForToolInvocation(input: {
9
- params: Record<string, unknown>;
10
- toolName: string;
11
- }): boolean;
9
+ export declare function shouldKeepProcessingReactionForToolInvocation(input: TurnToolInvocation): boolean;
12
10
  /** Start Junior's automatic Slack processing reaction for one inbound message. */
13
11
  export declare function startSlackProcessingReaction(args: {
14
12
  logException: (error: unknown, eventName: string, context?: Record<string, unknown>, attributes?: Record<string, unknown>, body?: string) => string | undefined;
@@ -1,7 +1,16 @@
1
+ /**
2
+ * Slack reply execution boundary.
3
+ *
4
+ * This module bridges prepared Slack thread state into `generateAssistantReply`
5
+ * and commits the resulting Slack-visible delivery/state updates. It is where
6
+ * queued messages, compaction, status updates, and Slack posting meet; agent
7
+ * internals stay behind the reply generator.
8
+ */
1
9
  import type { Message, Thread } from "chat";
2
10
  import type { SlackAdapter } from "@chat-adapter/slack";
3
11
  import { generateAssistantReply as generateAssistantReplyImpl } from "@/chat/respond";
4
12
  import type { PreparedTurnState } from "@/chat/runtime/turn-preparation";
13
+ import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnToolInvocation } from "@/chat/runtime/turn-input";
5
14
  import { type ConversationMemoryService } from "@/chat/services/conversation-memory";
6
15
  import type { ContextCompactor } from "@/chat/services/context-compaction";
7
16
  import { lookupSlackUser } from "@/chat/slack/user";
@@ -32,27 +41,15 @@ interface ReplyExecutorDeps {
32
41
  filename?: string;
33
42
  promptText?: string;
34
43
  }>>;
35
- prepareTurnState: (args: {
36
- explicitMention: boolean;
37
- message: Message;
38
- thread: Thread;
39
- userText: string;
40
- context: {
41
- threadId?: string;
42
- requesterId?: string;
43
- channelId?: string;
44
- runId?: string;
45
- };
46
- }) => Promise<PreparedTurnState>;
44
+ prepareTurnState: (args: PrepareTurnStateInput) => Promise<PreparedTurnState>;
47
45
  services: ReplyExecutorServices;
48
46
  }
47
+ /** Build the Slack reply handler that prepares state, runs Pi, and delivers replies. */
49
48
  export declare function createReplyToThread(deps: ReplyExecutorDeps): (thread: Thread, message: Message, options?: {
50
49
  beforeFirstResponsePost?: () => Promise<void>;
51
50
  explicitMention?: boolean;
52
- onToolInvocation?: (invocation: {
53
- params: Record<string, unknown>;
54
- toolName: string;
55
- }) => void;
51
+ onToolInvocation?: (invocation: TurnToolInvocation) => void;
56
52
  preparedState?: PreparedTurnState;
53
+ queuedMessages?: QueuedTurnMessage[];
57
54
  }) => Promise<void>;
58
55
  export {};
@@ -1,5 +1,14 @@
1
- import type { Message, Thread } from "chat";
2
- import type { SubscribedReplyDecision } from "@/chat/services/subscribed-reply-policy";
1
+ /**
2
+ * Slack event runtime.
3
+ *
4
+ * This module owns inbound Slack routing decisions for mentions, subscribed
5
+ * messages, assistant lifecycle events, and retryable turn pauses. It should
6
+ * normalize text/queued context and decide reply vs silence while keeping
7
+ * Pi/MCP internals and durable session storage behind injected services.
8
+ */
9
+ import type { Message, MessageContext, Thread } from "chat";
10
+ import type { SubscribedReplyDecision, SubscribedReplyPolicy } from "@/chat/services/subscribed-reply-policy";
11
+ import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnMessageText, type TurnToolInvocation } from "@/chat/runtime/turn-input";
3
12
  export interface AssistantLifecycleEvent {
4
13
  channelId: string;
5
14
  context?: {
@@ -9,18 +18,10 @@ export interface AssistantLifecycleEvent {
9
18
  threadTs: string;
10
19
  userId?: string;
11
20
  }
12
- export interface ThreadContext {
13
- channelId?: string;
14
- requesterId?: string;
15
- threadId?: string;
16
- runId?: string;
17
- }
18
21
  export interface ReplyHooks {
19
22
  beforeFirstResponsePost?: () => Promise<void>;
20
- onToolInvocation?: (invocation: {
21
- params: Record<string, unknown>;
22
- toolName: string;
23
- }) => void;
23
+ messageContext?: MessageContext;
24
+ onToolInvocation?: (invocation: TurnToolInvocation) => void;
24
25
  }
25
26
  export interface SlackTurnRuntimeDependencies<TPreparedState> {
26
27
  assistantUserName: string;
@@ -48,8 +49,8 @@ export interface SlackTurnRuntimeDependencies<TPreparedState> {
48
49
  completedAtMs: number;
49
50
  decision: SubscribedReplyDecision;
50
51
  message: Message;
52
+ text: TurnMessageText;
51
53
  thread: Thread;
52
- userText: string;
53
54
  }) => Promise<void>;
54
55
  onSubscribedMessageSkipped: (args: {
55
56
  completedAtMs: number;
@@ -62,30 +63,15 @@ export interface SlackTurnRuntimeDependencies<TPreparedState> {
62
63
  preparedState: TPreparedState;
63
64
  thread: Thread;
64
65
  }) => Promise<void>;
65
- prepareTurnState: (args: {
66
- context: ThreadContext;
67
- explicitMention: boolean;
68
- message: Message;
69
- thread: Thread;
70
- userText: string;
71
- }) => Promise<TPreparedState>;
66
+ prepareTurnState: (args: PrepareTurnStateInput) => Promise<TPreparedState>;
72
67
  replyToThread: (thread: Thread, message: Message, options?: {
73
68
  beforeFirstResponsePost?: () => Promise<void>;
74
69
  explicitMention?: boolean;
75
- onToolInvocation?: (invocation: {
76
- params: Record<string, unknown>;
77
- toolName: string;
78
- }) => void;
70
+ onToolInvocation?: (invocation: TurnToolInvocation) => void;
79
71
  preparedState?: TPreparedState;
72
+ queuedMessages?: QueuedTurnMessage[];
80
73
  }) => Promise<void>;
81
- decideSubscribedReply: (args: {
82
- context: ThreadContext;
83
- conversationContext?: string;
84
- hasAttachments?: boolean;
85
- isExplicitMention?: boolean;
86
- rawText: string;
87
- text: string;
88
- }) => Promise<SubscribedReplyDecision>;
74
+ decideSubscribedReply: SubscribedReplyPolicy;
89
75
  stripLeadingBotMention: (text: string, options: {
90
76
  stripLeadingSlackMentionToken?: boolean;
91
77
  }) => string;
@@ -97,4 +83,5 @@ export interface SlackTurnRuntime<_TPreparedState, TAssistantEvent extends Assis
97
83
  handleNewMention: (thread: Thread, message: Message, hooks?: ReplyHooks) => Promise<void>;
98
84
  handleSubscribedMessage: (thread: Thread, message: Message, hooks?: ReplyHooks) => Promise<void>;
99
85
  }
86
+ /** Build the Slack event runtime that routes mentions and subscribed messages. */
100
87
  export declare function createSlackTurnRuntime<TPreparedState, TAssistantEvent extends AssistantLifecycleEvent = AssistantLifecycleEvent>(deps: SlackTurnRuntimeDependencies<TPreparedState>): SlackTurnRuntime<TPreparedState, TAssistantEvent>;
@@ -1,4 +1,4 @@
1
- import { type Thread } from "chat";
1
+ import type { Thread } from "chat";
2
2
  import type { ChannelConfigurationService } from "@/chat/configuration/types";
3
3
  import type { ThreadConversationState } from "@/chat/state/conversation";
4
4
  import { type ThreadArtifactsState } from "@/chat/state/artifacts";
@@ -0,0 +1,29 @@
1
+ import type { Message, Thread } from "chat";
2
+ export interface TurnContext {
3
+ channelId?: string;
4
+ requesterId?: string;
5
+ threadId?: string;
6
+ runId?: string;
7
+ }
8
+ export interface TurnMessageText {
9
+ rawText: string;
10
+ userText: string;
11
+ }
12
+ export interface TurnToolInvocation {
13
+ params: Record<string, unknown>;
14
+ toolName: string;
15
+ }
16
+ export interface QueuedTurnMessage extends TurnMessageText {
17
+ explicitMention: boolean;
18
+ message: Message;
19
+ }
20
+ export interface PrepareTurnStateInput {
21
+ context: TurnContext;
22
+ explicitMention: boolean;
23
+ message: Message;
24
+ queuedMessages?: QueuedTurnMessage[];
25
+ text: TurnMessageText;
26
+ thread: Thread;
27
+ }
28
+ /** Preserve skipped Slack messages as turn input without duplicating stored state. */
29
+ export declare function combineTurnText(queuedMessages: readonly TurnMessageText[], latestText: TurnMessageText): TurnMessageText;
@@ -1,7 +1,7 @@
1
- import type { Message, Thread } from "chat";
2
1
  import type { ThreadConversationState } from "@/chat/state/conversation";
3
2
  import { type ThreadArtifactsState } from "@/chat/state/artifacts";
4
3
  import type { ChannelConfigurationService } from "@/chat/configuration/types";
4
+ import type { PrepareTurnStateInput, TurnContext } from "@/chat/runtime/turn-input";
5
5
  export interface PreparedTurnState {
6
6
  artifacts: ThreadArtifactsState;
7
7
  configuration?: Record<string, unknown>;
@@ -14,30 +14,10 @@ export interface PreparedTurnState {
14
14
  userMessageId?: string;
15
15
  }
16
16
  export interface PrepareTurnStateDeps {
17
- compactConversationIfNeeded: (conversation: ThreadConversationState, context: {
18
- threadId?: string;
19
- channelId?: string;
20
- requesterId?: string;
21
- runId?: string;
22
- }) => Promise<void>;
23
- hydrateConversationVisionContext: (conversation: ThreadConversationState, context: {
24
- threadId?: string;
25
- channelId?: string;
26
- requesterId?: string;
27
- runId?: string;
17
+ compactConversationIfNeeded: (conversation: ThreadConversationState, context: TurnContext) => Promise<void>;
18
+ hydrateConversationVisionContext: (conversation: ThreadConversationState, context: TurnContext & {
28
19
  threadTs?: string;
29
20
  }) => Promise<void>;
30
21
  }
31
22
  /** Build the turn-state preparer from injected conversation services. */
32
- export declare function createPrepareTurnState(deps: PrepareTurnStateDeps): (args: {
33
- explicitMention: boolean;
34
- message: Message;
35
- thread: Thread;
36
- userText: string;
37
- context: {
38
- threadId?: string;
39
- requesterId?: string;
40
- channelId?: string;
41
- runId?: string;
42
- };
43
- }) => Promise<PreparedTurnState>;
23
+ export declare function createPrepareTurnState(deps: PrepareTurnStateDeps): (args: PrepareTurnStateInput) => Promise<PreparedTurnState>;
@@ -11,7 +11,7 @@ export interface RetryableTurnMetadata {
11
11
  authProvider?: string;
12
12
  authThinkingLevel?: TurnThinkingSelection["thinkingLevel"];
13
13
  authUsage?: AgentTurnUsage;
14
- checkpointVersion?: number;
14
+ version?: number;
15
15
  conversationId?: string;
16
16
  sessionId?: string;
17
17
  sliceId?: number;
@@ -42,8 +42,7 @@ export declare function markTurnClosed(args: {
42
42
  updateConversationStats: (conversation: ThreadConversationState) => void;
43
43
  }): void;
44
44
  /**
45
- * Mark a turn as completed after final reply delivery succeeds and make its Pi
46
- * session the reusable history source for the next turn.
45
+ * Mark a turn as completed after final reply delivery succeeds.
47
46
  */
48
47
  export declare function markTurnCompleted(args: {
49
48
  conversation: ThreadConversationState;
@@ -0,0 +1,4 @@
1
+ /** Build a Sentry conversation URL only when the runtime has enough Sentry config. */
2
+ export declare function buildSentryConversationUrl(conversationId: string): string | undefined;
3
+ /** Build a Sentry trace URL only when the runtime has enough Sentry config. */
4
+ export declare function buildSentryTraceUrl(traceId: string): string | undefined;
@@ -13,7 +13,7 @@ export interface CompactContextArgs {
13
13
  conversationContext?: string;
14
14
  conversationId: string;
15
15
  onCompactionStart?: () => void;
16
- previousSessionId: string;
16
+ piMessages: PiMessage[];
17
17
  metadata?: {
18
18
  channelId?: string;
19
19
  requesterId?: string;
@@ -24,10 +24,9 @@ export interface CompactContextArgs {
24
24
  export interface CompactContextResult {
25
25
  compacted: boolean;
26
26
  piMessages?: PiMessage[];
27
- reason?: "below_threshold" | "missing_context" | "not_completed" | "summary_failed";
28
- sessionId?: string;
27
+ reason?: "below_threshold" | "missing_context" | "summary_failed";
29
28
  }
30
29
  /** Build retained user messages for a compacted Pi replacement history. */
31
30
  export declare function selectRetainedUserMessages(messages: PiMessage[], maxTokens?: number): PiMessage[];
32
- /** Build the service that owns local context compaction and checkpoint forks. */
31
+ /** Build the service that owns local context compaction. */
33
32
  export declare function createContextCompactor(deps: ContextCompactorDeps): ContextCompactor;
@@ -16,7 +16,7 @@ export declare function getConversationPendingAuth(args: {
16
16
  export declare function clearPendingAuth(conversation: ThreadConversationState, sessionId?: string): void;
17
17
  /**
18
18
  * Apply a new pending-auth record to the conversation and, when replacing a
19
- * different session's pending-auth, mark the prior checkpoint as superseded.
19
+ * different session's pending-auth, mark the prior session record as abandoned.
20
20
  * Callers are responsible for persisting the mutated conversation afterwards.
21
21
  */
22
22
  export declare function applyPendingAuthUpdate(args: {
@@ -1,3 +1,4 @@
1
+ import { type SubscribedDecisionInput } from "@/chat/services/subscribed-decision";
1
2
  import type { completeObject } from "@/chat/pi/client";
2
3
  export interface SubscribedReplyPolicyDeps {
3
4
  completeObject: typeof completeObject;
@@ -7,17 +8,5 @@ export interface SubscribedReplyDecision {
7
8
  shouldReply: boolean;
8
9
  shouldUnsubscribe?: boolean;
9
10
  }
10
- export type SubscribedReplyPolicy = (args: {
11
- rawText: string;
12
- text: string;
13
- conversationContext?: string;
14
- hasAttachments?: boolean;
15
- isExplicitMention?: boolean;
16
- context: {
17
- threadId?: string;
18
- requesterId?: string;
19
- channelId?: string;
20
- runId?: string;
21
- };
22
- }) => Promise<SubscribedReplyDecision>;
11
+ export type SubscribedReplyPolicy = (args: SubscribedDecisionInput) => Promise<SubscribedReplyDecision>;
23
12
  export declare function createSubscribedReplyPolicy(deps: SubscribedReplyPolicyDeps): SubscribedReplyPolicy;
@@ -1,9 +1,8 @@
1
1
  export interface TurnContinuationRequest {
2
2
  conversationId: string;
3
- expectedCheckpointVersion: number;
3
+ expectedVersion: number;
4
4
  sessionId: string;
5
5
  }
6
- export type TurnTimeoutResumeRequest = TurnContinuationRequest;
7
6
  /** Bound automatic timeout continuation so one bad turn cannot loop forever. */
8
7
  export declare function canScheduleTurnTimeoutResume(nextSliceId: number | undefined): boolean;
9
8
  /** Build the callback request for an awaiting automatic turn continuation. */
@@ -0,0 +1,82 @@
1
+ import { type AgentTurnSessionRecord, type AgentTurnRequester } from "@/chat/state/turn-session";
2
+ import type { PiMessage } from "@/chat/pi/messages";
3
+ import { type AgentTurnUsage } from "@/chat/usage";
4
+ export interface TurnSessionContext {
5
+ conversationId?: string;
6
+ sessionId?: string;
7
+ }
8
+ export interface TurnSessionState {
9
+ canUseTurnSession: boolean;
10
+ resumedFromSessionRecord: boolean;
11
+ currentSliceId: number;
12
+ existingSessionRecord?: AgentTurnSessionRecord;
13
+ }
14
+ interface SessionRecordLogContext {
15
+ threadId?: string;
16
+ requesterId?: string;
17
+ channelId?: string;
18
+ runId?: string;
19
+ assistantUserName?: string;
20
+ modelId: string;
21
+ }
22
+ /** Load turn session record state for a conversation/session pair. */
23
+ export declare function loadTurnSessionRecord(ctx: TurnSessionContext): Promise<TurnSessionState>;
24
+ /** Persist the latest safe in-progress boundary without scheduling continuation. */
25
+ export declare function persistRunningSessionRecord(args: {
26
+ channelName?: string;
27
+ conversationId: string;
28
+ sessionId: string;
29
+ sliceId: number;
30
+ messages: PiMessage[];
31
+ loadedSkillNames?: string[];
32
+ logContext: SessionRecordLogContext;
33
+ requester?: AgentTurnRequester;
34
+ }): Promise<void>;
35
+ /** Persist a completed turn session record. */
36
+ export declare function persistCompletedSessionRecord(args: {
37
+ channelName?: string;
38
+ conversationId: string;
39
+ currentDurationMs?: number;
40
+ currentUsage?: AgentTurnUsage;
41
+ sessionId: string;
42
+ sliceId: number;
43
+ allMessages: PiMessage[];
44
+ loadedSkillNames?: string[];
45
+ logContext: SessionRecordLogContext;
46
+ requester?: AgentTurnRequester;
47
+ }): Promise<void>;
48
+ /**
49
+ * Persist an auth-pause session record. Returns the durable record only when
50
+ * the caller can safely hand the user to an authorization resume flow.
51
+ */
52
+ export declare function persistAuthPauseSessionRecord(args: {
53
+ channelName?: string;
54
+ conversationId: string;
55
+ sessionId: string;
56
+ currentSliceId: number;
57
+ currentDurationMs?: number;
58
+ currentUsage?: AgentTurnUsage;
59
+ messages: PiMessage[];
60
+ loadedSkillNames?: string[];
61
+ errorMessage: string;
62
+ logContext: SessionRecordLogContext;
63
+ requester?: AgentTurnRequester;
64
+ }): Promise<AgentTurnSessionRecord | undefined>;
65
+ /**
66
+ * Persist a timeout session record at the last safe boundary. Returns the durable
67
+ * record when persistence succeeds so callers can enqueue a continuation.
68
+ */
69
+ export declare function persistTimeoutSessionRecord(args: {
70
+ channelName?: string;
71
+ conversationId: string;
72
+ sessionId: string;
73
+ currentSliceId: number;
74
+ currentDurationMs?: number;
75
+ currentUsage?: AgentTurnUsage;
76
+ messages: PiMessage[];
77
+ loadedSkillNames?: string[];
78
+ errorMessage: string;
79
+ logContext: SessionRecordLogContext;
80
+ requester?: AgentTurnRequester;
81
+ }): Promise<AgentTurnSessionRecord | undefined>;
82
+ export {};
@@ -25,4 +25,7 @@ export declare function maybeUpdateAssistantTitle(args: {
25
25
  requesterId?: string;
26
26
  runId?: string;
27
27
  threadId?: string;
28
- }): Promise<string | undefined>;
28
+ }): Promise<{
29
+ sourceMessageId: string;
30
+ title?: string;
31
+ } | undefined>;