@llblab/pi-kit 0.28.0 → 0.29.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/BACKLOG.md +2 -1
- package/CHANGELOG.md +4 -0
- package/README.md +3 -3
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +2 -2
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +5 -2
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +7 -0
- package/node_modules/@llblab/pi-state-flow/README.md +7 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +94 -47
- package/node_modules/@llblab/pi-state-flow/dist/lib/recovery.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +8 -27
- package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +16 -151
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.d.ts +3 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/snapshot.js +4 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +1 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +4 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +2 -0
- package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +5 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +0 -4
- package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +0 -36
- package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +20 -31
- package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +8 -9
- package/node_modules/@llblab/pi-state-flow/docs/filesystem-recovery.md +4 -4
- package/node_modules/@llblab/pi-state-flow/docs/fork-contract.md +18 -23
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +19 -21
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +24 -25
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +89 -48
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +22 -146
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +6 -3
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +4 -2
- package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +7 -1
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +0 -36
- package/node_modules/@llblab/pi-state-flow/package.json +1 -1
- package/package.json +2 -2
|
@@ -9,8 +9,6 @@ const MAX_LEGACY_VALIDATION_ATTEMPT = 7;
|
|
|
9
9
|
/** Missing operational capability is not evidence that a checkpoint target is invalid. */
|
|
10
10
|
export class RevisionUnavailableError extends Error {}
|
|
11
11
|
|
|
12
|
-
/** Expired history cannot be restored, but explicit activation may use validated current memory. */
|
|
13
|
-
export class HistoryBoundaryExpiredError extends RevisionUnavailableError {}
|
|
14
12
|
|
|
15
13
|
export type StateFlowMode = "active" | "passive" | "off";
|
|
16
14
|
export type InactiveMode = Exclude<StateFlowMode, "active">;
|
|
@@ -57,6 +55,11 @@ export interface StateFlowSnapshot {
|
|
|
57
55
|
|
|
58
56
|
export type Snapshot = StateFlowSnapshot;
|
|
59
57
|
|
|
58
|
+
/** Failed Active selection retains its policy and fences inference until explicit recovery or an inactive choice. */
|
|
59
|
+
export function isActiveRestorationBlocked(snapshot: Snapshot): boolean {
|
|
60
|
+
return snapshot.config.mode === "active" && snapshot.meta.validation?.attempt === 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
60
63
|
export interface SessionRuntime {
|
|
61
64
|
config: SnapshotConfig;
|
|
62
65
|
meta: SnapshotMeta & {
|
|
@@ -249,7 +252,7 @@ export function parseRetainedPiCheckpoint(value: unknown, inactiveMode: Inactive
|
|
|
249
252
|
};
|
|
250
253
|
}
|
|
251
254
|
|
|
252
|
-
export function migrationFailure(data: JsonObject, error: string, mode:
|
|
255
|
+
export function migrationFailure(data: JsonObject, error: string, mode: StateFlowMode = "passive"): Snapshot {
|
|
253
256
|
const meta = restoredMeta(data.meta, data);
|
|
254
257
|
meta.validation = {
|
|
255
258
|
attempt: 0,
|
|
@@ -2,7 +2,7 @@ import type { ArtifactInvalidationReason } from "./artifact.ts";
|
|
|
2
2
|
import type { RecentTransitionWindow } from "./history.ts";
|
|
3
3
|
import { ownedTopLevelKeys } from "./ownership.ts";
|
|
4
4
|
import { conciseDiagnostic } from "./protocol.ts";
|
|
5
|
-
import type
|
|
5
|
+
import { isActiveRestorationBlocked, type Snapshot } from "./snapshot.ts";
|
|
6
6
|
import { overlayStates, projectSemanticState, type SemanticState, type ScopedStates, type StateScope } from "./state.ts";
|
|
7
7
|
import type { ScopeRevisions, TransitionBoundary } from "./temporal.ts";
|
|
8
8
|
|
|
@@ -40,7 +40,7 @@ export function formatScopeRevisionVector(revisions: ScopeRevisions): string {
|
|
|
40
40
|
export function compactStatus(snapshot: Snapshot, _revisions: ScopeRevisions, colorize: Colorize): string | undefined {
|
|
41
41
|
const { mode } = snapshot.config;
|
|
42
42
|
if (mode === "off") return undefined;
|
|
43
|
-
return `${colorize("accent", "state-flow")} ${colorize("dim", mode)}`;
|
|
43
|
+
return `${colorize("accent", "state-flow")} ${colorize("dim", isActiveRestorationBlocked(snapshot) ? "active (blocked)" : mode)}`;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function countArtifacts(states: ScopedStates, scope: StateScope): number {
|
|
@@ -101,6 +101,8 @@ export function detailedStatus(snapshot: Snapshot, diagnostics: StatusDiagnostic
|
|
|
101
101
|
const hasArtifacts = available && (["global", "cwd", "session"] as const).some((scope) => artifacts(scope) > 0);
|
|
102
102
|
|
|
103
103
|
return [
|
|
104
|
+
`Mode: ${snapshot.config.mode}`,
|
|
105
|
+
...(isActiveRestorationBlocked(snapshot) ? ["Inference blocked: Active memory restoration failed. Use /state-flow-active for current memory or select Passive/Off for native context."] : []),
|
|
104
106
|
`Repository: ${diagnostics.repositoryRoot}`,
|
|
105
107
|
`Scope keys: CWD ${diagnostics.cwdScopeKey}; session ${diagnostics.sessionScopeKey}`,
|
|
106
108
|
...temporalLines,
|
|
@@ -21,6 +21,8 @@ export function stateFlowTelegramSectionSpecifiers(moduleUrl = import.meta.url):
|
|
|
21
21
|
export interface StateFlowTelegramSnapshot {
|
|
22
22
|
/** The current session's selected mode. */
|
|
23
23
|
mode: StateFlowMode;
|
|
24
|
+
/** Failed Active restoration fences inference without silently selecting an inactive mode. */
|
|
25
|
+
inferenceBlocked?: boolean;
|
|
24
26
|
/** Legacy branch step retained for existing adapter ports; current runtime ports also supply owner revisions. */
|
|
25
27
|
step: number;
|
|
26
28
|
revisions?: ScopeRevisions;
|
|
@@ -132,7 +134,7 @@ export interface StateFlowTelegramAdapter {
|
|
|
132
134
|
|
|
133
135
|
/** Main-menu section label shows only the current session mode. */
|
|
134
136
|
export function formatStateFlowSectionLabel(snapshot: StateFlowTelegramSnapshot): string {
|
|
135
|
-
return `🌀 State Flow: ${snapshot.mode}`;
|
|
137
|
+
return `🌀 State Flow: ${snapshot.mode}${snapshot.mode === "active" && snapshot.inferenceBlocked ? " (blocked)" : ""}`;
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
export const STATE_FLOW_MODES = ["off", "passive", "active"] as const satisfies readonly StateFlowMode[];
|
|
@@ -160,6 +162,10 @@ export function buildStateFlowSectionView(
|
|
|
160
162
|
return {
|
|
161
163
|
text: [
|
|
162
164
|
`<b>🌀 State Flow:</b> <code>${snapshot.mode}</code>`,
|
|
165
|
+
...(snapshot.mode === "active" && snapshot.inferenceBlocked ? [
|
|
166
|
+
"",
|
|
167
|
+
"<b>Inference blocked:</b> Active memory restoration failed. Select Active to accept current session memory, or Passive/Off to permit native context.",
|
|
168
|
+
] : []),
|
|
163
169
|
"",
|
|
164
170
|
"<b>Mode</b> — choose a workflow (switching modes never erases stored memory):",
|
|
165
171
|
"",
|
|
@@ -235,42 +235,6 @@ export function constrainTemporalState(view: TemporalState, historyLimit: number
|
|
|
235
235
|
return next;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
/** Select one scope at a proven retained boundary from its owning runtime lineage. */
|
|
239
|
-
export function selectScopeStreamAtBoundary(stream: ScopeStream, scope: StateScope, boundary: TransitionBoundary, historyLimit = DEFAULT_HISTORY_LIMIT): ScopeStream {
|
|
240
|
-
validateHistoryLimit(historyLimit);
|
|
241
|
-
validateBoundary(boundary);
|
|
242
|
-
validateScopeStream(stream, scope, historyLimit);
|
|
243
|
-
if (boundary.position < stream.checkpoint.through.position) {
|
|
244
|
-
throw new Error("Selected State Flow history boundary predates the retained scope checkpoint");
|
|
245
|
-
}
|
|
246
|
-
const selected = structuredClone(stream);
|
|
247
|
-
const retained = selected.patches.filter(({ transition }) => transition.position <= boundary.position);
|
|
248
|
-
selected.revision -= selected.patches.length - retained.length;
|
|
249
|
-
selected.patches = retained;
|
|
250
|
-
validateScopeStream(selected, scope, historyLimit);
|
|
251
|
-
return selected;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/** Select one still-retained causal boundary without consulting an external history store. */
|
|
255
|
-
export function selectTemporalStateBoundary(view: TemporalState, boundaryId: string, historyLimit = DEFAULT_HISTORY_LIMIT): TemporalState {
|
|
256
|
-
validateHistoryLimit(historyLimit);
|
|
257
|
-
validateTemporalState(view, historyLimit);
|
|
258
|
-
if (typeof boundaryId !== "string" || boundaryId.trim().length === 0) throw new Error("State Flow temporal boundary identity must be non-empty");
|
|
259
|
-
const index = view.lineage.findIndex(({ id }) => id === boundaryId);
|
|
260
|
-
if (index < 0) throw new Error("Selected State Flow history boundary is outside the retained temporal window");
|
|
261
|
-
const target = view.lineage[index]!;
|
|
262
|
-
const selected = structuredClone(view);
|
|
263
|
-
selected.lineage = selected.lineage.slice(0, index + 1);
|
|
264
|
-
for (const scope of SCOPES) {
|
|
265
|
-
const stream = selected.scopes[scope];
|
|
266
|
-
const retained = stream.patches.filter(({ transition }) => transition.position <= target.position);
|
|
267
|
-
stream.revision -= stream.patches.length - retained.length;
|
|
268
|
-
stream.patches = retained;
|
|
269
|
-
}
|
|
270
|
-
validateTemporalState(selected, historyLimit);
|
|
271
|
-
return selected;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
238
|
/** Current independent scope revisions; Effective uses this vector rather than inventing a scalar owner. */
|
|
275
239
|
export function temporalScopeRevisions(view: TemporalState): ScopeRevisions {
|
|
276
240
|
const revisions = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@llblab/pi-clean-room": "0.3.0",
|
|
47
47
|
"@llblab/pi-codex-usage": "0.12.1",
|
|
48
48
|
"@llblab/pi-grow-loop": "0.9.0",
|
|
49
|
-
"@llblab/pi-state-flow": "0.
|
|
49
|
+
"@llblab/pi-state-flow": "0.26.0",
|
|
50
50
|
"@llblab/pi-telegram": "0.52.0",
|
|
51
51
|
"@llblab/skills": "1.15.0"
|
|
52
52
|
},
|