@arnilo/prism 0.7.0 → 0.9.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.
Files changed (182) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +12 -11
  3. package/dist/agent-approval.d.ts +15 -2
  4. package/dist/agent-approval.js +5 -1
  5. package/dist/agent-event-source.d.ts +9 -1
  6. package/dist/agent-event-source.js +10 -3
  7. package/dist/agent-loops.js +7 -4
  8. package/dist/agent-run-lifecycle.d.ts +15 -1
  9. package/dist/agent-run-lifecycle.js +91 -10
  10. package/dist/agent-run-state.d.ts +34 -2
  11. package/dist/agent-run-state.js +68 -6
  12. package/dist/agent-session/helpers.js +20 -1
  13. package/dist/agent-session/session/assemble.js +250 -27
  14. package/dist/agent-session/session/persist.d.ts +27 -0
  15. package/dist/agent-session/session/persist.js +94 -12
  16. package/dist/agent-session/session/provider-round.d.ts +14 -4
  17. package/dist/agent-session/session/provider-round.js +197 -25
  18. package/dist/agent-session/session/tool-round.js +24 -2
  19. package/dist/agent-session/session/types.d.ts +36 -2
  20. package/dist/agent-session/session.d.ts +40 -4
  21. package/dist/agent-session/session.js +78 -5
  22. package/dist/attention-compiler.d.ts +51 -2
  23. package/dist/attention-compiler.js +282 -21
  24. package/dist/cache-helpers.d.ts +4 -2
  25. package/dist/cache-helpers.js +8 -6
  26. package/dist/checkpoint-restore.d.ts +45 -0
  27. package/dist/checkpoint-restore.js +54 -0
  28. package/dist/checkpoints.js +7 -11
  29. package/dist/context-budget.d.ts +2 -1
  30. package/dist/context-budget.js +24 -2
  31. package/dist/contracts-core/agent.d.ts +30 -0
  32. package/dist/contracts-core/attention.d.ts +95 -0
  33. package/dist/contracts-core/content.d.ts +15 -0
  34. package/dist/contracts-core/guardrail-packs.d.ts +41 -0
  35. package/dist/contracts-core/guardrail-packs.js +2 -0
  36. package/dist/contracts-core/loop.d.ts +42 -0
  37. package/dist/contracts-core/provider.d.ts +25 -0
  38. package/dist/contracts-core/run-limits.d.ts +21 -0
  39. package/dist/contracts-core/session.d.ts +23 -5
  40. package/dist/contracts-core/session.js +21 -2
  41. package/dist/contracts-core/usage.d.ts +40 -0
  42. package/dist/contracts-core/usage.js +8 -0
  43. package/dist/contracts-core.d.ts +2 -0
  44. package/dist/contracts-core.js +2 -0
  45. package/dist/contracts-protocol.d.ts +90 -4
  46. package/dist/contracts-run-state.d.ts +82 -6
  47. package/dist/evidence-grounding.d.ts +29 -0
  48. package/dist/evidence-grounding.js +162 -0
  49. package/dist/guardrail-packs/coding-standard.d.ts +3 -0
  50. package/dist/guardrail-packs/coding-standard.js +63 -0
  51. package/dist/guardrail-packs/destructive-commands.d.ts +3 -0
  52. package/dist/guardrail-packs/destructive-commands.js +46 -0
  53. package/dist/guardrail-packs/errors.d.ts +7 -0
  54. package/dist/guardrail-packs/errors.js +9 -0
  55. package/dist/guardrail-packs/index.d.ts +4 -0
  56. package/dist/guardrail-packs/index.js +15 -0
  57. package/dist/guardrail-packs/secrets-hygiene.d.ts +3 -0
  58. package/dist/guardrail-packs/secrets-hygiene.js +23 -0
  59. package/dist/guardrail-packs/types.d.ts +16 -0
  60. package/dist/guardrail-packs/types.js +2 -0
  61. package/dist/guardrail-packs/validation-respect.d.ts +3 -0
  62. package/dist/guardrail-packs/validation-respect.js +53 -0
  63. package/dist/guardrails.d.ts +20 -1
  64. package/dist/guardrails.js +268 -0
  65. package/dist/host-composition.d.ts +13 -0
  66. package/dist/host-composition.js +33 -2
  67. package/dist/index.d.ts +19 -10
  68. package/dist/index.js +11 -6
  69. package/dist/input.d.ts +8 -1
  70. package/dist/input.js +68 -6
  71. package/dist/middleware.d.ts +37 -2
  72. package/dist/middleware.js +41 -0
  73. package/dist/node/session-store-jsonl.js +18 -3
  74. package/dist/observability.js +6 -0
  75. package/dist/provider-events.d.ts +11 -3
  76. package/dist/provider-events.js +62 -4
  77. package/dist/providers/openai-compatible.js +6 -3
  78. package/dist/providers/transport.d.ts +3 -1
  79. package/dist/providers/transport.js +36 -0
  80. package/dist/redaction.js +18 -2
  81. package/dist/run-bundle.d.ts +89 -0
  82. package/dist/run-bundle.js +150 -0
  83. package/dist/run-limits.d.ts +11 -1
  84. package/dist/run-limits.js +46 -0
  85. package/dist/session-stores.d.ts +12 -1
  86. package/dist/session-stores.js +21 -4
  87. package/dist/testing/agent-event-source-conformance.js +41 -2
  88. package/dist/testing/prefix-stability-conformance.d.ts +30 -0
  89. package/dist/testing/prefix-stability-conformance.js +104 -0
  90. package/dist/testing/session-store-conformance.d.ts +3 -2
  91. package/dist/testing/session-store-conformance.js +48 -0
  92. package/dist/testing/state-concurrency-conformance.js +5 -12
  93. package/dist/tools.d.ts +5 -0
  94. package/dist/tools.js +11 -3
  95. package/dist/usage-estimation.d.ts +29 -0
  96. package/dist/usage-estimation.js +79 -0
  97. package/docs/ag-ui.md +5 -0
  98. package/docs/agent-events.md +68 -1
  99. package/docs/agent-loops.md +33 -0
  100. package/docs/agent-session-runtime.md +5 -3
  101. package/docs/attention-compiler.md +89 -8
  102. package/docs/coding-agent-tools.md +1 -1
  103. package/docs/coding-security.md +1 -0
  104. package/docs/coding-tools.md +0 -1
  105. package/docs/compaction-and-retry.md +1 -1
  106. package/docs/compaction-observational-memory.md +34 -7
  107. package/docs/connected-apps.md +116 -0
  108. package/docs/context-and-skills.md +13 -0
  109. package/docs/core.md +1 -1
  110. package/docs/diagrams.md +6 -6
  111. package/docs/document-reader.md +9 -9
  112. package/docs/documents.md +32 -11
  113. package/docs/durable-runs.md +129 -0
  114. package/docs/embeddings.md +5 -0
  115. package/docs/enterprise-postgres-state.md +4 -0
  116. package/docs/evaluations.md +5 -0
  117. package/docs/execution-timeline.md +84 -1
  118. package/docs/guardrails.md +71 -2
  119. package/docs/history/079-messaging-primitive-review.md +391 -0
  120. package/docs/history/080-messaging-followon-primitive-review.md +234 -0
  121. package/docs/history/081-connected-apps-primitive-review.md +74 -0
  122. package/docs/history/083-prism-work-primitive-review.md +84 -0
  123. package/docs/history/084-primitive-review.md +96 -0
  124. package/docs/history/085-honesty-and-cut-primitive-review.md +91 -0
  125. package/docs/history/README.md +5 -0
  126. package/docs/history/release-handoffs.md +38 -0
  127. package/docs/host-compositions.md +8 -6
  128. package/docs/host-security.md +2 -2
  129. package/docs/index.md +66 -29
  130. package/docs/input-and-prompt-assembly.md +3 -3
  131. package/docs/knowledge-sync.md +4 -0
  132. package/docs/live-testing.md +5 -3
  133. package/docs/mcp-tools.md +1 -0
  134. package/docs/messaging-channel-operations.md +166 -0
  135. package/docs/messaging-channels.md +150 -0
  136. package/docs/middleware-hooks.md +38 -2
  137. package/docs/migrate-to-0.8.md +124 -0
  138. package/docs/migrate-to-0.9.md +210 -0
  139. package/docs/migration.md +43 -0
  140. package/docs/model-registry.md +12 -2
  141. package/docs/multi-agent-patterns.md +25 -2
  142. package/docs/node-jsonl-session-store.md +7 -1
  143. package/docs/observability.md +7 -3
  144. package/docs/openapi-tools.md +1 -1
  145. package/docs/operations.md +1 -3
  146. package/docs/options-index.md +36 -3
  147. package/docs/peer-dependencies.md +6 -6
  148. package/docs/policy-and-audit.md +13 -1
  149. package/docs/postgres-persistence.md +1 -1
  150. package/docs/prefix-stability-conformance.md +93 -0
  151. package/docs/provider-caching.md +4 -4
  152. package/docs/provider-conformance.md +16 -0
  153. package/docs/provider-layer.md +2 -2
  154. package/docs/provider-packages.md +20 -20
  155. package/docs/providers/neuralwatt.md +5 -1
  156. package/docs/public-contracts.md +2 -2
  157. package/docs/rag.md +102 -4
  158. package/docs/release-and-install.md +55 -47
  159. package/docs/run-bundle.md +92 -0
  160. package/docs/runs-and-usage.md +57 -6
  161. package/docs/scoped-agent-memory.md +262 -0
  162. package/docs/server.md +2 -0
  163. package/docs/session-store-conformance.md +1 -2
  164. package/docs/session-stores.md +17 -17
  165. package/docs/sheets.md +9 -9
  166. package/docs/signal-channel.md +112 -0
  167. package/docs/speech.md +5 -1
  168. package/docs/sqlite-persistence.md +1 -1
  169. package/docs/supervisors.md +32 -12
  170. package/docs/telegram-channel.md +157 -0
  171. package/docs/testing.md +2 -2
  172. package/docs/tools.md +17 -0
  173. package/docs/wiki.md +1 -1
  174. package/docs/work-artifacts-and-review.md +1 -1
  175. package/docs/work-connectors.md +9 -9
  176. package/docs/work-sandbox.md +115 -0
  177. package/docs/work-tools.md +38 -16
  178. package/docs/workflows.md +5 -0
  179. package/package.json +9 -3
  180. package/templates/business-worker/manifest.json +2 -1
  181. package/templates/business-worker/src/agent.ts.tmpl +1 -1
  182. package/templates/business-worker/src/tests/agent.test.ts.tmpl +1 -1
@@ -1,8 +1,8 @@
1
1
  /** session (0.2.5 plan 025 Task 1 split). Moved verbatim from agent-session.ts; public surface unchanged behind the barrel. */
2
- import { ActiveDurableRun } from "../agent-approval.js";
2
+ import { ActiveDurableRun, ActiveDurableRunExtras } from "../agent-approval.js";
3
3
  import type { PendingToolCall, StoredAgentRunState } from "../agent-run-state.js";
4
- import { type AttentionStickyFrontier, type PersistedAttentionStickyFrontier } from "../attention-compiler.js";
5
- import type { Agent, AgentEvent, AgentRunResult, AgentRunState, AgentRunStateOptions, AgentSession, AgentSessionConfig, AIProvider, CompactionOptions, CompactionResult, ErrorInfo, Message, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunDecision, RunOptions, SessionEntry, Skill, SteerOptions, SubscribeOptions, ToolDefinition, ToolEffectStore, Usage } from "../contracts.js";
4
+ import { type AttentionFoldLedger, type AttentionStickyFrontier, type PersistedAttentionFoldLedger, type PersistedAttentionStickyFrontier } from "../attention-compiler.js";
5
+ import type { Agent, AgentEvent, AgentRunResult, AgentRunState, AgentRunStateOptions, AgentSession, AgentSessionConfig, AIProvider, CompactionOptions, CompactionResult, ContextMeter, ErrorInfo, Guardrails, Message, OwnershipScope, PendingDecision, PromptVersionRef, ProviderRequest, RunDecision, RunOptions, SessionEntry, Skill, SteerOptions, SubscribeOptions, ToolCallSummary, ToolDefinition, ToolEffectStore, Usage } from "../contracts.js";
6
6
  import type { AgentIdentity } from "../identity.js";
7
7
  import type { AgentInput } from "../input.js";
8
8
  import type { RunLimitTracker } from "../run-limits.js";
@@ -30,9 +30,21 @@ export declare class RuntimeAgentSession implements AgentSession {
30
30
  activeIdentity?: AgentIdentity;
31
31
  private activeIdempotencyKey?;
32
32
  private activeGuardrails?;
33
+ /** Plan 092 Task 2: guardrail packs compiled once in the constructor; merged into every run's `activeGuardrails`. */
34
+ readonly packGuardrails?: Guardrails;
35
+ /** Original pack refs, carried into `fork()`/`clone()` so a branch cannot silently lose its policy. */
36
+ private readonly guardrailPackRefs?;
33
37
  activeMetadata?: Readonly<Record<string, unknown>>;
34
38
  activePromptVersion?: PromptVersionRef;
35
39
  activeLimits?: RunLimitTracker;
40
+ /** Plan 091 T2: input tokens of the latest provider turn plus whether the provider reported
41
+ * them; set by the usage seam, read by `contextMeter()`. */
42
+ activeInputMeter?: {
43
+ readonly tokens: number;
44
+ readonly source: "reported" | "estimated";
45
+ };
46
+ /** Bounded last-N tool-call summaries of the active run (plan 087 T2): ids, names, arg hashes. */
47
+ activeRecentToolCalls?: ToolCallSummary[];
36
48
  activeLimitOutputBuffer: boolean;
37
49
  activeDurable?: ActiveDurableRun;
38
50
  activeLoop?: import("../contracts.js").AgentLoopStrategy;
@@ -43,6 +55,8 @@ export declare class RuntimeAgentSession implements AgentSession {
43
55
  }>;
44
56
  activeLoopTurn: number;
45
57
  private readonly loadedSkills;
58
+ /** Run-owned only: loaded bodies and URI resources retain first insertion order within one provider loop. */
59
+ readonly tailSegments: Map<string, Message>;
46
60
  /** Tools activated via `search_tools` this session (plan 041); names-only in persistence. */
47
61
  readonly activatedTools: import("../tool-search.js").ActiveToolSet;
48
62
  /** Plan 018 Task 6 (closeout `checkpoint-bodies`): persisted exact instructions, registry-independent. */
@@ -62,6 +76,17 @@ export declare class RuntimeAgentSession implements AgentSession {
62
76
  /** Plan 074 P3: restore a frontier validated at checkpoint load, so a resumed run keeps its
63
77
  * stubs instead of re-deciding its first turn from the ratio. */
64
78
  restoreAttentionSticky(persisted: PersistedAttentionStickyFrontier): void;
79
+ /** Session-owned folded bodies (plan 086 T3); created on first use like the frontier, so a
80
+ * compiler-off session allocates nothing. */
81
+ private attentionFold?;
82
+ /** Set per run from the resolved compiler: `durable: true` opts the fold ledger and its
83
+ * frontier into checkpoints even when `persistSessionState` is off. */
84
+ attentionDurable: boolean;
85
+ attentionFoldFor(): AttentionFoldLedger;
86
+ /** Plan 086 T3: bounded ledger snapshot for a durable checkpoint; `undefined` before any fold. */
87
+ serializedAttentionFold(): PersistedAttentionFoldLedger | undefined;
88
+ /** Plan 086 T3: adopt a ledger validated at checkpoint load, so a resumed fold is byte-identical. */
89
+ restoreAttentionFold(ledger: AttentionFoldLedger): void;
65
90
  /** Plan 015 Task 4: re-add persisted loaded-skill names (names only; bodies re-resolve on demand). */
66
91
  restoreLoadedSkills(names: readonly string[]): void;
67
92
  /** Plan 041: re-add persisted activated-tool names (names only; inert for absent tools). */
@@ -79,10 +104,19 @@ export declare class RuntimeAgentSession implements AgentSession {
79
104
  readonly agent: Agent;
80
105
  });
81
106
  get leafId(): string | undefined;
107
+ /**
108
+ * Context-fill read (plan 091 T2): the latest provider turn's input tokens —
109
+ * provider-reported when it reported, else a labeled estimate — plus the
110
+ * per-request cap and cumulative run input budget, resolved exactly as
111
+ * `provider_turn_finished.budgets` resolves them. Before any provider turn in
112
+ * this session it estimates stored history, so a non-reporting model still
113
+ * shows a working meter instead of zero. Never billing; estimates are labeled.
114
+ */
115
+ contextMeter(): ContextMeter;
82
116
  subscribe(options?: SubscribeOptions): AsyncIterable<AgentEvent>;
83
117
  run(input: AgentInput, options?: RunOptions): Promise<AgentRunResult>;
84
118
  steer(input: AgentInput, options?: SteerOptions): void;
85
- resumeDurable(state: StoredAgentRunState, runState: AgentRunStateOptions, ownership?: OwnershipScope, signal?: AbortSignal, decisions?: ReadonlyMap<string, RunDecision>): Promise<AgentRunResult>;
119
+ resumeDurable(state: StoredAgentRunState, runState: AgentRunStateOptions, ownership?: OwnershipScope, signal?: AbortSignal, decisions?: ReadonlyMap<string, RunDecision>, extras?: ActiveDurableRunExtras): Promise<AgentRunResult>;
86
120
  recordDurableResumption(runId: string, interruption: import("../contracts.js").AgentRunInterruption, version: number, ownership?: OwnershipScope): Promise<void>;
87
121
  recordDurableDenial(runId: string, interruption: import("../contracts.js").AgentRunInterruption, version: number, ownership?: OwnershipScope): Promise<void>;
88
122
  private runInternal;
@@ -95,6 +129,8 @@ export declare class RuntimeAgentSession implements AgentSession {
95
129
  readonly limit?: import("../contracts.js").RunLimitBreach;
96
130
  readonly error?: ErrorInfo;
97
131
  readonly abortReason?: string;
132
+ readonly stopReason?: import("../contracts.js").AgentFinishReason;
133
+ readonly stopDetail?: string;
98
134
  readonly runState?: AgentRunState;
99
135
  readonly interruption?: import("../contracts.js").AgentRunInterruption;
100
136
  }): AgentRunResult;
@@ -1,10 +1,10 @@
1
1
  /** session (0.2.5 plan 025 Task 1 split). Moved verbatim from agent-session.ts; public surface unchanged behind the barrel. */
2
2
  import { policyList } from "../agent-tool-dispatch.js";
3
- import { createAttentionStickyFrontier, resolveInputCap, restoreAttentionStickyFrontier, serializeAttentionStickyFrontier, } from "../attention-compiler.js";
3
+ import { createAttentionFoldLedger, createAttentionStickyFrontier, resolveInputCap, restoreAttentionStickyFrontier, serializeAttentionFoldLedger, serializeAttentionStickyFrontier, } from "../attention-compiler.js";
4
4
  import { createDefaultCompactionStrategy, isCompactionEntryData } from "../compaction.js";
5
- import { estimateAssemblyTokens, estimateTextTokens } from "../context-budget.js";
5
+ import { estimateAssemblyTokens, estimateMessageTokens, estimateTextTokens } from "../context-budget.js";
6
6
  import { DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, resolveShouldCompact, } from "../contracts.js";
7
- import { GuardrailError, runGuardrails } from "../guardrails.js";
7
+ import { compileGuardrailPacks, GuardrailError, runGuardrails } from "../guardrails.js";
8
8
  import { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, normalizeProviderRequestPolicyResult, } from "../provider-request-policy.js";
9
9
  import { redactAgentEvent, redactProviderRequest, redactRunLedgerRecord, redactSecrets, redactSessionEntry } from "../redaction.js";
10
10
  import { createMemorySessionStore, createSessionEntry, getSessionBranchEntries, rebuildSessionContext } from "../session-stores.js";
@@ -39,9 +39,18 @@ export class RuntimeAgentSession {
39
39
  activeIdentity;
40
40
  activeIdempotencyKey;
41
41
  activeGuardrails;
42
+ /** Plan 092 Task 2: guardrail packs compiled once in the constructor; merged into every run's `activeGuardrails`. */
43
+ packGuardrails;
44
+ /** Original pack refs, carried into `fork()`/`clone()` so a branch cannot silently lose its policy. */
45
+ guardrailPackRefs;
42
46
  activeMetadata;
43
47
  activePromptVersion;
44
48
  activeLimits;
49
+ /** Plan 091 T2: input tokens of the latest provider turn plus whether the provider reported
50
+ * them; set by the usage seam, read by `contextMeter()`. */
51
+ activeInputMeter;
52
+ /** Bounded last-N tool-call summaries of the active run (plan 087 T2): ids, names, arg hashes. */
53
+ activeRecentToolCalls;
45
54
  activeLimitOutputBuffer = false;
46
55
  activeDurable;
47
56
  activeLoop;
@@ -49,6 +58,8 @@ export class RuntimeAgentSession {
49
58
  activeGatedRound;
50
59
  activeLoopTurn = 1;
51
60
  loadedSkills = createLoadedSkillSet();
61
+ /** Run-owned only: loaded bodies and URI resources retain first insertion order within one provider loop. */
62
+ tailSegments = new Map();
52
63
  /** Tools activated via `search_tools` this session (plan 041); names-only in persistence. */
53
64
  activatedTools = createActiveToolSet();
54
65
  /** Plan 018 Task 6 (closeout `checkpoint-bodies`): persisted exact instructions, registry-independent. */
@@ -77,6 +88,24 @@ export class RuntimeAgentSession {
77
88
  restoreAttentionSticky(persisted) {
78
89
  this.attentionSticky = restoreAttentionStickyFrontier(persisted);
79
90
  }
91
+ /** Session-owned folded bodies (plan 086 T3); created on first use like the frontier, so a
92
+ * compiler-off session allocates nothing. */
93
+ attentionFold;
94
+ /** Set per run from the resolved compiler: `durable: true` opts the fold ledger and its
95
+ * frontier into checkpoints even when `persistSessionState` is off. */
96
+ attentionDurable = false;
97
+ attentionFoldFor() {
98
+ this.attentionFold ??= createAttentionFoldLedger();
99
+ return this.attentionFold;
100
+ }
101
+ /** Plan 086 T3: bounded ledger snapshot for a durable checkpoint; `undefined` before any fold. */
102
+ serializedAttentionFold() {
103
+ return this.attentionFold && this.attentionFold.bodies.size > 0 ? serializeAttentionFoldLedger(this.attentionFold) : undefined;
104
+ }
105
+ /** Plan 086 T3: adopt a ledger validated at checkpoint load, so a resumed fold is byte-identical. */
106
+ restoreAttentionFold(ledger) {
107
+ this.attentionFold = ledger;
108
+ }
80
109
  /** Plan 015 Task 4: re-add persisted loaded-skill names (names only; bodies re-resolve on demand). */
81
110
  restoreLoadedSkills(names) {
82
111
  for (const name of names)
@@ -110,10 +139,46 @@ export class RuntimeAgentSession {
110
139
  this.store = config.store ?? config.agent.config.store ?? createMemorySessionStore();
111
140
  this.currentLeafId = config.leafId;
112
141
  this.snapshotCacheTtlMs = resolveSnapshotCacheTtlMs(config.snapshotCacheTtlMs);
142
+ this.packGuardrails = compileGuardrailPacks(config.guardrailPacks);
143
+ this.guardrailPackRefs = config.guardrailPacks;
144
+ const usageEstimation = config.agent.config.usageEstimation;
145
+ if (usageEstimation !== undefined && usageEstimation !== "fallback" && usageEstimation !== "off") {
146
+ throw new TypeError('usageEstimation must be "fallback" or "off"');
147
+ }
113
148
  }
114
149
  get leafId() {
115
150
  return this.currentLeafId;
116
151
  }
152
+ /**
153
+ * Context-fill read (plan 091 T2): the latest provider turn's input tokens —
154
+ * provider-reported when it reported, else a labeled estimate — plus the
155
+ * per-request cap and cumulative run input budget, resolved exactly as
156
+ * `provider_turn_finished.budgets` resolves them. Before any provider turn in
157
+ * this session it estimates stored history, so a non-reporting model still
158
+ * shows a working meter instead of zero. Never billing; estimates are labeled.
159
+ */
160
+ contextMeter() {
161
+ const model = this.agent.config.model;
162
+ const inputTokens = this.activeInputMeter?.tokens ?? estimateMessageTokens(this.history, model.model).tokens;
163
+ const source = this.activeInputMeter?.source ?? "estimated";
164
+ let inputCap;
165
+ try {
166
+ const setting = this.agent.config.attentionCompiler;
167
+ const options = typeof setting === "object" && setting !== null ? setting : undefined;
168
+ inputCap = resolveInputCap(options ? { maxInputTokens: options.maxInputTokens, reserveTokens: options.reserveTokens } : {}, model);
169
+ }
170
+ catch {
171
+ inputCap = undefined; // undialed model: omit instead of throwing a state read
172
+ }
173
+ const runInputBudget = this.activeLimits?.limits.maxInputTokens ?? undefined;
174
+ return {
175
+ inputTokens,
176
+ source,
177
+ ...(inputCap === undefined ? {} : { inputCap }),
178
+ ...(runInputBudget == null ? {} : { runInputBudget }),
179
+ ...(inputCap === undefined ? {} : { usedRatio: inputTokens / inputCap }),
180
+ };
181
+ }
117
182
  subscribe(options = {}) {
118
183
  const subscriber = new EventSubscriber(this.id, options, () => this.subscribers.delete(subscriber));
119
184
  this.subscribers.add(subscriber);
@@ -147,12 +212,13 @@ export class RuntimeAgentSession {
147
212
  this.pendingSoftInterrupt = true;
148
213
  }
149
214
  }
150
- async resumeDurable(state, runState, ownership, signal, decisions) {
215
+ async resumeDurable(state, runState, ownership, signal, decisions, extras) {
151
216
  return this.runInternal(state.input ?? [], { runState, ownership, signal }, state.runId, {
152
217
  options: runState,
153
218
  state,
154
219
  version: state.version,
155
220
  decisions,
221
+ ...extras,
156
222
  });
157
223
  }
158
224
  async recordDurableResumption(runId, interruption, version, ownership) {
@@ -232,6 +298,8 @@ export class RuntimeAgentSession {
232
298
  limit: input.limit,
233
299
  error: input.error,
234
300
  abortReason: input.abortReason,
301
+ stopReason: input.stopReason,
302
+ stopDetail: input.stopDetail,
235
303
  runState: input.runState,
236
304
  interruption: input.interruption,
237
305
  };
@@ -239,7 +307,10 @@ export class RuntimeAgentSession {
239
307
  async compact(options = {}) {
240
308
  if (this.activeRun)
241
309
  throw new Error("Agent session already has an active run");
242
- return this.compactBranch(options, undefined, options.signal, "manual");
310
+ const result = await this.compactBranch(options, undefined, options.signal, "manual");
311
+ // Plan 091 T2: history changed, so a pre-compaction meter reading would overstate the context.
312
+ this.activeInputMeter = undefined;
313
+ return result;
243
314
  }
244
315
  abort(reason) {
245
316
  this.activeRun?.abort(reason);
@@ -262,6 +333,7 @@ export class RuntimeAgentSession {
262
333
  store: this.store,
263
334
  leafId: options.leafId ?? this.currentLeafId,
264
335
  metadata: this.metadata,
336
+ ...(this.guardrailPackRefs ? { guardrailPacks: this.guardrailPackRefs } : {}),
265
337
  });
266
338
  }
267
339
  async clone(options = {}) {
@@ -284,6 +356,7 @@ export class RuntimeAgentSession {
284
356
  store: this.store,
285
357
  leafId: branch.length ? remap.get(branch[branch.length - 1].id) : undefined,
286
358
  metadata: this.metadata,
359
+ ...(this.guardrailPackRefs ? { guardrailPacks: this.guardrailPackRefs } : {}),
287
360
  });
288
361
  }
289
362
  branchReader() {
@@ -5,7 +5,7 @@
5
5
  * frozen prefix. The assembly branch lives in `input.ts`; opt-in agent wiring (Task 5) is not
6
6
  * part of this module. */
7
7
  import { type ContextBudgetMessageGroups } from "./context-budget.js";
8
- import type { AttentionCompiler, AttentionCompilerContext, AttentionCompilerOptions, AttentionCompilerSetting, AttentionInputCapOptions, AttentionReport, ContextBlock, Skill, ToolDefinition } from "./contracts.js";
8
+ import type { AttentionCompiler, AttentionCompilerContext, AttentionCompilerOptions, AttentionCompilerSetting, AttentionInputCapOptions, AttentionReport, AttentionTrigger, AttentionTriggerDecision, AttentionTriggerState, ContextBlock, Skill, ToolDefinition } from "./contracts.js";
9
9
  import { type CompactionTrigger } from "./contracts-core/compaction.js";
10
10
  import type { SecretRedactor } from "./redaction.js";
11
11
  import { type ResolvedToolResultFoldOptions } from "./tool-result-fold.js";
@@ -25,13 +25,29 @@ export declare function resolveAttentionReserveTokens(value: unknown): number;
25
25
  /** C2: host `maxInputTokens` wins; otherwise `contextWindow - (maxOutputTokens ?? 0) - reserve`.
26
26
  * Shared with the `input_ratio` compaction trigger (Task 4). Throws when no cap can be derived. */
27
27
  export declare function resolveInputCap(options?: AttentionInputCapOptions, model?: AttentionCompilerContext["model"]): number;
28
+ /**
29
+ * Build the frozen per-turn state the axes read: the compiler supplies the cap and the run budget
30
+ * (so a caller cannot silently drop the budget and fall back to the input cap), the caller
31
+ * supplies what only the turn knows.
32
+ */
33
+ export declare function attentionTriggerState(compiler: Pick<AttentionCompiler, "inputCap" | "runInputBudget">, turn: {
34
+ readonly estimatedInputTokens: number;
35
+ readonly runInputTokens?: number;
36
+ readonly turn?: number;
37
+ }): AttentionTriggerState;
38
+ /**
39
+ * Evaluate the fold axes in order against one turn's state; the first axis that fires wins, and
40
+ * its `targetTokens` (when it has one) is what the stages fold to. Called at most twice per turn —
41
+ * once at turn start, once after the stages — so a host predicate never runs per row.
42
+ */
43
+ export declare function evaluateAttentionTrigger(axes: readonly AttentionTrigger[], state: AttentionTriggerState): AttentionTriggerDecision;
28
44
  /** Validate compiler options + resolve the input cap. No provider I/O; unknown or
29
45
  * unresolvable input throws here rather than on the first turn. */
30
46
  export declare function createAttentionCompiler(options?: AttentionCompilerOptions, context?: AttentionCompilerContext): AttentionCompiler;
31
47
  /** Resolve the run's compiler from the agent setting plus an optional run overlay, validating
32
48
  * both eagerly (no provider I/O) so a typo fails at run start, not on some later turn (C12).
33
49
  * Returns `undefined` when the compiler is off — the assembly path then allocates nothing. */
34
- export declare function resolveRunAttentionCompiler(agent: AttentionCompilerSetting | undefined, run: AttentionCompilerSetting | undefined, model: AttentionCompilerContext["model"]): AttentionCompiler | undefined;
50
+ export declare function resolveRunAttentionCompiler(agent: AttentionCompilerSetting | undefined, run: AttentionCompilerSetting | undefined, model: AttentionCompilerContext["model"], runInputBudget?: number | null): AttentionCompiler | undefined;
35
51
  /** Caller-owned sticky frontier: what this session leaf already mutated (C10). Mutations are
36
52
  * monotonic, so a stubbed call stays stubbed and stripped thinking stays stripped even on a
37
53
  * later under-ratio turn — restoring either would rewrite the prompt-cache prefix. */
@@ -53,9 +69,15 @@ export interface AttentionCompileOptions {
53
69
  * decide fold-eligibility. Omitted → the deterministic stub and `keepLast` alone. */
54
70
  readonly fold?: ResolvedToolResultFoldOptions;
55
71
  readonly frontier?: AttentionStickyFrontier;
72
+ /** Session-owned folded bodies (plan 086 T3): a body stored here is re-applied instead of
73
+ * re-summarized, so a sticky row stays byte-identical and the host `summarize` runs once per
74
+ * row instead of once per turn. Omit for one-shot assemblies. */
75
+ readonly attentionFold?: AttentionFoldLedger;
56
76
  readonly redactor?: SecretRedactor;
57
77
  readonly signal?: AbortSignal;
58
78
  readonly turn?: number;
79
+ /** Run input tokens already charged this run; the `run_input_ratio` axis projects onto it. */
80
+ readonly runInputTokens?: number;
59
81
  readonly sessionId?: string;
60
82
  readonly runId?: string;
61
83
  }
@@ -90,6 +112,33 @@ export declare function serializeAttentionStickyFrontier(frontier: AttentionStic
90
112
  export declare function parseAttentionStickyFrontier(value: unknown): PersistedAttentionStickyFrontier | undefined;
91
113
  /** Rebuild a frontier from a restored snapshot; callers hold the session that owns it. */
92
114
  export declare function restoreAttentionStickyFrontier(persisted: PersistedAttentionStickyFrontier): AttentionStickyFrontier;
115
+ /** Session-owned folded bodies, keyed by tool call id. A row is summarized once: every later
116
+ * turn re-applies the stored body, so a sticky row stays byte-identical for the provider cache
117
+ * and the host `summarize` is not called again for it. Bodies are already redacted and capped by
118
+ * the fold that produced them, so nothing here needs redaction at persistence time. */
119
+ export interface AttentionFoldLedger {
120
+ /** toolCallId → stub body (never the payload); insertion order is fold order, oldest first. */
121
+ readonly bodies: Map<string, string>;
122
+ }
123
+ export declare function createAttentionFoldLedger(): AttentionFoldLedger;
124
+ /** Serialized fold ledger (plan 086 T3). Stub bodies only — no payload, and every entry was
125
+ * already capped and redacted when it was folded, so a durable resume restores it verbatim. */
126
+ export interface PersistedAttentionFoldLedger {
127
+ readonly v: 1;
128
+ /** Oldest-first, so a restored ledger is the tail of the folds the session made. */
129
+ readonly bodies: readonly {
130
+ readonly id: string;
131
+ readonly body: string;
132
+ }[];
133
+ }
134
+ /** Bounded snapshot of a live ledger; caller-owned (the runtime persists it, the compiler never
135
+ * writes anywhere). */
136
+ export declare function serializeAttentionFoldLedger(ledger: AttentionFoldLedger): PersistedAttentionFoldLedger;
137
+ /** Validate a persisted ledger from an untrusted store (plan 086 T3). Malformed *entries* are
138
+ * dropped one by one — a body the compiler cannot trust simply re-summarizes on the next turn —
139
+ * while a malformed *shape* yields `undefined` so the caller starts from an empty ledger.
140
+ * Never throws: a resume must not fail because a checkpoint was hand-edited. */
141
+ export declare function restoreAttentionFoldLedger(value: unknown): AttentionFoldLedger | undefined;
93
142
  /** Consecutive `truncated` turns that arm compaction by default. */
94
143
  export declare const DEFAULT_ATTENTION_TRUNCATION_THRESHOLD = 2;
95
144
  export interface AttentionTruncationTriggerOptions {