@modelprofile.com/flexharness 9.5.0 → 9.6.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.js +12 -4
- package/dist_ts/interfaces.d.ts +8 -0
- package/dist_ts/interfaces.js +1 -1
- package/dist_ts/utils.json.js +5 -1
- package/package.json +3 -3
- package/readme.md +4 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.ts +11 -3
- package/ts/interfaces.ts +8 -0
- package/ts/readme.md +4 -4
- package/ts/utils.json.ts +4 -0
package/ts/readme.md
CHANGED
|
@@ -608,9 +608,9 @@ Queue payloads, status records, and `prompt.*` queue events are process-local. T
|
|
|
608
608
|
|
|
609
609
|
The reservation save is the admission point. A save failure produces no start events or active audit. If disposal begins while that save is in flight and the save commits, admission still resolves and its completion settles as cancelled; disposal waits for terminal finalization.
|
|
610
610
|
|
|
611
|
-
`listMessagePage()` returns the newest contiguous page in chronological order. `limit` must be an integer from 1 through 50 and defaults to 50. `nextCursor` is opaque, limited to 4096 UTF-8 bytes, bound to the resolved storage namespace and session, and remains stable when newer messages are appended. Mismatched and stale cursors fail validation. `getMessage()` performs an exact lookup. Transfer identifiers are limited to 512 bytes, text and reasoning parts to 96 KiB, complete messages to 480 KiB, and complete page envelopes to 512 KiB. A page may therefore contain fewer messages than requested. Oversized text is truncated and an otherwise oversized parts collection is replaced with an explicit elision marker; metadata that still cannot fit fails validation. Canonical private Agent events are unchanged.
|
|
611
|
+
`listMessagePage()` returns the newest contiguous page in chronological order. `limit` must be an integer from 1 through 50 and defaults to 50. `nextCursor` is opaque, limited to 4096 UTF-8 bytes, bound to the resolved storage namespace and session, and remains stable when newer messages are appended. Mismatched and stale cursors fail validation. Each page carries `startIndex`, the zero-based index of its first message in the session's visible history (for an empty page, the index the page ends at), so a consumer can order and page by absolute position. Appending messages leaves every index unchanged; a branch after an undo reuses the positions of the history it replaces, so a consumer re-reads its pages after `session.history.changed`. `getMessage()` performs an exact lookup. Transfer identifiers are limited to 512 bytes, text and reasoning parts to 96 KiB, complete messages to 480 KiB, and complete page envelopes to 512 KiB. A page may therefore contain fewer messages than requested. Oversized text is truncated and an otherwise oversized parts collection is replaced with an explicit elision marker; metadata that still cannot fit fails validation. Canonical private Agent events are unchanged.
|
|
612
612
|
|
|
613
|
-
`updateSession()` supports title replacement, explicit title clearing with `null`, and archive state through `archived`. Title-only updates remain available while prompts are queued or running, while permission is pending, and after archival. Requests containing `archived` are rejected while the session has any outstanding prompt or pending permission; a mixed title-and-archive request is rejected atomically without changing the title. Archived sessions expose `archivedAt`. Deleting a session cascades through its complete descendant subtree. One durable root-keyed tombstone group hides every newly affected live session, and the delete also joins any already-separate descendant cleanup groups without rewriting their roots. FlexHarness then cancels queued and active subtree work, emits terminal queue events, waits for admitted initialization, and purges runtime queue status while cleaning runtime and persisted domains child-first. The requested root tombstone is removed last after every domain confirms cleanup; project-management cleanup confirmation is a retained durable project tombstone rather than physical removal. A successful live `deleteSession()` call emits `session.deleted` for each session it newly tombstoned; retries of an existing tombstone and automatic load, retirement, or disposal cleanup emit no deletion events. Direct deletion of a descendant cascades only through that descendant's subtree. Cleanup authority follows the resolved storage namespace, so scope aliases share the same groups. A partial failure retains durable ownership for retry by a later `deleteSession()`, namespace load, `retireScope()`, or `dispose()` call.
|
|
613
|
+
`updateSession()` supports title replacement, explicit title clearing with `null`, and archive state through `archived`. Title-only updates remain available while prompts are queued or running, while permission is pending, and after archival. Requests containing `archived` are rejected while the session has any outstanding prompt or pending permission; a mixed title-and-archive request is rejected atomically without changing the title. Archived sessions expose `archivedAt`. Deleting a session cascades through its complete descendant subtree. One durable root-keyed tombstone group hides every newly affected live session, and the delete also joins any already-separate descendant cleanup groups without rewriting their roots. FlexHarness then cancels queued and active subtree work, emits terminal queue events, waits for admitted initialization, and purges runtime queue status while cleaning runtime and persisted domains child-first. The requested root tombstone is removed last after every domain confirms cleanup; project-management cleanup confirmation is a retained durable project tombstone rather than physical removal. An imported session can hold no project-management state, so its deletion writes no project tombstone. A successful live `deleteSession()` call emits `session.deleted` for each session it newly tombstoned; retries of an existing tombstone and automatic load, retirement, or disposal cleanup emit no deletion events. Direct deletion of a descendant cascades only through that descendant's subtree. Cleanup authority follows the resolved storage namespace, so scope aliases share the same groups. A partial failure retains durable ownership for retry by a later `deleteSession()`, namespace load, `retireScope()`, or `dispose()` call.
|
|
614
614
|
|
|
615
615
|
`deleteSessionGenerationCohort()` is the generation-fenced destructive form for controllers. Its `root` and every `authorizedCohort` entry use the exact `{ sessionId, sessionGenerationId, sessionGenerationSequence }` shape. The cohort contains unique entries in strictly ascending `sessionId` order and is limited by `FLEX_SESSION_GENERATION_COHORT_MAX_ENTRIES` (2048). FlexHarness atomically validates the matching root, its complete live subtree, and every retained descendant tombstone group before reserving deletion. A missing or different root generation returns `{ matched: false }` without touching a newer generation; a missing or mismatched cascade entry throws before new tombstoning or cleanup. Extra valid entries do not expand the cascade. A matched partial cleanup remains retryable with the same authority and resolves to `{ matched: true }` when cleanup completes. The existing `deleteSession()` method remains available for callers that intentionally own the complete reusable-ID namespace.
|
|
616
616
|
|
|
@@ -790,7 +790,7 @@ Workspace reversion is generic and application-defined. It does not reverse netw
|
|
|
790
790
|
|
|
791
791
|
Every configured value must be an integer from 1 through its hard maximum. Pruning removes complete prefixes rather than splitting an undo unit. Excluded run IDs prevent a committed branch from re-entering model context, while pending releases retain provider ownership until acknowledgement.
|
|
792
792
|
|
|
793
|
-
`retireScope()` stops runtime ownership for the complete resolved storage namespace without deleting its durable snapshot. It does not load a namespace that has no cached or in-flight state. For loaded state, it preserves and waits for persistence that has already started, while later queued reads, writes, and run admissions reject with `FlexHarnessAbortError`. It cancels queued prompts and cancellable runs, rejects pending permissions, emits queue terminal events, waits for committing runs, terminal persistence, queue drains, tool-handle closure, and detached tool-provider cleanup, then purges queue status and clears and evicts the cached state. Failed cleanup ownership remains cached so a later `retireScope()` or `dispose()` call can retry it. Calls through storage-key aliases share the same retirement drain. A later call can load the durable namespace again after successful retirement if the application still resolves it.
|
|
793
|
+
`retireScope()` stops runtime ownership for the complete resolved storage namespace without deleting its durable snapshot. It does not load a namespace that has no cached or in-flight state. For loaded state, it preserves and waits for persistence that has already started, while later queued reads, writes, and run admissions reject with `FlexHarnessAbortError`. It cancels queued prompts and cancellable runs, rejects pending permissions, emits queue terminal events, waits for committing runs, terminal persistence, queue drains, tool-handle closure, and detached tool-provider cleanup, then purges queue status and clears and evicts the cached state. Failed cleanup ownership remains cached so a later `retireScope()` or `dispose()` call can retry it. Calls through storage-key aliases share the same retirement drain. A later call can load the durable namespace again after successful retirement if the application still resolves it. A loaded namespace keeps every session's messages in memory, so `retireScope()` is also the supported way for a host to evict a scope it has stopped using, such as an opened archive of imported sessions. Retirement releases every staged session import and cancels queued prompts and runs, so a host retires only a scope with no open import and no work it still wants.
|
|
794
794
|
|
|
795
795
|
Normal retirement-induced cancellation does not make `retireScope()` reject. Unexpected failures observed through run finalization or scoped cleanup are surfaced without dropping the resources that still require cleanup. One such failure is thrown directly; multiple failures are reported through `FlexHarnessRunError`. Calling retirement or disposal again retries retained cleanup ownership.
|
|
796
796
|
|
|
@@ -886,7 +886,7 @@ Some bounds are fixed:
|
|
|
886
886
|
|
|
887
887
|
Staged runs are held in memory until the commit, so the memory of open imports is bounded by `maxOpenImports` × `maxSessionBytes`. Retiring the scope, disposing the harness or the idle expiry discards staged imports. The expiry timer does not keep the process alive.
|
|
888
888
|
|
|
889
|
-
**Stores.** The import adds no store method. Scope snapshots carry the optional session `origin`, and a store that validates session keys exactly must accept it. The commit writes the whole projection in one save at revision 1. FlexHarness versions before 9.5.0 reject the new key under their strict reader, so a downgrade over imported sessions is unsupported.
|
|
889
|
+
**Stores.** The import adds no store method. Scope snapshots carry the optional session `origin`, and a store that validates session keys exactly must accept it. The commit writes the whole projection in one save at revision 1. FlexHarness versions before 9.5.0 reject the new key under their strict reader, so a downgrade over imported sessions is unsupported. The tombstone that reserves an import, or that deletes an imported session, carries the optional `imported: true`, and a store that validates tombstone keys exactly must accept it. FlexHarness 9.5.x rejects a scope snapshot that holds such a tombstone; one exists only while an import commits or an imported session is deleted, or after either was interrupted.
|
|
890
890
|
|
|
891
891
|
## Permissions
|
|
892
892
|
|
package/ts/utils.json.ts
CHANGED
|
@@ -942,6 +942,7 @@ export function assertFlexScopeSnapshot(value: unknown): asserts value is IFlexS
|
|
|
942
942
|
'depth',
|
|
943
943
|
'parentSessionId',
|
|
944
944
|
'subagent',
|
|
945
|
+
'imported',
|
|
945
946
|
],
|
|
946
947
|
path,
|
|
947
948
|
);
|
|
@@ -967,6 +968,9 @@ export function assertFlexScopeSnapshot(value: unknown): asserts value is IFlexS
|
|
|
967
968
|
`${path}.subagent does not match its parentSessionId.`,
|
|
968
969
|
);
|
|
969
970
|
}
|
|
971
|
+
if (tombstone.imported !== undefined && tombstone.imported !== true) {
|
|
972
|
+
throw new FlexHarnessStoreFormatError(`${path}.imported must be true when present.`);
|
|
973
|
+
}
|
|
970
974
|
const hasRoot = tombstone.rootSessionId !== undefined;
|
|
971
975
|
const hasDepth = tombstone.depth !== undefined;
|
|
972
976
|
if (hasRoot !== hasDepth) {
|