@sentry/junior 0.93.0 → 0.95.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-FTQ5EGPO.js} +9 -10
- package/dist/api/people/list.js +7 -7
- package/dist/api/people/profile.js +7 -7
- package/dist/api/people/shared.d.ts +2 -2
- package/dist/api-reference.d.ts +1 -1
- package/dist/app.js +474 -231
- package/dist/{catalog-runtime-NZHMSMYC.js → catalog-runtime-2D7IVKUT.js} +3 -3
- 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/egress/credentialed.d.ts +1 -1
- package/dist/chat/identities/sql.d.ts +1 -1
- package/dist/chat/logging.d.ts +2 -1
- package/dist/chat/resource-events/store.d.ts +2 -1
- package/dist/chat/runtime/reply-executor.d.ts +8 -0
- package/dist/chat/runtime/thread-state.d.ts +2 -0
- package/dist/chat/sandbox/egress/schemas.d.ts +4 -0
- package/dist/chat/sandbox/egress/session.d.ts +2 -2
- package/dist/chat/sandbox/resources.d.ts +4 -0
- 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 +6 -0
- 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/xml.d.ts +2 -0
- package/dist/{chunk-NYWPISSO.js → chunk-2XXEKR44.js} +1 -1
- package/dist/{chunk-QGEWC27H.js → chunk-5XMNOD3S.js} +5 -7
- package/dist/{chunk-NFXSLTYG.js → chunk-6ONME5IG.js} +864 -62
- package/dist/{chunk-LFLTJQVR.js → chunk-7FBGKXPE.js} +4 -0
- package/dist/{chunk-MC4ZZE4Q.js → chunk-AYP4ERVZ.js} +1 -1
- package/dist/{chunk-GHGPTPBL.js → chunk-B7PUBQQM.js} +1 -1
- package/dist/chunk-CM5EZD5F.js +17 -0
- package/dist/chunk-CRRBJ3JP.js +1037 -0
- package/dist/{chunk-G3E7SCME.js → chunk-CZEX6KIQ.js} +23 -0
- package/dist/{chunk-TNUUATT7.js → chunk-E3E2XNCN.js} +2 -2
- package/dist/{chunk-LNCREA5Z.js → chunk-EKNJM5IG.js} +3 -127
- package/dist/{chunk-NAPITCZ6.js → chunk-GUE7HTNR.js} +251 -6
- package/dist/{chunk-BTH37NCU.js → chunk-GVOUCI2O.js} +1 -1
- package/dist/{chunk-YYBX2BD5.js → chunk-GY34VGP5.js} +1 -1
- package/dist/{chunk-JJUJ4CO2.js → chunk-HCXXB35T.js} +1489 -360
- package/dist/{chunk-YTNPU7I2.js → chunk-HDTO3A74.js} +2 -2
- package/dist/{chunk-YJ4OPVNA.js → chunk-HZNJLKKI.js} +1 -1
- package/dist/{chunk-HDNWZMUN.js → chunk-KDPCGVIT.js} +116 -51
- package/dist/chunk-N4RNJ32C.js +48 -0
- package/dist/{chunk-UUB3D2XI.js → chunk-NSCHU54X.js} +8 -10
- package/dist/{chunk-PFXC67GJ.js → chunk-RAIB6WSG.js} +6 -80
- package/dist/chunk-WAGQ377B.js +724 -0
- package/dist/{chunk-6H4PP63X.js → chunk-WCMQJE4F.js} +24 -14
- package/dist/{chunk-S6QKIGRM.js → chunk-WPOJ443W.js} +15 -25
- package/dist/{chunk-MAVOJ54A.js → chunk-XX4N4E6C.js} +25 -388
- package/dist/cli/chat.js +24 -23
- package/dist/cli/check.js +4 -4
- package/dist/cli/plugins.js +11 -12
- package/dist/cli/snapshot-warmup.js +7 -8
- package/dist/cli/upgrade.js +78 -17
- 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-W55B74OP.js +24 -0
- package/dist/deployment.d.ts +2 -0
- package/dist/handlers/retention.d.ts +6 -0
- package/dist/instrumentation.js +16 -3
- package/dist/legacy-import-ZPLGLAFD.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 +17 -0
- package/dist/reporting/conversations/transcript.d.ts +28 -0
- package/dist/reporting/conversations/types.d.ts +178 -0
- package/dist/reporting/conversations.d.ts +1 -178
- package/dist/reporting.d.ts +4 -3
- package/dist/reporting.js +603 -827
- package/dist/{runner-XAZPJNAQ.js → runner-OOSBDYRK.js} +35 -41
- package/dist/{validation-KYAWETI4.js → validation-QCGRFRFZ.js} +4 -4
- package/migrations/README.md +32 -0
- package/migrations/meta/0000_snapshot.json +978 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +9 -6
- 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
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureLegacyConversationImport
|
|
3
|
+
} from "./chunk-CRRBJ3JP.js";
|
|
4
|
+
import {
|
|
5
|
+
contextProvenance,
|
|
6
|
+
getAgentStepStore,
|
|
7
|
+
getConversationStore,
|
|
8
|
+
instructionActors,
|
|
9
|
+
instructionProvenanceFor
|
|
10
|
+
} from "./chunk-6ONME5IG.js";
|
|
11
|
+
import {
|
|
12
|
+
getStateAdapter
|
|
13
|
+
} from "./chunk-GUE7HTNR.js";
|
|
14
|
+
import {
|
|
15
|
+
toStoredSlackActor
|
|
16
|
+
} from "./chunk-WPOJ443W.js";
|
|
17
|
+
|
|
18
|
+
// src/chat/conversations/projection.ts
|
|
19
|
+
import { isDeepStrictEqual } from "util";
|
|
20
|
+
function authorizationObservationMessage(entry, createdAtMs) {
|
|
21
|
+
const label = entry.kind === "mcp" ? "MCP authorization" : "Authorization";
|
|
22
|
+
return {
|
|
23
|
+
role: "user",
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: "text",
|
|
27
|
+
text: `${label} completed for provider "${entry.provider}". Continue the blocked request and retry the provider operation if needed.`
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
timestamp: createdAtMs
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function piEntryProvenance(entry) {
|
|
34
|
+
return entry.provenance ?? contextProvenance;
|
|
35
|
+
}
|
|
36
|
+
function projectSteps(steps, opts) {
|
|
37
|
+
const messages = [];
|
|
38
|
+
const provenance = [];
|
|
39
|
+
const seqs = [];
|
|
40
|
+
for (const step of steps) {
|
|
41
|
+
if (opts?.maxSeq !== void 0 && step.seq > opts.maxSeq) {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
if (step.entry.type === "pi_message") {
|
|
45
|
+
messages.push(step.entry.message);
|
|
46
|
+
provenance.push(piEntryProvenance(step.entry));
|
|
47
|
+
seqs.push(step.seq);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (step.entry.type === "authorization_completed") {
|
|
51
|
+
messages.push(
|
|
52
|
+
authorizationObservationMessage(step.entry, step.createdAtMs)
|
|
53
|
+
);
|
|
54
|
+
provenance.push(contextProvenance);
|
|
55
|
+
seqs.push(step.seq);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { messages, provenance, seqs };
|
|
59
|
+
}
|
|
60
|
+
function connectedMcpProvidersFromSteps(steps) {
|
|
61
|
+
const providers = /* @__PURE__ */ new Set();
|
|
62
|
+
for (const step of steps) {
|
|
63
|
+
if (step.entry.type === "mcp_provider_connected") {
|
|
64
|
+
providers.add(step.entry.provider);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return [...providers].sort((left, right) => left.localeCompare(right));
|
|
68
|
+
}
|
|
69
|
+
function isUserMessage(message) {
|
|
70
|
+
return message.role === "user";
|
|
71
|
+
}
|
|
72
|
+
function countMatchingPrefix(left, right) {
|
|
73
|
+
const limit = Math.min(left.length, right.length);
|
|
74
|
+
for (let index = 0; index < limit; index += 1) {
|
|
75
|
+
if (!isDeepStrictEqual(left[index], right[index])) {
|
|
76
|
+
return index;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return limit;
|
|
80
|
+
}
|
|
81
|
+
function resolveCommitProvenance(args) {
|
|
82
|
+
if (args.explicitProvenance) {
|
|
83
|
+
if (args.explicitProvenance.length !== args.nextMessages.length) {
|
|
84
|
+
throw new Error("commit provenance must align one-to-one with messages");
|
|
85
|
+
}
|
|
86
|
+
return args.explicitProvenance;
|
|
87
|
+
}
|
|
88
|
+
const matchingPrefix = args.matchingPrefix;
|
|
89
|
+
const provenance = args.nextMessages.map(
|
|
90
|
+
(_, index) => index < matchingPrefix ? args.existing.provenance[index] ?? contextProvenance : contextProvenance
|
|
91
|
+
);
|
|
92
|
+
if (args.newMessageProvenance) {
|
|
93
|
+
for (let index = args.nextMessages.length - 1; index >= matchingPrefix; index -= 1) {
|
|
94
|
+
if (isUserMessage(args.nextMessages[index])) {
|
|
95
|
+
provenance[index] = args.newMessageProvenance;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (args.trailingMessageProvenance) {
|
|
101
|
+
if (args.trailingMessageProvenance.length > provenance.length) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"trailing commit provenance cannot exceed committed messages"
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
const newMessageCount = args.nextMessages.length - matchingPrefix;
|
|
107
|
+
if (args.trailingMessageProvenance.length > newMessageCount) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
"trailing commit provenance must align to newly committed messages"
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
const start = provenance.length - args.trailingMessageProvenance.length;
|
|
113
|
+
args.trailingMessageProvenance.forEach((entry, offset) => {
|
|
114
|
+
provenance[start + offset] = entry;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return provenance;
|
|
118
|
+
}
|
|
119
|
+
async function importLegacyIfNeeded(args) {
|
|
120
|
+
await ensureLegacyConversationImport({ conversationId: args.conversationId });
|
|
121
|
+
}
|
|
122
|
+
async function loadProjection(args) {
|
|
123
|
+
await importLegacyIfNeeded(args);
|
|
124
|
+
const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
|
|
125
|
+
return projectSteps(steps).messages;
|
|
126
|
+
}
|
|
127
|
+
async function loadProjectionWithProvenance(args) {
|
|
128
|
+
await importLegacyIfNeeded(args);
|
|
129
|
+
const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
|
|
130
|
+
const { messages, provenance } = projectSteps(steps);
|
|
131
|
+
return { messages, provenance };
|
|
132
|
+
}
|
|
133
|
+
async function loadTurnProjection(args) {
|
|
134
|
+
await importLegacyIfNeeded(args);
|
|
135
|
+
const stepStore = getAgentStepStore();
|
|
136
|
+
if (args.committedSeq < 0) {
|
|
137
|
+
return projectSteps(await stepStore.loadCurrentEpoch(args.conversationId));
|
|
138
|
+
}
|
|
139
|
+
const history = await stepStore.loadHistory(args.conversationId);
|
|
140
|
+
const committedStep = history.find((step) => step.seq === args.committedSeq);
|
|
141
|
+
if (!committedStep) {
|
|
142
|
+
return void 0;
|
|
143
|
+
}
|
|
144
|
+
const epochSteps = history.filter(
|
|
145
|
+
(step) => step.contextEpoch === committedStep.contextEpoch
|
|
146
|
+
);
|
|
147
|
+
return args.includeTail ? projectSteps(epochSteps) : projectSteps(epochSteps, { maxSeq: args.committedSeq });
|
|
148
|
+
}
|
|
149
|
+
async function loadConnectedMcpProviders(args) {
|
|
150
|
+
await importLegacyIfNeeded(args);
|
|
151
|
+
const steps = await getAgentStepStore().loadCurrentEpoch(args.conversationId);
|
|
152
|
+
return connectedMcpProvidersFromSteps(steps);
|
|
153
|
+
}
|
|
154
|
+
function messageTimestamp(message) {
|
|
155
|
+
const timestamp = message.timestamp;
|
|
156
|
+
return typeof timestamp === "number" ? timestamp : Date.now();
|
|
157
|
+
}
|
|
158
|
+
async function commitMessages(args) {
|
|
159
|
+
const stepStore = getAgentStepStore();
|
|
160
|
+
const existing = projectSteps(
|
|
161
|
+
await stepStore.loadCurrentEpoch(args.conversationId)
|
|
162
|
+
);
|
|
163
|
+
const matchingPrefix = countMatchingPrefix(existing.messages, args.messages);
|
|
164
|
+
const nextProvenance = resolveCommitProvenance({
|
|
165
|
+
existing,
|
|
166
|
+
nextMessages: args.messages,
|
|
167
|
+
matchingPrefix,
|
|
168
|
+
...args.provenance ? { explicitProvenance: args.provenance } : {},
|
|
169
|
+
...args.trailingMessageProvenance ? { trailingMessageProvenance: args.trailingMessageProvenance } : {},
|
|
170
|
+
...args.newMessageProvenance ? { newMessageProvenance: args.newMessageProvenance } : {}
|
|
171
|
+
});
|
|
172
|
+
if (matchingPrefix === existing.messages.length) {
|
|
173
|
+
const newMessages = args.messages.slice(matchingPrefix);
|
|
174
|
+
await stepStore.append(
|
|
175
|
+
args.conversationId,
|
|
176
|
+
newMessages.map((message, index) => ({
|
|
177
|
+
entry: {
|
|
178
|
+
type: "pi_message",
|
|
179
|
+
message,
|
|
180
|
+
provenance: nextProvenance[matchingPrefix + index]
|
|
181
|
+
},
|
|
182
|
+
createdAtMs: messageTimestamp(message)
|
|
183
|
+
}))
|
|
184
|
+
);
|
|
185
|
+
} else {
|
|
186
|
+
await stepStore.startEpoch(args.conversationId, {
|
|
187
|
+
reason: "rollback",
|
|
188
|
+
messages: args.messages.map((message, index) => ({
|
|
189
|
+
message,
|
|
190
|
+
createdAtMs: messageTimestamp(message),
|
|
191
|
+
provenance: nextProvenance[index]
|
|
192
|
+
}))
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
const committed = projectSteps(
|
|
196
|
+
await stepStore.loadCurrentEpoch(args.conversationId)
|
|
197
|
+
);
|
|
198
|
+
return {
|
|
199
|
+
committedSeq: committed.seqs.at(-1) ?? -1,
|
|
200
|
+
messageSeqs: committed.seqs,
|
|
201
|
+
provenance: nextProvenance
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
async function recordMcpProviderConnected(args) {
|
|
205
|
+
const stepStore = getAgentStepStore();
|
|
206
|
+
const steps = await stepStore.loadCurrentEpoch(args.conversationId);
|
|
207
|
+
if (connectedMcpProvidersFromSteps(steps).includes(args.provider)) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
await stepStore.append(args.conversationId, [
|
|
211
|
+
{
|
|
212
|
+
entry: { type: "mcp_provider_connected", provider: args.provider },
|
|
213
|
+
createdAtMs: Date.now()
|
|
214
|
+
}
|
|
215
|
+
]);
|
|
216
|
+
}
|
|
217
|
+
async function recordAuthorizationRequested(args) {
|
|
218
|
+
const stepStore = getAgentStepStore();
|
|
219
|
+
const steps = await stepStore.loadCurrentEpoch(args.conversationId);
|
|
220
|
+
if (steps.some(
|
|
221
|
+
(step) => step.entry.type === "authorization_requested" && step.entry.authorizationId === args.authorizationId
|
|
222
|
+
)) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
await stepStore.append(args.conversationId, [
|
|
226
|
+
{
|
|
227
|
+
entry: {
|
|
228
|
+
type: "authorization_requested",
|
|
229
|
+
kind: args.kind,
|
|
230
|
+
provider: args.provider,
|
|
231
|
+
actorId: args.actorId,
|
|
232
|
+
authorizationId: args.authorizationId,
|
|
233
|
+
delivery: args.delivery
|
|
234
|
+
},
|
|
235
|
+
createdAtMs: Date.now()
|
|
236
|
+
}
|
|
237
|
+
]);
|
|
238
|
+
}
|
|
239
|
+
async function recordAuthorizationCompleted(args) {
|
|
240
|
+
const stepStore = getAgentStepStore();
|
|
241
|
+
const steps = await stepStore.loadCurrentEpoch(args.conversationId);
|
|
242
|
+
if (steps.some(
|
|
243
|
+
(step) => step.entry.type === "authorization_completed" && step.entry.authorizationId === args.authorizationId
|
|
244
|
+
)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
await stepStore.append(args.conversationId, [
|
|
248
|
+
{
|
|
249
|
+
entry: {
|
|
250
|
+
type: "authorization_completed",
|
|
251
|
+
kind: args.kind,
|
|
252
|
+
provider: args.provider,
|
|
253
|
+
actorId: args.actorId,
|
|
254
|
+
authorizationId: args.authorizationId
|
|
255
|
+
},
|
|
256
|
+
createdAtMs: Date.now()
|
|
257
|
+
}
|
|
258
|
+
]);
|
|
259
|
+
}
|
|
260
|
+
async function recordToolExecutionStarted(args) {
|
|
261
|
+
await getAgentStepStore().append(args.conversationId, [
|
|
262
|
+
{
|
|
263
|
+
entry: {
|
|
264
|
+
type: "tool_execution_started",
|
|
265
|
+
toolCallId: args.toolCallId,
|
|
266
|
+
toolName: args.toolName,
|
|
267
|
+
...args.args !== void 0 ? { args: args.args } : {}
|
|
268
|
+
},
|
|
269
|
+
createdAtMs: args.createdAtMs ?? Date.now()
|
|
270
|
+
}
|
|
271
|
+
]);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/chat/state/turn-session.ts
|
|
275
|
+
import { THREAD_STATE_TTL_MS } from "chat";
|
|
276
|
+
import {
|
|
277
|
+
actorSchema,
|
|
278
|
+
destinationSchema,
|
|
279
|
+
sourceSchema
|
|
280
|
+
} from "@sentry/junior-plugin-api";
|
|
281
|
+
import { z } from "zod";
|
|
282
|
+
var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session";
|
|
283
|
+
var AGENT_TURN_SESSION_INDEX_KEY = `${AGENT_TURN_SESSION_PREFIX}:index`;
|
|
284
|
+
var AGENT_TURN_SESSION_INDEX_MAX_LENGTH = 5e3;
|
|
285
|
+
var AGENT_TURN_SESSION_TTL_MS = THREAD_STATE_TTL_MS;
|
|
286
|
+
var agentTurnSessionStatusSchema = z.enum([
|
|
287
|
+
"running",
|
|
288
|
+
"awaiting_resume",
|
|
289
|
+
"completed",
|
|
290
|
+
"failed",
|
|
291
|
+
"abandoned"
|
|
292
|
+
]);
|
|
293
|
+
var agentTurnSurfaceSchema = z.enum([
|
|
294
|
+
"slack",
|
|
295
|
+
"api",
|
|
296
|
+
"scheduler",
|
|
297
|
+
"internal"
|
|
298
|
+
]);
|
|
299
|
+
var agentTurnResumeReasonSchema = z.enum([
|
|
300
|
+
"timeout",
|
|
301
|
+
"auth",
|
|
302
|
+
"yield"
|
|
303
|
+
]);
|
|
304
|
+
var nonNegativeNumberSchema = z.number().finite().nonnegative();
|
|
305
|
+
var seqCursorSchema = z.number().int().min(-1);
|
|
306
|
+
var agentTurnUsageSchema = z.object({
|
|
307
|
+
inputTokens: nonNegativeNumberSchema.optional(),
|
|
308
|
+
outputTokens: nonNegativeNumberSchema.optional(),
|
|
309
|
+
cachedInputTokens: nonNegativeNumberSchema.optional(),
|
|
310
|
+
cacheCreationTokens: nonNegativeNumberSchema.optional(),
|
|
311
|
+
totalTokens: nonNegativeNumberSchema.optional()
|
|
312
|
+
}).strict();
|
|
313
|
+
var agentTurnSessionSummarySchema = z.object({
|
|
314
|
+
channelName: z.string().min(1).optional(),
|
|
315
|
+
version: z.number().int().nonnegative(),
|
|
316
|
+
conversationId: z.string().min(1),
|
|
317
|
+
cumulativeDurationMs: nonNegativeNumberSchema,
|
|
318
|
+
cumulativeUsage: agentTurnUsageSchema.optional(),
|
|
319
|
+
destination: destinationSchema.optional(),
|
|
320
|
+
source: sourceSchema.optional(),
|
|
321
|
+
lastProgressAtMs: nonNegativeNumberSchema,
|
|
322
|
+
loadedSkillNames: z.array(z.string()).optional(),
|
|
323
|
+
modelId: z.string().min(1).optional(),
|
|
324
|
+
reasoningLevel: z.string().min(1).optional(),
|
|
325
|
+
actor: actorSchema.optional(),
|
|
326
|
+
resumeReason: agentTurnResumeReasonSchema.optional(),
|
|
327
|
+
resumedFromSliceId: z.number().int().nonnegative().optional(),
|
|
328
|
+
sessionId: z.string().min(1),
|
|
329
|
+
sliceId: z.number().int().nonnegative(),
|
|
330
|
+
startedAtMs: nonNegativeNumberSchema,
|
|
331
|
+
state: agentTurnSessionStatusSchema,
|
|
332
|
+
surface: agentTurnSurfaceSchema.optional(),
|
|
333
|
+
traceId: z.string().optional(),
|
|
334
|
+
updatedAtMs: nonNegativeNumberSchema
|
|
335
|
+
}).strict();
|
|
336
|
+
var storedAgentTurnSessionRecordSchema = agentTurnSessionSummarySchema.extend({
|
|
337
|
+
committedSeq: seqCursorSchema,
|
|
338
|
+
errorMessage: z.string().optional(),
|
|
339
|
+
turnStartSeq: seqCursorSchema.optional()
|
|
340
|
+
}).strict();
|
|
341
|
+
function agentTurnSessionKey(conversationId, sessionId) {
|
|
342
|
+
return `${AGENT_TURN_SESSION_PREFIX}:${conversationId}:${sessionId}`;
|
|
343
|
+
}
|
|
344
|
+
function agentTurnSessionConversationIndexKey(conversationId) {
|
|
345
|
+
return `${AGENT_TURN_SESSION_PREFIX}:conversation:${conversationId}:index`;
|
|
346
|
+
}
|
|
347
|
+
function conversationExecutionFromSummary(summary) {
|
|
348
|
+
const status = summary.state === "completed" || summary.state === "abandoned" ? "idle" : summary.state;
|
|
349
|
+
return {
|
|
350
|
+
status,
|
|
351
|
+
runId: summary.sessionId,
|
|
352
|
+
updatedAtMs: summary.updatedAtMs
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function sessionLogActor(actor) {
|
|
356
|
+
return actor?.platform === "slack" ? toStoredSlackActor(actor) : void 0;
|
|
357
|
+
}
|
|
358
|
+
function parseAgentTurnSessionRecord(value) {
|
|
359
|
+
return storedAgentTurnSessionRecordSchema.parse(value);
|
|
360
|
+
}
|
|
361
|
+
function parseAgentTurnSessionSummary(value) {
|
|
362
|
+
return agentTurnSessionSummarySchema.parse(value);
|
|
363
|
+
}
|
|
364
|
+
async function appendAgentTurnSessionSummary(summary, ttlMs) {
|
|
365
|
+
const stateAdapter = getStateAdapter();
|
|
366
|
+
await Promise.all([
|
|
367
|
+
stateAdapter.appendToList(AGENT_TURN_SESSION_INDEX_KEY, summary, {
|
|
368
|
+
maxLength: AGENT_TURN_SESSION_INDEX_MAX_LENGTH,
|
|
369
|
+
ttlMs
|
|
370
|
+
}),
|
|
371
|
+
stateAdapter.appendToList(
|
|
372
|
+
agentTurnSessionConversationIndexKey(summary.conversationId),
|
|
373
|
+
summary,
|
|
374
|
+
{ ttlMs }
|
|
375
|
+
)
|
|
376
|
+
]);
|
|
377
|
+
}
|
|
378
|
+
async function recordConversationActivityMetadata(args) {
|
|
379
|
+
const conversationStore = args.conversationStore ?? getConversationStore();
|
|
380
|
+
const source = args.summary.destination?.platform === "local" ? "local" : args.summary.surface;
|
|
381
|
+
await conversationStore.recordActivity({
|
|
382
|
+
activityAtMs: args.summary.updatedAtMs,
|
|
383
|
+
channelName: args.summary.channelName,
|
|
384
|
+
conversationId: args.summary.conversationId,
|
|
385
|
+
destination: args.summary.destination,
|
|
386
|
+
nowMs: args.nowMs,
|
|
387
|
+
actor: sessionLogActor(args.summary.actor),
|
|
388
|
+
source,
|
|
389
|
+
visibility: args.destinationVisibility
|
|
390
|
+
});
|
|
391
|
+
await conversationStore.recordExecution({
|
|
392
|
+
channelName: args.summary.channelName,
|
|
393
|
+
conversationId: args.summary.conversationId,
|
|
394
|
+
createdAtMs: args.summary.startedAtMs,
|
|
395
|
+
destination: args.summary.destination,
|
|
396
|
+
execution: conversationExecutionFromSummary(args.summary),
|
|
397
|
+
lastActivityAtMs: args.summary.updatedAtMs,
|
|
398
|
+
actor: sessionLogActor(args.summary.actor),
|
|
399
|
+
source,
|
|
400
|
+
updatedAtMs: args.nowMs,
|
|
401
|
+
visibility: args.destinationVisibility
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
function materializeAgentTurnSessionRecord(stored, piProjection, turnStartMessageIndex) {
|
|
405
|
+
return {
|
|
406
|
+
version: stored.version,
|
|
407
|
+
...stored.channelName ? { channelName: stored.channelName } : {},
|
|
408
|
+
conversationId: stored.conversationId,
|
|
409
|
+
sessionId: stored.sessionId,
|
|
410
|
+
sliceId: stored.sliceId,
|
|
411
|
+
state: stored.state,
|
|
412
|
+
startedAtMs: stored.startedAtMs,
|
|
413
|
+
lastProgressAtMs: stored.lastProgressAtMs,
|
|
414
|
+
updatedAtMs: stored.updatedAtMs,
|
|
415
|
+
piMessages: piProjection.messages,
|
|
416
|
+
piMessageProvenance: piProjection.provenance,
|
|
417
|
+
actors: instructionActors(piProjection.provenance),
|
|
418
|
+
cumulativeDurationMs: stored.cumulativeDurationMs,
|
|
419
|
+
...stored.destination ? { destination: stored.destination } : {},
|
|
420
|
+
...stored.source ? { source: stored.source } : {},
|
|
421
|
+
...stored.cumulativeUsage ? { cumulativeUsage: stored.cumulativeUsage } : {},
|
|
422
|
+
...stored.resumeReason ? { resumeReason: stored.resumeReason } : {},
|
|
423
|
+
...stored.errorMessage ? { errorMessage: stored.errorMessage } : {},
|
|
424
|
+
...stored.loadedSkillNames ? { loadedSkillNames: stored.loadedSkillNames } : {},
|
|
425
|
+
...stored.modelId ? { modelId: stored.modelId } : {},
|
|
426
|
+
...stored.reasoningLevel ? { reasoningLevel: stored.reasoningLevel } : {},
|
|
427
|
+
...stored.actor ? { actor: stored.actor } : {},
|
|
428
|
+
...stored.resumedFromSliceId !== void 0 ? { resumedFromSliceId: stored.resumedFromSliceId } : {},
|
|
429
|
+
...stored.surface ? { surface: stored.surface } : {},
|
|
430
|
+
...stored.traceId ? { traceId: stored.traceId } : {},
|
|
431
|
+
...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {}
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
async function getStoredAgentTurnSessionRecord(conversationId, sessionId) {
|
|
435
|
+
const stateAdapter = getStateAdapter();
|
|
436
|
+
await stateAdapter.connect();
|
|
437
|
+
const value = await stateAdapter.get(
|
|
438
|
+
agentTurnSessionKey(conversationId, sessionId)
|
|
439
|
+
);
|
|
440
|
+
return value == null ? void 0 : parseAgentTurnSessionRecord(value);
|
|
441
|
+
}
|
|
442
|
+
async function getAgentTurnSessionRecord(conversationId, sessionId) {
|
|
443
|
+
const parsed = await getStoredAgentTurnSessionRecord(
|
|
444
|
+
conversationId,
|
|
445
|
+
sessionId
|
|
446
|
+
);
|
|
447
|
+
if (!parsed) {
|
|
448
|
+
return void 0;
|
|
449
|
+
}
|
|
450
|
+
const piProjection = await loadTurnProjection({
|
|
451
|
+
conversationId,
|
|
452
|
+
committedSeq: parsed.committedSeq,
|
|
453
|
+
// Unfinished records include the current-epoch tail so parked input
|
|
454
|
+
// appended after the last safe boundary stays model-visible on resume.
|
|
455
|
+
includeTail: parsed.state === "running" || parsed.state === "awaiting_resume"
|
|
456
|
+
});
|
|
457
|
+
if (!piProjection) {
|
|
458
|
+
return void 0;
|
|
459
|
+
}
|
|
460
|
+
const turnStartMessageIndex = parsed.turnStartSeq === void 0 ? void 0 : piProjection.seqs.filter((seq) => seq <= parsed.turnStartSeq).length;
|
|
461
|
+
return materializeAgentTurnSessionRecord(
|
|
462
|
+
parsed,
|
|
463
|
+
piProjection,
|
|
464
|
+
turnStartMessageIndex
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
function buildStoredRecord(args) {
|
|
468
|
+
const nowMs = Date.now();
|
|
469
|
+
return {
|
|
470
|
+
version: (args.previousVersion ?? 0) + 1,
|
|
471
|
+
...args.channelName ? { channelName: args.channelName } : {},
|
|
472
|
+
conversationId: args.conversationId,
|
|
473
|
+
sessionId: args.sessionId,
|
|
474
|
+
sliceId: args.sliceId,
|
|
475
|
+
state: args.state,
|
|
476
|
+
startedAtMs: args.startedAtMs ?? nowMs,
|
|
477
|
+
lastProgressAtMs: args.lastProgressAtMs ?? nowMs,
|
|
478
|
+
updatedAtMs: nowMs,
|
|
479
|
+
committedSeq: args.committedSeq,
|
|
480
|
+
...args.turnStartSeq !== void 0 ? { turnStartSeq: args.turnStartSeq } : {},
|
|
481
|
+
cumulativeDurationMs: args.cumulativeDurationMs,
|
|
482
|
+
...args.cumulativeUsage ? { cumulativeUsage: args.cumulativeUsage } : {},
|
|
483
|
+
...args.destination ? { destination: args.destination } : {},
|
|
484
|
+
...args.source ? { source: args.source } : {},
|
|
485
|
+
...args.actor ? { actor: args.actor } : {},
|
|
486
|
+
...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : {},
|
|
487
|
+
...args.modelId ? { modelId: args.modelId } : {},
|
|
488
|
+
...args.reasoningLevel ? { reasoningLevel: args.reasoningLevel } : {},
|
|
489
|
+
...args.resumeReason ? { resumeReason: args.resumeReason } : {},
|
|
490
|
+
...args.errorMessage ? { errorMessage: args.errorMessage } : {},
|
|
491
|
+
...args.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.resumedFromSliceId } : {},
|
|
492
|
+
...args.surface ? { surface: args.surface } : {},
|
|
493
|
+
...args.traceId ? { traceId: args.traceId } : {}
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
async function setStoredRecord(args) {
|
|
497
|
+
const stateAdapter = getStateAdapter();
|
|
498
|
+
await stateAdapter.connect();
|
|
499
|
+
await recordConversationActivityMetadata({
|
|
500
|
+
conversationStore: args.conversationStore,
|
|
501
|
+
destinationVisibility: args.destinationVisibility,
|
|
502
|
+
nowMs: Date.now(),
|
|
503
|
+
summary: args.record
|
|
504
|
+
});
|
|
505
|
+
await stateAdapter.set(
|
|
506
|
+
agentTurnSessionKey(args.record.conversationId, args.record.sessionId),
|
|
507
|
+
args.record,
|
|
508
|
+
args.ttlMs
|
|
509
|
+
);
|
|
510
|
+
const {
|
|
511
|
+
committedSeq: _committedSeq,
|
|
512
|
+
errorMessage: _errorMessage,
|
|
513
|
+
turnStartSeq: _turnStartSeq,
|
|
514
|
+
...summary
|
|
515
|
+
} = args.record;
|
|
516
|
+
await appendAgentTurnSessionSummary(summary, args.ttlMs);
|
|
517
|
+
return materializeAgentTurnSessionRecord(
|
|
518
|
+
args.record,
|
|
519
|
+
{
|
|
520
|
+
messages: [...args.piMessages],
|
|
521
|
+
provenance: [...args.piMessageProvenance]
|
|
522
|
+
},
|
|
523
|
+
args.turnStartMessageIndex
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
async function updateAgentTurnSessionState(args) {
|
|
527
|
+
const parsed = await getStoredAgentTurnSessionRecord(
|
|
528
|
+
args.existing.conversationId,
|
|
529
|
+
args.existing.sessionId
|
|
530
|
+
);
|
|
531
|
+
if (!parsed || parsed.version !== args.existing.version) {
|
|
532
|
+
return void 0;
|
|
533
|
+
}
|
|
534
|
+
return await setStoredRecord({
|
|
535
|
+
piMessages: args.existing.piMessages,
|
|
536
|
+
piMessageProvenance: args.existing.piMessageProvenance,
|
|
537
|
+
ttlMs: AGENT_TURN_SESSION_TTL_MS,
|
|
538
|
+
...args.existing.turnStartMessageIndex !== void 0 ? { turnStartMessageIndex: args.existing.turnStartMessageIndex } : {},
|
|
539
|
+
record: buildStoredRecord({
|
|
540
|
+
conversationId: args.existing.conversationId,
|
|
541
|
+
sessionId: args.existing.sessionId,
|
|
542
|
+
sliceId: args.existing.sliceId,
|
|
543
|
+
state: args.state,
|
|
544
|
+
committedSeq: parsed.committedSeq,
|
|
545
|
+
...parsed.turnStartSeq !== void 0 ? { turnStartSeq: parsed.turnStartSeq } : {},
|
|
546
|
+
...parsed.channelName ? { channelName: parsed.channelName } : {},
|
|
547
|
+
startedAtMs: parsed.startedAtMs,
|
|
548
|
+
lastProgressAtMs: parsed.lastProgressAtMs,
|
|
549
|
+
previousVersion: parsed.version,
|
|
550
|
+
cumulativeDurationMs: args.existing.cumulativeDurationMs,
|
|
551
|
+
...args.existing.cumulativeUsage ? { cumulativeUsage: args.existing.cumulativeUsage } : {},
|
|
552
|
+
...args.existing.destination ? { destination: args.existing.destination } : {},
|
|
553
|
+
...args.existing.source ? { source: args.existing.source } : {},
|
|
554
|
+
...args.existing.loadedSkillNames ? { loadedSkillNames: args.existing.loadedSkillNames } : {},
|
|
555
|
+
...args.existing.modelId ? { modelId: args.existing.modelId } : {},
|
|
556
|
+
...args.existing.reasoningLevel ? { reasoningLevel: args.existing.reasoningLevel } : {},
|
|
557
|
+
...args.existing.actor ? { actor: args.existing.actor } : {},
|
|
558
|
+
...args.existing.resumeReason ? { resumeReason: args.existing.resumeReason } : {},
|
|
559
|
+
...args.existing.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.existing.resumedFromSliceId } : {},
|
|
560
|
+
...args.existing.surface ? { surface: args.existing.surface } : {},
|
|
561
|
+
...args.existing.traceId ? { traceId: args.existing.traceId } : {},
|
|
562
|
+
...args.errorMessage ?? args.existing.errorMessage ? { errorMessage: args.errorMessage ?? args.existing.errorMessage } : {}
|
|
563
|
+
})
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
async function upsertAgentTurnSessionRecord(args) {
|
|
567
|
+
const existingRecord = await getStoredAgentTurnSessionRecord(
|
|
568
|
+
args.conversationId,
|
|
569
|
+
args.sessionId
|
|
570
|
+
);
|
|
571
|
+
const ttlMs = Math.max(1, args.ttlMs ?? AGENT_TURN_SESSION_TTL_MS);
|
|
572
|
+
const instructionActor = args.actor ?? existingRecord?.actor;
|
|
573
|
+
const commit = await commitMessages({
|
|
574
|
+
conversationId: args.conversationId,
|
|
575
|
+
messages: args.piMessages,
|
|
576
|
+
...instructionActor ? { newMessageProvenance: instructionProvenanceFor(instructionActor) } : {},
|
|
577
|
+
...args.trailingMessageProvenance ? { trailingMessageProvenance: args.trailingMessageProvenance } : {}
|
|
578
|
+
});
|
|
579
|
+
const turnStartSeq = args.turnStartMessageIndex === void 0 ? existingRecord?.turnStartSeq : args.turnStartMessageIndex <= 0 ? -1 : commit.messageSeqs[args.turnStartMessageIndex - 1] ?? commit.committedSeq;
|
|
580
|
+
const turnStartMessageIndex = args.turnStartMessageIndex ?? (turnStartSeq === void 0 ? void 0 : commit.messageSeqs.filter((seq) => seq <= turnStartSeq).length);
|
|
581
|
+
return await setStoredRecord({
|
|
582
|
+
conversationStore: args.conversationStore,
|
|
583
|
+
destinationVisibility: args.destinationVisibility,
|
|
584
|
+
piMessages: args.piMessages,
|
|
585
|
+
piMessageProvenance: commit.provenance,
|
|
586
|
+
ttlMs,
|
|
587
|
+
...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {},
|
|
588
|
+
record: buildStoredRecord({
|
|
589
|
+
...args.channelName ?? existingRecord?.channelName ? { channelName: args.channelName ?? existingRecord?.channelName } : {},
|
|
590
|
+
conversationId: args.conversationId,
|
|
591
|
+
sessionId: args.sessionId,
|
|
592
|
+
sliceId: args.sliceId,
|
|
593
|
+
state: args.state,
|
|
594
|
+
...existingRecord?.startedAtMs !== void 0 ? { startedAtMs: existingRecord.startedAtMs } : {},
|
|
595
|
+
...args.lastProgressAtMs !== void 0 ? { lastProgressAtMs: args.lastProgressAtMs } : {},
|
|
596
|
+
committedSeq: commit.committedSeq,
|
|
597
|
+
...turnStartSeq !== void 0 ? { turnStartSeq } : {},
|
|
598
|
+
previousVersion: existingRecord?.version,
|
|
599
|
+
cumulativeDurationMs: args.cumulativeDurationMs ?? existingRecord?.cumulativeDurationMs ?? 0,
|
|
600
|
+
...args.cumulativeUsage ? { cumulativeUsage: args.cumulativeUsage } : {},
|
|
601
|
+
...args.destination ?? existingRecord?.destination ? { destination: args.destination ?? existingRecord?.destination } : {},
|
|
602
|
+
...args.source ?? existingRecord?.source ? { source: args.source ?? existingRecord?.source } : {},
|
|
603
|
+
...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : {},
|
|
604
|
+
...existingRecord?.modelId ?? args.modelId ? { modelId: existingRecord?.modelId ?? args.modelId } : {},
|
|
605
|
+
...args.reasoningLevel ?? existingRecord?.reasoningLevel ? {
|
|
606
|
+
reasoningLevel: args.reasoningLevel ?? existingRecord?.reasoningLevel
|
|
607
|
+
} : {},
|
|
608
|
+
...args.actor ?? existingRecord?.actor ? { actor: args.actor ?? existingRecord?.actor } : {},
|
|
609
|
+
...args.resumeReason ? { resumeReason: args.resumeReason } : {},
|
|
610
|
+
...args.errorMessage ? { errorMessage: args.errorMessage } : {},
|
|
611
|
+
...args.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.resumedFromSliceId } : {},
|
|
612
|
+
...args.surface ?? existingRecord?.surface ? { surface: args.surface ?? existingRecord?.surface } : {},
|
|
613
|
+
...args.traceId ?? existingRecord?.traceId ? { traceId: args.traceId ?? existingRecord?.traceId } : {}
|
|
614
|
+
})
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
async function recordAgentTurnSessionSummary(args) {
|
|
618
|
+
const existing = await getStoredAgentTurnSessionRecord(
|
|
619
|
+
args.conversationId,
|
|
620
|
+
args.sessionId
|
|
621
|
+
);
|
|
622
|
+
const nowMs = Date.now();
|
|
623
|
+
const ttlMs = Math.max(1, args.ttlMs ?? AGENT_TURN_SESSION_TTL_MS);
|
|
624
|
+
const summary = {
|
|
625
|
+
version: existing?.version ?? 0,
|
|
626
|
+
...args.channelName ?? existing?.channelName ? { channelName: args.channelName ?? existing?.channelName } : {},
|
|
627
|
+
conversationId: args.conversationId,
|
|
628
|
+
sessionId: args.sessionId,
|
|
629
|
+
sliceId: args.sliceId,
|
|
630
|
+
startedAtMs: existing?.startedAtMs ?? args.startedAtMs ?? nowMs,
|
|
631
|
+
lastProgressAtMs: args.lastProgressAtMs ?? nowMs,
|
|
632
|
+
state: args.state,
|
|
633
|
+
updatedAtMs: nowMs,
|
|
634
|
+
cumulativeDurationMs: args.cumulativeDurationMs ?? existing?.cumulativeDurationMs ?? 0,
|
|
635
|
+
...args.cumulativeUsage ?? existing?.cumulativeUsage ? { cumulativeUsage: args.cumulativeUsage ?? existing?.cumulativeUsage } : {},
|
|
636
|
+
...args.destination ?? existing?.destination ? { destination: args.destination ?? existing?.destination } : {},
|
|
637
|
+
...args.source ?? existing?.source ? { source: args.source ?? existing?.source } : {},
|
|
638
|
+
...args.actor ?? existing?.actor ? { actor: args.actor ?? existing?.actor } : {},
|
|
639
|
+
...args.loadedSkillNames ? { loadedSkillNames: args.loadedSkillNames } : existing?.loadedSkillNames ? { loadedSkillNames: existing.loadedSkillNames } : {},
|
|
640
|
+
...existing?.modelId ?? args.modelId ? { modelId: existing?.modelId ?? args.modelId } : {},
|
|
641
|
+
...args.reasoningLevel ?? existing?.reasoningLevel ? { reasoningLevel: args.reasoningLevel ?? existing?.reasoningLevel } : {},
|
|
642
|
+
...args.resumeReason ? { resumeReason: args.resumeReason } : {},
|
|
643
|
+
...args.surface ?? existing?.surface ? { surface: args.surface ?? existing?.surface } : {},
|
|
644
|
+
...args.traceId ?? existing?.traceId ? { traceId: args.traceId ?? existing?.traceId } : {}
|
|
645
|
+
};
|
|
646
|
+
await recordConversationActivityMetadata({
|
|
647
|
+
conversationStore: args.conversationStore,
|
|
648
|
+
destinationVisibility: args.destinationVisibility,
|
|
649
|
+
nowMs,
|
|
650
|
+
summary
|
|
651
|
+
});
|
|
652
|
+
await appendAgentTurnSessionSummary(summary, ttlMs);
|
|
653
|
+
}
|
|
654
|
+
async function readAgentTurnSessionSummariesFromIndex(key) {
|
|
655
|
+
const stateAdapter = getStateAdapter();
|
|
656
|
+
await stateAdapter.connect();
|
|
657
|
+
const values = await stateAdapter.getList(key);
|
|
658
|
+
const summaries = /* @__PURE__ */ new Map();
|
|
659
|
+
for (const value of [...values].reverse()) {
|
|
660
|
+
const summary = parseAgentTurnSessionSummary(value);
|
|
661
|
+
const key2 = `${summary.conversationId}:${summary.sessionId}`;
|
|
662
|
+
if (!summaries.has(key2)) {
|
|
663
|
+
summaries.set(key2, summary);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return [...summaries.values()].sort(
|
|
667
|
+
(left, right) => right.updatedAtMs - left.updatedAtMs
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
async function listAgentTurnSessionSummariesForConversation(conversationId) {
|
|
671
|
+
const summaries = await readAgentTurnSessionSummariesFromIndex(
|
|
672
|
+
agentTurnSessionConversationIndexKey(conversationId)
|
|
673
|
+
);
|
|
674
|
+
if (summaries.length > 0) {
|
|
675
|
+
return summaries;
|
|
676
|
+
}
|
|
677
|
+
return (await readAgentTurnSessionSummariesFromIndex(AGENT_TURN_SESSION_INDEX_KEY)).filter((summary) => summary.conversationId === conversationId);
|
|
678
|
+
}
|
|
679
|
+
async function abandonAgentTurnSessionRecord(args) {
|
|
680
|
+
const existing = await getAgentTurnSessionRecord(
|
|
681
|
+
args.conversationId,
|
|
682
|
+
args.sessionId
|
|
683
|
+
);
|
|
684
|
+
if (!existing || existing.state === "completed" || existing.state === "failed" || existing.state === "abandoned") {
|
|
685
|
+
return void 0;
|
|
686
|
+
}
|
|
687
|
+
return await updateAgentTurnSessionState({
|
|
688
|
+
existing,
|
|
689
|
+
state: "abandoned",
|
|
690
|
+
errorMessage: args.errorMessage ?? existing.errorMessage
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
async function failAgentTurnSessionRecord(args) {
|
|
694
|
+
const existing = await getAgentTurnSessionRecord(
|
|
695
|
+
args.conversationId,
|
|
696
|
+
args.sessionId
|
|
697
|
+
);
|
|
698
|
+
if (!existing || existing.state === "completed" || existing.state === "failed" || existing.state === "abandoned" || existing.version !== args.expectedVersion) {
|
|
699
|
+
return void 0;
|
|
700
|
+
}
|
|
701
|
+
return await updateAgentTurnSessionState({
|
|
702
|
+
existing,
|
|
703
|
+
state: "failed",
|
|
704
|
+
errorMessage: args.errorMessage ?? existing.errorMessage
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export {
|
|
709
|
+
projectSteps,
|
|
710
|
+
loadProjection,
|
|
711
|
+
loadProjectionWithProvenance,
|
|
712
|
+
loadConnectedMcpProviders,
|
|
713
|
+
commitMessages,
|
|
714
|
+
recordMcpProviderConnected,
|
|
715
|
+
recordAuthorizationRequested,
|
|
716
|
+
recordAuthorizationCompleted,
|
|
717
|
+
recordToolExecutionStarted,
|
|
718
|
+
getAgentTurnSessionRecord,
|
|
719
|
+
upsertAgentTurnSessionRecord,
|
|
720
|
+
recordAgentTurnSessionSummary,
|
|
721
|
+
listAgentTurnSessionSummariesForConversation,
|
|
722
|
+
abandonAgentTurnSessionRecord,
|
|
723
|
+
failAgentTurnSessionRecord
|
|
724
|
+
};
|