@modelprofile.com/flexharness 9.10.0 → 10.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.d.ts +2 -0
- package/dist_ts/classes.flexharness.js +101 -7
- package/dist_ts/interfaces.d.ts +1 -0
- package/dist_ts/utils.harnessoptions.js +2 -1
- package/dist_ts_kvm/classes.browserkvm.js +3 -3
- package/dist_ts_kvm/plugins.d.ts +1 -1
- package/dist_ts_kvm/plugins.js +2 -2
- package/package.json +6 -6
- package/readme.md +10 -6
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.ts +102 -7
- package/ts/interfaces.ts +1 -0
- package/ts/readme.md +10 -6
- package/ts/utils.harnessoptions.ts +1 -0
- package/ts_kvm/classes.browserkvm.ts +2 -2
- package/ts_kvm/plugins.ts +1 -1
package/ts/readme.md
CHANGED
|
@@ -403,26 +403,29 @@ Normal Flex session cleanup always waits in-flight local project operations, the
|
|
|
403
403
|
|
|
404
404
|
`InMemoryFlexProjectManagementStore` is the standalone in-memory implementation. `InMemoryFlexHarnessStores` and `JsonFileFlexHarnessStores` include `projectManagement` as a required bundle member. `assertFlexProjectManagementSnapshot()` validates live records, `assertFlexProjectManagementTombstone()` validates tombstones, and `assertFlexProjectManagementRecord()` validates the union. `createEmptyFlexProjectManagementSnapshot(sessionGenerationId, sessionGenerationSequence)` returns a revision-0 live state for the supplied current generation.
|
|
405
405
|
|
|
406
|
-
##
|
|
406
|
+
## Subagents
|
|
407
407
|
|
|
408
|
-
`subagents` enables
|
|
408
|
+
`subagents` enables the harness-owned `delegate` and `delegate_result` tools when at least one definition exists and the session depth is below `maxSubagentDepth`. A tool provider cannot replace either enabled built-in. Delegation is asynchronous by default: `delegate` returns `{ taskId, status: 'running', runId }` after durable child admission, so the parent can continue independent work. `delegate_result({ taskId, waitMs? })` reads live status and, once settled, bounded final text and model identity; its optional wait is limited to 240 seconds and observes parent cancellation. Set `foreground: true` to await the final answer in `delegate` itself. Children remain owned by the parent turn: Stop cancels its exact child runs, and the parent joins them before releasing authority and finalizing. A child result arriving while inference is still active enters the parent's next model context as untrusted task data.
|
|
409
409
|
|
|
410
410
|
The model calls it with this exact input shape:
|
|
411
411
|
|
|
412
|
+
When upgrading from 9.x, callers that require the previous synchronous delegate result must pass `foreground: true`. Tool providers must also leave the newly reserved `delegate_result` name available when subagents are enabled.
|
|
413
|
+
|
|
412
414
|
```typescript
|
|
413
415
|
interface IDelegateInput {
|
|
414
416
|
description: string;
|
|
415
417
|
prompt: string;
|
|
416
418
|
subagentType: string;
|
|
417
419
|
taskId?: string;
|
|
420
|
+
foreground?: boolean;
|
|
418
421
|
}
|
|
419
422
|
```
|
|
420
423
|
|
|
421
424
|
Before creating or resuming a child, FlexHarness requests permission on the parent run with `kind: 'subagent.start'`, the parent `toolCallId`, and separately bounded harness-owned agent/task metadata. Its metadata includes `childSessionId`, the exact ID reserved for this call: FlexHarness derives it deterministically when `taskId` is omitted and copies the supplied candidate when `taskId` is present. A resume also retains that candidate as `taskId`. This block is not truncated by `toolOutputLimits`. The reserved ID binds permission handling before child creation but does not prove that the child exists or is owned: applications must treat the later delegated admission context as authoritative. The controller answers through the normal permission APIs. This request has no `rememberKey`, so `always` is invalid; controllers use `once` or `reject`.
|
|
422
425
|
|
|
423
|
-
Each new invocation creates a durable child `IFlexSession` with immutable `parentSessionId`, origin `parentRunId`, origin `parentToolCallId`, `agent`, and `depth`. New public roots persist `depth: 0`; legacy schema-1 roots may omit it. These fields are harness-owned; public `createSession()` remains limited to `sessionId`, `sessionGenerationId`, and `title`. Child sessions reject direct `prompt()`, `startPrompt()`, `enqueuePrompt()`, and `schedulePrompt()` calls and run only through the
|
|
426
|
+
Each new invocation creates a durable child `IFlexSession` with immutable `parentSessionId`, origin `parentRunId`, origin `parentToolCallId`, `agent`, and `depth`. New public roots persist `depth: 0`; legacy schema-1 roots may omit it. These fields are harness-owned; public `createSession()` remains limited to `sessionId`, `sessionGenerationId`, and `title`. Child sessions reject direct `prompt()`, `startPrompt()`, `enqueuePrompt()`, and `schedulePrompt()` calls and run only through the `delegate` tool. The model and tool resolver contexts receive optional immutable `parentSessionId` and `agent` values so integrations can apply agent-specific model and tool policy. Child prompts use the definition's `modelHint`, `system`, and `maxSteps`.
|
|
424
427
|
|
|
425
|
-
The parent tool part receives `childSessionId`
|
|
428
|
+
The parent tool part receives `childSessionId` as soon as the child is acquired, so a host can offer an authorized live transcript. A foreground call also adds the resolved child model to its part and returns bounded JSON:
|
|
426
429
|
|
|
427
430
|
```typescript
|
|
428
431
|
{
|
|
@@ -687,7 +690,7 @@ At most 128 custom commands may be registered. Every registration must be a plai
|
|
|
687
690
|
|
|
688
691
|
`/undo` and `/redo`, plus `undoSession()` and `redoSession()`, move a durable history cursor. The direct methods return `{ revertedRunId }` and `{ restoredRunId }`; the slash forms return `{ type: 'operation', name: 'undo' | 'redo' }`. Each committed cursor move emits one `session.history.changed` event with `direction`, `runId`, and the selected session identity. A committed branch emits the same event with `direction: 'branch'` and no `runId`, so controllers should refresh the complete selected session. Capture finalization, cleanup, and metadata-only changes do not emit this event.
|
|
689
692
|
|
|
690
|
-
A completed root-session turn defines an operation-group boundary. Failed and cancelled turns after it belong to that group; leading failed or cancelled turns belong to the first completed group. No completed boundary means there is nothing to undo. Undo applies selected segments in reverse order and redo applies them in forward order. Without `turnReversionProvider`, only transcript and future model context move. Hidden messages disappear from `getMessages()`, message pages, exact message lookup, and future model context. Starting a new prompt, template, handler, or compaction from an undone position commits a branch: hidden messages and segments are removed durably and cannot be redone. Successful event archival also commits hidden redo history; a missing compaction or failed archive leaves it intact.
|
|
693
|
+
A completed root-session turn defines an operation-group boundary. Failed and cancelled turns after it belong to that group; leading failed or cancelled turns belong to the first completed group. No completed boundary means there is nothing to undo. Undo applies selected segments in reverse order and redo applies them in forward order. Without `turnReversionProvider`, only transcript and future model context move. Hidden messages disappear from `getMessages()`, message pages, exact message lookup, and future model context. Starting a new prompt, template, handler, or compaction from an undone position commits a branch: hidden messages and segments are removed durably and cannot be redone. Successful event archival also commits hidden redo history; a missing compaction or failed archive leaves it intact. Automatic budget compaction archives covered events after generation finalization and advances the same undo horizon; set `contextCompactionBytes: false` to disable that automatic policy.
|
|
691
694
|
|
|
692
695
|
Two horizons bound undo. Retention pruning removes the oldest complete visible units when `reversionLimits` is exceeded. Explicit event archival marks covered turns context-unavailable and prunes complete prefixes that can no longer be rebuilt; FlexHarness never crosses that archive horizon. Manual compaction without archival retains the original events and remains undoable. Schema-1 projection history and sessions migrated from `2.x` have no reversion segments, so historical turns are not retroactively undoable; newly written turns are tracked normally.
|
|
693
696
|
|
|
@@ -790,7 +793,7 @@ The protocol is durable and inspectable:
|
|
|
790
793
|
|
|
791
794
|
1. FlexHarness persists a `preparing` capture intent before calling `prepare()`, before model or tool execution. The provider must establish exclusive capture ownership for that `storageKey` and retain it until `release()` succeeds.
|
|
792
795
|
2. `inspectCapture()` returns `missing`, `prepared`, `finalized`, or `unknown`. A finalized V1 result includes `reference`; a finalized V2 result includes the complete tagged `outcome`. `missing` is safe only while the durable state is still `preparing`; a missing prepared or finalizing capture, an `unknown` result, or an inspection failure fences the namespace.
|
|
793
|
-
3. `finalize()` closes the capture and returns its JSON-safe V1 reference or complete V2 outcome. FlexHarness may call it during normal finalization or recovery after `inspectCapture()` reports `prepared`. Failed and cancelled root turns are captured too. A root capture spans
|
|
796
|
+
3. `finalize()` closes the capture and returns its JSON-safe V1 reference or complete V2 outcome. FlexHarness may call it during normal finalization or recovery after `inspectCapture()` reports `prepared`. Failed and cancelled root turns are captured too. A root capture spans its admitted subagent effects, including asynchronous children joined before finalization, although child transcript records remain separate. A failed parent cancels its outstanding children before joining them.
|
|
794
797
|
4. Before undo or redo, FlexHarness persists an apply write-ahead record. `inspectApply()` must report the exact durable outcome for the supplied `operationId`: `not-applied` means no effect occurred, `applied` means the complete effect occurred, and `unknown` means the provider cannot prove either result. FlexHarness calls `apply()` only for `not-applied`; after an apply error it inspects again, and an `unknown` result or inspection failure fences the namespace. Progress is persisted after each segment, and the transcript cursor moves only after the complete unit succeeds. Known zero-progress failures leave the cursor unchanged and can be retried; partial progress retains the write-ahead record and resumes after restart. Caller cancellation is honored until the first workspace segment makes progress; recovery then continues with fresh bounded maintenance signals until the unit and cursor commit. Providers must treat `operationId` idempotently.
|
|
795
798
|
5. `release()` relinquishes the capture after no-change or nonrevertible V2 finalization, branch commitment, retention or archive pruning, session deletion, or other durable removal. It must be idempotent: an unacknowledged release remains persisted and is retried before FlexHarness discards the reference.
|
|
796
799
|
|
|
@@ -960,6 +963,7 @@ A `contextCompactor` states which model to compact with from the model the compa
|
|
|
960
963
|
| `reason` | Compaction | Model members |
|
|
961
964
|
| --- | --- | --- |
|
|
962
965
|
| `context-overflow` | A run's context overflowed, including a delegated run's | `resolvedModel`: the `IFlexResolvedModel` the model resolver returned for that run, frozen; a delegated run's overflow carries the delegated run's own model |
|
|
966
|
+
| `context-budget` | Settled history exceeds `contextCompactionBytes` before a generation's first inference (256 KiB by default with a compactor) | `resolvedModel`: the exact model resolved for that run, including its delegated model |
|
|
963
967
|
| `manual` | `/compact` or `compactSession()` | `modelHint`: the `modelHint` of the `/compact` execution options or of `compactSession(scopeId, sessionId, { modelHint })`, when one was passed |
|
|
964
968
|
| `retention` | Event retention | none |
|
|
965
969
|
|
|
@@ -380,6 +380,7 @@ export function normalizeAgentSessionPolicy<TScope>(
|
|
|
380
380
|
return {
|
|
381
381
|
...(policy.contextBuilder === undefined ? {} : { contextBuilder: policy.contextBuilder }),
|
|
382
382
|
...(policy.contextCompactor === undefined ? {} : { contextCompactor: policy.contextCompactor }),
|
|
383
|
+
...(policy.contextCompactionBytes === undefined ? {} : { contextCompactionBytes: policy.contextCompactionBytes }),
|
|
383
384
|
...(policy.eventRetention === undefined ? {} : { eventRetention: policy.eventRetention }),
|
|
384
385
|
...(policy.changeListenerTimeoutMs === undefined
|
|
385
386
|
? {}
|
|
@@ -256,9 +256,9 @@ export class BrowserKvm implements IKvmDriver {
|
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
await usernameElement.click({
|
|
259
|
+
await usernameElement.click({ count: 3 });
|
|
260
260
|
await usernameElement.type(this.options.username);
|
|
261
|
-
await passwordElement.click({
|
|
261
|
+
await passwordElement.click({ count: 3 });
|
|
262
262
|
await passwordElement.type(this.options.password);
|
|
263
263
|
await passwordElement.press('Enter');
|
|
264
264
|
|