@modelprofile.com/flexharness 1.0.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/.smartconfig.json +34 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.flexharness.d.ts +61 -0
- package/dist_ts/classes.flexharness.js +1312 -0
- package/dist_ts/classes.stores.d.ts +26 -0
- package/dist_ts/classes.stores.js +156 -0
- package/dist_ts/errors.d.ts +44 -0
- package/dist_ts/errors.js +105 -0
- package/dist_ts/index.d.ts +5 -0
- package/dist_ts/index.js +6 -0
- package/dist_ts/interfaces.d.ts +288 -0
- package/dist_ts/interfaces.js +2 -0
- package/dist_ts/plugins.d.ts +7 -0
- package/dist_ts/plugins.js +9 -0
- package/dist_ts/utils.json.d.ts +8 -0
- package/dist_ts/utils.json.js +540 -0
- package/dist_ts/utils.prompt.d.ts +8 -0
- package/dist_ts/utils.prompt.js +170 -0
- package/license.md +21 -0
- package/package.json +36 -0
- package/readme.hints.md +29 -0
- package/readme.md +285 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.flexharness.ts +1648 -0
- package/ts/classes.stores.ts +195 -0
- package/ts/errors.ts +125 -0
- package/ts/index.ts +5 -0
- package/ts/interfaces.ts +369 -0
- package/ts/plugins.ts +15 -0
- package/ts/utils.json.ts +651 -0
- package/ts/utils.prompt.ts +193 -0
|
@@ -0,0 +1,1312 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { FlexHarnessAbortError, FlexHarnessCallbackOverflowError, FlexHarnessClosedError, FlexHarnessNotFoundError, FlexHarnessPermissionRejectedError, FlexHarnessPermissionStateError, FlexHarnessRunError, FlexHarnessSessionBusyError, FlexHarnessValidationError, errorMessage, errorToInfo, } from './errors.js';
|
|
3
|
+
import { InMemoryFlexHarnessStore } from './classes.stores.js';
|
|
4
|
+
import { assertFlexHarnessSnapshot, cloneSerializable, deepFreeze, normalizeJsonValue, resolveJsonLimits, serializeAgentMessages, } from './utils.json.js';
|
|
5
|
+
import { hydrateAgentMessages, normalizeFlexPrompt, } from './utils.prompt.js';
|
|
6
|
+
const DEFAULT_CALLBACK_LIMITS = {
|
|
7
|
+
maxEvents: 10_000,
|
|
8
|
+
maxOutputBytes: 1024 * 1024,
|
|
9
|
+
maxParts: 2_000,
|
|
10
|
+
};
|
|
11
|
+
function isAsyncIterable(value) {
|
|
12
|
+
return Boolean(value &&
|
|
13
|
+
typeof value === 'object' &&
|
|
14
|
+
typeof value[Symbol.asyncIterator] === 'function');
|
|
15
|
+
}
|
|
16
|
+
async function* normalizeAsyncIterable(iterable, limits) {
|
|
17
|
+
for await (const value of iterable) {
|
|
18
|
+
yield normalizeJsonValue(value, limits);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function wrapToolSet(tools, limits) {
|
|
22
|
+
const wrapped = {};
|
|
23
|
+
for (const [name, tool] of Object.entries(tools)) {
|
|
24
|
+
const toolRecord = tool;
|
|
25
|
+
if (typeof toolRecord.execute !== 'function') {
|
|
26
|
+
wrapped[name] = tool;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const execute = toolRecord.execute;
|
|
30
|
+
wrapped[name] = {
|
|
31
|
+
...toolRecord,
|
|
32
|
+
execute(input, options) {
|
|
33
|
+
const output = execute.call(tool, input, options);
|
|
34
|
+
if (isAsyncIterable(output)) {
|
|
35
|
+
return normalizeAsyncIterable(output, limits);
|
|
36
|
+
}
|
|
37
|
+
return Promise.resolve(output).then((value) => normalizeJsonValue(value, limits));
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return wrapped;
|
|
42
|
+
}
|
|
43
|
+
function publicSnapshot(value) {
|
|
44
|
+
return deepFreeze(cloneSerializable(value));
|
|
45
|
+
}
|
|
46
|
+
function validateIdentifier(value, name) {
|
|
47
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
48
|
+
throw new FlexHarnessValidationError(`${name} must be a non-empty string.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function validateModelIdentity(identity) {
|
|
52
|
+
validateIdentifier(identity.provider, 'model identity provider');
|
|
53
|
+
validateIdentifier(identity.model, 'model identity model');
|
|
54
|
+
if (identity.displayName !== undefined) {
|
|
55
|
+
validateIdentifier(identity.displayName, 'model identity displayName');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function combineErrors(errors) {
|
|
59
|
+
if (errors.length === 1) {
|
|
60
|
+
return errors[0];
|
|
61
|
+
}
|
|
62
|
+
return new FlexHarnessRunError(errors);
|
|
63
|
+
}
|
|
64
|
+
function isAbortError(error) {
|
|
65
|
+
return (error instanceof FlexHarnessAbortError ||
|
|
66
|
+
(error instanceof DOMException && error.name === 'AbortError') ||
|
|
67
|
+
(error instanceof Error && error.name === 'AbortError'));
|
|
68
|
+
}
|
|
69
|
+
function makeUsage(result) {
|
|
70
|
+
return {
|
|
71
|
+
inputTokens: result.usage.inputTokens,
|
|
72
|
+
outputTokens: result.usage.outputTokens,
|
|
73
|
+
totalTokens: result.usage.totalTokens,
|
|
74
|
+
cacheReadTokens: result.usage.cacheReadTokens,
|
|
75
|
+
cacheWriteTokens: result.usage.cacheWriteTokens,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function base64Size(data) {
|
|
79
|
+
const compact = data.replace(/\s/g, '');
|
|
80
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(compact) || compact.length % 4 === 1) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return Buffer.from(compact, 'base64').byteLength;
|
|
84
|
+
}
|
|
85
|
+
function describeAttachment(part) {
|
|
86
|
+
let source = 'inline-base64';
|
|
87
|
+
let sizeBytes;
|
|
88
|
+
let inferredMediaType;
|
|
89
|
+
if (/^data:/i.test(part.data)) {
|
|
90
|
+
source = 'data-url';
|
|
91
|
+
const commaIndex = part.data.indexOf(',');
|
|
92
|
+
if (commaIndex >= 0) {
|
|
93
|
+
const metadata = part.data.slice(5, commaIndex);
|
|
94
|
+
const payload = part.data.slice(commaIndex + 1);
|
|
95
|
+
const metadataParts = metadata.split(';');
|
|
96
|
+
if (metadataParts[0]?.includes('/'))
|
|
97
|
+
inferredMediaType = metadataParts[0];
|
|
98
|
+
if (metadataParts.some((entry) => entry.toLowerCase() === 'base64')) {
|
|
99
|
+
sizeBytes = base64Size(payload);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
try {
|
|
103
|
+
sizeBytes = Buffer.byteLength(decodeURIComponent(payload));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Malformed URL encoding keeps size indeterminate without exposing the payload.
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
try {
|
|
113
|
+
const url = new URL(part.data);
|
|
114
|
+
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
115
|
+
source = 'remote-url';
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
sizeBytes = base64Size(part.data);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
sizeBytes = base64Size(part.data);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
source,
|
|
127
|
+
...(sizeBytes !== undefined ? { sizeBytes } : {}),
|
|
128
|
+
...(part.mediaType ?? inferredMediaType
|
|
129
|
+
? { mediaType: part.mediaType ?? inferredMediaType }
|
|
130
|
+
: {}),
|
|
131
|
+
...(part.name ? { name: part.name } : {}),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function validateUpdateSessionOptions(options) {
|
|
135
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
136
|
+
throw new FlexHarnessValidationError('updateSession options must be a plain object.');
|
|
137
|
+
}
|
|
138
|
+
const keys = Object.keys(options);
|
|
139
|
+
if (keys.length === 0) {
|
|
140
|
+
throw new FlexHarnessValidationError('updateSession requires title or archived.');
|
|
141
|
+
}
|
|
142
|
+
const unsupportedKey = keys.find((key) => key !== 'title' && key !== 'archived');
|
|
143
|
+
if (unsupportedKey) {
|
|
144
|
+
throw new FlexHarnessValidationError(`updateSession does not support "${unsupportedKey}".`);
|
|
145
|
+
}
|
|
146
|
+
if (Object.prototype.hasOwnProperty.call(options, 'title')) {
|
|
147
|
+
if (options.title !== null)
|
|
148
|
+
validateIdentifier(options.title, 'title');
|
|
149
|
+
}
|
|
150
|
+
if (Object.prototype.hasOwnProperty.call(options, 'archived') &&
|
|
151
|
+
typeof options.archived !== 'boolean') {
|
|
152
|
+
throw new FlexHarnessValidationError('archived must be a boolean.');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function resolveCallbackLimits(limits = {}) {
|
|
156
|
+
const resolved = {
|
|
157
|
+
maxEvents: limits.maxEvents ?? DEFAULT_CALLBACK_LIMITS.maxEvents,
|
|
158
|
+
maxOutputBytes: limits.maxOutputBytes ?? DEFAULT_CALLBACK_LIMITS.maxOutputBytes,
|
|
159
|
+
maxParts: limits.maxParts ?? DEFAULT_CALLBACK_LIMITS.maxParts,
|
|
160
|
+
};
|
|
161
|
+
for (const [name, value] of Object.entries(resolved)) {
|
|
162
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
163
|
+
throw new FlexHarnessValidationError(`callbackLimits.${name} must be a positive integer.`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return resolved;
|
|
167
|
+
}
|
|
168
|
+
export class FlexHarness {
|
|
169
|
+
scopeResolver;
|
|
170
|
+
modelResolver;
|
|
171
|
+
toolProvider;
|
|
172
|
+
store;
|
|
173
|
+
runner;
|
|
174
|
+
toolOutputLimits;
|
|
175
|
+
callbackLimits;
|
|
176
|
+
stateLoads = new Map();
|
|
177
|
+
listeners = new Set();
|
|
178
|
+
detachedToolCleanups = new Set();
|
|
179
|
+
sequence = 0;
|
|
180
|
+
closed = false;
|
|
181
|
+
disposePromise;
|
|
182
|
+
constructor(options) {
|
|
183
|
+
this.scopeResolver = options.scopeResolver;
|
|
184
|
+
this.modelResolver = options.modelResolver;
|
|
185
|
+
this.toolProvider = options.toolProvider;
|
|
186
|
+
this.store = options.store ?? new InMemoryFlexHarnessStore();
|
|
187
|
+
this.runner = options.runner ?? plugins.runAgent;
|
|
188
|
+
this.toolOutputLimits = resolveJsonLimits(options.toolOutputLimits);
|
|
189
|
+
this.callbackLimits = resolveCallbackLimits(options.callbackLimits);
|
|
190
|
+
}
|
|
191
|
+
async listSessions(scopeId) {
|
|
192
|
+
const { state } = await this.resolveState(scopeId);
|
|
193
|
+
await state.saveTail;
|
|
194
|
+
return publicSnapshot([...state.sessions.values()]
|
|
195
|
+
.map((entry) => entry.session)
|
|
196
|
+
.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)));
|
|
197
|
+
}
|
|
198
|
+
async createSession(scopeId, options = {}) {
|
|
199
|
+
const { state } = await this.resolveState(scopeId);
|
|
200
|
+
const sessionId = options.sessionId ?? plugins.crypto.randomUUID();
|
|
201
|
+
validateIdentifier(sessionId, 'sessionId');
|
|
202
|
+
if (options.title !== undefined) {
|
|
203
|
+
validateIdentifier(options.title, 'title');
|
|
204
|
+
}
|
|
205
|
+
const session = await this.mutateAndSave(state, () => {
|
|
206
|
+
if (state.sessions.has(sessionId)) {
|
|
207
|
+
throw new FlexHarnessValidationError(`Session "${sessionId}" already exists.`);
|
|
208
|
+
}
|
|
209
|
+
const timestamp = new Date().toISOString();
|
|
210
|
+
const nextSession = {
|
|
211
|
+
scopeId,
|
|
212
|
+
sessionId,
|
|
213
|
+
...(options.title ? { title: options.title } : {}),
|
|
214
|
+
createdAt: timestamp,
|
|
215
|
+
updatedAt: timestamp,
|
|
216
|
+
status: 'idle',
|
|
217
|
+
activity: { status: 'idle' },
|
|
218
|
+
};
|
|
219
|
+
state.sessions.set(sessionId, {
|
|
220
|
+
session: nextSession,
|
|
221
|
+
messages: [],
|
|
222
|
+
modelHistory: [],
|
|
223
|
+
rememberedPermissionKeys: new Set(),
|
|
224
|
+
});
|
|
225
|
+
return publicSnapshot(nextSession);
|
|
226
|
+
});
|
|
227
|
+
this.emitEvent(scopeId, sessionId, {
|
|
228
|
+
type: 'session.created',
|
|
229
|
+
session,
|
|
230
|
+
});
|
|
231
|
+
return session;
|
|
232
|
+
}
|
|
233
|
+
async getSession(scopeId, sessionId) {
|
|
234
|
+
const { state } = await this.resolveState(scopeId);
|
|
235
|
+
await state.saveTail;
|
|
236
|
+
return publicSnapshot(this.requireSession(state, sessionId).session);
|
|
237
|
+
}
|
|
238
|
+
async updateSession(scopeId, sessionId, options) {
|
|
239
|
+
validateUpdateSessionOptions(options);
|
|
240
|
+
const { state } = await this.resolveState(scopeId);
|
|
241
|
+
const session = await this.mutateAndSave(state, () => {
|
|
242
|
+
const stored = this.requireMutableSession(state, sessionId);
|
|
243
|
+
const timestamp = new Date().toISOString();
|
|
244
|
+
if (Object.prototype.hasOwnProperty.call(options, 'title')) {
|
|
245
|
+
if (options.title === null) {
|
|
246
|
+
delete stored.session.title;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
stored.session.title = options.title;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (options.archived === true) {
|
|
253
|
+
stored.session.archivedAt ??= timestamp;
|
|
254
|
+
}
|
|
255
|
+
else if (options.archived === false) {
|
|
256
|
+
delete stored.session.archivedAt;
|
|
257
|
+
}
|
|
258
|
+
stored.session.updatedAt = timestamp;
|
|
259
|
+
return publicSnapshot(stored.session);
|
|
260
|
+
});
|
|
261
|
+
this.emitEvent(scopeId, sessionId, {
|
|
262
|
+
type: 'session.updated',
|
|
263
|
+
session,
|
|
264
|
+
});
|
|
265
|
+
return session;
|
|
266
|
+
}
|
|
267
|
+
async deleteSession(scopeId, sessionId) {
|
|
268
|
+
const { state } = await this.resolveState(scopeId);
|
|
269
|
+
const session = await this.mutateAndSave(state, () => {
|
|
270
|
+
const stored = this.requireMutableSession(state, sessionId);
|
|
271
|
+
const deletedSession = publicSnapshot(stored.session);
|
|
272
|
+
state.sessions.delete(sessionId);
|
|
273
|
+
return deletedSession;
|
|
274
|
+
});
|
|
275
|
+
this.emitEvent(scopeId, sessionId, {
|
|
276
|
+
type: 'session.deleted',
|
|
277
|
+
session,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async getMessages(scopeId, sessionId) {
|
|
281
|
+
const { state } = await this.resolveState(scopeId);
|
|
282
|
+
await state.saveTail;
|
|
283
|
+
return publicSnapshot(this.requireSession(state, sessionId).messages);
|
|
284
|
+
}
|
|
285
|
+
async prompt(scopeId, sessionId, prompt, options = {}) {
|
|
286
|
+
const normalizedPrompt = normalizeFlexPrompt(prompt);
|
|
287
|
+
if (options.maxSteps !== undefined && (!Number.isSafeInteger(options.maxSteps) || options.maxSteps < 1)) {
|
|
288
|
+
throw new FlexHarnessValidationError('maxSteps must be a positive integer.');
|
|
289
|
+
}
|
|
290
|
+
const resolved = await this.resolveState(scopeId);
|
|
291
|
+
await resolved.state.saveTail;
|
|
292
|
+
this.assertOpen();
|
|
293
|
+
this.requireSession(resolved.state, sessionId);
|
|
294
|
+
if (resolved.state.activeRuns.has(sessionId)) {
|
|
295
|
+
throw new FlexHarnessSessionBusyError(sessionId);
|
|
296
|
+
}
|
|
297
|
+
const run = {
|
|
298
|
+
scopeId,
|
|
299
|
+
sessionId,
|
|
300
|
+
runId: plugins.crypto.randomUUID(),
|
|
301
|
+
userMessageId: plugins.crypto.randomUUID(),
|
|
302
|
+
assistantMessageId: plugins.crypto.randomUUID(),
|
|
303
|
+
controller: new AbortController(),
|
|
304
|
+
finalizer: Promise.reject(new Error('Run finalizer was not initialized.')),
|
|
305
|
+
callbackEventCount: 0,
|
|
306
|
+
callbackOutputBytes: 0,
|
|
307
|
+
callbackParts: [],
|
|
308
|
+
callbacksClosed: false,
|
|
309
|
+
previousHistory: [],
|
|
310
|
+
reasoningPartIds: new Map(),
|
|
311
|
+
toolPartIds: new Map(),
|
|
312
|
+
pendingPermissionIds: new Set(),
|
|
313
|
+
phase: 'resolving',
|
|
314
|
+
};
|
|
315
|
+
void run.finalizer.catch(() => undefined);
|
|
316
|
+
resolved.state.activeRuns.set(sessionId, run);
|
|
317
|
+
run.finalizer = this.executeRun(resolved, run, normalizedPrompt, options);
|
|
318
|
+
return run.finalizer;
|
|
319
|
+
}
|
|
320
|
+
async abort(scopeId, sessionId, reason) {
|
|
321
|
+
const { state } = await this.resolveState(scopeId);
|
|
322
|
+
const run = state.activeRuns.get(sessionId);
|
|
323
|
+
if (!run || run.phase === 'committing') {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
const error = new FlexHarnessAbortError(reason ?? 'The run was aborted by the caller.');
|
|
327
|
+
if (run.internalFailure === undefined)
|
|
328
|
+
run.ownerCancellation ??= error;
|
|
329
|
+
this.rejectRunPermissions(state, run, error);
|
|
330
|
+
run.controller.abort(error);
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
async listPendingPermissions(scopeId, sessionId) {
|
|
334
|
+
const { state } = await this.resolveState(scopeId);
|
|
335
|
+
await state.saveTail;
|
|
336
|
+
return publicSnapshot([...state.pendingPermissions.values()]
|
|
337
|
+
.map((pending) => pending.request)
|
|
338
|
+
.filter((request) => !sessionId || request.sessionId === sessionId)
|
|
339
|
+
.sort((left, right) => left.createdAt.localeCompare(right.createdAt)));
|
|
340
|
+
}
|
|
341
|
+
async respondToPermission(scopeId, sessionId, permissionId, decision) {
|
|
342
|
+
const { state } = await this.resolveState(scopeId);
|
|
343
|
+
const pending = state.pendingPermissions.get(permissionId);
|
|
344
|
+
if (!pending || pending.request.sessionId !== sessionId) {
|
|
345
|
+
throw new FlexHarnessNotFoundError('Permission', permissionId);
|
|
346
|
+
}
|
|
347
|
+
const response = pending.responseTail.then(() => this.applyPermissionResponse(state, pending, decision));
|
|
348
|
+
pending.responseTail = response.then(() => undefined, () => undefined);
|
|
349
|
+
return response;
|
|
350
|
+
}
|
|
351
|
+
subscribe(listener) {
|
|
352
|
+
this.assertOpen();
|
|
353
|
+
this.listeners.add(listener);
|
|
354
|
+
let subscribed = true;
|
|
355
|
+
return () => {
|
|
356
|
+
if (!subscribed)
|
|
357
|
+
return;
|
|
358
|
+
subscribed = false;
|
|
359
|
+
this.listeners.delete(listener);
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
async dispose() {
|
|
363
|
+
if (this.disposePromise) {
|
|
364
|
+
return this.disposePromise;
|
|
365
|
+
}
|
|
366
|
+
this.closed = true;
|
|
367
|
+
this.disposePromise = this.disposeInternal();
|
|
368
|
+
return this.disposePromise;
|
|
369
|
+
}
|
|
370
|
+
async disposeInternal() {
|
|
371
|
+
const states = (await Promise.allSettled([...this.stateLoads.values()])).flatMap((result) => (result.status === 'fulfilled' ? [result.value] : []));
|
|
372
|
+
const finalizers = [];
|
|
373
|
+
for (const state of states) {
|
|
374
|
+
for (const run of state.activeRuns.values()) {
|
|
375
|
+
finalizers.push(run.finalizer);
|
|
376
|
+
if (run.phase === 'committing')
|
|
377
|
+
continue;
|
|
378
|
+
const error = new FlexHarnessAbortError('The run was aborted because FlexHarness was disposed.');
|
|
379
|
+
if (run.internalFailure === undefined)
|
|
380
|
+
run.ownerCancellation ??= error;
|
|
381
|
+
this.rejectRunPermissions(state, run, error);
|
|
382
|
+
run.controller.abort(error);
|
|
383
|
+
}
|
|
384
|
+
for (const pending of [...state.pendingPermissions.values()]) {
|
|
385
|
+
this.rejectPending(state, pending, new FlexHarnessAbortError('Permission was rejected because FlexHarness was disposed.'));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const results = await Promise.allSettled(finalizers);
|
|
389
|
+
await Promise.all(states.map((state) => state.saveTail));
|
|
390
|
+
const detachedCleanupResults = await Promise.allSettled([...this.detachedToolCleanups]);
|
|
391
|
+
this.listeners.clear();
|
|
392
|
+
this.stateLoads.clear();
|
|
393
|
+
this.detachedToolCleanups.clear();
|
|
394
|
+
for (const state of states) {
|
|
395
|
+
state.sessions.clear();
|
|
396
|
+
state.activeRuns.clear();
|
|
397
|
+
state.pendingPermissions.clear();
|
|
398
|
+
}
|
|
399
|
+
const unexpectedErrors = [];
|
|
400
|
+
for (const result of results) {
|
|
401
|
+
if (result.status === 'fulfilled')
|
|
402
|
+
continue;
|
|
403
|
+
if (result.reason instanceof FlexHarnessRunError) {
|
|
404
|
+
for (const error of result.reason.errors) {
|
|
405
|
+
if (!isAbortError(error))
|
|
406
|
+
unexpectedErrors.push(error);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (!isAbortError(result.reason)) {
|
|
410
|
+
unexpectedErrors.push(result.reason);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
for (const result of detachedCleanupResults) {
|
|
414
|
+
if (result.status === 'rejected')
|
|
415
|
+
unexpectedErrors.push(result.reason);
|
|
416
|
+
}
|
|
417
|
+
if (unexpectedErrors.length > 0) {
|
|
418
|
+
throw combineErrors(unexpectedErrors);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
async executeRun(resolved, run, prompt, options) {
|
|
422
|
+
let modelResolution;
|
|
423
|
+
let toolHandle;
|
|
424
|
+
let result;
|
|
425
|
+
let serializedResultMessages;
|
|
426
|
+
let originalError;
|
|
427
|
+
let reserved = false;
|
|
428
|
+
try {
|
|
429
|
+
const reservation = await this.reserveRun(resolved.state, run, prompt);
|
|
430
|
+
reserved = true;
|
|
431
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
432
|
+
type: 'run.started',
|
|
433
|
+
runId: run.runId,
|
|
434
|
+
messageId: run.userMessageId,
|
|
435
|
+
session: reservation.session,
|
|
436
|
+
});
|
|
437
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
438
|
+
type: 'message.created',
|
|
439
|
+
runId: run.runId,
|
|
440
|
+
messageId: run.userMessageId,
|
|
441
|
+
message: reservation.userMessage,
|
|
442
|
+
});
|
|
443
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
444
|
+
type: 'message.created',
|
|
445
|
+
runId: run.runId,
|
|
446
|
+
messageId: run.assistantMessageId,
|
|
447
|
+
message: reservation.assistantMessage,
|
|
448
|
+
});
|
|
449
|
+
const modelOutcome = Promise.resolve()
|
|
450
|
+
.then(() => this.modelResolver.resolveModel({
|
|
451
|
+
scopeId: run.scopeId,
|
|
452
|
+
scope: resolved.scope.scope,
|
|
453
|
+
sessionId: run.sessionId,
|
|
454
|
+
runId: run.runId,
|
|
455
|
+
...(options.modelHint ? { modelHint: options.modelHint } : {}),
|
|
456
|
+
signal: run.controller.signal,
|
|
457
|
+
}))
|
|
458
|
+
.then((value) => ({ source: 'model', success: true, value }), (error) => ({ source: 'model', success: false, error }));
|
|
459
|
+
const toolOutcome = Promise.resolve()
|
|
460
|
+
.then(() => this.toolProvider
|
|
461
|
+
? this.toolProvider.provideTools({
|
|
462
|
+
scopeId: run.scopeId,
|
|
463
|
+
scope: resolved.scope.scope,
|
|
464
|
+
sessionId: run.sessionId,
|
|
465
|
+
runId: run.runId,
|
|
466
|
+
signal: run.controller.signal,
|
|
467
|
+
requestPermission: (request) => this.requestPermission(resolved.state, run, request),
|
|
468
|
+
})
|
|
469
|
+
: undefined)
|
|
470
|
+
.then((value) => ({ source: 'tools', success: true, value }), (error) => ({ source: 'tools', success: false, error }));
|
|
471
|
+
let resolveAbort;
|
|
472
|
+
const abortOutcome = new Promise((resolve) => {
|
|
473
|
+
resolveAbort = resolve;
|
|
474
|
+
});
|
|
475
|
+
const onResolverAbort = () => {
|
|
476
|
+
resolveAbort({
|
|
477
|
+
source: 'abort',
|
|
478
|
+
success: false,
|
|
479
|
+
error: run.controller.signal.reason ?? new FlexHarnessAbortError(),
|
|
480
|
+
});
|
|
481
|
+
};
|
|
482
|
+
run.controller.signal.addEventListener('abort', onResolverAbort, { once: true });
|
|
483
|
+
if (run.controller.signal.aborted)
|
|
484
|
+
onResolverAbort();
|
|
485
|
+
const firstResolver = await Promise.race([modelOutcome, toolOutcome, abortOutcome]);
|
|
486
|
+
if (!firstResolver.success) {
|
|
487
|
+
run.controller.signal.removeEventListener('abort', onResolverAbort);
|
|
488
|
+
if (firstResolver.source !== 'abort') {
|
|
489
|
+
this.abortRunInternally(run, firstResolver.error);
|
|
490
|
+
}
|
|
491
|
+
if (firstResolver.source !== 'tools') {
|
|
492
|
+
this.observeDetachedToolProvider(toolOutcome);
|
|
493
|
+
}
|
|
494
|
+
throw firstResolver.error;
|
|
495
|
+
}
|
|
496
|
+
if (firstResolver.source === 'model') {
|
|
497
|
+
modelResolution = firstResolver.value;
|
|
498
|
+
try {
|
|
499
|
+
validateModelIdentity(modelResolution.identity);
|
|
500
|
+
}
|
|
501
|
+
catch (error) {
|
|
502
|
+
run.controller.signal.removeEventListener('abort', onResolverAbort);
|
|
503
|
+
this.abortRunInternally(run, error);
|
|
504
|
+
this.observeDetachedToolProvider(toolOutcome);
|
|
505
|
+
throw error;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
toolHandle = firstResolver.value;
|
|
510
|
+
}
|
|
511
|
+
const secondResolver = await Promise.race([
|
|
512
|
+
firstResolver.source === 'model' ? toolOutcome : modelOutcome,
|
|
513
|
+
abortOutcome,
|
|
514
|
+
]);
|
|
515
|
+
run.controller.signal.removeEventListener('abort', onResolverAbort);
|
|
516
|
+
if (!secondResolver.success) {
|
|
517
|
+
if (secondResolver.source !== 'abort') {
|
|
518
|
+
this.abortRunInternally(run, secondResolver.error);
|
|
519
|
+
}
|
|
520
|
+
if (firstResolver.source === 'model' && secondResolver.source === 'abort') {
|
|
521
|
+
this.observeDetachedToolProvider(toolOutcome);
|
|
522
|
+
}
|
|
523
|
+
throw secondResolver.error;
|
|
524
|
+
}
|
|
525
|
+
if (secondResolver.source === 'model') {
|
|
526
|
+
modelResolution = secondResolver.value;
|
|
527
|
+
try {
|
|
528
|
+
validateModelIdentity(modelResolution.identity);
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
this.abortRunInternally(run, error);
|
|
532
|
+
throw error;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
toolHandle = secondResolver.value;
|
|
537
|
+
}
|
|
538
|
+
if (run.controller.signal.aborted) {
|
|
539
|
+
throw run.controller.signal.reason;
|
|
540
|
+
}
|
|
541
|
+
const runnerOptions = {
|
|
542
|
+
model: modelResolution.model,
|
|
543
|
+
prompt: prompt.agentPrompt,
|
|
544
|
+
messages: hydrateAgentMessages(run.previousHistory),
|
|
545
|
+
sessionId: run.sessionId,
|
|
546
|
+
abort: run.controller.signal,
|
|
547
|
+
...(options.system ?? modelResolution.system
|
|
548
|
+
? { system: options.system ?? modelResolution.system }
|
|
549
|
+
: {}),
|
|
550
|
+
...(toolHandle ? { tools: wrapToolSet(toolHandle.tools, this.toolOutputLimits) } : {}),
|
|
551
|
+
...(modelResolution.providerOptions
|
|
552
|
+
? { providerOptions: modelResolution.providerOptions }
|
|
553
|
+
: {}),
|
|
554
|
+
...(modelResolution.cache !== undefined ? { cache: modelResolution.cache } : {}),
|
|
555
|
+
...(options.maxSteps ?? modelResolution.maxSteps
|
|
556
|
+
? { maxSteps: options.maxSteps ?? modelResolution.maxSteps }
|
|
557
|
+
: {}),
|
|
558
|
+
onToken: (delta) => this.onTextDelta(run, delta),
|
|
559
|
+
onReasoningStart: (id) => this.onReasoningStart(run, id),
|
|
560
|
+
onReasoningDelta: (id, delta) => this.onReasoningDelta(run, id, delta),
|
|
561
|
+
onReasoningEnd: (id, text) => this.onReasoningEnd(run, id, text),
|
|
562
|
+
onToolCallStart: (event) => this.onToolStart(run, event),
|
|
563
|
+
onToolCallFinish: (event) => this.onToolFinish(run, event),
|
|
564
|
+
};
|
|
565
|
+
run.phase = 'running';
|
|
566
|
+
result = await this.runner(runnerOptions);
|
|
567
|
+
if (run.callbackError) {
|
|
568
|
+
throw run.callbackError;
|
|
569
|
+
}
|
|
570
|
+
if (run.controller.signal.aborted) {
|
|
571
|
+
throw run.controller.signal.reason;
|
|
572
|
+
}
|
|
573
|
+
serializedResultMessages = serializeAgentMessages(result.messages);
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
originalError = error ?? new Error('The run failed without an error value.');
|
|
577
|
+
}
|
|
578
|
+
run.callbacksClosed = true;
|
|
579
|
+
run.phase = 'closing';
|
|
580
|
+
if (run.callbackError && originalError !== run.callbackError) {
|
|
581
|
+
originalError = originalError === undefined
|
|
582
|
+
? run.callbackError
|
|
583
|
+
: combineErrors([originalError, run.callbackError]);
|
|
584
|
+
}
|
|
585
|
+
if (originalError !== undefined && run.ownerCancellation === undefined) {
|
|
586
|
+
run.internalFailure ??= originalError;
|
|
587
|
+
}
|
|
588
|
+
if (!reserved) {
|
|
589
|
+
resolved.state.activeRuns.delete(run.sessionId);
|
|
590
|
+
throw originalError;
|
|
591
|
+
}
|
|
592
|
+
this.rejectRunPermissions(resolved.state, run, originalError ??
|
|
593
|
+
run.ownerCancellation ??
|
|
594
|
+
new FlexHarnessAbortError('The run ended before permission was resolved.'));
|
|
595
|
+
const closeResult = await Promise.allSettled([
|
|
596
|
+
Promise.resolve().then(() => toolHandle?.close?.()),
|
|
597
|
+
]).then(([settled]) => settled);
|
|
598
|
+
const errorsBeforePersistence = [];
|
|
599
|
+
if (originalError !== undefined)
|
|
600
|
+
errorsBeforePersistence.push(originalError);
|
|
601
|
+
if (originalError === undefined &&
|
|
602
|
+
run.ownerCancellation !== undefined) {
|
|
603
|
+
errorsBeforePersistence.push(run.ownerCancellation);
|
|
604
|
+
}
|
|
605
|
+
if (closeResult.status === 'rejected') {
|
|
606
|
+
errorsBeforePersistence.push(closeResult.reason);
|
|
607
|
+
run.internalFailure ??= closeResult.reason;
|
|
608
|
+
}
|
|
609
|
+
run.phase = 'committing';
|
|
610
|
+
if (originalError === undefined &&
|
|
611
|
+
run.ownerCancellation !== undefined &&
|
|
612
|
+
!errorsBeforePersistence.includes(run.ownerCancellation)) {
|
|
613
|
+
errorsBeforePersistence.push(run.ownerCancellation);
|
|
614
|
+
}
|
|
615
|
+
const cancelled = run.ownerCancellation !== undefined && run.internalFailure === undefined;
|
|
616
|
+
const terminalError = errorsBeforePersistence.length > 0
|
|
617
|
+
? combineErrors(errorsBeforePersistence)
|
|
618
|
+
: undefined;
|
|
619
|
+
const persistenceResult = await Promise.allSettled([this.finalizeRun(resolved.state, run, prompt, modelResolution, result, serializedResultMessages, terminalError, cancelled)]).then(([settled]) => settled);
|
|
620
|
+
if (persistenceResult.status === 'rejected') {
|
|
621
|
+
const allErrors = [...errorsBeforePersistence, persistenceResult.reason];
|
|
622
|
+
const combinedError = combineErrors(allErrors);
|
|
623
|
+
const fallback = this.applyRunFinalState(resolved.state, run, prompt, modelResolution, result, serializedResultMessages, combinedError, cancelled);
|
|
624
|
+
resolved.state.activeRuns.delete(run.sessionId);
|
|
625
|
+
this.emitFinalMutationEvents(run, fallback);
|
|
626
|
+
this.emitFinalRunEvent(run, fallback.assistantMessage, combinedError, cancelled);
|
|
627
|
+
throw combinedError;
|
|
628
|
+
}
|
|
629
|
+
const finalized = persistenceResult.value;
|
|
630
|
+
resolved.state.activeRuns.delete(run.sessionId);
|
|
631
|
+
this.emitFinalRunEvent(run, finalized.assistantMessage, terminalError, cancelled);
|
|
632
|
+
if (terminalError !== undefined)
|
|
633
|
+
throw terminalError;
|
|
634
|
+
return {
|
|
635
|
+
runId: run.runId,
|
|
636
|
+
sessionId: run.sessionId,
|
|
637
|
+
userMessage: finalized.userMessage,
|
|
638
|
+
assistantMessage: finalized.assistantMessage,
|
|
639
|
+
model: publicSnapshot(modelResolution.identity),
|
|
640
|
+
usage: publicSnapshot(makeUsage(result)),
|
|
641
|
+
finishReason: result.finishReason,
|
|
642
|
+
steps: result.steps,
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
async reserveRun(state, run, prompt) {
|
|
646
|
+
return this.mutateAndSave(state, () => {
|
|
647
|
+
const stored = this.requireSession(state, run.sessionId);
|
|
648
|
+
const timestamp = new Date().toISOString();
|
|
649
|
+
run.previousHistory = cloneSerializable(stored.modelHistory);
|
|
650
|
+
const userMessage = {
|
|
651
|
+
messageId: run.userMessageId,
|
|
652
|
+
sessionId: run.sessionId,
|
|
653
|
+
runId: run.runId,
|
|
654
|
+
role: 'user',
|
|
655
|
+
status: 'streaming',
|
|
656
|
+
createdAt: timestamp,
|
|
657
|
+
parts: prompt.parts.map((part) => {
|
|
658
|
+
if (part.type === 'text') {
|
|
659
|
+
return {
|
|
660
|
+
partId: plugins.crypto.randomUUID(),
|
|
661
|
+
type: 'text',
|
|
662
|
+
text: part.text,
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
const attachment = {
|
|
666
|
+
partId: plugins.crypto.randomUUID(),
|
|
667
|
+
type: 'attachment',
|
|
668
|
+
attachmentType: part.type,
|
|
669
|
+
...describeAttachment(part),
|
|
670
|
+
};
|
|
671
|
+
return attachment;
|
|
672
|
+
}),
|
|
673
|
+
};
|
|
674
|
+
const assistantMessage = {
|
|
675
|
+
messageId: run.assistantMessageId,
|
|
676
|
+
sessionId: run.sessionId,
|
|
677
|
+
runId: run.runId,
|
|
678
|
+
role: 'assistant',
|
|
679
|
+
status: 'streaming',
|
|
680
|
+
createdAt: timestamp,
|
|
681
|
+
parts: [],
|
|
682
|
+
};
|
|
683
|
+
stored.messages.push(userMessage, assistantMessage);
|
|
684
|
+
stored.session.status = 'running';
|
|
685
|
+
stored.session.activity = {
|
|
686
|
+
runId: run.runId,
|
|
687
|
+
status: 'running',
|
|
688
|
+
startedAt: timestamp,
|
|
689
|
+
};
|
|
690
|
+
stored.session.updatedAt = timestamp;
|
|
691
|
+
return {
|
|
692
|
+
session: publicSnapshot(stored.session),
|
|
693
|
+
userMessage: publicSnapshot(userMessage),
|
|
694
|
+
assistantMessage: publicSnapshot(assistantMessage),
|
|
695
|
+
};
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
async finalizeRun(state, run, prompt, model, result, serializedResultMessages, originalError, cancelled) {
|
|
699
|
+
const final = await this.mutateAndSave(state, () => this.applyRunFinalState(state, run, prompt, model, result, serializedResultMessages, originalError, cancelled));
|
|
700
|
+
this.emitFinalMutationEvents(run, final);
|
|
701
|
+
return final;
|
|
702
|
+
}
|
|
703
|
+
applyRunFinalState(state, run, prompt, model, result, serializedResultMessages, originalError, cancelled) {
|
|
704
|
+
const stored = this.requireSession(state, run.sessionId);
|
|
705
|
+
const userMessage = this.requireMessage(stored, run.userMessageId);
|
|
706
|
+
const assistantMessage = this.requireMessage(stored, run.assistantMessageId);
|
|
707
|
+
assistantMessage.parts = cloneSerializable(run.callbackParts);
|
|
708
|
+
const timestamp = new Date().toISOString();
|
|
709
|
+
const terminalParts = [];
|
|
710
|
+
const success = originalError === undefined &&
|
|
711
|
+
!cancelled &&
|
|
712
|
+
model !== undefined &&
|
|
713
|
+
result !== undefined &&
|
|
714
|
+
serializedResultMessages !== undefined;
|
|
715
|
+
for (const part of assistantMessage.parts) {
|
|
716
|
+
if (part.type === 'reasoning' && part.status === 'running') {
|
|
717
|
+
part.status = success ? 'completed' : 'cancelled';
|
|
718
|
+
terminalParts.push(publicSnapshot(part));
|
|
719
|
+
}
|
|
720
|
+
if (part.type === 'tool' && part.status === 'running') {
|
|
721
|
+
part.status = success ? 'failed' : cancelled ? 'cancelled' : 'failed';
|
|
722
|
+
part.error = success
|
|
723
|
+
? 'Tool execution ended without a terminal event.'
|
|
724
|
+
: cancelled
|
|
725
|
+
? 'Tool execution was cancelled.'
|
|
726
|
+
: errorMessage(originalError);
|
|
727
|
+
terminalParts.push(publicSnapshot(part));
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (success) {
|
|
731
|
+
if (!assistantMessage.parts.some((part) => part.type === 'text')) {
|
|
732
|
+
assistantMessage.parts.push({
|
|
733
|
+
partId: plugins.crypto.randomUUID(),
|
|
734
|
+
type: 'text',
|
|
735
|
+
text: result.text,
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
const usage = makeUsage(result);
|
|
739
|
+
userMessage.status = 'completed';
|
|
740
|
+
userMessage.completedAt = timestamp;
|
|
741
|
+
assistantMessage.status = 'completed';
|
|
742
|
+
assistantMessage.completedAt = timestamp;
|
|
743
|
+
assistantMessage.model = cloneSerializable(model.identity);
|
|
744
|
+
assistantMessage.usage = usage;
|
|
745
|
+
stored.modelHistory = [
|
|
746
|
+
...run.previousHistory,
|
|
747
|
+
cloneSerializable(prompt.modelMessage),
|
|
748
|
+
...serializedResultMessages,
|
|
749
|
+
];
|
|
750
|
+
stored.session.status = 'idle';
|
|
751
|
+
stored.session.activity = {
|
|
752
|
+
runId: run.runId,
|
|
753
|
+
status: 'idle',
|
|
754
|
+
startedAt: stored.session.activity.startedAt,
|
|
755
|
+
completedAt: timestamp,
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
const status = cancelled ? 'cancelled' : 'failed';
|
|
760
|
+
const message = errorMessage(originalError);
|
|
761
|
+
userMessage.status = status;
|
|
762
|
+
userMessage.completedAt = timestamp;
|
|
763
|
+
userMessage.error = message;
|
|
764
|
+
assistantMessage.status = status;
|
|
765
|
+
assistantMessage.completedAt = timestamp;
|
|
766
|
+
assistantMessage.error = message;
|
|
767
|
+
if (model)
|
|
768
|
+
assistantMessage.model = cloneSerializable(model.identity);
|
|
769
|
+
stored.session.status = status;
|
|
770
|
+
stored.session.activity = {
|
|
771
|
+
runId: run.runId,
|
|
772
|
+
status,
|
|
773
|
+
startedAt: stored.session.activity.startedAt,
|
|
774
|
+
completedAt: timestamp,
|
|
775
|
+
error: message,
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
stored.session.updatedAt = timestamp;
|
|
779
|
+
return {
|
|
780
|
+
userMessage: publicSnapshot(userMessage),
|
|
781
|
+
assistantMessage: publicSnapshot(assistantMessage),
|
|
782
|
+
terminalParts,
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
emitFinalMutationEvents(run, final) {
|
|
786
|
+
for (const part of final.terminalParts) {
|
|
787
|
+
this.emitPartEvent(run, 'part.completed', part);
|
|
788
|
+
}
|
|
789
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
790
|
+
type: 'message.updated',
|
|
791
|
+
runId: run.runId,
|
|
792
|
+
messageId: run.userMessageId,
|
|
793
|
+
message: final.userMessage,
|
|
794
|
+
});
|
|
795
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
796
|
+
type: 'message.updated',
|
|
797
|
+
runId: run.runId,
|
|
798
|
+
messageId: run.assistantMessageId,
|
|
799
|
+
message: final.assistantMessage,
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
emitFinalRunEvent(run, message, error, cancelled) {
|
|
803
|
+
const status = error
|
|
804
|
+
? cancelled
|
|
805
|
+
? 'cancelled'
|
|
806
|
+
: 'failed'
|
|
807
|
+
: 'completed';
|
|
808
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
809
|
+
type: 'run.finished',
|
|
810
|
+
runId: run.runId,
|
|
811
|
+
messageId: run.assistantMessageId,
|
|
812
|
+
status,
|
|
813
|
+
message,
|
|
814
|
+
...(error !== undefined ? { error: errorToInfo(error) } : {}),
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
onTextDelta(run, delta) {
|
|
818
|
+
if (!delta || run.callbacksClosed || run.callbackError)
|
|
819
|
+
return;
|
|
820
|
+
const lastPart = run.callbackParts.at(-1);
|
|
821
|
+
const created = lastPart?.type !== 'text';
|
|
822
|
+
const byteLength = Buffer.byteLength(delta);
|
|
823
|
+
if (!this.reserveCallbackCapacity(run, created ? 2 : 1, byteLength, created ? 1 : 0))
|
|
824
|
+
return;
|
|
825
|
+
const part = lastPart?.type === 'text'
|
|
826
|
+
? lastPart
|
|
827
|
+
: { partId: plugins.crypto.randomUUID(), type: 'text', text: '' };
|
|
828
|
+
if (created)
|
|
829
|
+
run.callbackParts.push(part);
|
|
830
|
+
part.text += delta;
|
|
831
|
+
if (created)
|
|
832
|
+
this.emitPartEvent(run, 'part.started', part);
|
|
833
|
+
this.emitPartEvent(run, 'part.delta', part, delta);
|
|
834
|
+
}
|
|
835
|
+
onReasoningStart(run, id) {
|
|
836
|
+
if (run.callbacksClosed || run.callbackError || run.reasoningPartIds.has(id))
|
|
837
|
+
return;
|
|
838
|
+
if (!this.reserveCallbackCapacity(run, 1, 0, 1))
|
|
839
|
+
return;
|
|
840
|
+
const part = {
|
|
841
|
+
partId: plugins.crypto.randomUUID(),
|
|
842
|
+
type: 'reasoning',
|
|
843
|
+
text: '',
|
|
844
|
+
status: 'running',
|
|
845
|
+
};
|
|
846
|
+
run.reasoningPartIds.set(id, part.partId);
|
|
847
|
+
run.callbackParts.push(part);
|
|
848
|
+
this.emitPartEvent(run, 'part.started', part);
|
|
849
|
+
}
|
|
850
|
+
onReasoningDelta(run, id, delta) {
|
|
851
|
+
if (run.callbacksClosed || run.callbackError || !delta)
|
|
852
|
+
return;
|
|
853
|
+
if (!run.reasoningPartIds.has(id))
|
|
854
|
+
this.onReasoningStart(run, id);
|
|
855
|
+
const partId = run.reasoningPartIds.get(id);
|
|
856
|
+
if (!partId || run.callbackError)
|
|
857
|
+
return;
|
|
858
|
+
const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'reasoning');
|
|
859
|
+
if (!part || part.type !== 'reasoning' || part.status !== 'running')
|
|
860
|
+
return;
|
|
861
|
+
if (!this.reserveCallbackCapacity(run, 1, Buffer.byteLength(delta), 0))
|
|
862
|
+
return;
|
|
863
|
+
part.text += delta;
|
|
864
|
+
this.emitPartEvent(run, 'part.delta', part, delta);
|
|
865
|
+
}
|
|
866
|
+
onReasoningEnd(run, id, text) {
|
|
867
|
+
if (run.callbacksClosed || run.callbackError)
|
|
868
|
+
return;
|
|
869
|
+
if (!run.reasoningPartIds.has(id))
|
|
870
|
+
this.onReasoningStart(run, id);
|
|
871
|
+
const partId = run.reasoningPartIds.get(id);
|
|
872
|
+
if (!partId || run.callbackError)
|
|
873
|
+
return;
|
|
874
|
+
const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'reasoning');
|
|
875
|
+
if (!part || part.type !== 'reasoning' || part.status !== 'running')
|
|
876
|
+
return;
|
|
877
|
+
const missingText = part.text.length === 0 ? text : '';
|
|
878
|
+
if (!this.reserveCallbackCapacity(run, 1, Buffer.byteLength(missingText), 0))
|
|
879
|
+
return;
|
|
880
|
+
if (missingText)
|
|
881
|
+
part.text = missingText;
|
|
882
|
+
part.status = 'completed';
|
|
883
|
+
this.emitPartEvent(run, 'part.completed', part);
|
|
884
|
+
}
|
|
885
|
+
onToolStart(run, event) {
|
|
886
|
+
if (run.callbacksClosed || run.callbackError || run.toolPartIds.has(event.toolCallId))
|
|
887
|
+
return;
|
|
888
|
+
const input = normalizeJsonValue(event.input, this.toolOutputLimits);
|
|
889
|
+
const byteLength = Buffer.byteLength(JSON.stringify(input));
|
|
890
|
+
if (!this.reserveCallbackCapacity(run, 1, byteLength, 1))
|
|
891
|
+
return;
|
|
892
|
+
const part = {
|
|
893
|
+
partId: plugins.crypto.randomUUID(),
|
|
894
|
+
type: 'tool',
|
|
895
|
+
toolCallId: event.toolCallId,
|
|
896
|
+
toolName: event.toolName,
|
|
897
|
+
status: 'running',
|
|
898
|
+
input,
|
|
899
|
+
};
|
|
900
|
+
run.toolPartIds.set(event.toolCallId, part.partId);
|
|
901
|
+
run.callbackParts.push(part);
|
|
902
|
+
this.emitPartEvent(run, 'part.started', part);
|
|
903
|
+
}
|
|
904
|
+
onToolFinish(run, event) {
|
|
905
|
+
if (run.callbacksClosed || run.callbackError)
|
|
906
|
+
return;
|
|
907
|
+
if (!run.toolPartIds.has(event.toolCallId))
|
|
908
|
+
this.onToolStart(run, event);
|
|
909
|
+
const partId = run.toolPartIds.get(event.toolCallId);
|
|
910
|
+
if (!partId || run.callbackError)
|
|
911
|
+
return;
|
|
912
|
+
const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'tool');
|
|
913
|
+
if (!part || part.type !== 'tool' || part.status !== 'running')
|
|
914
|
+
return;
|
|
915
|
+
const output = event.success
|
|
916
|
+
? normalizeJsonValue(event.output, this.toolOutputLimits)
|
|
917
|
+
: undefined;
|
|
918
|
+
const byteLength = event.success
|
|
919
|
+
? Buffer.byteLength(JSON.stringify(output))
|
|
920
|
+
: Buffer.byteLength(event.error);
|
|
921
|
+
if (!this.reserveCallbackCapacity(run, 1, byteLength, 0))
|
|
922
|
+
return;
|
|
923
|
+
if (event.success) {
|
|
924
|
+
part.status = 'completed';
|
|
925
|
+
part.output = output;
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
part.status = 'failed';
|
|
929
|
+
part.error = event.error;
|
|
930
|
+
}
|
|
931
|
+
this.emitPartEvent(run, 'part.completed', part);
|
|
932
|
+
}
|
|
933
|
+
reserveCallbackCapacity(run, eventCount, outputBytes, partCount) {
|
|
934
|
+
const nextEvents = run.callbackEventCount + eventCount;
|
|
935
|
+
const nextOutputBytes = run.callbackOutputBytes + outputBytes;
|
|
936
|
+
const nextParts = run.callbackParts.length + partCount;
|
|
937
|
+
if (nextEvents > this.callbackLimits.maxEvents ||
|
|
938
|
+
nextOutputBytes > this.callbackLimits.maxOutputBytes ||
|
|
939
|
+
nextParts > this.callbackLimits.maxParts) {
|
|
940
|
+
const error = new FlexHarnessCallbackOverflowError(`Callback buffer exceeded its limit (${nextEvents} events, ${nextOutputBytes} bytes, ${nextParts} parts).`);
|
|
941
|
+
run.callbackError = error;
|
|
942
|
+
this.abortRunInternally(run, error);
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
run.callbackEventCount = nextEvents;
|
|
946
|
+
run.callbackOutputBytes = nextOutputBytes;
|
|
947
|
+
return true;
|
|
948
|
+
}
|
|
949
|
+
async requestPermission(state, run, input) {
|
|
950
|
+
validateIdentifier(input.kind, 'permission kind');
|
|
951
|
+
validateIdentifier(input.description, 'permission description');
|
|
952
|
+
if (input.rememberKey !== undefined)
|
|
953
|
+
validateIdentifier(input.rememberKey, 'rememberKey');
|
|
954
|
+
if (input.toolCallId !== undefined)
|
|
955
|
+
validateIdentifier(input.toolCallId, 'toolCallId');
|
|
956
|
+
if (run.controller.signal.aborted) {
|
|
957
|
+
throw run.controller.signal.reason;
|
|
958
|
+
}
|
|
959
|
+
await state.saveTail;
|
|
960
|
+
if (run.controller.signal.aborted) {
|
|
961
|
+
throw run.controller.signal.reason;
|
|
962
|
+
}
|
|
963
|
+
if (state.activeRuns.get(run.sessionId) !== run ||
|
|
964
|
+
run.callbacksClosed ||
|
|
965
|
+
run.phase === 'closing' ||
|
|
966
|
+
run.phase === 'committing') {
|
|
967
|
+
throw new FlexHarnessPermissionStateError(`Run "${run.runId}" no longer accepts permission requests.`);
|
|
968
|
+
}
|
|
969
|
+
const stored = this.requireSession(state, run.sessionId);
|
|
970
|
+
if (input.rememberKey && stored.rememberedPermissionKeys.has(input.rememberKey)) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
const request = {
|
|
974
|
+
permissionId: plugins.crypto.randomUUID(),
|
|
975
|
+
scopeId: run.scopeId,
|
|
976
|
+
sessionId: run.sessionId,
|
|
977
|
+
runId: run.runId,
|
|
978
|
+
kind: input.kind,
|
|
979
|
+
description: input.description,
|
|
980
|
+
...(input.toolCallId ? { toolCallId: input.toolCallId } : {}),
|
|
981
|
+
...(input.rememberKey ? { rememberKey: input.rememberKey } : {}),
|
|
982
|
+
...(input.metadata !== undefined ? { metadata: cloneSerializable(input.metadata) } : {}),
|
|
983
|
+
createdAt: new Date().toISOString(),
|
|
984
|
+
};
|
|
985
|
+
let resolvePermission;
|
|
986
|
+
let rejectPermission;
|
|
987
|
+
const permissionPromise = new Promise((resolve, reject) => {
|
|
988
|
+
resolvePermission = resolve;
|
|
989
|
+
rejectPermission = reject;
|
|
990
|
+
});
|
|
991
|
+
void permissionPromise.catch(() => undefined);
|
|
992
|
+
const abortListener = () => {
|
|
993
|
+
const pending = state.pendingPermissions.get(request.permissionId);
|
|
994
|
+
if (pending)
|
|
995
|
+
this.rejectPending(state, pending, run.controller.signal.reason);
|
|
996
|
+
};
|
|
997
|
+
const pending = {
|
|
998
|
+
request,
|
|
999
|
+
run,
|
|
1000
|
+
resolve: resolvePermission,
|
|
1001
|
+
reject: rejectPermission,
|
|
1002
|
+
settled: false,
|
|
1003
|
+
responding: false,
|
|
1004
|
+
responseTail: Promise.resolve(),
|
|
1005
|
+
abortListener,
|
|
1006
|
+
};
|
|
1007
|
+
state.pendingPermissions.set(request.permissionId, pending);
|
|
1008
|
+
run.pendingPermissionIds.add(request.permissionId);
|
|
1009
|
+
run.controller.signal.addEventListener('abort', abortListener, { once: true });
|
|
1010
|
+
try {
|
|
1011
|
+
await this.mutateAndSave(state, () => {
|
|
1012
|
+
const current = this.requireSession(state, run.sessionId);
|
|
1013
|
+
current.session.status = 'waiting_permission';
|
|
1014
|
+
current.session.activity.status = 'waiting_permission';
|
|
1015
|
+
current.session.updatedAt = new Date().toISOString();
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
catch (error) {
|
|
1019
|
+
state.pendingPermissions.delete(request.permissionId);
|
|
1020
|
+
run.pendingPermissionIds.delete(request.permissionId);
|
|
1021
|
+
run.controller.signal.removeEventListener('abort', abortListener);
|
|
1022
|
+
throw error;
|
|
1023
|
+
}
|
|
1024
|
+
if (pending.settled) {
|
|
1025
|
+
return permissionPromise;
|
|
1026
|
+
}
|
|
1027
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
1028
|
+
type: 'permission.requested',
|
|
1029
|
+
runId: run.runId,
|
|
1030
|
+
request: publicSnapshot(request),
|
|
1031
|
+
});
|
|
1032
|
+
return permissionPromise;
|
|
1033
|
+
}
|
|
1034
|
+
async applyPermissionResponse(state, pending, decision) {
|
|
1035
|
+
if (pending.settled) {
|
|
1036
|
+
throw new FlexHarnessPermissionStateError(`Permission "${pending.request.permissionId}" has already been resolved.`);
|
|
1037
|
+
}
|
|
1038
|
+
if (!['once', 'always', 'reject'].includes(decision)) {
|
|
1039
|
+
throw new FlexHarnessPermissionStateError(`Unknown permission decision "${decision}".`);
|
|
1040
|
+
}
|
|
1041
|
+
if (decision === 'always' && !pending.request.rememberKey) {
|
|
1042
|
+
throw new FlexHarnessPermissionStateError('The always decision requires the permission request to provide rememberKey.');
|
|
1043
|
+
}
|
|
1044
|
+
const rememberKey = pending.request.rememberKey;
|
|
1045
|
+
let addedRememberKey = false;
|
|
1046
|
+
pending.responding = true;
|
|
1047
|
+
try {
|
|
1048
|
+
await this.mutateAndSave(state, () => {
|
|
1049
|
+
const stored = this.requireSession(state, pending.request.sessionId);
|
|
1050
|
+
if (decision === 'always' && rememberKey) {
|
|
1051
|
+
addedRememberKey = !stored.rememberedPermissionKeys.has(rememberKey);
|
|
1052
|
+
stored.rememberedPermissionKeys.add(rememberKey);
|
|
1053
|
+
}
|
|
1054
|
+
const hasOtherPending = [...state.pendingPermissions.values()].some((entry) => entry !== pending &&
|
|
1055
|
+
!entry.settled &&
|
|
1056
|
+
entry.request.sessionId === pending.request.sessionId);
|
|
1057
|
+
stored.session.status = hasOtherPending ? 'waiting_permission' : 'running';
|
|
1058
|
+
stored.session.activity.status = hasOtherPending ? 'waiting_permission' : 'running';
|
|
1059
|
+
stored.session.updatedAt = new Date().toISOString();
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
catch (error) {
|
|
1063
|
+
pending.responding = false;
|
|
1064
|
+
if (pending.abortReason !== undefined) {
|
|
1065
|
+
const abortReason = pending.abortReason;
|
|
1066
|
+
this.forceRejectPending(state, pending, abortReason);
|
|
1067
|
+
throw combineErrors([abortReason, error]);
|
|
1068
|
+
}
|
|
1069
|
+
throw error;
|
|
1070
|
+
}
|
|
1071
|
+
if (pending.abortReason !== undefined) {
|
|
1072
|
+
const abortReason = pending.abortReason;
|
|
1073
|
+
const rollbackPromise = addedRememberKey && rememberKey
|
|
1074
|
+
? this.mutateAndSave(state, () => {
|
|
1075
|
+
this.requireSession(state, pending.request.sessionId).rememberedPermissionKeys.delete(rememberKey);
|
|
1076
|
+
})
|
|
1077
|
+
: Promise.resolve();
|
|
1078
|
+
pending.responding = false;
|
|
1079
|
+
this.forceRejectPending(state, pending, abortReason);
|
|
1080
|
+
try {
|
|
1081
|
+
await rollbackPromise;
|
|
1082
|
+
}
|
|
1083
|
+
catch (rollbackError) {
|
|
1084
|
+
throw combineErrors([abortReason, rollbackError]);
|
|
1085
|
+
}
|
|
1086
|
+
throw abortReason;
|
|
1087
|
+
}
|
|
1088
|
+
pending.settled = true;
|
|
1089
|
+
pending.responding = false;
|
|
1090
|
+
state.pendingPermissions.delete(pending.request.permissionId);
|
|
1091
|
+
pending.run.pendingPermissionIds.delete(pending.request.permissionId);
|
|
1092
|
+
pending.run.controller.signal.removeEventListener('abort', pending.abortListener);
|
|
1093
|
+
this.emitEvent(pending.request.scopeId, pending.request.sessionId, {
|
|
1094
|
+
type: 'permission.resolved',
|
|
1095
|
+
runId: pending.request.runId,
|
|
1096
|
+
request: publicSnapshot(pending.request),
|
|
1097
|
+
decision,
|
|
1098
|
+
});
|
|
1099
|
+
if (decision === 'reject') {
|
|
1100
|
+
pending.reject(new FlexHarnessPermissionRejectedError(pending.request.permissionId));
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
pending.resolve();
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
rejectRunPermissions(state, run, error) {
|
|
1107
|
+
for (const permissionId of [...run.pendingPermissionIds]) {
|
|
1108
|
+
const pending = state.pendingPermissions.get(permissionId);
|
|
1109
|
+
if (pending)
|
|
1110
|
+
this.rejectPending(state, pending, error);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
rejectPending(state, pending, error) {
|
|
1114
|
+
if (pending.settled)
|
|
1115
|
+
return;
|
|
1116
|
+
if (pending.responding) {
|
|
1117
|
+
pending.abortReason ??= error;
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
this.forceRejectPending(state, pending, error);
|
|
1121
|
+
}
|
|
1122
|
+
forceRejectPending(state, pending, error) {
|
|
1123
|
+
if (pending.settled)
|
|
1124
|
+
return;
|
|
1125
|
+
pending.settled = true;
|
|
1126
|
+
state.pendingPermissions.delete(pending.request.permissionId);
|
|
1127
|
+
pending.run.pendingPermissionIds.delete(pending.request.permissionId);
|
|
1128
|
+
pending.run.controller.signal.removeEventListener('abort', pending.abortListener);
|
|
1129
|
+
pending.reject(error);
|
|
1130
|
+
}
|
|
1131
|
+
emitPartEvent(run, type, part, delta) {
|
|
1132
|
+
this.emitEvent(run.scopeId, run.sessionId, {
|
|
1133
|
+
type,
|
|
1134
|
+
runId: run.runId,
|
|
1135
|
+
messageId: run.assistantMessageId,
|
|
1136
|
+
partId: part.partId,
|
|
1137
|
+
part: publicSnapshot(part),
|
|
1138
|
+
...(delta !== undefined ? { delta } : {}),
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
abortRunInternally(run, error) {
|
|
1142
|
+
run.internalFailure ??= error ?? new Error('Internal FlexHarness run failure.');
|
|
1143
|
+
if (!run.controller.signal.aborted) {
|
|
1144
|
+
run.controller.abort(run.internalFailure);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
observeDetachedToolProvider(outcomePromise) {
|
|
1148
|
+
const cleanup = outcomePromise.then(async (outcome) => {
|
|
1149
|
+
if (outcome.success && outcome.source === 'tools' && outcome.value?.close) {
|
|
1150
|
+
await Promise.resolve().then(() => outcome.value.close());
|
|
1151
|
+
}
|
|
1152
|
+
});
|
|
1153
|
+
this.detachedToolCleanups.add(cleanup);
|
|
1154
|
+
void cleanup.then(() => this.detachedToolCleanups.delete(cleanup), () => undefined);
|
|
1155
|
+
}
|
|
1156
|
+
emitEvent(scopeId, sessionId, details) {
|
|
1157
|
+
const event = deepFreeze(cloneSerializable({
|
|
1158
|
+
eventId: plugins.crypto.randomUUID(),
|
|
1159
|
+
sequence: ++this.sequence,
|
|
1160
|
+
timestamp: new Date().toISOString(),
|
|
1161
|
+
scopeId,
|
|
1162
|
+
sessionId,
|
|
1163
|
+
...details,
|
|
1164
|
+
}));
|
|
1165
|
+
for (const listener of this.listeners) {
|
|
1166
|
+
try {
|
|
1167
|
+
listener(event);
|
|
1168
|
+
}
|
|
1169
|
+
catch {
|
|
1170
|
+
// Listener failures are isolated from the run and from other listeners.
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
async resolveState(scopeId) {
|
|
1175
|
+
this.assertOpen();
|
|
1176
|
+
validateIdentifier(scopeId, 'scopeId');
|
|
1177
|
+
const scope = await this.scopeResolver.resolveScope(scopeId);
|
|
1178
|
+
this.assertOpen();
|
|
1179
|
+
validateIdentifier(scope.storageKey, 'resolved storageKey');
|
|
1180
|
+
let stateLoad = this.stateLoads.get(scope.storageKey);
|
|
1181
|
+
if (!stateLoad) {
|
|
1182
|
+
stateLoad = this.loadState(scope.storageKey);
|
|
1183
|
+
this.stateLoads.set(scope.storageKey, stateLoad);
|
|
1184
|
+
void stateLoad.catch(() => {
|
|
1185
|
+
if (this.stateLoads.get(scope.storageKey) === stateLoad) {
|
|
1186
|
+
this.stateLoads.delete(scope.storageKey);
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
const state = await stateLoad;
|
|
1191
|
+
this.assertOpen();
|
|
1192
|
+
return { scope, state };
|
|
1193
|
+
}
|
|
1194
|
+
async loadState(storageKey) {
|
|
1195
|
+
const loaded = await this.store.load(storageKey);
|
|
1196
|
+
if (loaded)
|
|
1197
|
+
assertFlexHarnessSnapshot(loaded);
|
|
1198
|
+
const snapshot = loaded ? cloneSerializable(loaded) : undefined;
|
|
1199
|
+
const sessions = new Map();
|
|
1200
|
+
const timestamp = new Date().toISOString();
|
|
1201
|
+
for (const stored of snapshot?.sessions ?? []) {
|
|
1202
|
+
if (stored.session.status === 'running' || stored.session.status === 'waiting_permission') {
|
|
1203
|
+
stored.session.status = 'idle';
|
|
1204
|
+
stored.session.activity = { status: 'idle' };
|
|
1205
|
+
stored.session.updatedAt = timestamp;
|
|
1206
|
+
}
|
|
1207
|
+
for (const message of stored.messages) {
|
|
1208
|
+
if (message.status === 'streaming') {
|
|
1209
|
+
message.status = 'cancelled';
|
|
1210
|
+
message.completedAt = timestamp;
|
|
1211
|
+
message.error = 'The process stopped before this message completed.';
|
|
1212
|
+
}
|
|
1213
|
+
for (const part of message.parts) {
|
|
1214
|
+
if (part.type === 'reasoning' && part.status === 'running') {
|
|
1215
|
+
part.status = 'cancelled';
|
|
1216
|
+
}
|
|
1217
|
+
if (part.type === 'tool' && part.status === 'running') {
|
|
1218
|
+
part.status = 'cancelled';
|
|
1219
|
+
part.error = 'The process stopped before this tool call completed.';
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
sessions.set(stored.session.sessionId, {
|
|
1224
|
+
session: stored.session,
|
|
1225
|
+
messages: stored.messages,
|
|
1226
|
+
modelHistory: stored.modelHistory,
|
|
1227
|
+
rememberedPermissionKeys: new Set(stored.rememberedPermissionKeys),
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
return {
|
|
1231
|
+
storageKey,
|
|
1232
|
+
revision: snapshot?.revision ?? 0,
|
|
1233
|
+
sessions,
|
|
1234
|
+
activeRuns: new Map(),
|
|
1235
|
+
pendingPermissions: new Map(),
|
|
1236
|
+
saveTail: Promise.resolve(),
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
mutateAndSave(state, mutation) {
|
|
1240
|
+
const operation = state.saveTail.then(async () => {
|
|
1241
|
+
const beforeMutation = this.createSnapshot(state, state.revision);
|
|
1242
|
+
try {
|
|
1243
|
+
const result = mutation();
|
|
1244
|
+
const expectedRevision = state.revision;
|
|
1245
|
+
const snapshot = this.createSnapshot(state, expectedRevision + 1);
|
|
1246
|
+
assertFlexHarnessSnapshot(snapshot);
|
|
1247
|
+
await this.store.save(state.storageKey, snapshot, expectedRevision);
|
|
1248
|
+
state.revision = snapshot.revision;
|
|
1249
|
+
return result;
|
|
1250
|
+
}
|
|
1251
|
+
catch (error) {
|
|
1252
|
+
this.restorePersistentState(state, beforeMutation);
|
|
1253
|
+
throw error;
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
state.saveTail = operation.then(() => undefined, () => undefined);
|
|
1257
|
+
return operation;
|
|
1258
|
+
}
|
|
1259
|
+
restorePersistentState(state, snapshot) {
|
|
1260
|
+
state.revision = snapshot.revision;
|
|
1261
|
+
state.sessions.clear();
|
|
1262
|
+
for (const stored of snapshot.sessions) {
|
|
1263
|
+
state.sessions.set(stored.session.sessionId, {
|
|
1264
|
+
session: cloneSerializable(stored.session),
|
|
1265
|
+
messages: cloneSerializable(stored.messages),
|
|
1266
|
+
modelHistory: cloneSerializable(stored.modelHistory),
|
|
1267
|
+
rememberedPermissionKeys: new Set(stored.rememberedPermissionKeys),
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
createSnapshot(state, revision) {
|
|
1272
|
+
const sessions = [...state.sessions.values()]
|
|
1273
|
+
.sort((left, right) => left.session.sessionId.localeCompare(right.session.sessionId))
|
|
1274
|
+
.map((stored) => ({
|
|
1275
|
+
session: cloneSerializable(stored.session),
|
|
1276
|
+
messages: cloneSerializable(stored.messages),
|
|
1277
|
+
modelHistory: cloneSerializable(stored.modelHistory),
|
|
1278
|
+
rememberedPermissionKeys: [...stored.rememberedPermissionKeys].sort(),
|
|
1279
|
+
}));
|
|
1280
|
+
return {
|
|
1281
|
+
schemaVersion: 1,
|
|
1282
|
+
revision,
|
|
1283
|
+
sessions,
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
requireSession(state, sessionId) {
|
|
1287
|
+
validateIdentifier(sessionId, 'sessionId');
|
|
1288
|
+
const session = state.sessions.get(sessionId);
|
|
1289
|
+
if (!session)
|
|
1290
|
+
throw new FlexHarnessNotFoundError('Session', sessionId);
|
|
1291
|
+
return session;
|
|
1292
|
+
}
|
|
1293
|
+
requireMessage(stored, messageId) {
|
|
1294
|
+
const message = stored.messages.find((entry) => entry.messageId === messageId);
|
|
1295
|
+
if (!message)
|
|
1296
|
+
throw new FlexHarnessNotFoundError('Message', messageId);
|
|
1297
|
+
return message;
|
|
1298
|
+
}
|
|
1299
|
+
requireMutableSession(state, sessionId) {
|
|
1300
|
+
const stored = this.requireSession(state, sessionId);
|
|
1301
|
+
const hasPendingPermission = [...state.pendingPermissions.values()].some((pending) => !pending.settled && pending.request.sessionId === sessionId);
|
|
1302
|
+
if (state.activeRuns.has(sessionId) || hasPendingPermission) {
|
|
1303
|
+
throw new FlexHarnessSessionBusyError(sessionId, 'cannot be changed while it has an active run or pending permission');
|
|
1304
|
+
}
|
|
1305
|
+
return stored;
|
|
1306
|
+
}
|
|
1307
|
+
assertOpen() {
|
|
1308
|
+
if (this.closed)
|
|
1309
|
+
throw new FlexHarnessClosedError();
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZmxleGhhcm5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixnQ0FBZ0MsRUFDaEMsc0JBQXNCLEVBQ3RCLHdCQUF3QixFQUN4QixrQ0FBa0MsRUFDbEMsK0JBQStCLEVBQy9CLG1CQUFtQixFQUNuQiwyQkFBMkIsRUFDM0IsMEJBQTBCLEVBQzFCLFlBQVksRUFDWixXQUFXLEdBQ1osTUFBTSxhQUFhLENBQUM7QUFtQ3JCLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQy9ELE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsaUJBQWlCLEVBQ2pCLFVBQVUsRUFDVixrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLHNCQUFzQixHQUN2QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsbUJBQW1CLEdBRXBCLE1BQU0sbUJBQW1CLENBQUM7QUF5RTNCLE1BQU0sdUJBQXVCLEdBQWtDO0lBQzdELFNBQVMsRUFBRSxNQUFNO0lBQ2pCLGNBQWMsRUFBRSxJQUFJLEdBQUcsSUFBSTtJQUMzQixRQUFRLEVBQUUsS0FBSztDQUNoQixDQUFDO0FBRUYsU0FBUyxlQUFlLENBQUMsS0FBYztJQUNyQyxPQUFPLE9BQU8sQ0FDWixLQUFLO1FBQ0gsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN6QixPQUFRLEtBQThDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLFVBQVUsQ0FDOUYsQ0FBQztBQUNKLENBQUM7QUFFRCxLQUFLLFNBQVMsQ0FBQyxDQUFDLHNCQUFzQixDQUNwQyxRQUFnQyxFQUNoQyxNQUErRTtJQUUvRSxJQUFJLEtBQUssRUFBRSxNQUFNLEtBQUssSUFBSSxRQUFRLEVB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
|