@modelprofile.com/flexharness 10.24.0 → 10.24.1
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.admission.d.ts +17 -0
- package/dist_ts/classes.flexharness.admission.js +263 -0
- package/dist_ts/classes.flexharness.callbacks.d.ts +38 -0
- package/dist_ts/classes.flexharness.callbacks.js +313 -0
- package/dist_ts/classes.flexharness.compaction.d.ts +25 -0
- package/dist_ts/classes.flexharness.compaction.js +87 -0
- package/dist_ts/classes.flexharness.configurations.d.ts +11 -0
- package/dist_ts/classes.flexharness.configurations.js +137 -0
- package/dist_ts/classes.flexharness.core.d.ts +143 -0
- package/dist_ts/classes.flexharness.core.js +1538 -0
- package/dist_ts/classes.flexharness.d.ts +2 -437
- package/dist_ts/classes.flexharness.deletion.d.ts +31 -0
- package/dist_ts/classes.flexharness.deletion.js +396 -0
- package/dist_ts/classes.flexharness.imports.d.ts +24 -0
- package/dist_ts/classes.flexharness.imports.js +345 -0
- package/dist_ts/classes.flexharness.js +119 -9776
- package/dist_ts/classes.flexharness.lifecycle.d.ts +47 -0
- package/dist_ts/classes.flexharness.lifecycle.js +625 -0
- package/dist_ts/classes.flexharness.permissions.d.ts +19 -0
- package/dist_ts/classes.flexharness.permissions.js +450 -0
- package/dist_ts/classes.flexharness.projects.d.ts +55 -0
- package/dist_ts/classes.flexharness.projects.js +575 -0
- package/dist_ts/classes.flexharness.prompts.d.ts +44 -0
- package/dist_ts/classes.flexharness.prompts.js +659 -0
- package/dist_ts/classes.flexharness.providers.d.ts +18 -0
- package/dist_ts/classes.flexharness.providers.js +267 -0
- package/dist_ts/classes.flexharness.results.d.ts +26 -0
- package/dist_ts/classes.flexharness.results.js +89 -0
- package/dist_ts/classes.flexharness.reversions.d.ts +52 -0
- package/dist_ts/classes.flexharness.reversions.js +1306 -0
- package/dist_ts/classes.flexharness.runs.d.ts +63 -0
- package/dist_ts/classes.flexharness.runs.js +1058 -0
- package/dist_ts/classes.flexharness.sessions.d.ts +20 -0
- package/dist_ts/classes.flexharness.sessions.js +381 -0
- package/dist_ts/classes.flexharness.slashcommands.d.ts +40 -0
- package/dist_ts/classes.flexharness.slashcommands.js +458 -0
- package/dist_ts/classes.flexharness.subagents.d.ts +31 -0
- package/dist_ts/classes.flexharness.subagents.js +690 -0
- package/dist_ts/classes.flexharness.tooldispatch.d.ts +53 -0
- package/dist_ts/classes.flexharness.tooldispatch.js +418 -0
- package/dist_ts/interfaces.flexharness.d.ts +455 -0
- package/dist_ts/interfaces.flexharness.js +2 -0
- package/dist_ts/utils.flexharness.d.ts +19 -0
- package/dist_ts/utils.flexharness.js +83 -0
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.admission.ts +331 -0
- package/ts/classes.flexharness.callbacks.ts +352 -0
- package/ts/classes.flexharness.compaction.ts +167 -0
- package/ts/classes.flexharness.configurations.ts +167 -0
- package/ts/classes.flexharness.core.ts +1830 -0
- package/ts/classes.flexharness.deletion.ts +616 -0
- package/ts/classes.flexharness.imports.ts +414 -0
- package/ts/classes.flexharness.lifecycle.ts +786 -0
- package/ts/classes.flexharness.permissions.ts +535 -0
- package/ts/classes.flexharness.projects.ts +1006 -0
- package/ts/classes.flexharness.prompts.ts +857 -0
- package/ts/classes.flexharness.providers.ts +322 -0
- package/ts/classes.flexharness.results.ts +98 -0
- package/ts/classes.flexharness.reversions.ts +1684 -0
- package/ts/classes.flexharness.runs.ts +1204 -0
- package/ts/classes.flexharness.sessions.ts +483 -0
- package/ts/classes.flexharness.slashcommands.ts +705 -0
- package/ts/classes.flexharness.subagents.ts +860 -0
- package/ts/classes.flexharness.tooldispatch.ts +475 -0
- package/ts/classes.flexharness.ts +147 -12567
- package/ts/interfaces.flexharness.ts +517 -0
- package/ts/utils.flexharness.ts +121 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IFlexToolHandle, IFlexToolProviderContext } from './interfaces.js';
|
|
2
|
+
import type { IStorageState, IActiveRun, IResolverOutcome } from './interfaces.flexharness.js';
|
|
3
|
+
import type { FlexHarnessCore } from './classes.flexharness.core.js';
|
|
4
|
+
/** Tool provider plumbing: run tool handles, resource tool providers and detached cleanups. */
|
|
5
|
+
export declare class FlexHarnessToolProviders<TScope> {
|
|
6
|
+
private readonly core;
|
|
7
|
+
constructor(core: FlexHarnessCore<TScope>);
|
|
8
|
+
normalizeToolHandle(run: IActiveRun, handle: IFlexToolHandle | undefined): IFlexToolHandle | undefined;
|
|
9
|
+
provideRunToolHandle(run: IActiveRun, context: Readonly<IFlexToolProviderContext<TScope>>): Promise<IFlexToolHandle | undefined>;
|
|
10
|
+
private normalizeResourceToolProviderDescriptors;
|
|
11
|
+
closePartialToolHandle(handle: IFlexToolHandle, run: IActiveRun): Promise<void>;
|
|
12
|
+
private retainDetachedCleanup;
|
|
13
|
+
observeDetachedToolProvider(outcome: Promise<IResolverOutcome<IFlexToolHandle | undefined>>, run: IActiveRun): void;
|
|
14
|
+
private trackDetachedCleanup;
|
|
15
|
+
private runDetachedCleanup;
|
|
16
|
+
beginDetachedCleanupSettlement(state: IStorageState): Promise<void>[];
|
|
17
|
+
settleDetachedCleanups(state: IStorageState, attempts: readonly Promise<void>[]): Promise<Error[]>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { FlexHarnessValidationError } from './errors.js';
|
|
2
|
+
import { requireSessionGeneration, createFlexResourceIdentityDigest, createFlexResourceToolNamespace, createFlexResourceToolName, combineErrors, } from './utils.flexharness.js';
|
|
3
|
+
const maxResourceToolProviders = 128;
|
|
4
|
+
/** Tool provider plumbing: run tool handles, resource tool providers and detached cleanups. */
|
|
5
|
+
export class FlexHarnessToolProviders {
|
|
6
|
+
core;
|
|
7
|
+
constructor(core) {
|
|
8
|
+
this.core = core;
|
|
9
|
+
}
|
|
10
|
+
normalizeToolHandle(run, handle) {
|
|
11
|
+
if (handle === undefined)
|
|
12
|
+
return undefined;
|
|
13
|
+
let close;
|
|
14
|
+
try {
|
|
15
|
+
close = handle.close;
|
|
16
|
+
if (close !== undefined && typeof close !== 'function') {
|
|
17
|
+
throw new FlexHarnessValidationError('Tool handle close must be a function.');
|
|
18
|
+
}
|
|
19
|
+
const tools = handle.tools;
|
|
20
|
+
this.core.runs.assertNoBuiltInToolCollisions(run, tools);
|
|
21
|
+
const catalog = handle.catalog;
|
|
22
|
+
if (catalog !== undefined && (typeof catalog !== 'object' || catalog === null)) {
|
|
23
|
+
throw new FlexHarnessValidationError('Tool handle catalog must be an object.');
|
|
24
|
+
}
|
|
25
|
+
const isReadOnlyToolCall = handle.isReadOnlyToolCall;
|
|
26
|
+
if (isReadOnlyToolCall !== undefined && typeof isReadOnlyToolCall !== 'function') {
|
|
27
|
+
throw new FlexHarnessValidationError('Tool handle isReadOnlyToolCall must be a function.');
|
|
28
|
+
}
|
|
29
|
+
const closeHandle = close;
|
|
30
|
+
return {
|
|
31
|
+
tools,
|
|
32
|
+
...(catalog === undefined ? {} : { catalog }),
|
|
33
|
+
...(isReadOnlyToolCall === undefined ? {} : {
|
|
34
|
+
isReadOnlyToolCall: (call) => isReadOnlyToolCall.call(handle, call),
|
|
35
|
+
}),
|
|
36
|
+
...(closeHandle ? { close: () => closeHandle.call(handle) } : {}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (close)
|
|
41
|
+
this.trackDetachedCleanup(run.state, run, () => close.call(handle));
|
|
42
|
+
throw this.core.projectExternalError(run, error, 'toolProvider');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async provideRunToolHandle(run, context) {
|
|
46
|
+
if (!this.core.resourceToolProviderResolver)
|
|
47
|
+
return this.core.toolProvider?.provideTools(context);
|
|
48
|
+
const resolverContext = Object.freeze({
|
|
49
|
+
scopeId: context.scopeId,
|
|
50
|
+
scope: context.scope,
|
|
51
|
+
sessionId: context.sessionId,
|
|
52
|
+
...requireSessionGeneration(run.stored.session),
|
|
53
|
+
runId: context.runId,
|
|
54
|
+
...(context.parentSessionId === undefined ? {} : { parentSessionId: context.parentSessionId }),
|
|
55
|
+
...(context.agent === undefined ? {} : { agent: context.agent }),
|
|
56
|
+
signal: context.signal,
|
|
57
|
+
});
|
|
58
|
+
const resolved = await this.core.resourceToolProviderResolver.resolveResourceToolProviders(resolverContext);
|
|
59
|
+
const descriptors = this.normalizeResourceToolProviderDescriptors(resolved);
|
|
60
|
+
const owned = [];
|
|
61
|
+
const tools = Object.create(null);
|
|
62
|
+
/** The handle and own name of each exposed resource tool, for the handle's classifier. */
|
|
63
|
+
const resourceTools = new Map();
|
|
64
|
+
const closeOwned = async () => {
|
|
65
|
+
const errors = [];
|
|
66
|
+
for (const entry of [...owned].reverse()) {
|
|
67
|
+
if (entry.closed || !entry.handle.close)
|
|
68
|
+
continue;
|
|
69
|
+
try {
|
|
70
|
+
await entry.handle.close();
|
|
71
|
+
entry.closed = true;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
errors.push(error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (errors.length > 0)
|
|
78
|
+
throw combineErrors(errors);
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
context.signal.throwIfAborted();
|
|
82
|
+
const applicationHandle = this.normalizeToolHandle(run, await this.core.toolProvider?.provideTools(context));
|
|
83
|
+
if (applicationHandle) {
|
|
84
|
+
owned.push({ handle: applicationHandle, closed: false });
|
|
85
|
+
for (const [toolName, tool] of Object.entries(applicationHandle.tools)) {
|
|
86
|
+
tools[toolName] = tool;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (const descriptor of descriptors) {
|
|
90
|
+
context.signal.throwIfAborted();
|
|
91
|
+
const namespace = createFlexResourceToolNamespace(descriptor.resourceId, descriptor.attachmentRevision);
|
|
92
|
+
const resourceIdentity = createFlexResourceIdentityDigest(descriptor.resourceId, descriptor.attachmentRevision);
|
|
93
|
+
const resourceContext = Object.freeze({
|
|
94
|
+
...context,
|
|
95
|
+
requestPermission: (request) => context.requestPermission({
|
|
96
|
+
...request,
|
|
97
|
+
kind: `resource.${resourceIdentity}.${request.kind}`,
|
|
98
|
+
...(request.rememberKey === undefined
|
|
99
|
+
? {}
|
|
100
|
+
: { rememberKey: `resource:${resourceIdentity}:${request.rememberKey}` }),
|
|
101
|
+
metadata: {
|
|
102
|
+
resourceId: descriptor.resourceId,
|
|
103
|
+
attachmentRevision: descriptor.attachmentRevision,
|
|
104
|
+
resourceIdentity,
|
|
105
|
+
toolNamespace: namespace,
|
|
106
|
+
...(request.metadata === undefined ? {} : { providerMetadata: request.metadata }),
|
|
107
|
+
},
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
110
|
+
const handle = this.normalizeToolHandle(run, await descriptor.provider.provideTools(resourceContext));
|
|
111
|
+
if (!handle)
|
|
112
|
+
continue;
|
|
113
|
+
owned.push({ handle, closed: false });
|
|
114
|
+
if (handle.catalog !== undefined) {
|
|
115
|
+
throw new FlexHarnessValidationError('Resource tool providers cannot supply a tool catalog.');
|
|
116
|
+
}
|
|
117
|
+
for (const [toolName, tool] of Object.entries(handle.tools)) {
|
|
118
|
+
const exposedName = createFlexResourceToolName(namespace, toolName);
|
|
119
|
+
if (Object.prototype.hasOwnProperty.call(tools, exposedName)) {
|
|
120
|
+
throw new FlexHarnessValidationError(`Duplicate exposed tool "${exposedName}".`);
|
|
121
|
+
}
|
|
122
|
+
tools[exposedName] = tool;
|
|
123
|
+
resourceTools.set(exposedName, { handle, toolName });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (owned.length === 0 && Object.keys(tools).length === 0)
|
|
127
|
+
return undefined;
|
|
128
|
+
const classifies = applicationHandle?.isReadOnlyToolCall !== undefined
|
|
129
|
+
|| [...resourceTools.values()].some((entry) => entry.handle.isReadOnlyToolCall !== undefined);
|
|
130
|
+
return {
|
|
131
|
+
tools: tools,
|
|
132
|
+
...(applicationHandle?.catalog === undefined ? {} : { catalog: applicationHandle.catalog }),
|
|
133
|
+
...(classifies ? {
|
|
134
|
+
isReadOnlyToolCall: ({ toolName, input }) => {
|
|
135
|
+
const resource = resourceTools.get(toolName);
|
|
136
|
+
return resource
|
|
137
|
+
? resource.handle.isReadOnlyToolCall?.({ toolName: resource.toolName, input }) === true
|
|
138
|
+
: applicationHandle?.isReadOnlyToolCall?.({ toolName, input }) === true;
|
|
139
|
+
},
|
|
140
|
+
} : {}),
|
|
141
|
+
...(owned.some((entry) => entry.handle.close) ? { close: closeOwned } : {}),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (owned.some((entry) => entry.handle.close && !entry.closed)) {
|
|
146
|
+
try {
|
|
147
|
+
await this.closePartialToolHandle({ tools: {}, close: closeOwned }, run);
|
|
148
|
+
}
|
|
149
|
+
catch (cleanupError) {
|
|
150
|
+
throw combineErrors([error, cleanupError]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
normalizeResourceToolProviderDescriptors(descriptors) {
|
|
157
|
+
if (!Array.isArray(descriptors) || descriptors.length > maxResourceToolProviders) {
|
|
158
|
+
throw new FlexHarnessValidationError(`Resource tool providers must be an array with at most ${maxResourceToolProviders} descriptors.`);
|
|
159
|
+
}
|
|
160
|
+
const resourceIds = new Set();
|
|
161
|
+
const namespaces = new Set();
|
|
162
|
+
return descriptors.map((descriptor, index) => {
|
|
163
|
+
if (!descriptor
|
|
164
|
+
|| typeof descriptor !== 'object'
|
|
165
|
+
|| Array.isArray(descriptor)
|
|
166
|
+
|| ![Object.prototype, null].includes(Object.getPrototypeOf(descriptor))) {
|
|
167
|
+
throw new FlexHarnessValidationError(`Resource tool provider descriptor ${index} is invalid.`);
|
|
168
|
+
}
|
|
169
|
+
const unsupported = Object.keys(descriptor).find((key) => !['resourceId', 'attachmentRevision', 'provider'].includes(key));
|
|
170
|
+
if (unsupported) {
|
|
171
|
+
throw new FlexHarnessValidationError(`Resource tool provider descriptor ${index} does not support "${unsupported}".`);
|
|
172
|
+
}
|
|
173
|
+
const resourceId = descriptor.resourceId;
|
|
174
|
+
const attachmentRevision = descriptor.attachmentRevision;
|
|
175
|
+
const provider = descriptor.provider;
|
|
176
|
+
const provideTools = provider?.provideTools;
|
|
177
|
+
const namespace = createFlexResourceToolNamespace(resourceId, attachmentRevision);
|
|
178
|
+
if (resourceIds.has(resourceId)) {
|
|
179
|
+
throw new FlexHarnessValidationError(`Duplicate resourceId "${resourceId}".`);
|
|
180
|
+
}
|
|
181
|
+
if (namespaces.has(namespace)) {
|
|
182
|
+
throw new FlexHarnessValidationError(`Duplicate resource tool namespace "${namespace}".`);
|
|
183
|
+
}
|
|
184
|
+
if (!provider || typeof provideTools !== 'function') {
|
|
185
|
+
throw new FlexHarnessValidationError(`Resource tool provider descriptor ${index} has no tool provider.`);
|
|
186
|
+
}
|
|
187
|
+
resourceIds.add(resourceId);
|
|
188
|
+
namespaces.add(namespace);
|
|
189
|
+
return {
|
|
190
|
+
resourceId,
|
|
191
|
+
attachmentRevision,
|
|
192
|
+
provider: {
|
|
193
|
+
provideTools: (context) => provideTools.call(provider, context),
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async closePartialToolHandle(handle, run) {
|
|
199
|
+
try {
|
|
200
|
+
await handle.close?.();
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const projected = this.core.projectExternalError(run, error, 'toolCleanup');
|
|
204
|
+
this.retainDetachedCleanup(run.state, run, () => handle.close?.(), projected);
|
|
205
|
+
throw projected;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
retainDetachedCleanup(state, run, cleanup, error) {
|
|
209
|
+
state.detachedCleanups.add({
|
|
210
|
+
cleanup,
|
|
211
|
+
projectError: (cleanupError) => this.core.projectExternalError(run, cleanupError, 'toolCleanup'),
|
|
212
|
+
error,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
observeDetachedToolProvider(outcome, run) {
|
|
216
|
+
this.trackDetachedCleanup(run.state, run, async () => {
|
|
217
|
+
const result = await outcome;
|
|
218
|
+
if (!result.success || result.source !== 'tools' || !result.value)
|
|
219
|
+
return;
|
|
220
|
+
const close = result.value.close;
|
|
221
|
+
if (close !== undefined && typeof close !== 'function') {
|
|
222
|
+
throw new FlexHarnessValidationError('Tool handle close must be a function.');
|
|
223
|
+
}
|
|
224
|
+
await close?.call(result.value);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
trackDetachedCleanup(state, run, cleanup) {
|
|
228
|
+
const retained = {
|
|
229
|
+
cleanup,
|
|
230
|
+
projectError: (error) => this.core.projectExternalError(run, error, 'toolCleanup'),
|
|
231
|
+
};
|
|
232
|
+
state.detachedCleanups.add(retained);
|
|
233
|
+
void this.runDetachedCleanup(state, retained);
|
|
234
|
+
}
|
|
235
|
+
runDetachedCleanup(state, retained) {
|
|
236
|
+
if (retained.completion)
|
|
237
|
+
return retained.completion;
|
|
238
|
+
retained.error = undefined;
|
|
239
|
+
let completion;
|
|
240
|
+
completion = Promise.resolve()
|
|
241
|
+
.then(retained.cleanup)
|
|
242
|
+
.then(() => {
|
|
243
|
+
state.detachedCleanups.delete(retained);
|
|
244
|
+
}, (error) => {
|
|
245
|
+
retained.error = retained.projectError(error);
|
|
246
|
+
})
|
|
247
|
+
.finally(() => {
|
|
248
|
+
if (retained.completion === completion)
|
|
249
|
+
retained.completion = undefined;
|
|
250
|
+
});
|
|
251
|
+
retained.completion = completion;
|
|
252
|
+
return completion;
|
|
253
|
+
}
|
|
254
|
+
beginDetachedCleanupSettlement(state) {
|
|
255
|
+
return [...state.detachedCleanups].map((cleanup) => cleanup.completion ?? this.runDetachedCleanup(state, cleanup));
|
|
256
|
+
}
|
|
257
|
+
async settleDetachedCleanups(state, attempts) {
|
|
258
|
+
await Promise.all(attempts);
|
|
259
|
+
await Promise.all([...state.detachedCleanups]
|
|
260
|
+
.map((cleanup) => cleanup.completion)
|
|
261
|
+
.filter((completion) => completion !== undefined));
|
|
262
|
+
return [...state.detachedCleanups]
|
|
263
|
+
.map((cleanup) => cleanup.error)
|
|
264
|
+
.filter((error) => error !== undefined);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5wcm92aWRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmZsZXhoYXJuZXNzLnByb3ZpZGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFjekQsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixnQ0FBZ0MsRUFDaEMsK0JBQStCLEVBQy9CLDBCQUEwQixFQUMxQixhQUFhLEdBQ2QsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQyxNQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQztBQUVyQywrRkFBK0Y7QUFDL0YsTUFBTSxPQUFPLHdCQUF3QjtJQUNOO0lBQTdCLFlBQTZCLElBQTZCO1FBQTdCLFNBQUksR0FBSixJQUFJLENBQXlCO0lBQUcsQ0FBQztJQUV2RCxtQkFBbUIsQ0FBQyxHQUFlLEVBQUUsTUFBbUM7UUFDN0UsSUFBSSxNQUFNLEtBQUssU0FBUztZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQzNDLElBQUksS0FBK0IsQ0FBQztRQUNwQyxJQUFJLENBQUM7WUFDSCxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztZQUNyQixJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksT0FBTyxLQUFLLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3ZELE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7WUFDRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO1lBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN6RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQy9CLElBQUksT0FBTyxLQUFLLFNBQVMsSUFBSSxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxP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
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type TJsonValue } from './interfaces.js';
|
|
2
|
+
import type { IActiveRun, IResultRead } from './interfaces.flexharness.js';
|
|
3
|
+
import type { FlexHarnessCore } from './classes.flexharness.core.js';
|
|
4
|
+
/** Budgeted tool output: oversized results stored behind result handles and read back by page. */
|
|
5
|
+
export declare class FlexHarnessResults<TScope> {
|
|
6
|
+
private readonly core;
|
|
7
|
+
/** A session's result writes, one at a time: they share the session's index of results. */
|
|
8
|
+
readonly resultQueues: Map<string, Promise<void>>;
|
|
9
|
+
constructor(core: FlexHarnessCore<TScope>);
|
|
10
|
+
/**
|
|
11
|
+
* The output the model gets: the output itself within the output budget, or, in a run with a
|
|
12
|
+
* catalog whose stores keep results, a handle to the stored output with a summary of it.
|
|
13
|
+
*/
|
|
14
|
+
budgetOutput(run: IActiveRun, output: unknown): Promise<TJsonValue>;
|
|
15
|
+
resultQueueKey(storageKey: string, sessionId: string): string;
|
|
16
|
+
/** The JSON bytes of one `results.get` page: the output budget, less room for the page's fields. */
|
|
17
|
+
private resultPageBytes;
|
|
18
|
+
/** One page of a stored result of the run's session, or the error `results.get` reports. */
|
|
19
|
+
readResult(run: IActiveRun, params: IResultRead): Promise<{
|
|
20
|
+
ok: true;
|
|
21
|
+
value: TJsonValue;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
error: TJsonValue;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { FLEX_RESULT_LIMITS, FLEX_RESULT_METHOD, } from './interfaces.js';
|
|
3
|
+
import { describeShape, resultPage, selectPath, summarizeResult } from './utils.results.js';
|
|
4
|
+
import { normalizeJsonValue } from './utils.json.js';
|
|
5
|
+
import { jsonBytes } from './utils.transfer.js';
|
|
6
|
+
import { queueOperation } from './utils.flexharness.js';
|
|
7
|
+
/** Budgeted tool output: oversized results stored behind result handles and read back by page. */
|
|
8
|
+
export class FlexHarnessResults {
|
|
9
|
+
core;
|
|
10
|
+
/** A session's result writes, one at a time: they share the session's index of results. */
|
|
11
|
+
resultQueues = new Map();
|
|
12
|
+
constructor(core) {
|
|
13
|
+
this.core = core;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The output the model gets: the output itself within the output budget, or, in a run with a
|
|
17
|
+
* catalog whose stores keep results, a handle to the stored output with a summary of it.
|
|
18
|
+
*/
|
|
19
|
+
async budgetOutput(run, output) {
|
|
20
|
+
const results = this.core.stores.results;
|
|
21
|
+
const maxBytes = this.core.toolOutputLimits.maxBytes;
|
|
22
|
+
if (!results || !run.toolCatalog)
|
|
23
|
+
return normalizeJsonValue(output, this.core.toolOutputLimits);
|
|
24
|
+
const stored = normalizeJsonValue(output, {
|
|
25
|
+
...this.core.toolOutputLimits,
|
|
26
|
+
maxBytes: Math.max(maxBytes, FLEX_RESULT_LIMITS.maxStoredBytes),
|
|
27
|
+
});
|
|
28
|
+
const bytes = jsonBytes(stored);
|
|
29
|
+
if (bytes <= maxBytes)
|
|
30
|
+
return stored;
|
|
31
|
+
const handle = `res_${plugins.crypto.randomBytes(8).toString('hex')}`;
|
|
32
|
+
const read = `Too large to return whole: read it page by page with execute({ method: "${FLEX_RESULT_METHOD}", `
|
|
33
|
+
+ `params: { handle: "${handle}", page: 1 } })${run.toolCatalog.codeMode
|
|
34
|
+
? `, or in run_code with await api.results.get("${handle}", { page: 1 })`
|
|
35
|
+
: ''}; a dotted \`path\` reads a part of it.`;
|
|
36
|
+
const result = {
|
|
37
|
+
$flexType: 'result',
|
|
38
|
+
handle,
|
|
39
|
+
bytes,
|
|
40
|
+
pages: resultPage(stored, '', 1, this.resultPageBytes()).pages,
|
|
41
|
+
summary: summarizeResult(stored, Math.min(FLEX_RESULT_LIMITS.summaryBytes, Math.floor(maxBytes / 4))),
|
|
42
|
+
read,
|
|
43
|
+
};
|
|
44
|
+
// A budget too small for even the handle keeps the truncated output.
|
|
45
|
+
if (jsonBytes(result) > maxBytes)
|
|
46
|
+
return normalizeJsonValue(output, this.core.toolOutputLimits);
|
|
47
|
+
const { storageKey } = run.state;
|
|
48
|
+
await queueOperation(this.resultQueues, this.resultQueueKey(storageKey, run.sessionId), async () => {
|
|
49
|
+
await results.save(storageKey, run.sessionId, handle, stored);
|
|
50
|
+
// The session keeps its latest results; older ones are deleted.
|
|
51
|
+
const handles = await results.list(storageKey, run.sessionId);
|
|
52
|
+
for (const old of handles.slice(0, Math.max(0, handles.length - FLEX_RESULT_LIMITS.maxResultsPerSession))) {
|
|
53
|
+
await results.delete(storageKey, run.sessionId, old);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
resultQueueKey(storageKey, sessionId) {
|
|
59
|
+
return JSON.stringify([storageKey, sessionId]);
|
|
60
|
+
}
|
|
61
|
+
/** The JSON bytes of one `results.get` page: the output budget, less room for the page's fields. */
|
|
62
|
+
resultPageBytes() {
|
|
63
|
+
return Math.max(64, this.core.toolOutputLimits.maxBytes - 512);
|
|
64
|
+
}
|
|
65
|
+
/** One page of a stored result of the run's session, or the error `results.get` reports. */
|
|
66
|
+
async readResult(run, params) {
|
|
67
|
+
const method = FLEX_RESULT_METHOD;
|
|
68
|
+
const stored = await this.core.stores.results.load(run.state.storageKey, run.sessionId, params.handle);
|
|
69
|
+
if (stored === undefined) {
|
|
70
|
+
return { ok: false, error: { error: 'unknown_handle', method, handle: params.handle, hint: `A handle reads one of the latest ${FLEX_RESULT_LIMITS.maxResultsPerSession} results this session stored.` } };
|
|
71
|
+
}
|
|
72
|
+
const path = params.path ?? '';
|
|
73
|
+
const value = selectPath(stored, path);
|
|
74
|
+
if (value === undefined) {
|
|
75
|
+
return { ok: false, error: { error: 'unknown_path', method, path, hint: `The result is ${describeShape(stored)}.` } };
|
|
76
|
+
}
|
|
77
|
+
const page = params.page ?? 1;
|
|
78
|
+
const content = resultPage(value, path, page, this.resultPageBytes());
|
|
79
|
+
if (!content) {
|
|
80
|
+
const pages = resultPage(value, path, 1, this.resultPageBytes()).pages;
|
|
81
|
+
return { ok: false, error: { error: 'unknown_page', method, page, pages } };
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
ok: true,
|
|
85
|
+
value: { handle: params.handle, path, page, pages: content.pages, ...content.range, value: content.value },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5yZXN1bHRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5mbGV4aGFybmVzcy5yZXN1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsa0JBQWtCLEdBR25CLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHeEQsa0dBQWtHO0FBQ2xHLE1BQU0sT0FBTyxrQkFBa0I7SUFJQTtJQUg3QiwyRkFBMkY7SUFDM0UsWUFBWSxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBRWhFLFlBQTZCLElBQTZCO1FBQTdCLFNBQUksR0FBSixJQUFJLENBQXlCO0lBQUcsQ0FBQztJQUU5RDs7O09BR0c7SUFDSSxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQWUsRUFBRSxNQUFlO1FBQ3hELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUN6QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQztRQUNyRCxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVc7WUFBRSxPQUFPLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDaEcsTUFBTSxNQUFNLEdBQUcs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QUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBRSxDQUFDLEtBQUssQ0FBQztZQUN4RSxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUM5RSxDQUFDO1FBQ0QsT0FBTztZQUNMLEVBQUUsRUFBRSxJQUFJO1lBQ1IsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUU7U0FDM0csQ0FBQztJQUNKLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { type IFlexReversionSegment, type IFlexRedoSessionResult, type IFlexSessionReversionInfo, type IFlexSessionTombstone, type IFlexUndoSessionResult } from './interfaces.js';
|
|
3
|
+
import type { TCanonicalOutcome, IStoredSessionState, IReversionGroup, IStorageState, IActiveRun } from './interfaces.flexharness.js';
|
|
4
|
+
import type { FlexHarnessCore } from './classes.flexharness.core.js';
|
|
5
|
+
/** Turn reversion: capture, undo and redo, and the release of reversion state. */
|
|
6
|
+
export declare class FlexHarnessReversions<TScope> {
|
|
7
|
+
private readonly core;
|
|
8
|
+
constructor(core: FlexHarnessCore<TScope>);
|
|
9
|
+
getSessionReversionInfo(scopeId: string, sessionId: string): Promise<IFlexSessionReversionInfo>;
|
|
10
|
+
undoSession(scopeId: string, sessionId: string, signal?: AbortSignal): Promise<IFlexUndoSessionResult>;
|
|
11
|
+
redoSession(scopeId: string, sessionId: string, signal?: AbortSignal): Promise<IFlexRedoSessionResult>;
|
|
12
|
+
reversionUnit(stored: IStoredSessionState, direction: 'undo' | 'redo'): {
|
|
13
|
+
target: IFlexReversionSegment;
|
|
14
|
+
segments: IFlexReversionSegment[];
|
|
15
|
+
toCursor: number;
|
|
16
|
+
} | undefined;
|
|
17
|
+
reversionGroups(stored: IStoredSessionState): IReversionGroup[];
|
|
18
|
+
private requireReversionIdle;
|
|
19
|
+
reversionUnavailableReason(state: IStorageState, stored: IStoredSessionState, allowPendingApply?: boolean, operationSignal?: AbortSignal): Promise<string | undefined>;
|
|
20
|
+
awaitReversionOperation<TResult>(operation: Promise<TResult>, signal?: AbortSignal): Promise<TResult>;
|
|
21
|
+
private changeReversionCursor;
|
|
22
|
+
changeReversionCursorResolved(scopeId: string, sessionId: string, direction: 'undo' | 'redo', scope: TScope, state: IStorageState, signal?: AbortSignal): Promise<string>;
|
|
23
|
+
reconcileContextAvailability(state: IStorageState, stored: IStoredSessionState): Promise<boolean>;
|
|
24
|
+
resumePendingApply(state: IStorageState, stored: IStoredSessionState, scopeId: string, scope: TScope, signal?: AbortSignal): Promise<void>;
|
|
25
|
+
private persistKnownNotApplied;
|
|
26
|
+
recoverPendingCapture(state: IStorageState, stored: IStoredSessionState, scopeId: string, scope: TScope, outcomes: Map<string, TCanonicalOutcome>): Promise<void>;
|
|
27
|
+
reversionId(kind: 'capture' | 'apply', storageKey: string, sessionId: string, value: string): string;
|
|
28
|
+
reversionProviderProtocolVersion(): 1 | 2 | undefined;
|
|
29
|
+
private reversionCaptureContext;
|
|
30
|
+
private withReversionMaintenanceSignal;
|
|
31
|
+
private inspectReversionCapture;
|
|
32
|
+
private finalizeReversionCapture;
|
|
33
|
+
private resolveReversionCaptureOutcome;
|
|
34
|
+
private normalizeReversionReference;
|
|
35
|
+
private normalizeReversionOutcome;
|
|
36
|
+
private normalizeAffectedWorkspaces;
|
|
37
|
+
prepareRunReversion(run: IActiveRun, signal: AbortSignal): Promise<void>;
|
|
38
|
+
finalizeRunReversion(run: IActiveRun, status: 'completed' | 'failed' | 'cancelled'): Promise<void>;
|
|
39
|
+
private applyFinalizedReversionOutcome;
|
|
40
|
+
private hiddenReversionSegments;
|
|
41
|
+
private enqueueReversionRelease;
|
|
42
|
+
private enqueueReversionReleaseReference;
|
|
43
|
+
pruneReversionState(stored: IStoredSessionState, reserveSegment?: boolean, dropNonUndoablePrefix?: boolean): void;
|
|
44
|
+
commitRevertedBranch(state: IStorageState, stored: IStoredSessionState, scopeId: string, scope: TScope): Promise<void>;
|
|
45
|
+
commitRevertedBranchState(stored: IStoredSessionState): boolean;
|
|
46
|
+
commitArchivedHiddenBranchState(stored: IStoredSessionState): boolean;
|
|
47
|
+
refreshAutomaticArchiveHorizon(stored: IStoredSessionState): void;
|
|
48
|
+
filterReversionContextEvents(stored: IStoredSessionState, events: readonly plugins.TAgentEvent[]): plugins.TAgentEvent[];
|
|
49
|
+
drainReversionReleases(state: IStorageState, stored: IStoredSessionState, scopeId: string, scope: TScope, throwOnFailure: boolean): Promise<void>;
|
|
50
|
+
releaseDeletedSessionReversions(state: IStorageState, storageKey: string, tombstone: IFlexSessionTombstone, scopeId: string, scope: TScope, stored?: IStoredSessionState): Promise<void>;
|
|
51
|
+
completedReversionCandidates(stored: IStoredSessionState): IFlexReversionSegment[];
|
|
52
|
+
}
|