@sentry/junior 0.94.0 → 0.96.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/dist/{agent-hooks-ZG7IDOIN.js → agent-hooks-5URSMY3O.js} +10 -11
- package/dist/api/people/list.js +8 -8
- package/dist/api/people/profile.js +8 -8
- package/dist/api/people/shared.d.ts +2 -2
- package/dist/api-reference.d.ts +2 -2
- package/dist/app.js +434 -199
- package/dist/{catalog-runtime-NZHMSMYC.js → catalog-runtime-MSMAYYIK.js} +4 -4
- package/dist/chat/advisor-request.d.ts +4 -0
- package/dist/chat/agent/request.d.ts +2 -0
- package/dist/chat/agent/resume.d.ts +2 -0
- package/dist/chat/conversations/history.d.ts +128 -0
- package/dist/chat/conversations/legacy-import.d.ts +38 -0
- package/dist/chat/conversations/messages.d.ts +39 -0
- package/dist/chat/conversations/projection.d.ts +94 -0
- package/dist/chat/conversations/retention.d.ts +36 -0
- package/dist/chat/conversations/sql/conversation-row.d.ts +14 -0
- package/dist/chat/conversations/sql/history.d.ts +4 -0
- package/dist/chat/conversations/sql/legacy-history-import.d.ts +55 -0
- package/dist/chat/conversations/sql/messages.d.ts +4 -0
- package/dist/chat/conversations/sql/migrations.d.ts +14 -3
- package/dist/chat/conversations/sql/purge.d.ts +53 -0
- package/dist/chat/conversations/sql/store.d.ts +7 -2
- package/dist/chat/conversations/store.d.ts +19 -0
- package/dist/chat/conversations/visible-compactions.d.ts +11 -0
- package/dist/chat/conversations/visible-messages.d.ts +47 -0
- package/dist/chat/db.d.ts +12 -1
- package/dist/chat/identities/sql.d.ts +1 -1
- package/dist/chat/logging.d.ts +4 -3
- package/dist/chat/plugins/auth/oauth-request.d.ts +2 -0
- package/dist/chat/resource-events/notification.d.ts +2 -0
- package/dist/chat/resource-events/store.d.ts +2 -1
- package/dist/chat/runtime/agent-run-outcome.d.ts +3 -0
- package/dist/chat/runtime/reply-executor.d.ts +8 -0
- package/dist/chat/runtime/thread-state.d.ts +2 -0
- package/dist/chat/sandbox/resources.d.ts +4 -0
- package/dist/chat/sentry.d.ts +1 -1
- package/dist/chat/services/mcp-auth-orchestration.d.ts +8 -0
- package/dist/chat/services/plugin-auth-orchestration.d.ts +12 -0
- package/dist/chat/services/turn-session-record.d.ts +14 -2
- package/dist/chat/sleep.d.ts +2 -0
- package/dist/chat/state/conversation.d.ts +7 -4
- package/dist/chat/state/session-log.d.ts +23 -1
- package/dist/chat/state/turn-session.d.ts +9 -1
- package/dist/chat/tool-support/private-trace-result.d.ts +4 -0
- package/dist/chat/tool-support/zod-tool.d.ts +1 -0
- package/dist/chat/tools/advisor/tool.d.ts +9 -4
- package/dist/chat/tools/definition.d.ts +2 -0
- package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -2
- package/dist/chat/tools/system-time.d.ts +8 -0
- package/dist/chat/usage.d.ts +27 -13
- package/dist/chat/xml.d.ts +2 -0
- package/dist/{chunk-TNUUATT7.js → chunk-2NAZZPPS.js} +2 -2
- package/dist/{chunk-NYWPISSO.js → chunk-2XXEKR44.js} +1 -1
- package/dist/chunk-5C6XTTFI.js +1037 -0
- package/dist/{chunk-3DA7X2U3.js → chunk-6GWA276C.js} +15 -0
- package/dist/{chunk-LFLTJQVR.js → chunk-7FBGKXPE.js} +4 -0
- package/dist/{chunk-LNCREA5Z.js → chunk-AAZXTVJT.js} +4 -128
- package/dist/{chunk-GHGPTPBL.js → chunk-B7PUBQQM.js} +1 -1
- package/dist/{chunk-6H4PP63X.js → chunk-BYZWPRJA.js} +24 -14
- package/dist/chunk-CM5EZD5F.js +17 -0
- package/dist/{chunk-G3E7SCME.js → chunk-CZEX6KIQ.js} +23 -0
- package/dist/{chunk-YJ4OPVNA.js → chunk-DZENG5ML.js} +1 -1
- package/dist/{chunk-QGEWC27H.js → chunk-GQ3GK22G.js} +5 -7
- package/dist/{chunk-YYBX2BD5.js → chunk-GY34VGP5.js} +1 -1
- package/dist/{chunk-S6QKIGRM.js → chunk-I35CTGPO.js} +71 -29
- package/dist/{chunk-KRMANDHI.js → chunk-IYM2SIVG.js} +1489 -355
- package/dist/{chunk-BTH37NCU.js → chunk-L7CDEIVJ.js} +12 -4
- package/dist/chunk-MNTINMWR.js +865 -0
- package/dist/{chunk-MAVOJ54A.js → chunk-P3YFQLEN.js} +25 -388
- package/dist/{chunk-YTNPU7I2.js → chunk-PMNN6ST4.js} +2 -2
- package/dist/{chunk-PFXC67GJ.js → chunk-RAIB6WSG.js} +6 -80
- package/dist/{chunk-NFXSLTYG.js → chunk-RITD7E5L.js} +864 -62
- package/dist/{chunk-UUB3D2XI.js → chunk-S5KZ5LPG.js} +8 -10
- package/dist/{chunk-HDNWZMUN.js → chunk-UKHVMPX5.js} +112 -103
- package/dist/chunk-WM6KHPBQ.js +48 -0
- package/dist/{chunk-MC4ZZE4Q.js → chunk-YDT7SNCN.js} +1 -1
- package/dist/{chunk-NAPITCZ6.js → chunk-YDVEH3SB.js} +251 -6
- package/dist/cli/chat.js +25 -24
- package/dist/cli/check.js +5 -5
- package/dist/cli/main.js +1 -1
- package/dist/cli/plugins.js +12 -13
- package/dist/cli/snapshot-warmup.js +8 -9
- package/dist/cli/upgrade.js +79 -18
- package/dist/db/schema/agent-steps.d.ts +134 -0
- package/dist/db/schema/conversation-messages.d.ts +153 -0
- package/dist/{chat/conversations/sql → db}/schema/conversations.d.ts +34 -0
- package/dist/{chat/conversations/sql → db}/schema.d.ts +319 -8
- package/dist/db-2D6RMG67.js +24 -0
- package/dist/deployment.d.ts +2 -0
- package/dist/handlers/retention.d.ts +6 -0
- package/dist/instrumentation.js +17 -4
- package/dist/legacy-import-VZ2MEGP7.js +17 -0
- package/dist/nitro.js +14 -4
- package/dist/reporting/conversations/activity.d.ts +40 -0
- package/dist/reporting/conversations/context.d.ts +8 -0
- package/dist/reporting/conversations/details.d.ts +6 -0
- package/dist/reporting/conversations/index.d.ts +4 -0
- package/dist/reporting/conversations/shared.d.ts +9 -0
- package/dist/reporting/conversations/statistics.d.ts +4 -0
- package/dist/reporting/conversations/summaries.d.ts +20 -0
- package/dist/reporting/conversations/transcript.d.ts +28 -0
- package/dist/reporting/conversations/types.d.ts +191 -0
- package/dist/reporting/conversations.d.ts +1 -178
- package/dist/reporting.d.ts +5 -4
- package/dist/reporting.js +703 -837
- package/dist/{runner-XAZPJNAQ.js → runner-JZBRQP4F.js} +36 -42
- package/dist/{sentry-EGFOV3DH.js → sentry-JMWTS32N.js} +11 -1
- package/dist/{validation-KYAWETI4.js → validation-6XOOQGME.js} +5 -5
- package/migrations/README.md +32 -0
- package/migrations/meta/0000_snapshot.json +978 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +10 -7
- package/dist/chat/sql/schema.d.ts +0 -1049
- package/dist/chat/state/conversation-details.d.ts +0 -47
- package/dist/chunk-7STN2ZSK.js +0 -250
- package/dist/chunk-LE5ANBUZ.js +0 -1040
- package/dist/chunk-QL66APYJ.js +0 -1377
- package/dist/db-YDN6AFJH.js +0 -18
- /package/dist/{chat/sql → db}/db.d.ts +0 -0
- /package/dist/{chat/sql → db}/executor.d.ts +0 -0
- /package/dist/{chat/sql → db}/neon.d.ts +0 -0
- /package/dist/{chat/sql → db}/postgres.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/destinations.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/identities.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/migrations.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/timestamps.d.ts +0 -0
- /package/dist/{chat/conversations/sql → db}/schema/users.d.ts +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pluginCatalogRuntime
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-L7CDEIVJ.js";
|
|
4
|
+
import "./chunk-I35CTGPO.js";
|
|
5
5
|
import "./chunk-OB42YVAE.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-6GWA276C.js";
|
|
7
7
|
import "./chunk-6APU57E6.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-7FBGKXPE.js";
|
|
9
9
|
import "./chunk-MLKGABMK.js";
|
|
10
10
|
export {
|
|
11
11
|
pluginCatalogRuntime
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Render the executor's advisor request in stable model-facing boundaries. */
|
|
2
|
+
export declare function renderAdvisorRequest(question: string, context: string): string;
|
|
3
|
+
/** Recover readable task and context text from an advisor request message. */
|
|
4
|
+
export declare function unwrapAdvisorRequest(text: string): string | undefined;
|
|
@@ -86,6 +86,8 @@ export interface AgentRunRouting {
|
|
|
86
86
|
export interface AgentRunPolicy {
|
|
87
87
|
/** Absolute wall-clock deadline for this host request, in milliseconds. */
|
|
88
88
|
turnDeadlineAtMs?: number;
|
|
89
|
+
/** Cancels provider work when the owning host request is abandoned. */
|
|
90
|
+
signal?: AbortSignal;
|
|
89
91
|
authorizationFlowMode?: AuthorizationFlowMode;
|
|
90
92
|
configuration?: Record<string, unknown>;
|
|
91
93
|
channelConfiguration?: ChannelConfigurationService;
|
|
@@ -25,6 +25,8 @@ interface ResumeStateArgs {
|
|
|
25
25
|
durability: AgentRunDurability;
|
|
26
26
|
getLoadedSkillNames: () => string[];
|
|
27
27
|
logContext: SessionRecordLogContext;
|
|
28
|
+
modelId: string;
|
|
29
|
+
getReasoningLevel: () => string | undefined;
|
|
28
30
|
recordActiveMcpProviders: () => Promise<void>;
|
|
29
31
|
actor?: Actor;
|
|
30
32
|
runSource: Source;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable agent execution history port.
|
|
3
|
+
*
|
|
4
|
+
* Steps are appended one row at a time under the conversation lease; context
|
|
5
|
+
* rebuilds (compaction/rollback) open a new epoch instead of rewriting history.
|
|
6
|
+
* The step envelope is strictly validated — an unknown type or malformed shape
|
|
7
|
+
* is corrupt state and fails loudly — while `pi_message` content stays
|
|
8
|
+
* permissive because the Pi SDK owns the message shape.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { type PiMessage } from "@/chat/pi/messages";
|
|
12
|
+
import { type PiMessageProvenance } from "@/chat/state/session-log";
|
|
13
|
+
/** Reason a new context epoch was opened. */
|
|
14
|
+
export type EpochReason = "compaction" | "rollback";
|
|
15
|
+
/** Strict step envelope reused by the SQL row codec; unknown types fail loudly. */
|
|
16
|
+
export declare const agentStepEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
17
|
+
type: z.ZodLiteral<"pi_message">;
|
|
18
|
+
schemaVersion: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
message: z.ZodPipe<z.ZodObject<{
|
|
20
|
+
role: z.ZodString;
|
|
21
|
+
}, z.core.$loose>, z.ZodTransform<import("@earendil-works/pi-ai").AssistantMessage | import("@earendil-works/pi-ai").UserMessage | import("@earendil-works/pi-ai").ToolResultMessage<any> | import("@earendil-works/pi-agent-core").CustomMessage<unknown> | import("@earendil-works/pi-agent-core").BashExecutionMessage | import("@earendil-works/pi-agent-core").BranchSummaryMessage | import("@earendil-works/pi-agent-core").CompactionSummaryMessage, {
|
|
22
|
+
[x: string]: unknown;
|
|
23
|
+
role: string;
|
|
24
|
+
}>>;
|
|
25
|
+
provenance: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
authority: z.ZodUnion<readonly [z.ZodLiteral<"instruction">, z.ZodLiteral<"context">]>;
|
|
27
|
+
actor: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
28
|
+
platform: z.ZodLiteral<"slack">;
|
|
29
|
+
teamId: z.ZodString;
|
|
30
|
+
email: z.ZodOptional<z.ZodString>;
|
|
31
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
32
|
+
userId: z.ZodString;
|
|
33
|
+
userName: z.ZodOptional<z.ZodString>;
|
|
34
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
35
|
+
platform: z.ZodLiteral<"local">;
|
|
36
|
+
email: z.ZodOptional<z.ZodString>;
|
|
37
|
+
fullName: z.ZodOptional<z.ZodString>;
|
|
38
|
+
userId: z.ZodString;
|
|
39
|
+
userName: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
41
|
+
platform: z.ZodLiteral<"system">;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
}, z.core.$strict>], "platform">>;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
46
|
+
type: z.ZodLiteral<"context_epoch_started">;
|
|
47
|
+
reason: z.ZodUnion<readonly [z.ZodLiteral<"compaction">, z.ZodLiteral<"rollback">]>;
|
|
48
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
49
|
+
type: z.ZodLiteral<"mcp_provider_connected">;
|
|
50
|
+
provider: z.ZodString;
|
|
51
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
52
|
+
type: z.ZodLiteral<"authorization_requested">;
|
|
53
|
+
kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
|
|
54
|
+
provider: z.ZodString;
|
|
55
|
+
actorId: z.ZodString;
|
|
56
|
+
authorizationId: z.ZodString;
|
|
57
|
+
delivery: z.ZodUnion<readonly [z.ZodLiteral<"private_link_sent">, z.ZodLiteral<"private_link_reused">]>;
|
|
58
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
59
|
+
type: z.ZodLiteral<"authorization_completed">;
|
|
60
|
+
kind: z.ZodUnion<readonly [z.ZodLiteral<"plugin">, z.ZodLiteral<"mcp">]>;
|
|
61
|
+
provider: z.ZodString;
|
|
62
|
+
actorId: z.ZodString;
|
|
63
|
+
authorizationId: z.ZodString;
|
|
64
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
65
|
+
type: z.ZodLiteral<"tool_execution_started">;
|
|
66
|
+
toolCallId: z.ZodString;
|
|
67
|
+
toolName: z.ZodString;
|
|
68
|
+
args: z.ZodOptional<z.ZodUnknown>;
|
|
69
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
70
|
+
type: z.ZodLiteral<"visible_context_compacted">;
|
|
71
|
+
compactions: z.ZodArray<z.ZodObject<{
|
|
72
|
+
coveredMessageIds: z.ZodArray<z.ZodString>;
|
|
73
|
+
createdAtMs: z.ZodNumber;
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
summary: z.ZodString;
|
|
76
|
+
}, z.core.$strip>>;
|
|
77
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
78
|
+
type: z.ZodLiteral<"subagent_started">;
|
|
79
|
+
subagentInvocationId: z.ZodString;
|
|
80
|
+
subagentKind: z.ZodString;
|
|
81
|
+
modelId: z.ZodOptional<z.ZodString>;
|
|
82
|
+
parentToolCallId: z.ZodOptional<z.ZodString>;
|
|
83
|
+
reasoningLevel: z.ZodOptional<z.ZodString>;
|
|
84
|
+
childConversationId: z.ZodString;
|
|
85
|
+
historyMode: z.ZodLiteral<"shared">;
|
|
86
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
87
|
+
type: z.ZodLiteral<"subagent_ended">;
|
|
88
|
+
subagentInvocationId: z.ZodString;
|
|
89
|
+
outcome: z.ZodUnion<readonly [z.ZodLiteral<"success">, z.ZodLiteral<"error">, z.ZodLiteral<"aborted">]>;
|
|
90
|
+
errorCode: z.ZodOptional<z.ZodString>;
|
|
91
|
+
}, z.core.$strip>], "type">;
|
|
92
|
+
/** One durable execution step's validated payload (sessionId lifted to epoch). */
|
|
93
|
+
export type AgentStepEntry = z.infer<typeof agentStepEntrySchema>;
|
|
94
|
+
/** A step read back from storage with its assigned order and epoch. */
|
|
95
|
+
export interface StoredAgentStep {
|
|
96
|
+
seq: number;
|
|
97
|
+
contextEpoch: number;
|
|
98
|
+
createdAtMs: number;
|
|
99
|
+
entry: AgentStepEntry;
|
|
100
|
+
}
|
|
101
|
+
/** A step to append; the store assigns `seq` and the current `context_epoch`. */
|
|
102
|
+
export interface NewAgentStep {
|
|
103
|
+
entry: AgentStepEntry;
|
|
104
|
+
createdAtMs: number;
|
|
105
|
+
}
|
|
106
|
+
/** A replacement Pi message written into a freshly opened epoch. */
|
|
107
|
+
export interface PiMessageStep {
|
|
108
|
+
message: PiMessage;
|
|
109
|
+
createdAtMs: number;
|
|
110
|
+
provenance?: PiMessageProvenance;
|
|
111
|
+
}
|
|
112
|
+
/** Persist and read the durable per-conversation agent execution history. */
|
|
113
|
+
export interface AgentStepStore {
|
|
114
|
+
/** Append steps in one transaction, assigning `seq = max+1` under the lease. */
|
|
115
|
+
append(conversationId: string, steps: NewAgentStep[]): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Open the next epoch in one transaction: a `context_epoch_started` marker
|
|
118
|
+
* followed by the replacement messages as ordinary `pi_message` rows.
|
|
119
|
+
*/
|
|
120
|
+
startEpoch(conversationId: string, opts: {
|
|
121
|
+
reason: EpochReason;
|
|
122
|
+
messages: PiMessageStep[];
|
|
123
|
+
}): Promise<void>;
|
|
124
|
+
/** Steps of the highest epoch in `seq` order (all types; caller filters). */
|
|
125
|
+
loadCurrentEpoch(conversationId: string): Promise<StoredAgentStep[]>;
|
|
126
|
+
/** All steps across all epochs in `seq` order, for audit and reporting. */
|
|
127
|
+
loadHistory(conversationId: string): Promise<StoredAgentStep[]>;
|
|
128
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ConversationCompaction, type ConversationMessage as ThreadConversationMessage } from "@/chat/state/conversation";
|
|
2
|
+
import { type SessionLogStore } from "@/chat/state/session-log";
|
|
3
|
+
import { type AdvisorSessionStore } from "@/chat/tools/advisor/session-store";
|
|
4
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
5
|
+
import type { ConversationMessageStore } from "./messages";
|
|
6
|
+
import type { Conversation } from "./store";
|
|
7
|
+
/** Legacy source seams used by the one-time migration. */
|
|
8
|
+
export interface LegacyImportDeps {
|
|
9
|
+
executor: JuniorSqlDatabase;
|
|
10
|
+
messageStore: ConversationMessageStore;
|
|
11
|
+
sessionLogStore?: SessionLogStore;
|
|
12
|
+
advisorSessionStore?: AdvisorSessionStore;
|
|
13
|
+
loadVisibleMessages?: (conversationId: string) => Promise<ThreadConversationMessage[]>;
|
|
14
|
+
legacyCompactions?: ConversationCompaction[];
|
|
15
|
+
/** Conversation metadata used for imported creation and activity clocks. */
|
|
16
|
+
conversationRecord?: Conversation;
|
|
17
|
+
/** Latest activity recovered from the legacy thread-state payload. */
|
|
18
|
+
legacyLastActivityAtMs?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Import one conversation's legacy Redis history into SQL, idempotently.
|
|
22
|
+
*
|
|
23
|
+
* Returns whether an import ran (false when step rows already exist or there is
|
|
24
|
+
* nothing legacy to import).
|
|
25
|
+
*/
|
|
26
|
+
export declare function importConversationFromLegacy(conversationId: string, deps: LegacyImportDeps): Promise<{
|
|
27
|
+
imported: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Lazy first-read import for a straggler the old deployment touched during
|
|
31
|
+
* promotion. Runs under the conversation lease the worker already holds before
|
|
32
|
+
* any turn/resume projection read; idempotent skip-if-rows-exist makes re-entry
|
|
33
|
+
* safe. Missing legacy keys produce empty reads for genuinely new conversations;
|
|
34
|
+
* actual Redis read failures surface through normal worker recovery.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ensureLegacyConversationImport(args: {
|
|
37
|
+
conversationId: string;
|
|
38
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visible conversation message port.
|
|
3
|
+
*
|
|
4
|
+
* Messages are immutable source facts recorded idempotently by source identity;
|
|
5
|
+
* the only mutable bookkeeping is the `replied_at` delivery mark.
|
|
6
|
+
*/
|
|
7
|
+
/** Author role of a visible conversation message. */
|
|
8
|
+
export type ConversationMessageRole = "user" | "assistant" | "system";
|
|
9
|
+
/** A source message to record; identity is `(conversationId, messageId)`. */
|
|
10
|
+
export interface NewConversationMessage {
|
|
11
|
+
messageId: string;
|
|
12
|
+
role: ConversationMessageRole;
|
|
13
|
+
text: string;
|
|
14
|
+
authorIdentityId?: string;
|
|
15
|
+
meta?: Record<string, unknown>;
|
|
16
|
+
createdAtMs: number;
|
|
17
|
+
}
|
|
18
|
+
/** A visible message read back from storage. */
|
|
19
|
+
export interface ConversationMessage {
|
|
20
|
+
conversationId: string;
|
|
21
|
+
messageId: string;
|
|
22
|
+
role: ConversationMessageRole;
|
|
23
|
+
text: string;
|
|
24
|
+
authorIdentityId?: string;
|
|
25
|
+
meta?: Record<string, unknown>;
|
|
26
|
+
repliedAtMs?: number;
|
|
27
|
+
createdAtMs: number;
|
|
28
|
+
}
|
|
29
|
+
/** Persist and read the visible per-conversation message transcript. */
|
|
30
|
+
export interface ConversationMessageStore {
|
|
31
|
+
/** Record source messages idempotently by `(conversation_id, message_id)`. */
|
|
32
|
+
record(conversationId: string, messages: NewConversationMessage[]): Promise<void>;
|
|
33
|
+
/** Set the mutable `replied_at` mark; content columns are never touched. */
|
|
34
|
+
markReplied(conversationId: string, messageId: string, repliedAtMs: number): Promise<void>;
|
|
35
|
+
/** List messages in `created_at` order. */
|
|
36
|
+
list(conversationId: string, opts?: {
|
|
37
|
+
limit?: number;
|
|
38
|
+
}): Promise<ConversationMessage[]>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { PiMessage } from "@/chat/pi/messages";
|
|
2
|
+
import { type AuthorizationKind, type PiMessageProvenance, type SessionProjection } from "@/chat/state/session-log";
|
|
3
|
+
import type { StoredAgentStep } from "@/chat/conversations/history";
|
|
4
|
+
/** Aligned step projection: `provenance[i]` and `seqs[i]` describe `messages[i]`. */
|
|
5
|
+
export interface StepProjection extends SessionProjection {
|
|
6
|
+
/** The `seq` of the step each projected message came from. */
|
|
7
|
+
seqs: number[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Materialize Pi messages with aligned provenance and source seqs from one
|
|
11
|
+
* epoch's steps. Steps above `maxSeq` (when given) are excluded so a terminal
|
|
12
|
+
* turn record reproduces exactly the boundary it committed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function projectSteps(steps: StoredAgentStep[], opts?: {
|
|
15
|
+
maxSeq?: number;
|
|
16
|
+
}): StepProjection;
|
|
17
|
+
interface ScopedConversation {
|
|
18
|
+
conversationId: string;
|
|
19
|
+
}
|
|
20
|
+
/** Load the current-epoch Pi projection for a conversation. */
|
|
21
|
+
export declare function loadProjection(args: ScopedConversation): Promise<PiMessage[]>;
|
|
22
|
+
/** Load the current-epoch Pi projection with aligned per-message provenance. */
|
|
23
|
+
export declare function loadProjectionWithProvenance(args: ScopedConversation): Promise<SessionProjection>;
|
|
24
|
+
/**
|
|
25
|
+
* Load a turn's committed Pi projection from the durable step store.
|
|
26
|
+
*
|
|
27
|
+
* The record stays pinned to the epoch containing its committed boundary, so a
|
|
28
|
+
* later rollback or compaction cannot silently rewrite what a stale record
|
|
29
|
+
* resumes from. Unfinished records (`includeTail`) also see that epoch's tail
|
|
30
|
+
* so parked input appended after the last safe boundary is model-visible; for
|
|
31
|
+
* a live run the committed epoch is the current epoch. Terminal records
|
|
32
|
+
* reproduce exactly the boundary they committed by cutting at `committedSeq`.
|
|
33
|
+
* Returns undefined when the committed boundary no longer exists (purged
|
|
34
|
+
* history) so callers fail closed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function loadTurnProjection(args: {
|
|
37
|
+
conversationId: string;
|
|
38
|
+
committedSeq: number;
|
|
39
|
+
includeTail: boolean;
|
|
40
|
+
}): Promise<StepProjection | undefined>;
|
|
41
|
+
/** Load MCP providers durably connected in this conversation's current epoch. */
|
|
42
|
+
export declare function loadConnectedMcpProviders(args: ScopedConversation): Promise<string[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Commit the turn's Pi history: append when it advanced the committed
|
|
45
|
+
* projection normally, or open a `rollback` epoch when it diverged (a
|
|
46
|
+
* provider-retry trim regenerated trailing assistant output). Returns the
|
|
47
|
+
* resolved provenance, the per-message step seqs, and the `seq` boundary that
|
|
48
|
+
* reproduces exactly the committed messages.
|
|
49
|
+
*/
|
|
50
|
+
export declare function commitMessages(args: {
|
|
51
|
+
conversationId: string;
|
|
52
|
+
messages: PiMessage[];
|
|
53
|
+
/** Explicit per-message provenance aligned one-to-one with `messages`. */
|
|
54
|
+
provenance?: PiMessageProvenance[];
|
|
55
|
+
/** Explicit provenance for the trailing newly committed messages. */
|
|
56
|
+
trailingMessageProvenance?: PiMessageProvenance[];
|
|
57
|
+
/** Default applied to the last new user message when no explicit array. */
|
|
58
|
+
newMessageProvenance?: PiMessageProvenance;
|
|
59
|
+
}): Promise<{
|
|
60
|
+
committedSeq: number;
|
|
61
|
+
messageSeqs: number[];
|
|
62
|
+
provenance: PiMessageProvenance[];
|
|
63
|
+
}>;
|
|
64
|
+
/** Record a successful MCP provider connection without duplicating the fact. */
|
|
65
|
+
export declare function recordMcpProviderConnected(args: {
|
|
66
|
+
conversationId: string;
|
|
67
|
+
provider: string;
|
|
68
|
+
}): Promise<void>;
|
|
69
|
+
/** Record that an OAuth/MCP authorization link was delivered or reused. */
|
|
70
|
+
export declare function recordAuthorizationRequested(args: {
|
|
71
|
+
conversationId: string;
|
|
72
|
+
kind: AuthorizationKind;
|
|
73
|
+
provider: string;
|
|
74
|
+
actorId: string;
|
|
75
|
+
authorizationId: string;
|
|
76
|
+
delivery: "private_link_sent" | "private_link_reused";
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
/** Record completed authorization as a chronological host observation for Pi. */
|
|
79
|
+
export declare function recordAuthorizationCompleted(args: {
|
|
80
|
+
conversationId: string;
|
|
81
|
+
kind: AuthorizationKind;
|
|
82
|
+
provider: string;
|
|
83
|
+
actorId: string;
|
|
84
|
+
authorizationId: string;
|
|
85
|
+
}): Promise<void>;
|
|
86
|
+
/** Record a host-observed parent tool start without adding it to Pi replay. */
|
|
87
|
+
export declare function recordToolExecutionStarted(args: {
|
|
88
|
+
conversationId: string;
|
|
89
|
+
args?: unknown;
|
|
90
|
+
createdAtMs?: number;
|
|
91
|
+
toolCallId: string;
|
|
92
|
+
toolName: string;
|
|
93
|
+
}): Promise<void>;
|
|
94
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
2
|
+
/** Content retention windows keyed by resolved conversation visibility. */
|
|
3
|
+
export declare const CONTENT_RETENTION_MS: {
|
|
4
|
+
readonly public: number;
|
|
5
|
+
readonly private: number;
|
|
6
|
+
};
|
|
7
|
+
/** Aggregate outcome of one bounded retention purge batch. */
|
|
8
|
+
export interface RetentionPurgeResult {
|
|
9
|
+
/** Root conversations examined and attempted this run. */
|
|
10
|
+
scanned: number;
|
|
11
|
+
/** Root trees successfully purged. */
|
|
12
|
+
purged: number;
|
|
13
|
+
/** Root trees whose purge failed and were skipped. */
|
|
14
|
+
failed: number;
|
|
15
|
+
/** Total conversation rows (roots plus descendants) stamped by the purge. */
|
|
16
|
+
conversations: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Run one bounded retention purge batch: delete expired root conversation trees
|
|
20
|
+
* oldest-activity-first. Each tree is purged transactionally in isolation, so a
|
|
21
|
+
* single failing tree is logged and skipped without aborting the batch, and the
|
|
22
|
+
* remainder of an over-limit backlog is left for the next run.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runRetentionPurge(executor: JuniorSqlDatabase, args: {
|
|
25
|
+
nowMs: number;
|
|
26
|
+
limit?: number;
|
|
27
|
+
}): Promise<RetentionPurgeResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Erase one conversation's content and descendants immediately, regardless of
|
|
30
|
+
* age, applying the same visibility-based metadata scrubbing as the purge job.
|
|
31
|
+
* The scrub decision uses the root's resolved visibility so erasing a child
|
|
32
|
+
* still fails closed to private for a private root.
|
|
33
|
+
*/
|
|
34
|
+
export declare function purgeConversation(executor: JuniorSqlDatabase, conversationId: string, opts?: {
|
|
35
|
+
nowMs?: number;
|
|
36
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
2
|
+
/**
|
|
3
|
+
* Establish the conversation metadata row on first contact for content writes
|
|
4
|
+
* (agent steps, visible transcript) that can land before activity recording has
|
|
5
|
+
* created the row, and whose tables FK to it.
|
|
6
|
+
*
|
|
7
|
+
* First contact creates the row; every later content write advances the
|
|
8
|
+
* activity clock so retention mirrors append-refresh semantics (each content
|
|
9
|
+
* append refreshes the retention window). The timestamp is content-intrinsic
|
|
10
|
+
* (the first item's `createdAtMs`), and `greatest(...)` guarantees a backfilled
|
|
11
|
+
* or imported historical write — which carries an old timestamp — can never
|
|
12
|
+
* regress `last_activity_at`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function ensureConversationRow(executor: JuniorSqlDatabase, conversationId: string, atMs: number): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
2
|
+
import type { PiMessage } from "@/chat/pi/messages";
|
|
3
|
+
import type { NewConversationMessage } from "../messages";
|
|
4
|
+
import { type SessionLogEntry } from "@/chat/state/session-log";
|
|
5
|
+
import { type AgentStepEntry } from "../history";
|
|
6
|
+
/** A converted legacy step with its explicit order and epoch pinned. */
|
|
7
|
+
export interface ImportedStep {
|
|
8
|
+
seq: number;
|
|
9
|
+
contextEpoch: number;
|
|
10
|
+
entry: AgentStepEntry;
|
|
11
|
+
createdAtMs: number;
|
|
12
|
+
}
|
|
13
|
+
/** Result of converting one conversation's legacy log. */
|
|
14
|
+
export interface ConvertedLegacyLog {
|
|
15
|
+
steps: ImportedStep[];
|
|
16
|
+
/** Deterministic advisor child conversation id, when a subagent was recorded. */
|
|
17
|
+
advisorChildConversationId?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert a legacy session log into ordered step rows with explicit epochs.
|
|
21
|
+
*
|
|
22
|
+
* `fallbackCreatedAtMs` supplies `created_at` for rows without an intrinsic
|
|
23
|
+
* timestamp (epoch markers, provider facts, timestamp-less messages); a real
|
|
24
|
+
* conversation-derived value is always passed so no import-time `now` is used.
|
|
25
|
+
*/
|
|
26
|
+
export declare function convertLegacySessionLog(args: {
|
|
27
|
+
conversationId: string;
|
|
28
|
+
entries: SessionLogEntry[];
|
|
29
|
+
fallbackCreatedAtMs: number;
|
|
30
|
+
}): ConvertedLegacyLog;
|
|
31
|
+
/** Convert an advisor session blob into epoch-0 child pi_message rows. */
|
|
32
|
+
export declare function convertAdvisorMessages(messages: PiMessage[], fallbackCreatedAtMs: number): ImportedStep[];
|
|
33
|
+
/** One conversation's converted history plus optional advisor child history. */
|
|
34
|
+
export interface LegacyImportWrite {
|
|
35
|
+
conversationId: string;
|
|
36
|
+
fallbackCreatedAtMs: number;
|
|
37
|
+
lastActivityAtMs: number;
|
|
38
|
+
messages?: Array<NewConversationMessage & {
|
|
39
|
+
repliedAtMs?: number;
|
|
40
|
+
}>;
|
|
41
|
+
steps: ImportedStep[];
|
|
42
|
+
child?: {
|
|
43
|
+
conversationId: string;
|
|
44
|
+
steps: ImportedStep[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Write a converted legacy history for one conversation, all-or-nothing.
|
|
49
|
+
*
|
|
50
|
+
* Serialized by a per-conversation advisory lock and skipped when step rows
|
|
51
|
+
* already exist, so a re-run (bulk or lazy) never double-imports. Parent and
|
|
52
|
+
* advisor-child rows land in one transaction; explicit `seq`/`context_epoch`
|
|
53
|
+
* are what make this need a dedicated writer rather than the narrow port.
|
|
54
|
+
*/
|
|
55
|
+
export declare function writeLegacyImport(executor: JuniorSqlDatabase, args: LegacyImportWrite): Promise<boolean>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
2
|
+
import type { ConversationMessageStore } from "../messages";
|
|
3
|
+
/** Create a SQL-backed conversation message store. */
|
|
4
|
+
export declare function createSqlConversationMessageStore(executor: JuniorSqlDatabase): ConversationMessageStore;
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { JuniorSqlMigrationExecutor } from "@/db/db";
|
|
2
|
+
import { juniorSqlSchema as schema } from "@/db/schema";
|
|
3
3
|
export interface Migration {
|
|
4
4
|
checksum: string;
|
|
5
5
|
id: string;
|
|
6
6
|
statements: readonly string[];
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Register a drizzle-kit-generated `.sql` file as a checksum-pinned migration.
|
|
10
|
+
*
|
|
11
|
+
* Migrations 0006 onward are authored by editing the Drizzle schema and running
|
|
12
|
+
* `pnpm --filter @sentry/junior db:generate`; each generated file becomes one
|
|
13
|
+
* line here. Statements are split on drizzle-kit's `--> statement-breakpoint`
|
|
14
|
+
* markers and applied by the custom `junior upgrade` runner (never
|
|
15
|
+
* `drizzle-kit migrate`). Migrations 0001–0005 predate kit and stay inline so
|
|
16
|
+
* their recorded checksums remain byte-stable.
|
|
17
|
+
*/
|
|
18
|
+
export declare function defineMigrationFromFile(id: string, fileName: string): Migration;
|
|
19
|
+
export declare const migrations: readonly [Migration, Migration, Migration, Migration, Migration];
|
|
9
20
|
export { schema };
|
|
10
21
|
/** Apply pending SQL schema migrations for queryable conversation records. */
|
|
11
22
|
export declare function migrateSchema(executor: JuniorSqlMigrationExecutor, migrationList?: readonly Migration[]): Promise<void>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { JuniorSqlDatabase } from "@/db/db";
|
|
2
|
+
import type { JuniorDestinationVisibility } from "@/db/schema/destinations";
|
|
3
|
+
/** An expired root conversation selected for purge, with its resolved visibility. */
|
|
4
|
+
export interface ExpiredRoot {
|
|
5
|
+
conversationId: string;
|
|
6
|
+
visibility: JuniorDestinationVisibility | null;
|
|
7
|
+
}
|
|
8
|
+
/** Outcome of purging one conversation tree. */
|
|
9
|
+
export interface PurgeTreeResult {
|
|
10
|
+
/** Whether this transaction still found the root eligible for purge. */
|
|
11
|
+
purged: boolean;
|
|
12
|
+
/** Root plus descendant conversation rows stamped by the purge. */
|
|
13
|
+
conversations: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Select expired root conversations for purge, oldest activity first.
|
|
17
|
+
*
|
|
18
|
+
* Roots have no parent, so visibility is read directly from the root's own
|
|
19
|
+
* destination; the private window applies to every non-`public` case. A row is
|
|
20
|
+
* skipped once it is fully purged — no content rows survive and no non-public
|
|
21
|
+
* scrub fields remain — so a bounded batch spends its budget on real work.
|
|
22
|
+
*/
|
|
23
|
+
export declare function selectExpiredRoots(executor: JuniorSqlDatabase, args: {
|
|
24
|
+
nowMs: number;
|
|
25
|
+
publicWindowMs: number;
|
|
26
|
+
privateWindowMs: number;
|
|
27
|
+
limit: number;
|
|
28
|
+
}): Promise<ExpiredRoot[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Purge one conversation tree in a single transaction: delete all message and
|
|
31
|
+
* step rows for the given conversation and every descendant, stamp
|
|
32
|
+
* `transcript_purged_at`, and — for non-public content — null the raw-payload
|
|
33
|
+
* metadata (`title`, `channel_name`, legacy actor JSON) so purged private
|
|
34
|
+
* conversations keep only safe metadata. The metadata rows themselves survive.
|
|
35
|
+
*/
|
|
36
|
+
export declare function purgeConversationTree(executor: JuniorSqlDatabase, args: {
|
|
37
|
+
rootConversationId: string;
|
|
38
|
+
scrubMetadata?: boolean;
|
|
39
|
+
nowMs: number;
|
|
40
|
+
retention?: {
|
|
41
|
+
privateWindowMs: number;
|
|
42
|
+
publicWindowMs: number;
|
|
43
|
+
};
|
|
44
|
+
}): Promise<PurgeTreeResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Walk `parent_conversation_id` to the root and return the root's destination
|
|
47
|
+
* visibility. Retention resolves visibility at purge time rather than storing an
|
|
48
|
+
* expiry, so a public↔private flip takes effect on the next pass.
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveRootVisibility(executor: JuniorSqlDatabase, conversationId: string): Promise<{
|
|
51
|
+
rootConversationId: string;
|
|
52
|
+
visibility: JuniorDestinationVisibility | null;
|
|
53
|
+
}>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Destination } from "@sentry/junior-plugin-api";
|
|
2
2
|
import type { ConversationPrivacy } from "@/chat/conversation-privacy";
|
|
3
|
-
import {
|
|
4
|
-
import type { JuniorSqlDatabase, JuniorSqlMigrationExecutor } from "@/
|
|
3
|
+
import type { StoredSlackActor } from "@/chat/actor";
|
|
4
|
+
import type { JuniorSqlDatabase, JuniorSqlMigrationExecutor } from "@/db/db";
|
|
5
5
|
import type { Conversation, ConversationExecution, ConversationSource, ConversationStore } from "../store";
|
|
6
6
|
export declare class SqlStore implements ConversationStore {
|
|
7
7
|
private readonly executor;
|
|
@@ -37,6 +37,11 @@ export declare class SqlStore implements ConversationStore {
|
|
|
37
37
|
updatedAtMs: number;
|
|
38
38
|
visibility?: ConversationPrivacy;
|
|
39
39
|
}): Promise<void>;
|
|
40
|
+
ensureChildConversation(args: {
|
|
41
|
+
conversationId: string;
|
|
42
|
+
parentConversationId: string;
|
|
43
|
+
nowMs?: number;
|
|
44
|
+
}): Promise<void>;
|
|
40
45
|
/** Copy one conversation record into SQL during backfill. */
|
|
41
46
|
backfillConversation(sourceConversation: Conversation): Promise<void>;
|
|
42
47
|
listByActivity(args?: {
|
|
@@ -22,6 +22,12 @@ export interface Conversation {
|
|
|
22
22
|
source?: ConversationSource;
|
|
23
23
|
title?: string;
|
|
24
24
|
updatedAtMs: number;
|
|
25
|
+
/**
|
|
26
|
+
* When retention purged this conversation's content. Set means messages and
|
|
27
|
+
* steps were deleted wholesale; reporting presents the transcript as expired
|
|
28
|
+
* rather than privacy-redacted (`../../../specs/data-redaction-policy.md`).
|
|
29
|
+
*/
|
|
30
|
+
transcriptPurgedAtMs?: number;
|
|
25
31
|
/** Persisted destination visibility. Undefined means no destination row exists. */
|
|
26
32
|
visibility?: ConversationPrivacy;
|
|
27
33
|
}
|
|
@@ -48,6 +54,19 @@ export interface ConversationStore {
|
|
|
48
54
|
/** Source-confirmed visibility from the current event's signal only. */
|
|
49
55
|
visibility?: ConversationPrivacy;
|
|
50
56
|
}): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Establish a subagent child conversation row linked to its parent.
|
|
59
|
+
*
|
|
60
|
+
* Advisor and future subagent histories live under their own child
|
|
61
|
+
* `conversation_id` with `parent_conversation_id` set; the child carries no
|
|
62
|
+
* destination and is excluded from top-level listings. Idempotent: it links a
|
|
63
|
+
* bare row a step append may have created first without clobbering it.
|
|
64
|
+
*/
|
|
65
|
+
ensureChildConversation(args: {
|
|
66
|
+
conversationId: string;
|
|
67
|
+
parentConversationId: string;
|
|
68
|
+
nowMs?: number;
|
|
69
|
+
}): Promise<void>;
|
|
51
70
|
/** Store task-execution metadata for long-term conversation history. */
|
|
52
71
|
recordExecution(args: {
|
|
53
72
|
channelName?: string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ThreadConversationState } from "@/chat/state/conversation";
|
|
2
|
+
/** Hydrate the durable visible-context compaction snapshot from SQL. */
|
|
3
|
+
export declare function hydrateConversationCompactions(args: {
|
|
4
|
+
conversation: ThreadConversationState;
|
|
5
|
+
conversationId: string;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
/** Persist a changed visible-context compaction snapshot in SQL agent history. */
|
|
8
|
+
export declare function persistConversationCompactions(args: {
|
|
9
|
+
conversation: ThreadConversationState;
|
|
10
|
+
conversationId: string;
|
|
11
|
+
}): Promise<void>;
|