@caupulican/pi-adaptative 0.96.4 → 0.96.5

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 (47) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +8 -0
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +3 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/agent-session-contracts.d.ts +1 -1
  8. package/dist/core/agent-session-contracts.d.ts.map +1 -1
  9. package/dist/core/agent-session-contracts.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +2 -0
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +29 -14
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -1
  15. package/dist/core/goals/goal-lifecycle.js +5 -1
  16. package/dist/core/goals/goal-lifecycle.js.map +1 -1
  17. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  18. package/dist/core/goals/goal-session-controller.js +3 -1
  19. package/dist/core/goals/goal-session-controller.js.map +1 -1
  20. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  21. package/dist/core/goals/goal-tool-core.js +32 -7
  22. package/dist/core/goals/goal-tool-core.js.map +1 -1
  23. package/dist/core/learning/durable-learning-state.d.ts +76 -0
  24. package/dist/core/learning/durable-learning-state.d.ts.map +1 -0
  25. package/dist/core/learning/durable-learning-state.js +493 -0
  26. package/dist/core/learning/durable-learning-state.js.map +1 -0
  27. package/dist/core/reflection-controller.d.ts +37 -7
  28. package/dist/core/reflection-controller.d.ts.map +1 -1
  29. package/dist/core/reflection-controller.js +278 -49
  30. package/dist/core/reflection-controller.js.map +1 -1
  31. package/dist/core/settings-manager.js.map +1 -1
  32. package/dist/core/tools/goal.d.ts.map +1 -1
  33. package/dist/core/tools/goal.js +6 -3
  34. package/dist/core/tools/goal.js.map +1 -1
  35. package/dist/modes/interactive/components/settings-selector.js +1 -1
  36. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  37. package/docs/durable-learning-state-design.md +217 -0
  38. package/docs/settings.md +5 -3
  39. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  40. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  41. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  42. package/examples/extensions/sandbox/package-lock.json +2 -2
  43. package/examples/extensions/sandbox/package.json +1 -1
  44. package/examples/extensions/with-deps/package-lock.json +2 -2
  45. package/examples/extensions/with-deps/package.json +1 -1
  46. package/npm-shrinkwrap.json +12 -12
  47. package/package.json +4 -4
@@ -13,6 +13,7 @@ import type { Api, Model, SimpleStreamOptions, Usage } from "@caupulican/pi-ai/t
13
13
  import { type IsolatedCompletionOptions, type IsolatedCompletionResult } from "./agent-session-contracts.ts";
14
14
  import type { LearningDecision } from "./autonomy/contracts.ts";
15
15
  import { type AutonomyTelemetryEvent } from "./autonomy/telemetry-events.ts";
16
+ import { type DurableLearningClaimToken, type DurableLearningCueAttachOutcome, type DurableLearningReviewMetadata, type DurableLearningState } from "./learning/durable-learning-state.ts";
16
17
  import { type LearningAuditRecord } from "./learning/learning-audit.ts";
17
18
  import { type DemandSignals, type ReflectionResult } from "./learning/reflection-engine.ts";
18
19
  import { type ReflectionTurnAnalysis } from "./learning/reflection-turn-analysis.ts";
@@ -77,12 +78,20 @@ export interface ReflectionControllerDeps {
77
78
  getCwd?(): string;
78
79
  /** Already-loaded root skill universe; avoids a second unbounded filesystem discovery during reflection. */
79
80
  getSkillsForAudit?(): readonly Skill[];
81
+ /** Root-owned durable version transition state; omitted by legacy or test hosts. */
82
+ getDurableLearningState?(): DurableLearningState | undefined;
83
+ /** Installed runtime identity used only for root-owned durable transition detection. */
84
+ getRuntimeVersion?(): string | undefined;
85
+ /** Versioned durable-memory interpretation policy. */
86
+ getMemoryPolicyVersion?(): string | undefined;
87
+ /** Bounded host warning sink for fail-safe state degradation. */
88
+ warn?(message: string): void;
80
89
  }
81
90
  export declare const SKILL_OVERLAP_CONSOLIDATION_REASON_CODE = "skill_overlap_consolidation_proposed";
82
91
  export declare const SKILL_AUDIT_UNAVAILABLE_REASON_CODE = "skill_audit_unavailable";
83
92
  export declare const CURRENT_TURN_REFLECTION_CUSTOM_TYPE = "reflection_cue";
84
93
  export declare const CURRENT_TURN_REFLECTION_STATE_CUSTOM_TYPE = "reflection_cue_state";
85
- export type CurrentTurnReflectionTrigger = "root-turn" | Exclude<DemandSignals["trigger"], "none">;
94
+ export type CurrentTurnReflectionTrigger = "root-turn" | "version-change" | Exclude<DemandSignals["trigger"], "none">;
86
95
  export interface CurrentTurnReflectionCueState {
87
96
  version: 1;
88
97
  revision: number;
@@ -91,6 +100,13 @@ export interface CurrentTurnReflectionCueState {
91
100
  triggers: CurrentTurnReflectionTrigger[];
92
101
  createdAt: string;
93
102
  updatedAt: string;
103
+ /** Provider-hidden token proving exact ownership of one version transition. */
104
+ versionChange?: {
105
+ token: DurableLearningClaimToken;
106
+ metadata: DurableLearningReviewMetadata;
107
+ };
108
+ /** Provider-hidden identity of the currently accepted cue-bearing request. */
109
+ activeRunToken?: string;
94
110
  }
95
111
  export interface CurrentTurnReflectionCuePlan {
96
112
  message: AgentMessage;
@@ -100,27 +116,41 @@ export interface CurrentTurnReflectionCuePlan {
100
116
  export declare class ReflectionController {
101
117
  private readonly deps;
102
118
  private readonly unsubscribeSettingsChanges;
119
+ private readonly durableLearningOwnerId;
120
+ private readonly emittedWarningCodes;
103
121
  private cueStateCacheInitialized;
104
122
  private cueStateCache;
123
+ private activeRunToken;
105
124
  constructor(deps: ReflectionControllerDeps);
106
125
  dispose(): void;
107
126
  private isAutomaticReflectionEnabled;
108
127
  /** Latest durable cue snapshot on the active session branch; custom state never enters model context. */
109
128
  getCurrentTurnCueState(): CurrentTurnReflectionCueState | undefined;
110
129
  /** Branch/session navigation invalidates the lazy latest-state index; ordinary appends do not. */
111
- invalidateCurrentTurnCueStateCache(): void;
130
+ invalidateCurrentTurnCueStateCache(options?: {
131
+ releaseActiveClaim?: boolean;
132
+ }): void;
112
133
  private persistCurrentTurnCueState;
134
+ private warnOnce;
135
+ private dismissCurrentTurnCue;
113
136
  private synchronizeCurrentTurnCueWithSettings;
137
+ private attachCurrentTurnCue;
138
+ /** Persist one logical ordinary cue without exposing claim metadata to callers. */
139
+ queueCurrentTurnCue(trigger: CurrentTurnReflectionTrigger): boolean;
114
140
  /**
115
- * Persist one logical pending cue. Repeated triggers merge into the existing pending snapshot;
116
- * they never append competing pending cues or retain raw transcript text.
141
+ * Root-turn entrypoint: reconcile installed runtime/policy state and atomically attach any exact
142
+ * version claim to the same provider cue. Fail-safe state faults degrade to an ordinary root cue.
117
143
  */
118
- queueCurrentTurnCue(trigger: CurrentTurnReflectionTrigger): boolean;
144
+ queueExternalRootTurnCue(): DurableLearningCueAttachOutcome;
119
145
  /**
120
- * Preview one transient provider-only cue. Discarded/replanned previews do nothing; the accepted
121
- * provider-plan commit closes exactly the captured cue id + revision.
146
+ * Preview one transient provider-only cue. An accepted cue remains visible across provider-tool
147
+ * continuation requests until AgentSession reports one strict terminal success or failure.
122
148
  */
123
149
  previewCurrentTurnCue(): CurrentTurnReflectionCuePlan | undefined;
150
+ /** Settle one accepted cue-bearing provider run at its authoritative AgentSession boundary. */
151
+ finishCurrentTurnCue(messages: AgentMessage[], options: {
152
+ willRetry: boolean;
153
+ }): void;
124
154
  /** Pure completed-turn projection used only by deterministic memory synchronization. */
125
155
  analyzeCompletedTurn(messages: AgentMessage[]): ReflectionTurnAnalysis;
126
156
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"reflection-controller.d.ts","sourceRoot":"","sources":["../../src/core/reflection-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reflection-controller.d.ts","sourceRoot":"","sources":["../../src/core/reflection-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAiC,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAElH,OAAO,KAAK,EACX,GAAG,EAGH,KAAK,EACL,mBAAmB,EAEnB,KAAK,EACL,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGN,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAkC,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAG7G,OAAO,EACN,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,KAAK,oBAAoB,EAGzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAKN,KAAK,mBAAmB,EAGxB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACN,KAAK,aAAa,EAGlB,KAAK,gBAAgB,EAErB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAyB,KAAK,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAC5G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACX,+BAA+B,EAC/B,4BAA4B,EAC5B,yBAAyB,EACzB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,WAAW,wBAAwB;IACxC,sFAAsF;IACtF,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,IAAI,KAAK,CAAC;IAClB,oGAAoG;IACpG,iBAAiB,IAAI,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,gBAAgB,IAAI,aAAa,CAAC;IAClC,yGAAyG;IACzG,gBAAgB,IAAI,aAAa,CAAC;IAClC,gGAAgG;IAChG,8BAA8B,IAAI,MAAM,CAAC;IACzC,8DAA8D;IAC9D,8BAA8B,CAC7B,KAAK,EAAE,yBAAyB,EAChC,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAC5C,sEAAsE;IACtE,iCAAiC,CAAC,QAAQ,EAAE,4BAA4B,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClH,8FAA8F;IAC9F,kBAAkB,IAAI,eAAe,CAAC;IACtC,8EAA8E;IAC9E,iBAAiB,IAAI,cAAc,CAAC;IACpC,qFAAqF;IACrF,WAAW,IAAI,MAAM,CAAC;IACtB,sEAAsE;IACtE,cAAc,IAAI,OAAO,CAAC;IAC1B,gFAAgF;IAChF,UAAU,IAAI,OAAO,CAAC;IACtB,4FAA4F;IAC5F,mBAAmB,IAAI,WAAW,CAAC;IACnC,sEAAsE;IACtE,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5C,mFAAmF;IACnF,iBAAiB,CAAC,IAAI,IAAI,CAAC;IAC3B,sFAAsF;IACtF,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3D,gGAAgG;IAChG,eAAe,CACd,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GACpE,MAAM,GAAG,SAAS,CAAC;IACtB,oEAAoE;IACpE,4BAA4B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACjE,4FAA4F;IAC5F,2BAA2B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;IAC5F,0FAA0F;IAC1F,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD;;;;;OAKG;IACH,MAAM,CAAC,IAAI,MAAM,CAAC;IAClB,4GAA4G;IAC5G,iBAAiB,CAAC,IAAI,SAAS,KAAK,EAAE,CAAC;IACvC,oFAAoF;IACpF,uBAAuB,CAAC,IAAI,oBAAoB,GAAG,SAAS,CAAC;IAC7D,wFAAwF;IACxF,iBAAiB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IACzC,sDAAsD;IACtD,sBAAsB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC9C,iEAAiE;IACjE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAID,eAAO,MAAM,uCAAuC,yCAAyC,CAAC;AAG9F,eAAO,MAAM,mCAAmC,4BAA4B,CAAC;AAE7E,eAAO,MAAM,mCAAmC,mBAAmB,CAAC;AACpE,eAAO,MAAM,yCAAyC,yBAAyB,CAAC;AAEhF,MAAM,MAAM,4BAA4B,GAAG,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AAEtH,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,QAAQ,EAAE,4BAA4B,EAAE,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,aAAa,CAAC,EAAE;QACf,KAAK,EAAE,yBAAyB,CAAC;QACjC,QAAQ,EAAE,6BAA6B,CAAC;KACxC,CAAC;IACF,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,4BAA4B;IAC5C,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC;IACrB,MAAM,IAAI,IAAI,CAAC;CACf;AAkGD,qBAAa,oBAAoB;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAa;IACxD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAgB;IACvD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,cAAc,CAAqB;IAE3C,YAAY,IAAI,EAAE,wBAAwB,EAMzC;IAED,OAAO,IAAI,IAAI,CAGd;IAED,OAAO,CAAC,4BAA4B;IASpC,yGAAyG;IACzG,sBAAsB,IAAI,6BAA6B,GAAG,SAAS,CAiBlE;IAED,kGAAkG;IAClG,kCAAkC,CAAC,OAAO,GAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI,CAevF;IAED,OAAO,CAAC,0BAA0B;IAMlC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,qBAAqB;IAyB7B,OAAO,CAAC,qCAAqC;IAK7C,OAAO,CAAC,oBAAoB;IAoE5B,mFAAmF;IACnF,mBAAmB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAGlE;IAED;;;OAGG;IACH,wBAAwB,IAAI,+BAA+B,CAsC1D;IAED;;;OAGG;IACH,qBAAqB,IAAI,4BAA4B,GAAG,SAAS,CAkFhE;IAED,+FAA+F;IAC/F,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CA6DpF;IAED,wFAAwF;IACxF,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,sBAAsB,CAOrE;IAED;;;;;;;;;;;;;OAaG;IACG,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAyO9F;IAED;;;;;;;;OAQG;IACG,iBAAiB,CAAC,KAAK,EAAE;QAC9B,OAAO,EAAE,aAAa,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,8FAA8F;QAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,kGAAkG;QAClG,6BAA6B,CAAC,EAAE,OAAO,CAAC;KACxC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgNnC;IAED,uBAAuB,IAAI,mBAAmB,EAAE,CAE/C;IAED;;;;;OAKG;IACG,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CA8FrF;IAED;;;;;;OAMG;YACW,qBAAqB;IAoGnC;;;;;;;;;OASG;IACH,OAAO,CAAC,2BAA2B;IA0CnC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;CAwB/B"}
@@ -15,6 +15,7 @@ import { computeLaneAffinityKey, DEFAULT_ISOLATED_LANE_KIND, } from "./agent-ses
15
15
  import { AUTONOMY_TELEMETRY_EVENT_TYPES } from "./autonomy/telemetry-events.js";
16
16
  import { PI_OKF_TYPES } from "./context/okf-memory.js";
17
17
  import { isCurrentSessionReflectionEnabled, resolveAutoLearnSettings } from "./learning/auto-learn-settings.js";
18
+ import { isDurableLearningClaimToken, isDurableLearningReviewMetadata, } from "./learning/durable-learning-state.js";
18
19
  import { APPLY_WRITE_REFUSED_REASON_CODE, appendLearningAuditSnapshot, contradictionsForReflectionWrite, getLearningAuditSnapshots, proposalFromReflectionWrite, rollbackPlanForReflectionWrite, } from "./learning/learning-audit.js";
19
20
  import { evaluateLearningDecision } from "./learning/learning-gate.js";
20
21
  import { ObservationStore, observationKey } from "./learning/observation-store.js";
@@ -34,11 +35,14 @@ const CURRENT_TURN_REFLECTION_CUE = [
34
35
  "Root reflection contract for this current turn:",
35
36
  "- Decide during this same turn whether the request or resulting evidence warrants durable learning.",
36
37
  "- When warranted, confront existing memory first, then use this root session's memory or skill tools now.",
38
+ "- Route canonical project semantics and evidence to OKF; keep ICM/workflow context as status plus OKF references, never duplicated project truth.",
39
+ "- Route stable collaborator preferences to USER, compact hot facts to MEMORY, and reusable procedures to skills.",
37
40
  "- Do not defer reflection, request another model turn, call an isolated completion, or launch a background learner or worker for reflection.",
38
41
  "- When nothing durable is warranted, continue normally and do not mention this cue.",
39
42
  ].join("\n");
40
43
  const CURRENT_TURN_REFLECTION_TRIGGERS = new Set([
41
44
  "root-turn",
45
+ "version-change",
42
46
  "complex",
43
47
  "corrective",
44
48
  "durable",
@@ -58,7 +62,12 @@ function parseCurrentTurnReflectionCueState(value) {
58
62
  candidate.triggers.length === 0 ||
59
63
  candidate.triggers.some((trigger) => !CURRENT_TURN_REFLECTION_TRIGGERS.has(trigger)) ||
60
64
  typeof candidate.createdAt !== "string" ||
61
- typeof candidate.updatedAt !== "string") {
65
+ typeof candidate.updatedAt !== "string" ||
66
+ (candidate.activeRunToken !== undefined && typeof candidate.activeRunToken !== "string") ||
67
+ (candidate.versionChange !== undefined &&
68
+ (!candidate.versionChange ||
69
+ !isDurableLearningClaimToken(candidate.versionChange.token) ||
70
+ !isDurableLearningReviewMetadata(candidate.versionChange.metadata)))) {
62
71
  return undefined;
63
72
  }
64
73
  return {
@@ -69,8 +78,35 @@ function parseCurrentTurnReflectionCueState(value) {
69
78
  triggers: [...new Set(candidate.triggers)],
70
79
  createdAt: candidate.createdAt,
71
80
  updatedAt: candidate.updatedAt,
81
+ ...(candidate.versionChange
82
+ ? {
83
+ versionChange: {
84
+ token: { ...candidate.versionChange.token },
85
+ metadata: { ...candidate.versionChange.metadata },
86
+ },
87
+ }
88
+ : {}),
89
+ ...(candidate.activeRunToken ? { activeRunToken: candidate.activeRunToken } : {}),
72
90
  };
73
91
  }
92
+ function versionClaimTokensMatch(left, right) {
93
+ return (left.transitionId === right.transitionId &&
94
+ left.claimId === right.claimId &&
95
+ left.ownerId === right.ownerId &&
96
+ left.runtimeVersion === right.runtimeVersion &&
97
+ left.memoryPolicyVersion === right.memoryPolicyVersion);
98
+ }
99
+ function hasStrictSuccessfulAssistantTerminal(messages) {
100
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
101
+ const message = messages[index];
102
+ if (message.role !== "assistant")
103
+ continue;
104
+ if (message.stopReason !== "stop" || message.errorMessage)
105
+ return false;
106
+ return message.content.some((part) => part.type === "text" && part.text.trim().length > 0);
107
+ }
108
+ return false;
109
+ }
74
110
  function parseOkfRollbackTarget(target) {
75
111
  if (!target)
76
112
  return undefined;
@@ -84,6 +120,8 @@ function parseOkfRollbackTarget(target) {
84
120
  }
85
121
  export class ReflectionController {
86
122
  constructor(deps) {
123
+ this.durableLearningOwnerId = randomUUID();
124
+ this.emittedWarningCodes = new Set();
87
125
  this.cueStateCacheInitialized = false;
88
126
  this.deps = deps;
89
127
  this.unsubscribeSettingsChanges = deps.getSettingsManager().subscribeChanges(() => {
@@ -92,6 +130,7 @@ export class ReflectionController {
92
130
  this.synchronizeCurrentTurnCueWithSettings();
93
131
  }
94
132
  dispose() {
133
+ this.dismissCurrentTurnCue();
95
134
  this.unsubscribeSettingsChanges();
96
135
  }
97
136
  isAutomaticReflectionEnabled() {
@@ -122,7 +161,18 @@ export class ReflectionController {
122
161
  return this.cueStateCache;
123
162
  }
124
163
  /** Branch/session navigation invalidates the lazy latest-state index; ordinary appends do not. */
125
- invalidateCurrentTurnCueStateCache() {
164
+ invalidateCurrentTurnCueStateCache(options = {}) {
165
+ if (options.releaseActiveClaim) {
166
+ const current = this.cueStateCacheInitialized ? this.cueStateCache : undefined;
167
+ const isActive = current?.status === "pending" ||
168
+ (current?.status === "consumed" &&
169
+ !!current.activeRunToken &&
170
+ current.activeRunToken === this.activeRunToken);
171
+ if (isActive && current?.versionChange) {
172
+ this.deps.getDurableLearningState?.()?.releaseClaim(current.versionChange.token);
173
+ }
174
+ this.activeRunToken = undefined;
175
+ }
126
176
  this.cueStateCacheInitialized = false;
127
177
  this.cueStateCache = undefined;
128
178
  }
@@ -131,68 +181,184 @@ export class ReflectionController {
131
181
  this.cueStateCache = state;
132
182
  this.cueStateCacheInitialized = true;
133
183
  }
134
- synchronizeCurrentTurnCueWithSettings() {
135
- if (this.isAutomaticReflectionEnabled())
184
+ warnOnce(code, message) {
185
+ if (this.emittedWarningCodes.has(code))
136
186
  return;
187
+ this.emittedWarningCodes.add(code);
188
+ this.deps.warn?.(message);
189
+ }
190
+ dismissCurrentTurnCue() {
137
191
  const current = this.getCurrentTurnCueState();
138
- if (current?.status !== "pending")
192
+ const isActive = current?.status === "pending" ||
193
+ (current?.status === "consumed" && !!current.activeRunToken && current.activeRunToken === this.activeRunToken);
194
+ if (!current || !isActive)
139
195
  return;
140
- this.persistCurrentTurnCueState({
141
- ...current,
142
- revision: current.revision + 1,
143
- status: "dismissed",
144
- updatedAt: new Date().toISOString(),
145
- });
196
+ try {
197
+ this.persistCurrentTurnCueState({
198
+ ...current,
199
+ revision: current.revision + 1,
200
+ status: "dismissed",
201
+ activeRunToken: undefined,
202
+ updatedAt: new Date().toISOString(),
203
+ });
204
+ }
205
+ catch {
206
+ this.warnOnce("cue-dismiss-failed", "Automatic reflection cue dismissal failed; its durable claim will expire safely.");
207
+ return;
208
+ }
209
+ this.activeRunToken = undefined;
210
+ if (current.versionChange)
211
+ this.deps.getDurableLearningState?.()?.releaseClaim(current.versionChange.token);
212
+ }
213
+ synchronizeCurrentTurnCueWithSettings() {
214
+ if (this.isAutomaticReflectionEnabled())
215
+ return;
216
+ this.dismissCurrentTurnCue();
217
+ }
218
+ attachCurrentTurnCue(trigger, versionChange, clearVersionChange = false) {
219
+ if (!this.isAutomaticReflectionEnabled()) {
220
+ this.synchronizeCurrentTurnCueWithSettings();
221
+ return "disabled";
222
+ }
223
+ try {
224
+ const current = this.getCurrentTurnCueState();
225
+ const updatedAt = new Date().toISOString();
226
+ if (current?.status === "pending") {
227
+ if (clearVersionChange && current.versionChange) {
228
+ const triggers = current.triggers.filter((existing) => existing !== "version-change");
229
+ if (!triggers.includes(trigger))
230
+ triggers.push(trigger);
231
+ this.persistCurrentTurnCueState({
232
+ ...current,
233
+ revision: current.revision + 1,
234
+ triggers,
235
+ versionChange: undefined,
236
+ updatedAt,
237
+ });
238
+ return "replaced-stale";
239
+ }
240
+ const alreadyHasTrigger = current.triggers.includes(trigger);
241
+ const alreadyHasVersionTrigger = !versionChange || current.triggers.includes("version-change");
242
+ const sameVersionClaim = !versionChange ||
243
+ (!!current.versionChange && versionClaimTokensMatch(current.versionChange.token, versionChange.token));
244
+ if (alreadyHasTrigger && alreadyHasVersionTrigger && sameVersionClaim)
245
+ return "coalesced";
246
+ const replacingVersionClaim = !!versionChange && !!current.versionChange && !sameVersionClaim;
247
+ const triggers = [...current.triggers];
248
+ if (!triggers.includes(trigger))
249
+ triggers.push(trigger);
250
+ if (versionChange && !triggers.includes("version-change"))
251
+ triggers.push("version-change");
252
+ this.persistCurrentTurnCueState({
253
+ ...current,
254
+ revision: current.revision + 1,
255
+ triggers,
256
+ updatedAt,
257
+ ...(versionChange ? { versionChange } : {}),
258
+ });
259
+ return replacingVersionClaim ? "replaced-stale" : "attached";
260
+ }
261
+ const triggers = [trigger];
262
+ if (versionChange && !triggers.includes("version-change"))
263
+ triggers.push("version-change");
264
+ this.persistCurrentTurnCueState({
265
+ version: 1,
266
+ revision: 1,
267
+ cueId: randomUUID(),
268
+ status: "pending",
269
+ triggers,
270
+ createdAt: updatedAt,
271
+ updatedAt,
272
+ ...(versionChange ? { versionChange } : {}),
273
+ });
274
+ return "attached";
275
+ }
276
+ catch {
277
+ this.warnOnce("cue-attach-failed", "Automatic reflection cue persistence failed; durable learning was not claimed.");
278
+ return "failed";
279
+ }
280
+ }
281
+ /** Persist one logical ordinary cue without exposing claim metadata to callers. */
282
+ queueCurrentTurnCue(trigger) {
283
+ const outcome = this.attachCurrentTurnCue(trigger);
284
+ return outcome === "attached" || outcome === "replaced-stale";
146
285
  }
147
286
  /**
148
- * Persist one logical pending cue. Repeated triggers merge into the existing pending snapshot;
149
- * they never append competing pending cues or retain raw transcript text.
287
+ * Root-turn entrypoint: reconcile installed runtime/policy state and atomically attach any exact
288
+ * version claim to the same provider cue. Fail-safe state faults degrade to an ordinary root cue.
150
289
  */
151
- queueCurrentTurnCue(trigger) {
290
+ queueExternalRootTurnCue() {
152
291
  if (!this.isAutomaticReflectionEnabled()) {
153
292
  this.synchronizeCurrentTurnCueWithSettings();
154
- return false;
293
+ return "disabled";
155
294
  }
156
- const current = this.getCurrentTurnCueState();
157
- const updatedAt = new Date().toISOString();
158
- if (current?.status === "pending") {
159
- if (current.triggers.includes(trigger))
160
- return false;
161
- const next = {
162
- ...current,
163
- revision: current.revision + 1,
164
- triggers: [...current.triggers, trigger],
165
- updatedAt,
166
- };
167
- this.persistCurrentTurnCueState(next);
168
- return true;
295
+ const state = this.deps.getDurableLearningState?.();
296
+ const runtimeVersion = this.deps.getRuntimeVersion?.();
297
+ const memoryPolicyVersion = this.deps.getMemoryPolicyVersion?.();
298
+ if (!state || !runtimeVersion || !memoryPolicyVersion) {
299
+ if (state && (!runtimeVersion || !memoryPolicyVersion)) {
300
+ this.warnOnce("version-identity-unavailable", "Installed runtime identity is unavailable; continuing with ordinary root reflection only.");
301
+ }
302
+ return this.attachCurrentTurnCue("root-turn", undefined, true);
169
303
  }
170
- const next = {
171
- version: 1,
172
- revision: 1,
173
- cueId: randomUUID(),
174
- status: "pending",
175
- triggers: [trigger],
176
- createdAt: updatedAt,
177
- updatedAt,
178
- };
179
- this.persistCurrentTurnCueState(next);
180
- return true;
304
+ const result = state.reconcileClaimAndAttach({ runtimeVersion, memoryPolicyVersion }, this.durableLearningOwnerId, (token, metadata) => this.attachCurrentTurnCue("root-turn", { token, metadata }));
305
+ if (result.warningCode) {
306
+ this.warnOnce(result.warningCode, `Durable learning state warning (${result.warningCode}); semantic memory remained unchanged.`);
307
+ }
308
+ if (result.status === "attached" ||
309
+ result.status === "coalesced" ||
310
+ result.status === "replaced-stale" ||
311
+ result.status === "disabled" ||
312
+ result.status === "failed") {
313
+ return result.status;
314
+ }
315
+ return this.attachCurrentTurnCue("root-turn", undefined, true);
181
316
  }
182
317
  /**
183
- * Preview one transient provider-only cue. Discarded/replanned previews do nothing; the accepted
184
- * provider-plan commit closes exactly the captured cue id + revision.
318
+ * Preview one transient provider-only cue. An accepted cue remains visible across provider-tool
319
+ * continuation requests until AgentSession reports one strict terminal success or failure.
185
320
  */
186
321
  previewCurrentTurnCue() {
187
- const current = this.getCurrentTurnCueState();
188
- if (current?.status !== "pending" || !this.isAutomaticReflectionEnabled())
322
+ let current = this.getCurrentTurnCueState();
323
+ if (!current || !this.isAutomaticReflectionEnabled())
324
+ return undefined;
325
+ let pending = current.status === "pending";
326
+ let continuing = current.status === "consumed" && !!this.activeRunToken && current.activeRunToken === this.activeRunToken;
327
+ if (!pending && !continuing)
189
328
  return undefined;
329
+ if (continuing && current.versionChange) {
330
+ const renewed = this.deps.getDurableLearningState?.()?.renewClaim(current.versionChange.token) ?? false;
331
+ if (!renewed) {
332
+ const withoutStaleClaim = {
333
+ ...current,
334
+ revision: current.revision + 1,
335
+ triggers: current.triggers.filter((trigger) => trigger !== "version-change"),
336
+ versionChange: undefined,
337
+ updatedAt: new Date().toISOString(),
338
+ };
339
+ try {
340
+ this.persistCurrentTurnCueState(withoutStaleClaim);
341
+ current = withoutStaleClaim;
342
+ pending = false;
343
+ continuing = true;
344
+ }
345
+ catch {
346
+ this.warnOnce("cue-stale-claim-removal-failed", "A stale durable version claim could not be removed from provider cue state; version metadata was withheld.");
347
+ return undefined;
348
+ }
349
+ }
350
+ }
190
351
  const cueId = current.cueId;
191
352
  const revision = current.revision;
353
+ const expectedStatus = current.status;
354
+ const expectedRunToken = current.activeRunToken;
355
+ const versionLine = current.versionChange
356
+ ? `\n- Installed-state transition: ${current.versionChange.metadata.reason}; runtime ${current.versionChange.metadata.previousRuntimeVersion ?? "unobserved"} to ${current.versionChange.metadata.runtimeVersion}; memory policy ${current.versionChange.metadata.previousMemoryPolicyVersion ?? "unobserved"} to ${current.versionChange.metadata.memoryPolicyVersion}. First observation is audit-only, and version movement alone is never semantic evidence. Revalidate current sources; update only the canonical durable owner when warranted.`
357
+ : "";
192
358
  const message = {
193
359
  role: "custom",
194
360
  customType: CURRENT_TURN_REFLECTION_CUSTOM_TYPE,
195
- content: `${CURRENT_TURN_REFLECTION_CUE}\n- Pending evidence classes: ${current.triggers.join(", ")}.`,
361
+ content: `${CURRENT_TURN_REFLECTION_CUE}\n- Pending evidence classes: ${current.triggers.join(", ")}.${versionLine}`,
196
362
  display: false,
197
363
  details: {
198
364
  version: 1,
@@ -200,15 +366,17 @@ export class ReflectionController {
200
366
  automaticProviderRequests: 0,
201
367
  cueId: current.cueId,
202
368
  triggers: current.triggers,
369
+ ...(current.versionChange ? { versionChange: { ...current.versionChange.metadata } } : {}),
203
370
  },
204
371
  timestamp: Date.now(),
205
372
  };
206
373
  const isCurrent = () => {
207
374
  const latest = this.getCurrentTurnCueState();
208
375
  return (this.isAutomaticReflectionEnabled() &&
209
- latest?.status === "pending" &&
376
+ latest?.status === expectedStatus &&
210
377
  latest.cueId === cueId &&
211
- latest.revision === revision);
378
+ latest.revision === revision &&
379
+ latest.activeRunToken === expectedRunToken);
212
380
  };
213
381
  return {
214
382
  message,
@@ -216,19 +384,80 @@ export class ReflectionController {
216
384
  commit: () => {
217
385
  if (!isCurrent())
218
386
  throw new Error("Reflection cue changed before provider-plan commit");
387
+ if (expectedStatus === "consumed")
388
+ return;
219
389
  const latest = this.getCurrentTurnCueState();
220
390
  if (!latest)
221
391
  throw new Error("Reflection cue disappeared before provider-plan commit");
222
- const next = {
392
+ const activeRunToken = randomUUID();
393
+ this.persistCurrentTurnCueState({
223
394
  ...latest,
224
395
  revision: latest.revision + 1,
225
396
  status: "consumed",
397
+ activeRunToken,
226
398
  updatedAt: new Date().toISOString(),
227
- };
228
- this.persistCurrentTurnCueState(next);
399
+ });
400
+ this.activeRunToken = activeRunToken;
229
401
  },
230
402
  };
231
403
  }
404
+ /** Settle one accepted cue-bearing provider run at its authoritative AgentSession boundary. */
405
+ finishCurrentTurnCue(messages, options) {
406
+ if (!this.isAutomaticReflectionEnabled()) {
407
+ this.synchronizeCurrentTurnCueWithSettings();
408
+ return;
409
+ }
410
+ const current = this.getCurrentTurnCueState();
411
+ if (current?.status !== "consumed" || !current.activeRunToken || current.activeRunToken !== this.activeRunToken) {
412
+ return;
413
+ }
414
+ const state = this.deps.getDurableLearningState?.();
415
+ if (options.willRetry) {
416
+ let versionChange = current.versionChange;
417
+ if (versionChange && !state?.renewClaim(versionChange.token))
418
+ versionChange = undefined;
419
+ try {
420
+ this.persistCurrentTurnCueState({
421
+ ...current,
422
+ revision: current.revision + 1,
423
+ status: "pending",
424
+ activeRunToken: undefined,
425
+ triggers: versionChange
426
+ ? current.triggers
427
+ : current.triggers.filter((trigger) => trigger !== "version-change"),
428
+ versionChange,
429
+ updatedAt: new Date().toISOString(),
430
+ });
431
+ this.activeRunToken = undefined;
432
+ }
433
+ catch {
434
+ this.warnOnce("cue-retry-failed", "Automatic reflection cue retry persistence failed; any durable claim will expire safely.");
435
+ }
436
+ return;
437
+ }
438
+ const success = hasStrictSuccessfulAssistantTerminal(messages);
439
+ try {
440
+ this.persistCurrentTurnCueState({
441
+ ...current,
442
+ revision: current.revision + 1,
443
+ activeRunToken: undefined,
444
+ updatedAt: new Date().toISOString(),
445
+ });
446
+ this.activeRunToken = undefined;
447
+ }
448
+ catch {
449
+ this.warnOnce("cue-finish-failed", "Automatic reflection cue completion persistence failed; any durable claim will expire safely.");
450
+ return;
451
+ }
452
+ if (!current.versionChange || !state)
453
+ return;
454
+ const settled = success
455
+ ? state.completeReview(current.versionChange.token)
456
+ : state.releaseClaim(current.versionChange.token);
457
+ if (!settled) {
458
+ this.warnOnce("version-claim-settle-failed", "Durable version claim no longer matched its exact transition; no semantic memory state was marked complete.");
459
+ }
460
+ }
232
461
  /** Pure completed-turn projection used only by deterministic memory synchronization. */
233
462
  analyzeCompletedTurn(messages) {
234
463
  const settingsManager = this.deps.getSettingsManager();