@sentry/junior 0.71.2 → 0.72.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.
- package/bin/junior.mjs +10 -0
- package/dist/api-reference.d.ts +2 -0
- package/dist/app.d.ts +5 -5
- package/dist/app.js +1039 -1971
- package/dist/chat/agent-dispatch/heartbeat.d.ts +0 -6
- package/dist/chat/mcp/errors.d.ts +3 -0
- package/dist/chat/mcp/tool-manager.d.ts +5 -1
- package/dist/chat/plugins/agent-hooks.d.ts +3 -2
- package/dist/chat/requester.d.ts +60 -0
- package/dist/chat/respond.d.ts +2 -6
- package/dist/chat/runtime/agent-continue-runner.d.ts +25 -0
- package/dist/chat/runtime/reply-executor.d.ts +4 -4
- package/dist/chat/runtime/turn.d.ts +2 -2
- package/dist/chat/services/agent-continue.d.ts +27 -0
- package/dist/chat/services/message-actor-identity.d.ts +12 -4
- package/dist/chat/services/turn-session-record.d.ts +10 -7
- package/dist/chat/slack/user.d.ts +4 -4
- package/dist/chat/state/adapter.d.ts +2 -0
- package/dist/chat/state/conversation-details.d.ts +4 -3
- package/dist/chat/state/session-log.d.ts +43 -0
- package/dist/chat/state/turn-session.d.ts +7 -10
- package/dist/chat/task-execution/queue.d.ts +1 -1
- package/dist/chat/task-execution/slack-work.d.ts +5 -5
- package/dist/chat/task-execution/store.d.ts +83 -48
- package/dist/chat/task-execution/worker.d.ts +3 -3
- package/dist/chat/tools/definition.d.ts +3 -0
- package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -1
- package/dist/chat/tools/types.d.ts +2 -5
- package/dist/{chunk-R62YWUNO.js → chunk-3FYPXHPL.js} +10 -28
- package/dist/chunk-4JXCSGSA.js +212 -0
- package/dist/{chunk-GT67ZWZQ.js → chunk-55XEZFGD.js} +5 -3
- package/dist/{chunk-BBXYXOJW.js → chunk-6GEYPE6T.js} +18 -523
- package/dist/chunk-G3E7SCME.js +28 -0
- package/dist/{chunk-UXG6TU2U.js → chunk-GB3AL54K.js} +8 -93
- package/dist/chunk-HNMUVGSR.js +1119 -0
- package/dist/{chunk-XE2VFQQN.js → chunk-ICKIDP7G.js} +1 -1
- package/dist/chunk-KVZL5NZS.js +519 -0
- package/dist/chunk-PP7AGSBU.js +185 -0
- package/dist/{chunk-B5HKWWQB.js → chunk-VLIO6RQR.js} +8 -6
- package/dist/{chunk-HOGQL2H6.js → chunk-VSNA5KAB.js} +177 -101
- package/dist/{chunk-76YMBKW7.js → chunk-XC33FJZN.js} +4 -12
- package/dist/{chunk-JS4HURDT.js → chunk-ZJQPA67D.js} +25 -25
- package/dist/cli/check.js +10 -8
- package/dist/cli/run.js +9 -1
- package/dist/cli/snapshot-warmup.js +10 -7
- package/dist/cli/upgrade.js +599 -0
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +5 -4
- package/dist/plugins.d.ts +1 -1
- package/dist/reporting/conversations.d.ts +116 -0
- package/dist/reporting.d.ts +24 -129
- package/dist/reporting.js +310 -158
- package/package.json +3 -3
- package/dist/chat/runtime/timeout-resume-runner.d.ts +0 -19
- package/dist/chat/services/requester-identity.d.ts +0 -19
- package/dist/chat/services/timeout-resume.d.ts +0 -23
- package/dist/handlers/turn-resume.d.ts +0 -4
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
2
|
-
/** Re-drive stale turn continuations whose internal callback vanished. */
|
|
3
|
-
export declare function recoverStaleTimeoutResumes(args: {
|
|
4
|
-
conversationWorkQueue?: ConversationWorkQueue;
|
|
5
|
-
limit?: number;
|
|
6
|
-
nowMs: number;
|
|
7
|
-
}): Promise<number>;
|
|
8
2
|
/** Re-drive stale core dispatches before invoking plugin heartbeat hooks. */
|
|
9
3
|
export declare function recoverStaleDispatches(args: {
|
|
10
4
|
limit?: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConversationPrivacy } from "@/chat/conversation-privacy";
|
|
1
2
|
/** Thrown when an MCP failure should be returned as a model-visible tool error. */
|
|
2
3
|
export declare class McpToolError extends Error {
|
|
3
4
|
constructor(message: string);
|
|
@@ -6,3 +7,5 @@ export declare class McpToolError extends Error {
|
|
|
6
7
|
export declare function getMcpAwareErrorType(error: unknown, fallback: string): string;
|
|
7
8
|
/** Return the display-safe error message for MCP-aware tool failures. */
|
|
8
9
|
export declare function getMcpAwareErrorMessage(error: unknown): string;
|
|
10
|
+
/** Return an error message safe for logs and span attributes. */
|
|
11
|
+
export declare function getMcpAwareTelemetryMessage(error: unknown, privacy: ConversationPrivacy | undefined): string;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
10
10
|
import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
11
|
+
import { type ConversationPrivacy } from "@/chat/conversation-privacy";
|
|
11
12
|
import type { SkillMetadata } from "@/chat/skills";
|
|
12
13
|
import type { PluginDefinition } from "@/chat/plugins/types";
|
|
13
14
|
import { McpAuthorizationRequiredError, type PluginMcpToolCallResult } from "./client";
|
|
@@ -36,7 +37,10 @@ export interface ManagedMcpToolDescriptor {
|
|
|
36
37
|
}
|
|
37
38
|
type ActiveMcpSkill = Pick<SkillMetadata, "name" | "pluginProvider">;
|
|
38
39
|
export interface ManagedMcpTool extends ManagedMcpToolDescriptor {
|
|
39
|
-
execute: (args: Record<string, unknown
|
|
40
|
+
execute: (args: Record<string, unknown>, options?: {
|
|
41
|
+
conversationPrivacy?: ConversationPrivacy;
|
|
42
|
+
toolCallId?: string;
|
|
43
|
+
}) => Promise<ManagedMcpToolResult>;
|
|
40
44
|
}
|
|
41
45
|
export declare class McpToolManager {
|
|
42
46
|
private readonly options;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentPluginRoute, PluginOperationalReport, SlackConversationLink, JuniorPluginRegistration } from "@sentry/junior-plugin-api";
|
|
2
2
|
import type { ToolDefinition } from "@/chat/tools/definition";
|
|
3
3
|
import type { ToolRuntimeContext } from "@/chat/tools/types";
|
|
4
4
|
import type { SandboxInstance } from "@/chat/sandbox/workspace";
|
|
5
|
+
import type { Requester } from "@/chat/requester";
|
|
5
6
|
/** Signal that a plugin intentionally denied a tool execution. */
|
|
6
7
|
export declare class AgentPluginHookDeniedError extends Error {
|
|
7
8
|
constructor(message: string);
|
|
@@ -37,5 +38,5 @@ export declare function getAgentPluginSlackConversationLink(conversationId: stri
|
|
|
37
38
|
export declare function getAgentPluginOperationalReports(nowMs?: number): Promise<PluginOperationalReport[]>;
|
|
38
39
|
/** Create one runner over runtime hook plugins registered by the app. */
|
|
39
40
|
export declare function createAgentPluginHookRunner(input?: {
|
|
40
|
-
requester?:
|
|
41
|
+
requester?: Requester;
|
|
41
42
|
}): AgentPluginHookRunner;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Slack requester identity.
|
|
3
|
+
*
|
|
4
|
+
* Runtime requesters are always workspace-scoped Slack actors. Stored requester
|
|
5
|
+
* parsing remains explicit so legacy durable records can resume without
|
|
6
|
+
* repairing malformed team or user ids.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export declare const storedSlackRequesterSchema: z.ZodObject<{
|
|
10
|
+
email: z.ZodOptional<z.ZodString>;
|
|
11
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
12
|
+
platform: z.ZodOptional<z.ZodLiteral<"slack">>;
|
|
13
|
+
slackUserId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
slackUserName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
teamId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
export interface Requester {
|
|
18
|
+
email?: string;
|
|
19
|
+
fullName?: string;
|
|
20
|
+
platform: "slack";
|
|
21
|
+
teamId: string;
|
|
22
|
+
userId: string;
|
|
23
|
+
userName?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SlackRequesterProfile {
|
|
26
|
+
email?: string;
|
|
27
|
+
fullName?: string;
|
|
28
|
+
userName?: string;
|
|
29
|
+
}
|
|
30
|
+
export type StoredSlackRequester = z.output<typeof storedSlackRequesterSchema>;
|
|
31
|
+
interface RequesterInput {
|
|
32
|
+
email?: string;
|
|
33
|
+
fullName?: string;
|
|
34
|
+
platform?: "slack";
|
|
35
|
+
teamId?: string;
|
|
36
|
+
userId?: string;
|
|
37
|
+
userName?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Keep actor ids exact at platform boundaries before they enter owned state. */
|
|
40
|
+
export declare function parseActorUserId(value: unknown): string | undefined;
|
|
41
|
+
/** Assert persisted actor ids without read-side repair. */
|
|
42
|
+
export declare function isActorUserId(value: string | undefined): value is string;
|
|
43
|
+
/** Build Junior's canonical requester from exact Slack team/user ids and profile data. */
|
|
44
|
+
export declare function createRequester(input: RequesterInput | undefined, context: {
|
|
45
|
+
teamId?: string;
|
|
46
|
+
userId?: string;
|
|
47
|
+
}): Requester | undefined;
|
|
48
|
+
/** Build Junior's canonical requester from Slack profile data. */
|
|
49
|
+
export declare function createSlackRequester(teamId: string, userId: string, profile: SlackRequesterProfile | null | undefined): Requester;
|
|
50
|
+
/** Parse a serialized Slack requester that crossed a runtime boundary. */
|
|
51
|
+
export declare function parseStoredSlackRequester(value: unknown): StoredSlackRequester | undefined;
|
|
52
|
+
/** Convert a runtime Slack requester into its durable session shape. */
|
|
53
|
+
export declare function toStoredSlackRequester(requester: Requester): StoredSlackRequester;
|
|
54
|
+
/** Rebuild a runtime requester from durable Slack requester state. */
|
|
55
|
+
export declare function createRequesterFromStoredSlackRequester(args: {
|
|
56
|
+
requester?: StoredSlackRequester;
|
|
57
|
+
teamId: string;
|
|
58
|
+
userId: string;
|
|
59
|
+
}): Requester;
|
|
60
|
+
export {};
|
package/dist/chat/respond.d.ts
CHANGED
|
@@ -10,17 +10,13 @@ import type { SlackConversationContext } from "@/chat/slack/conversation-context
|
|
|
10
10
|
import { type AssistantReply, type AgentTurnDiagnostics } from "@/chat/services/turn-result";
|
|
11
11
|
import type { AgentTurnSurface } from "@/chat/state/turn-session";
|
|
12
12
|
import type { CredentialContext } from "@/chat/credentials/context";
|
|
13
|
+
import { type Requester } from "@/chat/requester";
|
|
13
14
|
import { type AuthorizationFlowMode } from "@/chat/services/auth-pause";
|
|
14
15
|
export type { AssistantReply, AgentTurnDiagnostics };
|
|
15
16
|
export interface ReplyRequestContext {
|
|
16
17
|
skillDirs?: string[];
|
|
17
18
|
credentialContext?: CredentialContext;
|
|
18
|
-
requester?:
|
|
19
|
-
userId?: string;
|
|
20
|
-
userName?: string;
|
|
21
|
-
fullName?: string;
|
|
22
|
-
email?: string;
|
|
23
|
-
};
|
|
19
|
+
requester?: Requester;
|
|
24
20
|
slackConversation?: SlackConversationContext;
|
|
25
21
|
destination?: Destination;
|
|
26
22
|
surface?: AgentTurnSurface;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resumeSlackTurn } from "@/chat/runtime/slack-resume";
|
|
2
|
+
import { type AgentContinueRequest } from "@/chat/services/agent-continue";
|
|
3
|
+
import type { generateAssistantReply } from "@/chat/respond";
|
|
4
|
+
/** Runtime ports for agent continuation scheduling. */
|
|
5
|
+
export interface AgentContinueRunnerOptions {
|
|
6
|
+
generateReply?: typeof generateAssistantReply;
|
|
7
|
+
resumeTurn?: typeof resumeSlackTurn;
|
|
8
|
+
scheduleAgentContinue?: (request: AgentContinueRequest) => Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Continue one paused Slack agent run from durable conversation state.
|
|
12
|
+
*
|
|
13
|
+
* Returns false when the session became stale before generation began.
|
|
14
|
+
*/
|
|
15
|
+
export declare function continueSlackAgentRun(payload: AgentContinueRequest, options?: AgentContinueRunnerOptions): Promise<boolean>;
|
|
16
|
+
/** Resume the first valid paused Slack session for an idle conversation. */
|
|
17
|
+
export declare function resumeAwaitingSlackContinuation(conversationId: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Retry agent continuation when the normal Slack thread lock is briefly busy.
|
|
20
|
+
*
|
|
21
|
+
* Returns false when the session became stale before generation began. A busy
|
|
22
|
+
* lock that is rescheduled still returns true because runnable work remains
|
|
23
|
+
* durable.
|
|
24
|
+
*/
|
|
25
|
+
export declare function continueSlackAgentRunWithLockRetry(payload: AgentContinueRequest, options?: AgentContinueRunnerOptions): Promise<boolean>;
|
|
@@ -15,17 +15,17 @@ import { type PrepareTurnStateInput, type QueuedTurnMessage, type TurnToolInvoca
|
|
|
15
15
|
import { type ConversationMemoryService } from "@/chat/services/conversation-memory";
|
|
16
16
|
import type { ContextCompactor } from "@/chat/services/context-compaction";
|
|
17
17
|
import { lookupSlackUser } from "@/chat/slack/user";
|
|
18
|
-
import type {
|
|
18
|
+
import type { AgentContinueRequest } from "@/chat/services/agent-continue";
|
|
19
19
|
export interface ReplyExecutorServices {
|
|
20
20
|
contextCompactor: ContextCompactor;
|
|
21
21
|
generateAssistantReply: typeof generateAssistantReplyImpl;
|
|
22
22
|
generateThreadTitle: ConversationMemoryService["generateThreadTitle"];
|
|
23
|
-
|
|
23
|
+
getAwaitingAgentContinueRequest: (args: {
|
|
24
24
|
conversationId: string;
|
|
25
25
|
sessionId: string;
|
|
26
|
-
}) => Promise<
|
|
26
|
+
}) => Promise<AgentContinueRequest | undefined>;
|
|
27
27
|
lookupSlackUser: typeof lookupSlackUser;
|
|
28
|
-
|
|
28
|
+
scheduleAgentContinue: (request: AgentContinueRequest) => Promise<void>;
|
|
29
29
|
}
|
|
30
30
|
interface ReplyExecutorDeps {
|
|
31
31
|
getSlackAdapter: () => SlackAdapter;
|
|
@@ -3,7 +3,7 @@ import type { AuthorizationPauseDisposition, AuthorizationPauseKind } from "@/ch
|
|
|
3
3
|
import type { TurnThinkingSelection } from "@/chat/services/turn-thinking-level";
|
|
4
4
|
import type { AgentTurnUsage } from "@/chat/usage";
|
|
5
5
|
export { buildDeterministicTurnId } from "@/chat/state/turn-id";
|
|
6
|
-
export type RetryableTurnReason = "mcp_auth_resume" | "plugin_auth_resume" | "
|
|
6
|
+
export type RetryableTurnReason = "mcp_auth_resume" | "plugin_auth_resume" | "agent_continue";
|
|
7
7
|
export interface RetryableTurnMetadata {
|
|
8
8
|
authDisposition?: AuthorizationPauseDisposition;
|
|
9
9
|
authDurationMs?: number;
|
|
@@ -16,7 +16,7 @@ export interface RetryableTurnMetadata {
|
|
|
16
16
|
sessionId?: string;
|
|
17
17
|
sliceId?: number;
|
|
18
18
|
}
|
|
19
|
-
/** Error indicating
|
|
19
|
+
/** Error indicating an agent run can continue later after timeout or auth pause. */
|
|
20
20
|
export declare class RetryableTurnError extends Error {
|
|
21
21
|
readonly code = "retryable_turn";
|
|
22
22
|
readonly metadata?: RetryableTurnMetadata;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable agent continuation scheduling.
|
|
3
|
+
*
|
|
4
|
+
* This module owns the queue handoff used when an agent run pauses at a safe
|
|
5
|
+
* Pi continuation boundary and needs another execution slice.
|
|
6
|
+
*/
|
|
7
|
+
import type { StateAdapter } from "chat";
|
|
8
|
+
import type { Destination } from "@sentry/junior-plugin-api";
|
|
9
|
+
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
10
|
+
export interface AgentContinueRequest {
|
|
11
|
+
conversationId: string;
|
|
12
|
+
destination: Destination;
|
|
13
|
+
expectedVersion: number;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ScheduleAgentContinueOptions {
|
|
17
|
+
nowMs?: number;
|
|
18
|
+
queue?: ConversationWorkQueue;
|
|
19
|
+
state?: StateAdapter;
|
|
20
|
+
}
|
|
21
|
+
/** Build the queue request for an awaiting automatic agent continuation. */
|
|
22
|
+
export declare function getAwaitingAgentContinueRequest(args: {
|
|
23
|
+
conversationId: string;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
}): Promise<AgentContinueRequest | undefined>;
|
|
26
|
+
/** Schedule durable conversation work to continue a paused agent run. */
|
|
27
|
+
export declare function scheduleAgentContinue(request: AgentContinueRequest, options?: ScheduleAgentContinueOptions): Promise<void>;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { Message } from "chat";
|
|
2
|
-
import { type
|
|
2
|
+
import { type Requester, type SlackRequesterProfile } from "@/chat/requester";
|
|
3
|
+
interface MessageAuthorIdentity {
|
|
4
|
+
email?: string;
|
|
5
|
+
fullName?: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
userName?: string;
|
|
8
|
+
}
|
|
9
|
+
type MessageActorIdentity = Requester | MessageAuthorIdentity;
|
|
3
10
|
/** Preserve runtime-owned identity on Chat SDK messages before persistence. */
|
|
4
|
-
export declare function bindMessageActorIdentity(message: Message,
|
|
11
|
+
export declare function bindMessageActorIdentity(message: Message, requester: Requester): Requester;
|
|
5
12
|
/** Read message identity without promoting adapter display fallbacks. */
|
|
6
|
-
export declare function getMessageActorIdentity(message: Message):
|
|
13
|
+
export declare function getMessageActorIdentity(message: Message): MessageActorIdentity | undefined;
|
|
7
14
|
/** Attach Slack display fields only after the author id is exact. */
|
|
8
|
-
export declare function ensureSlackMessageActorIdentity(message: Message, lookupSlackUser: (userId: string) => Promise<
|
|
15
|
+
export declare function ensureSlackMessageActorIdentity(message: Message, teamId: string, lookupSlackUser: (teamId: string, userId: string) => Promise<SlackRequesterProfile | null | undefined>): Promise<Requester>;
|
|
16
|
+
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { type AgentTurnSessionRecord, type
|
|
1
|
+
import { type AgentTurnSessionRecord, type AgentTurnSurface } from "@/chat/state/turn-session";
|
|
2
|
+
import type { StoredSlackRequester } from "@/chat/requester";
|
|
2
3
|
import type { Destination } from "@sentry/junior-plugin-api";
|
|
3
4
|
import type { PiMessage } from "@/chat/pi/messages";
|
|
4
5
|
import { type AgentTurnUsage } from "@/chat/usage";
|
|
5
|
-
export declare const
|
|
6
|
+
export declare const AGENT_CONTINUE_MAX_SLICES = 48;
|
|
6
7
|
export interface TurnSessionContext {
|
|
7
8
|
conversationId?: string;
|
|
8
9
|
sessionId?: string;
|
|
@@ -33,8 +34,9 @@ export declare function persistRunningSessionRecord(args: {
|
|
|
33
34
|
messages: PiMessage[];
|
|
34
35
|
loadedSkillNames?: string[];
|
|
35
36
|
logContext: SessionRecordLogContext;
|
|
36
|
-
requester?:
|
|
37
|
+
requester?: StoredSlackRequester;
|
|
37
38
|
surface?: AgentTurnSurface;
|
|
39
|
+
turnStartMessageIndex?: number;
|
|
38
40
|
}): Promise<boolean>;
|
|
39
41
|
/** Persist a completed turn session record. */
|
|
40
42
|
export declare function persistCompletedSessionRecord(args: {
|
|
@@ -48,8 +50,9 @@ export declare function persistCompletedSessionRecord(args: {
|
|
|
48
50
|
allMessages: PiMessage[];
|
|
49
51
|
loadedSkillNames?: string[];
|
|
50
52
|
logContext: SessionRecordLogContext;
|
|
51
|
-
requester?:
|
|
53
|
+
requester?: StoredSlackRequester;
|
|
52
54
|
surface?: AgentTurnSurface;
|
|
55
|
+
turnStartMessageIndex?: number;
|
|
53
56
|
}): Promise<void>;
|
|
54
57
|
/**
|
|
55
58
|
* Persist an auth-pause session record. Returns the durable record only when
|
|
@@ -67,7 +70,7 @@ export declare function persistAuthPauseSessionRecord(args: {
|
|
|
67
70
|
loadedSkillNames?: string[];
|
|
68
71
|
errorMessage: string;
|
|
69
72
|
logContext: SessionRecordLogContext;
|
|
70
|
-
requester?:
|
|
73
|
+
requester?: StoredSlackRequester;
|
|
71
74
|
surface?: AgentTurnSurface;
|
|
72
75
|
}): Promise<AgentTurnSessionRecord | undefined>;
|
|
73
76
|
/**
|
|
@@ -86,7 +89,7 @@ export declare function persistTimeoutSessionRecord(args: {
|
|
|
86
89
|
loadedSkillNames?: string[];
|
|
87
90
|
errorMessage: string;
|
|
88
91
|
logContext: SessionRecordLogContext;
|
|
89
|
-
requester?:
|
|
92
|
+
requester?: StoredSlackRequester;
|
|
90
93
|
surface?: AgentTurnSurface;
|
|
91
94
|
}): Promise<AgentTurnSessionRecord | undefined>;
|
|
92
95
|
/**
|
|
@@ -104,7 +107,7 @@ export declare function persistYieldSessionRecord(args: {
|
|
|
104
107
|
loadedSkillNames?: string[];
|
|
105
108
|
errorMessage: string;
|
|
106
109
|
logContext: SessionRecordLogContext;
|
|
107
|
-
requester?:
|
|
110
|
+
requester?: StoredSlackRequester;
|
|
108
111
|
surface?: AgentTurnSurface;
|
|
109
112
|
}): Promise<AgentTurnSessionRecord | undefined>;
|
|
110
113
|
export {};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Requester } from "@/chat/requester";
|
|
2
2
|
interface SlackUserLookupResult {
|
|
3
3
|
userName?: string;
|
|
4
4
|
fullName?: string;
|
|
5
5
|
email?: string;
|
|
6
6
|
}
|
|
7
7
|
/** Fetch Slack user profile info with in-memory TTL cache to avoid repeated API calls. */
|
|
8
|
-
export declare function lookupSlackUser(userId?: string): Promise<SlackUserLookupResult | null>;
|
|
9
|
-
/** Resolve the canonical Slack
|
|
10
|
-
export declare function
|
|
8
|
+
export declare function lookupSlackUser(teamId: string, userId?: string): Promise<SlackUserLookupResult | null>;
|
|
9
|
+
/** Resolve the canonical Slack requester from Slack profile data. */
|
|
10
|
+
export declare function lookupSlackRequester(teamId: string, userId: string): Promise<Requester>;
|
|
11
11
|
export {};
|
|
@@ -5,5 +5,7 @@ export declare function getConnectedStateContext(): Promise<{
|
|
|
5
5
|
redisStateAdapter?: RedisStateAdapter;
|
|
6
6
|
stateAdapter: StateAdapter;
|
|
7
7
|
}>;
|
|
8
|
+
/** Return the Redis adapter only when the caller is using the default state adapter. */
|
|
9
|
+
export declare function getDefaultRedisStateAdapterFor(adapter: StateAdapter): Promise<RedisStateAdapter | undefined>;
|
|
8
10
|
export declare function getStateAdapter(): StateAdapter;
|
|
9
11
|
export declare function disconnectStateAdapter(): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type StoredSlackRequester } from "@/chat/requester";
|
|
2
|
+
import type { AgentTurnSurface } from "./turn-session";
|
|
2
3
|
export interface ConversationDetailsRecord {
|
|
3
4
|
conversationId: string;
|
|
4
5
|
/** Generated display title from the LLM. Absent until title has been produced. */
|
|
@@ -10,7 +11,7 @@ export interface ConversationDetailsRecord {
|
|
|
10
11
|
/** Surface on which the conversation was started. */
|
|
11
12
|
originSurface?: AgentTurnSurface;
|
|
12
13
|
/** Requester who initiated the conversation (first turn). */
|
|
13
|
-
originRequester?:
|
|
14
|
+
originRequester?: StoredSlackRequester;
|
|
14
15
|
/** Timestamp of the first turn in the conversation. */
|
|
15
16
|
startedAtMs?: number;
|
|
16
17
|
}
|
|
@@ -21,7 +22,7 @@ export interface ConversationDetailsRecord {
|
|
|
21
22
|
export declare function initConversationContext(conversationId: string, context: {
|
|
22
23
|
channelName?: string;
|
|
23
24
|
originSurface?: AgentTurnSurface;
|
|
24
|
-
originRequester?:
|
|
25
|
+
originRequester?: StoredSlackRequester;
|
|
25
26
|
startedAtMs: number;
|
|
26
27
|
}): Promise<void>;
|
|
27
28
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { PiMessage } from "@/chat/pi/messages";
|
|
3
|
+
import { type StoredSlackRequester } from "@/chat/requester";
|
|
3
4
|
declare const authorizationKindSchema: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
|
|
4
5
|
declare const sessionLogEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
5
6
|
schemaVersion: z.ZodLiteral<1>;
|
|
@@ -11,6 +12,14 @@ declare const sessionLogEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
11
12
|
[x: string]: unknown;
|
|
12
13
|
role: string;
|
|
13
14
|
}>>;
|
|
15
|
+
requester: z.ZodOptional<z.ZodObject<{
|
|
16
|
+
email: z.ZodOptional<z.ZodString>;
|
|
17
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
18
|
+
platform: z.ZodOptional<z.ZodLiteral<"slack">>;
|
|
19
|
+
slackUserId: z.ZodOptional<z.ZodString>;
|
|
20
|
+
slackUserName: z.ZodOptional<z.ZodString>;
|
|
21
|
+
teamId: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strict>>;
|
|
14
23
|
}, z.core.$strip>, z.ZodObject<{
|
|
15
24
|
schemaVersion: z.ZodLiteral<1>;
|
|
16
25
|
type: z.ZodLiteral<"projection_reset">;
|
|
@@ -21,6 +30,26 @@ declare const sessionLogEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
21
30
|
[x: string]: unknown;
|
|
22
31
|
role: string;
|
|
23
32
|
}>>>;
|
|
33
|
+
requester: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
email: z.ZodOptional<z.ZodString>;
|
|
35
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
36
|
+
platform: z.ZodOptional<z.ZodLiteral<"slack">>;
|
|
37
|
+
slackUserId: z.ZodOptional<z.ZodString>;
|
|
38
|
+
slackUserName: z.ZodOptional<z.ZodString>;
|
|
39
|
+
teamId: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
42
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
43
|
+
type: z.ZodLiteral<"requester_recorded">;
|
|
44
|
+
sessionId: z.ZodDefault<z.ZodString>;
|
|
45
|
+
requester: z.ZodObject<{
|
|
46
|
+
email: z.ZodOptional<z.ZodString>;
|
|
47
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
48
|
+
platform: z.ZodOptional<z.ZodLiteral<"slack">>;
|
|
49
|
+
slackUserId: z.ZodOptional<z.ZodString>;
|
|
50
|
+
slackUserName: z.ZodOptional<z.ZodString>;
|
|
51
|
+
teamId: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}, z.core.$strict>;
|
|
24
53
|
}, z.core.$strip>, z.ZodObject<{
|
|
25
54
|
schemaVersion: z.ZodLiteral<1>;
|
|
26
55
|
type: z.ZodLiteral<"mcp_provider_connected">;
|
|
@@ -46,6 +75,7 @@ declare const sessionLogEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
46
75
|
requesterId: z.ZodString;
|
|
47
76
|
authorizationId: z.ZodString;
|
|
48
77
|
}, z.core.$strip>], "type">;
|
|
78
|
+
/** Requester identity stored with turn-start messages for durable continuation. */
|
|
49
79
|
export type SessionLogEntry = z.infer<typeof sessionLogEntrySchema>;
|
|
50
80
|
export type AuthorizationKind = z.infer<typeof authorizationKindSchema>;
|
|
51
81
|
interface Scope {
|
|
@@ -60,6 +90,10 @@ export interface SessionLogStore {
|
|
|
60
90
|
append(args: AppendArgs): Promise<void>;
|
|
61
91
|
read(scope: Scope): Promise<SessionLogEntry[]>;
|
|
62
92
|
}
|
|
93
|
+
export interface SessionProjection {
|
|
94
|
+
messages: PiMessage[];
|
|
95
|
+
requester?: StoredSlackRequester;
|
|
96
|
+
}
|
|
63
97
|
/** Load the committed Pi-message projection for a conversation. */
|
|
64
98
|
export declare function loadMessages(args: Scope & {
|
|
65
99
|
store?: SessionLogStore;
|
|
@@ -71,6 +105,14 @@ export declare function loadProjection(args: Scope & {
|
|
|
71
105
|
store?: SessionLogStore;
|
|
72
106
|
sessionId?: string;
|
|
73
107
|
}): Promise<PiMessage[]>;
|
|
108
|
+
/**
|
|
109
|
+
* Load the Pi-message projection and derived requester identity in one read.
|
|
110
|
+
* Used at continuation boundaries to avoid a second log scan.
|
|
111
|
+
*/
|
|
112
|
+
export declare function loadProjectionWithRequester(args: Scope & {
|
|
113
|
+
store?: SessionLogStore;
|
|
114
|
+
sessionId?: string;
|
|
115
|
+
}): Promise<SessionProjection>;
|
|
74
116
|
/** Load MCP providers that were durably connected in this conversation. */
|
|
75
117
|
export declare function loadConnectedMcpProviders(args: Scope & {
|
|
76
118
|
store?: SessionLogStore;
|
|
@@ -111,6 +153,7 @@ export declare function commitMessages(args: Scope & {
|
|
|
111
153
|
store?: SessionLogStore;
|
|
112
154
|
messages: PiMessage[];
|
|
113
155
|
ttlMs: number;
|
|
156
|
+
requester?: StoredSlackRequester;
|
|
114
157
|
}): Promise<{
|
|
115
158
|
sessionId: string;
|
|
116
159
|
}>;
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import type { Destination } from "@sentry/junior-plugin-api";
|
|
2
2
|
import type { PiMessage } from "@/chat/pi/messages";
|
|
3
|
+
import { type StoredSlackRequester } from "@/chat/requester";
|
|
3
4
|
import type { AgentTurnUsage } from "@/chat/usage";
|
|
4
5
|
export type AgentTurnSessionStatus = "running" | "awaiting_resume" | "completed" | "failed" | "abandoned";
|
|
5
6
|
export type AgentTurnSurface = "slack" | "api" | "scheduler" | "internal";
|
|
6
7
|
export type AgentTurnResumeReason = "timeout" | "auth" | "yield";
|
|
7
|
-
export interface AgentTurnRequester {
|
|
8
|
-
email?: string;
|
|
9
|
-
fullName?: string;
|
|
10
|
-
slackUserId?: string;
|
|
11
|
-
slackUserName?: string;
|
|
12
|
-
}
|
|
13
8
|
export interface AgentTurnSessionRecord {
|
|
14
9
|
channelName?: string;
|
|
15
10
|
version: number;
|
|
@@ -21,7 +16,7 @@ export interface AgentTurnSessionRecord {
|
|
|
21
16
|
lastProgressAtMs: number;
|
|
22
17
|
loadedSkillNames?: string[];
|
|
23
18
|
piMessages: PiMessage[];
|
|
24
|
-
requester?:
|
|
19
|
+
requester?: StoredSlackRequester;
|
|
25
20
|
resumeReason?: AgentTurnResumeReason;
|
|
26
21
|
resumedFromSliceId?: number;
|
|
27
22
|
sessionId: string;
|
|
@@ -30,9 +25,10 @@ export interface AgentTurnSessionRecord {
|
|
|
30
25
|
state: AgentTurnSessionStatus;
|
|
31
26
|
surface?: AgentTurnSurface;
|
|
32
27
|
traceId?: string;
|
|
28
|
+
turnStartMessageIndex?: number;
|
|
33
29
|
updatedAtMs: number;
|
|
34
30
|
}
|
|
35
|
-
export type AgentTurnSessionSummary = Omit<AgentTurnSessionRecord, "errorMessage" | "piMessages">;
|
|
31
|
+
export type AgentTurnSessionSummary = Omit<AgentTurnSessionRecord, "errorMessage" | "piMessages" | "turnStartMessageIndex">;
|
|
36
32
|
/** Read a materialized turn session record for resume and history loading. */
|
|
37
33
|
export declare function getAgentTurnSessionRecord(conversationId: string, sessionId: string): Promise<AgentTurnSessionRecord | undefined>;
|
|
38
34
|
/** Commit stable Pi session state and advance the turn session record. */
|
|
@@ -49,11 +45,12 @@ export declare function upsertAgentTurnSessionRecord(args: {
|
|
|
49
45
|
state: AgentTurnSessionStatus;
|
|
50
46
|
surface?: AgentTurnSurface;
|
|
51
47
|
piMessages: PiMessage[];
|
|
52
|
-
requester?:
|
|
48
|
+
requester?: StoredSlackRequester;
|
|
53
49
|
resumeReason?: AgentTurnResumeReason;
|
|
54
50
|
errorMessage?: string;
|
|
55
51
|
resumedFromSliceId?: number;
|
|
56
52
|
traceId?: string;
|
|
53
|
+
turnStartMessageIndex?: number;
|
|
57
54
|
ttlMs?: number;
|
|
58
55
|
}): Promise<AgentTurnSessionRecord>;
|
|
59
56
|
/** Record turn-session metadata without storing conversation messages. */
|
|
@@ -65,7 +62,7 @@ export declare function recordAgentTurnSessionSummary(args: {
|
|
|
65
62
|
destination?: Destination;
|
|
66
63
|
lastProgressAtMs?: number;
|
|
67
64
|
loadedSkillNames?: string[];
|
|
68
|
-
requester?:
|
|
65
|
+
requester?: StoredSlackRequester;
|
|
69
66
|
resumeReason?: AgentTurnResumeReason;
|
|
70
67
|
sessionId: string;
|
|
71
68
|
sliceId: number;
|
|
@@ -3,7 +3,7 @@ export interface ConversationQueueMessage {
|
|
|
3
3
|
conversationId: string;
|
|
4
4
|
destination: Destination;
|
|
5
5
|
}
|
|
6
|
-
export type ConversationQueueMessageRejectReason = "destination_mismatch" | "expired" | "malformed" | "signature_mismatch"
|
|
6
|
+
export type ConversationQueueMessageRejectReason = "destination_mismatch" | "expired" | "malformed" | "signature_mismatch";
|
|
7
7
|
export declare class ConversationQueueMessageRejectedError extends Error {
|
|
8
8
|
conversationId?: string;
|
|
9
9
|
reason: ConversationQueueMessageRejectReason;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { SlackAdapter } from "@chat-adapter/slack";
|
|
2
2
|
import { Message, ThreadImpl, type SerializedMessage, type SerializedThread, type StateAdapter } from "chat";
|
|
3
3
|
import type { SlackTurnRuntime } from "@/chat/runtime/slack-runtime";
|
|
4
|
-
import type {
|
|
4
|
+
import type { InboundMessage } from "@/chat/task-execution/store";
|
|
5
5
|
import type { ConversationWorkerContext, ConversationWorkerResult } from "@/chat/task-execution/worker";
|
|
6
6
|
import { type SlackInstallationContext } from "@/chat/slack/adapter-context";
|
|
7
|
-
import { type
|
|
7
|
+
import { type SlackRequesterProfile } from "@/chat/requester";
|
|
8
8
|
export type SlackConversationRoute = "mention" | "subscribed";
|
|
9
9
|
export interface SlackConversationMessageMetadata {
|
|
10
10
|
[key: string]: unknown;
|
|
@@ -16,8 +16,8 @@ export interface SlackConversationMessageMetadata {
|
|
|
16
16
|
}
|
|
17
17
|
export interface CreateSlackConversationWorkerOptions {
|
|
18
18
|
getSlackAdapter: () => SlackAdapter;
|
|
19
|
-
lookupSlackUser?: (userId: string) => Promise<
|
|
20
|
-
resumeAwaitingContinuation
|
|
19
|
+
lookupSlackUser?: (teamId: string, userId: string) => Promise<SlackRequesterProfile | null | undefined>;
|
|
20
|
+
resumeAwaitingContinuation: (conversationId: string) => Promise<boolean>;
|
|
21
21
|
runtime: Pick<SlackTurnRuntime<unknown>, "handleNewMention" | "handleSubscribedMessage">;
|
|
22
22
|
state?: StateAdapter;
|
|
23
23
|
}
|
|
@@ -31,4 +31,4 @@ export declare function buildSlackInboundMessage(args: {
|
|
|
31
31
|
receivedAtMs: number;
|
|
32
32
|
route: SlackConversationRoute;
|
|
33
33
|
thread: ThreadImpl;
|
|
34
|
-
}):
|
|
34
|
+
}): InboundMessage;
|