@modelprofile.com/flexharness 10.23.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.
Files changed (83) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/classes.flexharness.admission.d.ts +17 -0
  3. package/dist_ts/classes.flexharness.admission.js +263 -0
  4. package/dist_ts/classes.flexharness.callbacks.d.ts +38 -0
  5. package/dist_ts/classes.flexharness.callbacks.js +313 -0
  6. package/dist_ts/classes.flexharness.compaction.d.ts +25 -0
  7. package/dist_ts/classes.flexharness.compaction.js +87 -0
  8. package/dist_ts/classes.flexharness.configurations.d.ts +11 -0
  9. package/dist_ts/classes.flexharness.configurations.js +137 -0
  10. package/dist_ts/classes.flexharness.core.d.ts +143 -0
  11. package/dist_ts/classes.flexharness.core.js +1538 -0
  12. package/dist_ts/classes.flexharness.d.ts +2 -437
  13. package/dist_ts/classes.flexharness.deletion.d.ts +31 -0
  14. package/dist_ts/classes.flexharness.deletion.js +396 -0
  15. package/dist_ts/classes.flexharness.imports.d.ts +24 -0
  16. package/dist_ts/classes.flexharness.imports.js +345 -0
  17. package/dist_ts/classes.flexharness.js +119 -9776
  18. package/dist_ts/classes.flexharness.lifecycle.d.ts +47 -0
  19. package/dist_ts/classes.flexharness.lifecycle.js +625 -0
  20. package/dist_ts/classes.flexharness.permissions.d.ts +19 -0
  21. package/dist_ts/classes.flexharness.permissions.js +450 -0
  22. package/dist_ts/classes.flexharness.projects.d.ts +55 -0
  23. package/dist_ts/classes.flexharness.projects.js +575 -0
  24. package/dist_ts/classes.flexharness.prompts.d.ts +44 -0
  25. package/dist_ts/classes.flexharness.prompts.js +659 -0
  26. package/dist_ts/classes.flexharness.providers.d.ts +18 -0
  27. package/dist_ts/classes.flexharness.providers.js +267 -0
  28. package/dist_ts/classes.flexharness.results.d.ts +26 -0
  29. package/dist_ts/classes.flexharness.results.js +89 -0
  30. package/dist_ts/classes.flexharness.reversions.d.ts +52 -0
  31. package/dist_ts/classes.flexharness.reversions.js +1306 -0
  32. package/dist_ts/classes.flexharness.runs.d.ts +63 -0
  33. package/dist_ts/classes.flexharness.runs.js +1058 -0
  34. package/dist_ts/classes.flexharness.sessions.d.ts +20 -0
  35. package/dist_ts/classes.flexharness.sessions.js +381 -0
  36. package/dist_ts/classes.flexharness.slashcommands.d.ts +40 -0
  37. package/dist_ts/classes.flexharness.slashcommands.js +458 -0
  38. package/dist_ts/classes.flexharness.subagents.d.ts +31 -0
  39. package/dist_ts/classes.flexharness.subagents.js +690 -0
  40. package/dist_ts/classes.flexharness.tooldispatch.d.ts +53 -0
  41. package/dist_ts/classes.flexharness.tooldispatch.js +418 -0
  42. package/dist_ts/interfaces.flexharness.d.ts +455 -0
  43. package/dist_ts/interfaces.flexharness.js +2 -0
  44. package/dist_ts/utils.flexharness.d.ts +19 -0
  45. package/dist_ts/utils.flexharness.js +83 -0
  46. package/dist_ts_compaction/plugins.d.ts +2 -2
  47. package/dist_ts_compaction/plugins.js +3 -3
  48. package/dist_ts_compaction/smartagent.compaction.js +6 -5
  49. package/dist_ts_stores_nosqldb/classes.nosqldbstores.d.ts +9 -0
  50. package/dist_ts_stores_nosqldb/classes.nosqldbstores.js +13 -1
  51. package/dist_ts_stores_nosqldb/classes.recordstore.d.ts +2 -2
  52. package/dist_ts_stores_nosqldb/classes.recordstore.js +3 -3
  53. package/package.json +3 -3
  54. package/readme.md +1 -1
  55. package/ts/00_commitinfo_data.ts +1 -1
  56. package/ts/classes.flexharness.admission.ts +331 -0
  57. package/ts/classes.flexharness.callbacks.ts +352 -0
  58. package/ts/classes.flexharness.compaction.ts +167 -0
  59. package/ts/classes.flexharness.configurations.ts +167 -0
  60. package/ts/classes.flexharness.core.ts +1830 -0
  61. package/ts/classes.flexharness.deletion.ts +616 -0
  62. package/ts/classes.flexharness.imports.ts +414 -0
  63. package/ts/classes.flexharness.lifecycle.ts +786 -0
  64. package/ts/classes.flexharness.permissions.ts +535 -0
  65. package/ts/classes.flexharness.projects.ts +1006 -0
  66. package/ts/classes.flexharness.prompts.ts +857 -0
  67. package/ts/classes.flexharness.providers.ts +322 -0
  68. package/ts/classes.flexharness.results.ts +98 -0
  69. package/ts/classes.flexharness.reversions.ts +1684 -0
  70. package/ts/classes.flexharness.runs.ts +1204 -0
  71. package/ts/classes.flexharness.sessions.ts +483 -0
  72. package/ts/classes.flexharness.slashcommands.ts +705 -0
  73. package/ts/classes.flexharness.subagents.ts +860 -0
  74. package/ts/classes.flexharness.tooldispatch.ts +475 -0
  75. package/ts/classes.flexharness.ts +147 -12567
  76. package/ts/interfaces.flexharness.ts +517 -0
  77. package/ts/readme.md +1 -1
  78. package/ts/utils.flexharness.ts +121 -0
  79. package/ts_compaction/plugins.ts +2 -2
  80. package/ts_compaction/smartagent.compaction.ts +5 -4
  81. package/ts_stores_nosqldb/classes.nosqldbstores.ts +13 -0
  82. package/ts_stores_nosqldb/classes.recordstore.ts +5 -5
  83. package/ts_stores_nosqldb/readme.md +7 -0
@@ -0,0 +1,313 @@
1
+ import * as plugins from './plugins.js';
2
+ import { FlexHarnessCallbackOverflowError } from './errors.js';
3
+ import { FLEX_TOOL_CATALOG_TOOL_NAMES, } from './interfaces.js';
4
+ import { normalizeJsonValue } from './utils.json.js';
5
+ import { jsonBytes } from './utils.transfer.js';
6
+ import { observeSessionMetricsCall, settleSessionMetricsOperation, } from './utils.sessionmetrics.js';
7
+ /** The model stream callbacks of a run: text, reasoning, tool, retry and usage events. */
8
+ export class FlexHarnessRunCallbacks {
9
+ core;
10
+ constructor(core) {
11
+ this.core = core;
12
+ }
13
+ onTextDelta(state, sessionId, delta) {
14
+ const run = this.callbackRun(state, sessionId);
15
+ if (!run || !delta)
16
+ return;
17
+ const lastPart = run.callbackParts.at(-1);
18
+ const created = lastPart?.type !== 'text';
19
+ const part = lastPart?.type === 'text'
20
+ ? lastPart
21
+ : { partId: plugins.crypto.randomUUID(), type: 'text', text: '' };
22
+ const accounting = this.textAppendAccounting(run, part, delta, created);
23
+ if (!accounting)
24
+ return;
25
+ if (!this.reserveCallbackCapacity(run, created ? 2 : 1, accounting.textUtf8Bytes - accounting.baseTextUtf8Bytes, created ? 1 : 0))
26
+ return;
27
+ if (created) {
28
+ run.callbackParts.push(part);
29
+ run.partTextUtf8Bytes.set(part.partId, 0);
30
+ this.core.emitPartEvent(run, 'part.started', part);
31
+ }
32
+ part.text += delta;
33
+ run.partTextUtf8Bytes.set(part.partId, accounting.textUtf8Bytes);
34
+ this.core.emitPartDeltaEvent(run, part, delta, accounting);
35
+ }
36
+ onReasoningStart(state, sessionId, id) {
37
+ const run = this.callbackRun(state, sessionId);
38
+ if (!run || run.reasoningPartIds.has(id))
39
+ return;
40
+ if (!this.reserveCallbackCapacity(run, 1, 0, 1))
41
+ return;
42
+ const part = {
43
+ partId: plugins.crypto.randomUUID(),
44
+ type: 'reasoning',
45
+ text: '',
46
+ status: 'running',
47
+ startedAt: new Date().toISOString(),
48
+ };
49
+ run.reasoningPartIds.set(id, part.partId);
50
+ run.callbackParts.push(part);
51
+ run.partTextUtf8Bytes.set(part.partId, 0);
52
+ this.core.emitPartEvent(run, 'part.started', part);
53
+ }
54
+ onReasoningDelta(state, sessionId, id, delta) {
55
+ const run = this.callbackRun(state, sessionId);
56
+ if (!run || !delta)
57
+ return;
58
+ if (!run.reasoningPartIds.has(id))
59
+ this.onReasoningStart(state, sessionId, id);
60
+ const partId = run.reasoningPartIds.get(id);
61
+ const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'reasoning');
62
+ if (!part || part.type !== 'reasoning' || part.status !== 'running')
63
+ return;
64
+ const accounting = this.textAppendAccounting(run, part, delta);
65
+ if (!accounting)
66
+ return;
67
+ if (!this.reserveCallbackCapacity(run, 1, accounting.textUtf8Bytes - accounting.baseTextUtf8Bytes, 0))
68
+ return;
69
+ part.text += delta;
70
+ run.partTextUtf8Bytes.set(part.partId, accounting.textUtf8Bytes);
71
+ this.core.emitPartDeltaEvent(run, part, delta, accounting);
72
+ }
73
+ onReasoningEnd(state, sessionId, id, text) {
74
+ const run = this.callbackRun(state, sessionId);
75
+ if (!run)
76
+ return;
77
+ if (!run.reasoningPartIds.has(id))
78
+ this.onReasoningStart(state, sessionId, id);
79
+ const partId = run.reasoningPartIds.get(id);
80
+ const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'reasoning');
81
+ if (!part || part.type !== 'reasoning' || part.status !== 'running')
82
+ return;
83
+ const missingText = part.text ? '' : text;
84
+ const missingTextUtf8Bytes = Buffer.byteLength(missingText, 'utf8');
85
+ if (!this.reserveCallbackCapacity(run, 1, missingTextUtf8Bytes, 0))
86
+ return;
87
+ if (missingText) {
88
+ part.text = missingText;
89
+ run.partTextUtf8Bytes.set(part.partId, missingTextUtf8Bytes);
90
+ }
91
+ part.status = 'completed';
92
+ part.completedAt = new Date().toISOString();
93
+ this.core.emitPartEvent(run, 'part.completed', part);
94
+ }
95
+ textAppendAccounting(run, part, delta, created = false) {
96
+ const baseTextUtf8Bytes = created ? 0 : run.partTextUtf8Bytes.get(part.partId);
97
+ if (baseTextUtf8Bytes === undefined) {
98
+ throw new Error('Flex part text byte accounting is unavailable.');
99
+ }
100
+ const trailingCodeUnit = part.text.charCodeAt(part.text.length - 1);
101
+ const leadingCodeUnit = delta.charCodeAt(0);
102
+ const joinsSurrogatePair = trailingCodeUnit >= 0xD800
103
+ && trailingCodeUnit <= 0xDBFF
104
+ && leadingCodeUnit >= 0xDC00
105
+ && leadingCodeUnit <= 0xDFFF;
106
+ const textUtf8Bytes = baseTextUtf8Bytes
107
+ + Buffer.byteLength(delta, 'utf8')
108
+ - (joinsSurrogatePair ? 2 : 0);
109
+ if (!Number.isSafeInteger(textUtf8Bytes)) {
110
+ this.failCallback(run, this.core.trustInternalError(new FlexHarnessCallbackOverflowError('Callback text byte accounting exceeded the safe integer range.')));
111
+ return undefined;
112
+ }
113
+ return { baseTextUtf8Bytes, textUtf8Bytes };
114
+ }
115
+ onToolStart(state, sessionId, event) {
116
+ const run = this.callbackRun(state, sessionId);
117
+ if (!run || run.toolPartIds.has(event.toolCallId))
118
+ return;
119
+ try {
120
+ // An execute call is the call of the catalog method it names.
121
+ const target = event.toolName === FLEX_TOOL_CATALOG_TOOL_NAMES.execute
122
+ ? run.toolCatalog?.callTarget(event.input)
123
+ : undefined;
124
+ const input = normalizeJsonValue(target ? target.params : event.input, this.core.toolOutputLimits);
125
+ if (!this.reserveCallbackCapacity(run, 1, jsonBytes(input), 1))
126
+ return;
127
+ const part = {
128
+ partId: plugins.crypto.randomUUID(),
129
+ type: 'tool',
130
+ toolCallId: this.core.boundedIdentifier(event.toolCallId, 'toolCallId'),
131
+ toolName: this.core.boundedIdentifier(target ? target.method : event.toolName, 'toolName'),
132
+ status: 'running',
133
+ input,
134
+ ...(event.parentToolCallId === undefined
135
+ ? {}
136
+ : { parentToolCallId: this.core.boundedIdentifier(event.parentToolCallId, 'parentToolCallId') }),
137
+ startedAt: new Date().toISOString(),
138
+ };
139
+ run.toolPartIds.set(event.toolCallId, part.partId);
140
+ run.callbackParts.push(part);
141
+ this.core.emitPartEvent(run, 'part.started', part);
142
+ }
143
+ catch (error) {
144
+ this.failCallback(run, this.core.projectExternalError(run, error, 'toolCallback'));
145
+ }
146
+ }
147
+ onToolFinish(state, sessionId, event) {
148
+ const run = this.callbackRun(state, sessionId);
149
+ if (!run)
150
+ return;
151
+ if (!run.toolPartIds.has(event.toolCallId))
152
+ this.onToolStart(state, sessionId, event);
153
+ const partId = run.toolPartIds.get(event.toolCallId);
154
+ const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'tool');
155
+ if (!part || part.type !== 'tool' || part.status !== 'running')
156
+ return;
157
+ try {
158
+ const trustedExecutionError = run.trustedToolExecutionErrors.get(event.toolCallId);
159
+ run.trustedToolExecutionErrors.delete(event.toolCallId);
160
+ const output = event.success ? normalizeJsonValue(event.output, this.core.toolOutputLimits) : undefined;
161
+ const projectedError = event.success
162
+ ? undefined
163
+ : this.core.projectExternalError(run, trustedExecutionError ?? event.error, 'toolCallback');
164
+ const bytes = event.success ? jsonBytes(output) : Buffer.byteLength(projectedError.message);
165
+ if (!this.reserveCallbackCapacity(run, 1, bytes - (part.output === undefined ? 0 : jsonBytes(part.output)), 0))
166
+ return;
167
+ if (event.success) {
168
+ part.status = 'completed';
169
+ part.output = output;
170
+ }
171
+ else {
172
+ part.status = 'failed';
173
+ delete part.output;
174
+ part.error = projectedError.message;
175
+ }
176
+ const original = run.deduplicatedToolCalls.get(event.toolCallId);
177
+ if (original !== undefined) {
178
+ part.deduplicatedFrom = this.core.boundedIdentifier(original, 'deduplicatedFrom');
179
+ }
180
+ part.completedAt = new Date().toISOString();
181
+ this.core.emitPartEvent(run, 'part.completed', part);
182
+ }
183
+ catch (error) {
184
+ this.failCallback(run, this.core.projectExternalError(run, error, 'toolCallback'));
185
+ }
186
+ }
187
+ onToolUpdate(state, sessionId, event) {
188
+ let run = this.callbackRun(state, sessionId);
189
+ if (!run)
190
+ return;
191
+ if (!run.toolPartIds.has(event.toolCallId)) {
192
+ this.onToolStart(state, sessionId, event);
193
+ run = this.callbackRun(state, sessionId);
194
+ if (!run)
195
+ return;
196
+ }
197
+ const partId = run.toolPartIds.get(event.toolCallId);
198
+ const part = run.callbackParts.find((entry) => entry.partId === partId && entry.type === 'tool');
199
+ if (!part || part.type !== 'tool' || part.status !== 'running')
200
+ return;
201
+ try {
202
+ const output = normalizeJsonValue(event.output, this.core.toolOutputLimits);
203
+ if (!this.reserveCallbackCapacity(run, 1, jsonBytes(output) - (part.output === undefined ? 0 : jsonBytes(part.output)), 0))
204
+ return;
205
+ part.output = output;
206
+ this.core.emitPartEvent(run, 'part.updated', part);
207
+ }
208
+ catch (error) {
209
+ this.failCallback(run, this.core.projectExternalError(run, error, 'toolCallback'));
210
+ }
211
+ }
212
+ onRetry(state, sessionId, retry) {
213
+ const run = this.callbackRun(state, sessionId);
214
+ if (!run || !this.reserveCallbackCapacity(run, 1, 0, 0))
215
+ return;
216
+ this.core.emitEvent(run.scopeId, run.stored.session, {
217
+ type: 'run.retrying',
218
+ runId: run.runId,
219
+ attempt: retry.attempt,
220
+ maxAttempts: retry.maxAttempts,
221
+ delayMs: retry.delayMs,
222
+ reason: retry.reason,
223
+ });
224
+ }
225
+ /**
226
+ * Emits the usage of every model call and adds reported usage to its run. A run executes a
227
+ * transactional generation, and `AgentSession.generate()` settles a transactional generation only
228
+ * after it has reported each of its model calls, also when it is aborted. `executeRun()` awaits
229
+ * that settlement before it builds the terminal, so the run is still active for each of its
230
+ * events: they all reach `run.usage` and precede its `run.finished`. The events bypass the
231
+ * callback limits and a failed callback: their number is bounded by the run's model calls, and
232
+ * the usage of a run that exhausted its callback budget or failed in a callback must not be lost.
233
+ */
234
+ onModelCallUsage(state, stored, event) {
235
+ try {
236
+ const { source, generationId, ...call } = event;
237
+ const sessionId = stored.session.sessionId;
238
+ const activeRun = state.activeRuns.get(sessionId);
239
+ const run = generationId !== undefined && activeRun?.runId === generationId ? activeRun : undefined;
240
+ const operation = source === 'compaction' ? stored.metricsCompaction : run?.metricsOperation;
241
+ if (!operation)
242
+ throw new Error('Model call usage has no owning metrics operation.');
243
+ observeSessionMetricsCall(operation, call);
244
+ let scopeId = run?.scopeId;
245
+ if (scopeId === undefined) {
246
+ const ambientContext = this.core.compaction.compactorInvocationContext.getStore();
247
+ const invocationContext = ambientContext
248
+ ? this.core.compaction.deferredCompactorContexts.get(ambientContext) ?? ambientContext
249
+ : undefined;
250
+ if (!invocationContext
251
+ || invocationContext.storageKey !== state.storageKey
252
+ || invocationContext.sessionId !== sessionId) {
253
+ throw new Error('Model call usage is missing its exact FlexHarness invocation context.');
254
+ }
255
+ scopeId = invocationContext.scopeId;
256
+ }
257
+ if (run && call.status === 'reported') {
258
+ for (const key of Object.keys(run.usage))
259
+ run.usage[key] += call.usage[key];
260
+ }
261
+ this.core.emitEvent(scopeId, stored.session, {
262
+ type: 'model.usage',
263
+ ...(generationId === undefined ? {} : { runId: generationId }),
264
+ source,
265
+ ...call,
266
+ });
267
+ }
268
+ catch (error) {
269
+ // AgentSession isolates the entire callback, including event/context failures. Join it later.
270
+ stored.metricsFailure ??= error;
271
+ throw error;
272
+ }
273
+ }
274
+ async settleMetricsOperation(state, stored, operation) {
275
+ try {
276
+ if (stored.metricsFailure !== undefined)
277
+ throw stored.metricsFailure;
278
+ await this.core.mutateProjection(state, stored, () => settleSessionMetricsOperation(stored.metrics, operation), true);
279
+ }
280
+ catch (error) {
281
+ stored.metricsFailure ??= error;
282
+ // Never allow a later operation to overwrite a marker whose spend was not durably joined.
283
+ state.lifecycle = 'fenced';
284
+ throw error;
285
+ }
286
+ }
287
+ callbackRun(state, sessionId) {
288
+ const run = state.activeRuns.get(sessionId);
289
+ return !run || run.callbacksClosed || run.callbackError ? undefined : run;
290
+ }
291
+ reserveCallbackCapacity(run, eventCount, outputBytes, partCount) {
292
+ const nextEvents = run.callbackEventCount + eventCount;
293
+ const nextOutputBytes = run.callbackOutputBytes + outputBytes;
294
+ const nextParts = run.callbackParts.length + partCount;
295
+ if (!Number.isSafeInteger(nextEvents)
296
+ || !Number.isSafeInteger(nextOutputBytes)
297
+ || !Number.isSafeInteger(nextParts)
298
+ || nextEvents > this.core.callbackLimits.maxEvents
299
+ || nextOutputBytes > this.core.callbackLimits.maxOutputBytes
300
+ || nextParts > this.core.callbackLimits.maxParts) {
301
+ this.failCallback(run, this.core.trustInternalError(new FlexHarnessCallbackOverflowError(`Callback buffer exceeded its limit (${nextEvents} events, ${nextOutputBytes} bytes, ${nextParts} parts).`)));
302
+ return false;
303
+ }
304
+ run.callbackEventCount = nextEvents;
305
+ run.callbackOutputBytes = nextOutputBytes;
306
+ return true;
307
+ }
308
+ failCallback(run, error) {
309
+ run.callbackError ??= error;
310
+ this.core.runs.abortRunInternally(run, error);
311
+ }
312
+ }
313
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5jYWxsYmFja3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmZsZXhoYXJuZXNzLmNhbGxiYWNrcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0QsT0FBTyxFQUNMLDRCQUE0QixHQU83QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLDZCQUE2QixHQUU5QixNQUFNLDJCQUEyQixDQUFDO0FBSW5DLDBGQUEwRjtBQUMxRixNQUFNLE9BQU8sdUJBQXVCO0lBQ0w7SUFBN0IsWUFBNkIsSUFBNkI7UUFBN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7SUFBRyxDQUFDO0lBRXZELFdBQVcsQ0FBQyxLQUFvQixFQUFFLFNBQWlCLEVBQUUsS0FBYTtRQUN2RSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU87UUFDM0IsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBRyxRQUFRLEVBQUUsSUFBSSxLQUFLLE1BQU0sQ0FBQztRQUMxQyxNQUFNLElBQUksR0FBRyxRQUFRLEVBQUUsSUFBSSxLQUFLLE1BQU07WUFDcEMsQ0FBQyxDQUFDLFFBQVE7WUFDVixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1B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
@@ -0,0 +1,25 @@
1
+ import * as plugins from './plugins.js';
2
+ import { FlexHarnessAbortError } from './errors.js';
3
+ import type { IFlexAgentContextCompactionOptions, IFlexAgentContextInvocation, IFlexCompactSessionOptions } from './interfaces.js';
4
+ import type { ICompactorInvocation, IStoredSessionState, IStorageState, IActiveRun } from './interfaces.flexharness.js';
5
+ import type { FlexHarnessCore } from './classes.flexharness.core.js';
6
+ /** Compaction hooks: compactor contexts and session compaction. */
7
+ export declare class FlexHarnessCompaction<TScope> {
8
+ private readonly core;
9
+ readonly compactorInvocationContext: plugins.AsyncLocalStorage<ICompactorInvocation<TScope>>;
10
+ readonly deferredCompactorContexts: WeakMap<IFlexAgentContextInvocation<unknown>, IFlexAgentContextInvocation<unknown>>;
11
+ constructor(core: FlexHarnessCore<TScope>);
12
+ compactSession(scopeId: string, sessionId: string, options?: IFlexCompactSessionOptions): Promise<void>;
13
+ compactStoredSession(scopeId: string, scope: TScope, state: IStorageState, stored: IStoredSessionState, modelHint: string | undefined, signal?: AbortSignal): Promise<void>;
14
+ abortCompactorLifecycle(stored: IStoredSessionState, reason: FlexHarnessAbortError): void;
15
+ createCompactorContext(scopeId: string, scope: TScope, storageKey: string, sessionId: string, modelHint?: string): ICompactorInvocation<TScope>;
16
+ /**
17
+ * The model the compacted work was dispatched on: the resolved model of the run whose context
18
+ * overflowed, or the model hint a manual compaction was requested with. Retention states none.
19
+ */
20
+ compactionModel(state: IStorageState, sessionId: string, ambientContext: IFlexAgentContextInvocation<TScope>, reason: IFlexAgentContextCompactionOptions['reason'], modelHint: string | undefined): Pick<IFlexAgentContextCompactionOptions<TScope>, 'resolvedModel' | 'modelHint'>;
21
+ withCompactorContext<TResult>(context: IFlexAgentContextInvocation<unknown>, operation: () => TResult): TResult;
22
+ createRunCompactorContext(run: IActiveRun): IFlexAgentContextInvocation<TScope>;
23
+ effectiveRunCompactorContext(run: IActiveRun): IFlexAgentContextInvocation<TScope>;
24
+ withRunCompactorContext<TResult>(run: IActiveRun, operation: () => TResult): TResult;
25
+ }
@@ -0,0 +1,87 @@
1
+ import * as plugins from './plugins.js';
2
+ import { FlexHarnessAbortError, FlexHarnessSlashCommandReentryError, FlexHarnessSlashCommandUnavailableError, } from './errors.js';
3
+ import { validateCompactSessionOptions } from './utils.validation.js';
4
+ /** Compaction hooks: compactor contexts and session compaction. */
5
+ export class FlexHarnessCompaction {
6
+ core;
7
+ compactorInvocationContext = new plugins.AsyncLocalStorage();
8
+ deferredCompactorContexts = new WeakMap();
9
+ constructor(core) {
10
+ this.core = core;
11
+ }
12
+ async compactSession(scopeId, sessionId, options = {}) {
13
+ const { modelHint } = validateCompactSessionOptions(options);
14
+ const { scope, state } = await this.core.resolveState(scopeId);
15
+ const stored = this.core.requireSession(state, sessionId);
16
+ this.core.assertSessionWritable(stored);
17
+ const invocationOwner = this.core.commands.slashCommandInvocationContext.getStore();
18
+ if (invocationOwner?.sessionKey === this.core.commands.slashCommandSessionKey(state.storageKey, sessionId)) {
19
+ throw this.core.trustInternalError(new FlexHarnessSlashCommandReentryError(sessionId));
20
+ }
21
+ this.core.assertStateAcceptingWork(state);
22
+ if (!this.core.agentSessionPolicy.contextCompactor) {
23
+ throw new FlexHarnessSlashCommandUnavailableError('compact', 'No context compactor is configured.');
24
+ }
25
+ this.core.commands.requireSessionAvailableForSlashCommand(state, stored, 'compact');
26
+ await this.core.commands.trackSlashCommandExecution(scopeId, state, sessionId, 'operation', undefined, async (signal) => {
27
+ await this.core.reversions.commitRevertedBranch(state, stored, scopeId, scope.scope);
28
+ await this.compactStoredSession(scopeId, scope.scope, state, stored, modelHint, signal);
29
+ });
30
+ }
31
+ async compactStoredSession(scopeId, scope, state, stored, modelHint, signal) {
32
+ try {
33
+ await this.withCompactorContext(this.createCompactorContext(scopeId, scope, state.storageKey, stored.session.sessionId, modelHint), () => stored.agentSession.compact(signal === undefined ? {} : { abort: signal }));
34
+ }
35
+ catch (error) {
36
+ throw this.core.projectOperationError(error, 'agentSession', scopeId, stored.session.sessionId, 'compaction');
37
+ }
38
+ }
39
+ abortCompactorLifecycle(stored, reason) {
40
+ if (!stored.compactorLifecycleController.signal.aborted) {
41
+ stored.compactorLifecycleController.abort(reason);
42
+ }
43
+ }
44
+ createCompactorContext(scopeId, scope, storageKey, sessionId, modelHint) {
45
+ return Object.freeze({
46
+ scopeId,
47
+ scope,
48
+ storageKey,
49
+ sessionId,
50
+ ...(modelHint === undefined ? {} : { modelHint }),
51
+ });
52
+ }
53
+ /**
54
+ * The model the compacted work was dispatched on: the resolved model of the run whose context
55
+ * overflowed, or the model hint a manual compaction was requested with. Retention states none.
56
+ */
57
+ compactionModel(state, sessionId, ambientContext, reason, modelHint) {
58
+ if (reason === 'manual')
59
+ return modelHint === undefined ? {} : { modelHint };
60
+ if (reason !== 'context-overflow' && reason !== 'context-budget')
61
+ return {};
62
+ const run = state.activeRuns.get(sessionId);
63
+ if (!run
64
+ || (ambientContext !== run.originCompactorContext && ambientContext !== run.deferredCompactorContext)) {
65
+ throw new Error('Context-overflow compaction is missing its exact FlexHarness run.');
66
+ }
67
+ const resolved = run.modelResolution;
68
+ if (!resolved)
69
+ throw new Error('Context-overflow compaction ran before its run resolved a model.');
70
+ return {
71
+ resolvedModel: Object.freeze({ ...resolved, identity: Object.freeze({ ...resolved.identity }) }),
72
+ };
73
+ }
74
+ withCompactorContext(context, operation) {
75
+ return this.compactorInvocationContext.run(context, operation);
76
+ }
77
+ createRunCompactorContext(run) {
78
+ return run.originCompactorContext;
79
+ }
80
+ effectiveRunCompactorContext(run) {
81
+ return (run.deferredCompactorContext ?? run.originCompactorContext);
82
+ }
83
+ withRunCompactorContext(run, operation) {
84
+ return this.withCompactorContext(this.effectiveRunCompactorContext(run), operation);
85
+ }
86
+ }
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5jb21wYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5mbGV4aGFybmVzcy5jb21wYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsbUNBQW1DLEVBQ25DLHVDQUF1QyxHQUN4QyxNQUFNLGFBQWEsQ0FBQztBQU1yQixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVN0RSxtRUFBbUU7QUFDbkUsTUFBTSxPQUFPLHFCQUFxQjtJQVNIO0lBUmIsMEJBQTBCLEdBQUcsSUFBSSxPQUFPLENBQUMsaUJBQWlCLEVBRXZFLENBQUM7SUFDWSx5QkFBeUIsR0FBRyxJQUFJLE9BQU8sRUFHcEQsQ0FBQztJQUVKLFlBQTZCLElBQTZCO1FBQTdCLFNBQUksR0FBSixJQUFJLENBQXlCO0lBQUcsQ0FBQztJQUV2RCxLQUFLLENBQUMsY0FBYyxDQUN6QixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsVUFBc0MsRUFBRTtRQUV4QyxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsNkJBQTZCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0QsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLDZCQUE2QixDQUFDLFFBQVEsRUFBRSxDQUFDO1FB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
@@ -0,0 +1,11 @@
1
+ import { FlexHarnessAbortError } from './errors.js';
2
+ import type { IStoredSessionState, IStorageState, IResolvedSessionConfiguration, ISessionConfigurationOwner } from './interfaces.flexharness.js';
3
+ import type { FlexHarnessCore } from './classes.flexharness.core.js';
4
+ /** Session configurations from the session configuration resolver, and their owners. */
5
+ export declare class FlexHarnessSessionConfigurations<TScope> {
6
+ private readonly core;
7
+ readonly sessionConfigurations: Map<string, ISessionConfigurationOwner<TScope>>;
8
+ constructor(core: FlexHarnessCore<TScope>);
9
+ resolveSessionConfiguration(scopeId: string, scope: TScope, state: IStorageState, stored: IStoredSessionState, signal?: AbortSignal): Promise<IResolvedSessionConfiguration<TScope>>;
10
+ abortSessionConfigurations(storageKey: string, reason: FlexHarnessAbortError, sessionIds?: ReadonlySet<string>): Promise<void> | undefined;
11
+ }
@@ -0,0 +1,137 @@
1
+ import { FlexHarnessAbortError, FlexHarnessValidationError } from './errors.js';
2
+ import { normalizeAllowedTools, normalizeSlashCommands, normalizeSubagents, } from './utils.harnessoptions.js';
3
+ import { requireSessionGeneration } from './utils.flexharness.js';
4
+ /** Session configurations from the session configuration resolver, and their owners. */
5
+ export class FlexHarnessSessionConfigurations {
6
+ core;
7
+ sessionConfigurations = new Map();
8
+ constructor(core) {
9
+ this.core = core;
10
+ }
11
+ async resolveSessionConfiguration(scopeId, scope, state, stored, signal) {
12
+ const configurationRef = stored.session.configurationRef;
13
+ if (configurationRef === undefined) {
14
+ return { subagents: this.core.subagents, slashCommands: this.core.slashCommands };
15
+ }
16
+ const sessionId = stored.session.sessionId;
17
+ const generation = requireSessionGeneration(stored.session);
18
+ const key = JSON.stringify([
19
+ state.storageKey,
20
+ sessionId,
21
+ generation.sessionGenerationId,
22
+ generation.sessionGenerationSequence,
23
+ configurationRef,
24
+ ]);
25
+ let owner = this.sessionConfigurations.get(key);
26
+ if (!owner) {
27
+ const controller = new AbortController();
28
+ const parent = stored.session.parentSessionId === undefined
29
+ ? undefined
30
+ : state.sessions.get(stored.session.parentSessionId);
31
+ if (stored.session.parentSessionId !== undefined && !parent) {
32
+ throw this.core.trustInternalError(new FlexHarnessAbortError('The session parent is no longer available.'));
33
+ }
34
+ const parentGeneration = parent === undefined ? undefined : requireSessionGeneration(parent.session);
35
+ const context = Object.freeze({
36
+ scopeId,
37
+ scope,
38
+ storageKey: state.storageKey,
39
+ sessionId,
40
+ ...generation,
41
+ configurationRef,
42
+ ...(parent === undefined ? {} : {
43
+ parentSessionId: parent.session.sessionId,
44
+ parentSessionGenerationId: parentGeneration.sessionGenerationId,
45
+ parentSessionGenerationSequence: parentGeneration.sessionGenerationSequence,
46
+ }),
47
+ ...(stored.session.agent === undefined ? {} : { agent: stored.session.agent }),
48
+ depth: stored.session.depth ?? 0,
49
+ signal: controller.signal,
50
+ });
51
+ let rejectAbort;
52
+ const aborted = new Promise((_resolve, reject) => { rejectAbort = reject; });
53
+ const onAbort = () => rejectAbort(controller.signal.reason);
54
+ controller.signal.addEventListener('abort', onAbort, { once: true });
55
+ const resolved = Promise.resolve().then(() => {
56
+ if (!this.core.sessionConfigurationResolver) {
57
+ throw new Error('A sessionConfigurationResolver is required for bound sessions.');
58
+ }
59
+ return this.core.sessionConfigurationResolver.resolveSessionConfiguration(context);
60
+ });
61
+ const completion = Promise.race([resolved, aborted]).then((configuration) => {
62
+ controller.signal.throwIfAborted();
63
+ if (state.lifecycle !== 'active'
64
+ || state.sessions.get(sessionId) !== stored
65
+ || stored.session.configurationRef !== configurationRef
66
+ || stored.session.sessionGenerationId !== generation.sessionGenerationId
67
+ || stored.session.sessionGenerationSequence !== generation.sessionGenerationSequence) {
68
+ throw this.core.trustInternalError(new FlexHarnessAbortError('The session configuration lost its session generation ownership.'));
69
+ }
70
+ if (!configuration
71
+ || typeof configuration !== 'object'
72
+ || Array.isArray(configuration)
73
+ || ![Object.prototype, null].includes(Object.getPrototypeOf(configuration))
74
+ || Reflect.ownKeys(configuration).some((name) => typeof name !== 'string' || !['subagents', 'slashCommands', 'allowedTools', 'permissionPolicy'].includes(name)))
75
+ throw new FlexHarnessValidationError('Resolved session configuration is invalid.');
76
+ if (configuration.permissionPolicy !== undefined && typeof configuration.permissionPolicy !== 'function') {
77
+ throw new FlexHarnessValidationError('Resolved session permissionPolicy must be a function.');
78
+ }
79
+ return Object.freeze({
80
+ subagents: normalizeSubagents(configuration.subagents),
81
+ slashCommands: normalizeSlashCommands(configuration.slashCommands),
82
+ allowedTools: normalizeAllowedTools(configuration.allowedTools),
83
+ permissionPolicy: configuration.permissionPolicy,
84
+ });
85
+ }).catch((error) => {
86
+ if (this.sessionConfigurations.get(key)?.completion === completion) {
87
+ this.sessionConfigurations.delete(key);
88
+ }
89
+ if (controller.signal.aborted)
90
+ throw controller.signal.reason;
91
+ throw this.core.projectOperationError(error, 'sessionConfigurationResolver', scopeId, sessionId, 'session-configuration');
92
+ }).finally(() => {
93
+ controller.signal.removeEventListener('abort', onAbort);
94
+ const current = this.sessionConfigurations.get(key);
95
+ if (current?.completion === completion)
96
+ current.settled = true;
97
+ });
98
+ owner = { storageKey: state.storageKey, sessionId, controller, completion, settled: false, waiters: 0 };
99
+ this.sessionConfigurations.set(key, owner);
100
+ }
101
+ owner.waiters++;
102
+ let onConsumerAbort;
103
+ const consumerAbort = signal && new Promise((_resolve, reject) => {
104
+ onConsumerAbort = () => reject(signal.reason ?? this.core.trustInternalError(new FlexHarnessAbortError('Session configuration resolution was aborted.')));
105
+ signal.addEventListener('abort', onConsumerAbort, { once: true });
106
+ if (signal.aborted)
107
+ onConsumerAbort();
108
+ });
109
+ try {
110
+ return await (consumerAbort
111
+ ? Promise.race([owner.completion, consumerAbort])
112
+ : owner.completion);
113
+ }
114
+ finally {
115
+ if (signal && onConsumerAbort)
116
+ signal.removeEventListener('abort', onConsumerAbort);
117
+ owner.waiters--;
118
+ if (owner.waiters === 0 && !owner.settled && !owner.controller.signal.aborted) {
119
+ if (this.sessionConfigurations.get(key) === owner)
120
+ this.sessionConfigurations.delete(key);
121
+ owner.controller.abort(this.core.trustInternalError(new FlexHarnessAbortError('Session configuration resolution has no active callers.')));
122
+ }
123
+ }
124
+ }
125
+ abortSessionConfigurations(storageKey, reason, sessionIds) {
126
+ const owners = [...this.sessionConfigurations.entries()].filter(([, owner]) => owner.storageKey === storageKey && (sessionIds === undefined || sessionIds.has(owner.sessionId)));
127
+ if (owners.length === 0)
128
+ return undefined;
129
+ for (const [key, owner] of owners) {
130
+ this.sessionConfigurations.delete(key);
131
+ if (!owner.controller.signal.aborted)
132
+ owner.controller.abort(reason);
133
+ }
134
+ return Promise.allSettled(owners.map(([, owner]) => owner.completion)).then(() => undefined);
135
+ }
136
+ }
137
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5jb25maWd1cmF0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZmxleGhhcm5lc3MuY29uZmlndXJhdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHFCQUFxQixFQUFFLDBCQUEwQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2hGLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsc0JBQXNCLEVBQ3RCLGtCQUFrQixHQUNuQixNQUFNLDJCQUEyQixDQUFDO0FBT25DLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR2xFLHdGQUF3RjtBQUN4RixNQUFNLE9BQU8sZ0NBQWdDO0lBR2Q7SUFGYixxQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFBOEMsQ0FBQztJQUU5RixZQUE2QixJQUE2QjtRQUE3QixTQUFJLEdBQUosSUFBSSxDQUF5QjtJQUFHLENBQUM7SUFFdkQsS0FBSyxDQUFDLDJCQUEyQixDQUN0QyxPQUFlLEVBQ2YsS0FBYSxFQUNiLEtBQW9CLEVBQ3BCLE1BQTJCLEVBQzNCLE1BQW9CO1FBRXBCLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztRQUN6RCxJQUFJLGdCQUFnQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDcEYsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBQzNDLE1BQU0sVUFBVSxHQUFHLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pC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