@modelprofile.com/flexharness 4.0.1 → 4.0.2
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/changelog.md +9 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.js +3 -3
- package/dist_ts/interfaces.d.ts +5 -1
- package/dist_ts/interfaces.js +1 -1
- package/package.json +1 -1
- package/readme.md +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.ts +10 -2
- package/ts/interfaces.ts +6 -0
package/dist_ts/interfaces.d.ts
CHANGED
|
@@ -441,6 +441,10 @@ export interface IFlexPermissionSnapshot {
|
|
|
441
441
|
}
|
|
442
442
|
export declare const FLEX_PROJECT_MANAGEMENT_SCHEMA_VERSION: 1;
|
|
443
443
|
export declare const FLEX_SESSION_GENERATION_ID_MAX_BYTES = 128;
|
|
444
|
+
export interface IFlexSessionGeneration {
|
|
445
|
+
sessionGenerationId: string;
|
|
446
|
+
sessionGenerationSequence: number;
|
|
447
|
+
}
|
|
444
448
|
export declare const FLEX_PROJECT_MANAGEMENT_LIMITS: Readonly<{
|
|
445
449
|
maxGoalBytes: number;
|
|
446
450
|
maxScratchpadBytes: number;
|
|
@@ -485,7 +489,7 @@ export interface IFlexProjectManagementWriteContext {
|
|
|
485
489
|
toolCallId?: string;
|
|
486
490
|
}
|
|
487
491
|
export interface IFlexProjectManagementStore {
|
|
488
|
-
load(storageKey: string, sessionId: string): Promise<TFlexProjectManagementRecord | undefined>;
|
|
492
|
+
load(storageKey: string, sessionId: string, sessionGeneration?: Readonly<IFlexSessionGeneration>): Promise<TFlexProjectManagementRecord | undefined>;
|
|
489
493
|
save(storageKey: string, sessionId: string, snapshot: IFlexProjectManagementSnapshot, expectedRevision: number, writeContext: IFlexProjectManagementWriteContext): Promise<void>;
|
|
490
494
|
tombstoneSession(storageKey: string, sessionId: string, tombstone: IFlexProjectManagementTombstone, expectedRevision: number): Promise<void>;
|
|
491
495
|
purgeNamespace(storageKey: string): Promise<void>;
|
package/dist_ts/interfaces.js
CHANGED
|
@@ -26,4 +26,4 @@ export const FLEX_REVERSION_MAX_AFFECTED_WORKSPACES = 64;
|
|
|
26
26
|
export const FLEX_REVERSION_WORKSPACE_ID_MAX_BYTES = 512;
|
|
27
27
|
export const FLEX_REVERSION_WORKSPACE_LABEL_MAX_BYTES = 2048;
|
|
28
28
|
export const FLEX_REVERSION_REASON_CODE_MAX_BYTES = 128;
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBMGpCQSxNQUFNLENBQUMsTUFBTSxzQ0FBc0MsR0FBRyxDQUFVLENBQUM7QUFDakUsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQUcsR0FBRyxDQUFDO0FBT3hELE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUQsWUFBWSxFQUFFLENBQUMsR0FBRyxJQUFJO0lBQ3RCLGtCQUFrQixFQUFFLEdBQUcsR0FBRyxJQUFJO0lBQzlCLG1CQUFtQixFQUFFLENBQUMsR0FBRyxJQUFJO0lBQzdCLGNBQWMsRUFBRSxHQUFHO0lBQ25CLFFBQVEsRUFBRSxHQUFHO0lBQ2IsYUFBYSxFQUFFLElBQUk7SUFDbkIsZ0JBQWdCLEVBQUUsSUFBSSxHQUFHLElBQUk7Q0FDOUIsQ0FBQyxDQUFDO0FBMExILE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDekQsaUJBQWlCLEVBQUUsR0FBRztJQUN0QixXQUFXLEVBQUUsR0FBRztJQUNoQixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLDJCQUEyQixFQUFFLElBQUk7Q0FDbEMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN6RCxpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLGlCQUFpQixFQUFFLE1BQU07SUFDekIsMkJBQTJCLEVBQUUsTUFBTTtDQUNwQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzdELE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLEVBQUUsQ0FBQztBQUN6RCxNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxHQUFHLENBQUM7QUFDekQsTUFBTSxDQUFDLE1BQU0sd0NBQXdDLEdBQUcsSUFBSSxDQUFDO0FBQzdELE1BQU0sQ0FBQyxNQUFNLG9DQUFvQyxHQUFHLEdBQUcsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/flexharness",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
package/readme.md
CHANGED
|
@@ -241,7 +241,7 @@ Public writes use `{ actor: 'application' }`. Tool writes use `{ actor: 'agent',
|
|
|
241
241
|
|
|
242
242
|
`FLEX_PROJECT_MANAGEMENT_LIMITS` exports the hard UTF-8 and aggregate limits: goal 8 KiB, scratchpad 128 KiB, task content 8 KiB, task ID 512 bytes, title 2048 bytes, 512 tasks, and a 1 MiB serialized snapshot. The aggregate bound leaves room for worst-case JSON escaping of a controller-valid scratchpad. Loaded snapshots reject extra fields, duplicate IDs, invalid status/priority/timestamps, non-JSON data, wrong schema/revision, and every exceeded bound before use.
|
|
243
243
|
|
|
244
|
-
`IFlexProjectManagementStore` is exact per `(storageKey, sessionId)`: `load`, CAS `save`, CAS `tombstoneSession`, and `purgeNamespace` must not collapse multiple sessions or storage namespaces. `load()` returns `TFlexProjectManagementRecord | undefined
|
|
244
|
+
`IFlexProjectManagementStore` is exact per `(storageKey, sessionId)`: `load`, CAS `save`, CAS `tombstoneSession`, and `purgeNamespace` must not collapse multiple sessions or storage namespaces. `load()` returns `TFlexProjectManagementRecord | undefined` and receives the current session generation as an optional third argument; FlexHarness always supplies it, while two-argument callers and stores remain compatible. Same-generation live saves use normal revision CAS, and a same-generation tombstone permanently rejects later live saves. A higher `sessionGenerationSequence` with a different strong `sessionGenerationId` may replace only an older tombstone using expected revision `0`; it cannot replace a live record. This resets the PM revision for a recreated core session while stale saves and tombstones from older generations remain fenced. Deleting a recreated session that made no PM writes still replaces the prior-generation tombstone with a revision-1 tombstone for the new generation.
|
|
245
245
|
|
|
246
246
|
Every newly created core session exposes and persists a strong random `sessionGenerationId` plus its monotonic `sessionGenerationSequence`. A legacy scope session without those fields is assigned a deterministic bounded ID derived from its immutable `storageKey`, `sessionId`, and `createdAt`; FlexHarness persists the repaired scope snapshot before accepting work. Grouped core deletion tombstones retain both fields after live metadata is removed.
|
|
247
247
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@modelprofile.com/flexharness',
|
|
6
|
-
version: '4.0.
|
|
6
|
+
version: '4.0.2',
|
|
7
7
|
description: 'Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.'
|
|
8
8
|
}
|
|
@@ -4391,7 +4391,11 @@ export class FlexHarness<TScope = unknown> {
|
|
|
4391
4391
|
): Promise<IFlexProjectManagementSnapshot> {
|
|
4392
4392
|
const store = this.stores.projectManagement;
|
|
4393
4393
|
const generation = requireSessionGeneration(stored.session);
|
|
4394
|
-
const record = await store.load(
|
|
4394
|
+
const record = await store.load(
|
|
4395
|
+
state.storageKey,
|
|
4396
|
+
stored.session.sessionId,
|
|
4397
|
+
Object.freeze({ ...generation }),
|
|
4398
|
+
);
|
|
4395
4399
|
if (record === undefined) {
|
|
4396
4400
|
return createEmptyFlexProjectManagementSnapshot(
|
|
4397
4401
|
generation.sessionGenerationId,
|
|
@@ -8795,7 +8799,11 @@ export class FlexHarness<TScope = unknown> {
|
|
|
8795
8799
|
const generation = requireSessionGeneration(sessionTombstone);
|
|
8796
8800
|
let lastConflict: FlexHarnessStoreConflictError | undefined;
|
|
8797
8801
|
for (let attempt = 0; attempt <= maxProjectManagementTombstoneConflicts; attempt++) {
|
|
8798
|
-
const current = await store.load(
|
|
8802
|
+
const current = await store.load(
|
|
8803
|
+
storageKey,
|
|
8804
|
+
sessionId,
|
|
8805
|
+
Object.freeze({ ...generation }),
|
|
8806
|
+
);
|
|
8799
8807
|
if (current !== undefined) {
|
|
8800
8808
|
assertFlexProjectManagementRecord(current);
|
|
8801
8809
|
if (current.sessionGenerationId === generation.sessionGenerationId) {
|
package/ts/interfaces.ts
CHANGED
|
@@ -571,6 +571,11 @@ export interface IFlexPermissionSnapshot {
|
|
|
571
571
|
export const FLEX_PROJECT_MANAGEMENT_SCHEMA_VERSION = 1 as const;
|
|
572
572
|
export const FLEX_SESSION_GENERATION_ID_MAX_BYTES = 128;
|
|
573
573
|
|
|
574
|
+
export interface IFlexSessionGeneration {
|
|
575
|
+
sessionGenerationId: string;
|
|
576
|
+
sessionGenerationSequence: number;
|
|
577
|
+
}
|
|
578
|
+
|
|
574
579
|
export const FLEX_PROJECT_MANAGEMENT_LIMITS = Object.freeze({
|
|
575
580
|
maxGoalBytes: 8 * 1024,
|
|
576
581
|
maxScratchpadBytes: 128 * 1024,
|
|
@@ -628,6 +633,7 @@ export interface IFlexProjectManagementStore {
|
|
|
628
633
|
load(
|
|
629
634
|
storageKey: string,
|
|
630
635
|
sessionId: string,
|
|
636
|
+
sessionGeneration?: Readonly<IFlexSessionGeneration>,
|
|
631
637
|
): Promise<TFlexProjectManagementRecord | undefined>;
|
|
632
638
|
save(
|
|
633
639
|
storageKey: string,
|