@arnilo/prism 0.8.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 (121) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +11 -11
  3. package/dist/agent-approval.d.ts +11 -2
  4. package/dist/agent-event-source.d.ts +9 -1
  5. package/dist/agent-event-source.js +10 -3
  6. package/dist/agent-loops.js +7 -4
  7. package/dist/agent-run-lifecycle.d.ts +15 -1
  8. package/dist/agent-run-lifecycle.js +63 -6
  9. package/dist/agent-run-state.d.ts +22 -2
  10. package/dist/agent-run-state.js +57 -5
  11. package/dist/agent-session/helpers.js +14 -0
  12. package/dist/agent-session/session/assemble.js +126 -24
  13. package/dist/agent-session/session/persist.d.ts +11 -0
  14. package/dist/agent-session/session/persist.js +37 -11
  15. package/dist/agent-session/session/provider-round.d.ts +14 -4
  16. package/dist/agent-session/session/provider-round.js +185 -19
  17. package/dist/agent-session/session/tool-round.js +20 -1
  18. package/dist/agent-session/session/types.d.ts +25 -2
  19. package/dist/agent-session/session.d.ts +38 -4
  20. package/dist/agent-session/session.js +76 -5
  21. package/dist/attention-compiler.d.ts +51 -2
  22. package/dist/attention-compiler.js +282 -21
  23. package/dist/cache-helpers.d.ts +4 -2
  24. package/dist/cache-helpers.js +8 -6
  25. package/dist/checkpoint-restore.d.ts +45 -0
  26. package/dist/checkpoint-restore.js +54 -0
  27. package/dist/context-budget.d.ts +2 -1
  28. package/dist/context-budget.js +24 -2
  29. package/dist/contracts-core/agent.d.ts +30 -0
  30. package/dist/contracts-core/attention.d.ts +95 -0
  31. package/dist/contracts-core/content.d.ts +10 -0
  32. package/dist/contracts-core/guardrail-packs.d.ts +41 -0
  33. package/dist/contracts-core/guardrail-packs.js +2 -0
  34. package/dist/contracts-core/provider.d.ts +25 -0
  35. package/dist/contracts-core/run-limits.d.ts +19 -0
  36. package/dist/contracts-core/session.d.ts +23 -5
  37. package/dist/contracts-core/session.js +21 -2
  38. package/dist/contracts-core/usage.d.ts +40 -0
  39. package/dist/contracts-core/usage.js +8 -0
  40. package/dist/contracts-core.d.ts +2 -0
  41. package/dist/contracts-core.js +2 -0
  42. package/dist/contracts-protocol.d.ts +76 -2
  43. package/dist/contracts-run-state.d.ts +56 -1
  44. package/dist/guardrail-packs/coding-standard.d.ts +3 -0
  45. package/dist/guardrail-packs/coding-standard.js +63 -0
  46. package/dist/guardrail-packs/destructive-commands.d.ts +3 -0
  47. package/dist/guardrail-packs/destructive-commands.js +46 -0
  48. package/dist/guardrail-packs/errors.d.ts +7 -0
  49. package/dist/guardrail-packs/errors.js +9 -0
  50. package/dist/guardrail-packs/index.d.ts +4 -0
  51. package/dist/guardrail-packs/index.js +15 -0
  52. package/dist/guardrail-packs/secrets-hygiene.d.ts +3 -0
  53. package/dist/guardrail-packs/secrets-hygiene.js +23 -0
  54. package/dist/guardrail-packs/types.d.ts +16 -0
  55. package/dist/guardrail-packs/types.js +2 -0
  56. package/dist/guardrail-packs/validation-respect.d.ts +3 -0
  57. package/dist/guardrail-packs/validation-respect.js +53 -0
  58. package/dist/guardrails.d.ts +20 -1
  59. package/dist/guardrails.js +268 -0
  60. package/dist/index.d.ts +14 -9
  61. package/dist/index.js +9 -6
  62. package/dist/input.d.ts +8 -1
  63. package/dist/input.js +68 -6
  64. package/dist/middleware.d.ts +37 -2
  65. package/dist/middleware.js +41 -0
  66. package/dist/node/session-store-jsonl.js +18 -3
  67. package/dist/observability.js +6 -0
  68. package/dist/provider-events.d.ts +8 -2
  69. package/dist/provider-events.js +60 -2
  70. package/dist/providers/openai-compatible.js +6 -3
  71. package/dist/run-bundle.js +2 -1
  72. package/dist/run-limits.d.ts +11 -1
  73. package/dist/run-limits.js +46 -0
  74. package/dist/session-stores.d.ts +12 -1
  75. package/dist/session-stores.js +21 -4
  76. package/dist/testing/agent-event-source-conformance.js +41 -2
  77. package/dist/testing/prefix-stability-conformance.d.ts +30 -0
  78. package/dist/testing/prefix-stability-conformance.js +104 -0
  79. package/dist/testing/session-store-conformance.d.ts +3 -2
  80. package/dist/testing/session-store-conformance.js +48 -0
  81. package/dist/tools.d.ts +5 -0
  82. package/dist/tools.js +11 -3
  83. package/dist/usage-estimation.d.ts +29 -0
  84. package/dist/usage-estimation.js +79 -0
  85. package/docs/agent-events.md +68 -1
  86. package/docs/agent-session-runtime.md +1 -0
  87. package/docs/attention-compiler.md +89 -8
  88. package/docs/coding-agent-tools.md +1 -1
  89. package/docs/compaction-and-retry.md +1 -1
  90. package/docs/compaction-observational-memory.md +33 -6
  91. package/docs/durable-runs.md +42 -0
  92. package/docs/embeddings.md +5 -0
  93. package/docs/evaluations.md +5 -0
  94. package/docs/execution-timeline.md +78 -1
  95. package/docs/guardrails.md +38 -2
  96. package/docs/index.md +32 -13
  97. package/docs/input-and-prompt-assembly.md +3 -3
  98. package/docs/knowledge-sync.md +4 -0
  99. package/docs/middleware-hooks.md +38 -2
  100. package/docs/migrate-to-0.9.md +210 -0
  101. package/docs/migration.md +13 -0
  102. package/docs/multi-agent-patterns.md +25 -2
  103. package/docs/node-jsonl-session-store.md +7 -1
  104. package/docs/observability.md +7 -3
  105. package/docs/options-index.md +2 -1
  106. package/docs/policy-and-audit.md +13 -1
  107. package/docs/prefix-stability-conformance.md +93 -0
  108. package/docs/provider-caching.md +4 -4
  109. package/docs/provider-conformance.md +16 -0
  110. package/docs/provider-packages.md +20 -20
  111. package/docs/public-contracts.md +2 -2
  112. package/docs/rag.md +101 -3
  113. package/docs/release-and-install.md +39 -37
  114. package/docs/runs-and-usage.md +43 -6
  115. package/docs/scoped-agent-memory.md +262 -0
  116. package/docs/session-store-conformance.md +1 -2
  117. package/docs/session-stores.md +17 -17
  118. package/docs/supervisors.md +32 -12
  119. package/docs/tools.md +17 -0
  120. package/docs/workflows.md +5 -0
  121. package/package.json +5 -1
@@ -1,6 +1,22 @@
1
+ import { GuardrailPackError } from "./guardrail-packs/errors.js";
2
+ export { GuardrailPackError } from "./guardrail-packs/errors.js";
3
+ import { BUILT_IN_GUARDRAIL_PACKS } from "./guardrail-packs/index.js";
1
4
  export const MAX_GUARDRAIL_CONCURRENCY = 16;
2
5
  const MAX_REASON_BYTES = 4 * 1024;
3
6
  const MAX_METADATA_BYTES = 16 * 1024;
7
+ /** Guardrail pack compile bounds (plan 092 Task 2). All ceilings are config-shape limits, not runtime budgets. */
8
+ export const MAX_GUARDRAIL_PACKS = 8;
9
+ export const MAX_GUARDRAIL_PACK_RULES = 64;
10
+ const MAX_PACK_ID_BYTES = 96;
11
+ const MAX_RULE_ID_BYTES = 96;
12
+ const MAX_RULE_REASON_BYTES = 512;
13
+ const MAX_RULE_ARG_PATHS = 8;
14
+ const MAX_PATTERN_BYTES = 4 * 1024;
15
+ const MAX_ARG_SCAN_DEPTH = 8;
16
+ const MAX_ARG_SCAN_STRINGS = 64;
17
+ const MAX_ARG_STRING_BYTES = 16 * 1024;
18
+ const MAX_PACK_NAME_BYTES = 128;
19
+ const OBSERVE_RULE_ID = "observe";
4
20
  export class GuardrailError extends Error {
5
21
  code;
6
22
  record;
@@ -60,6 +76,258 @@ export function assertGuardrailsAllowed(result) {
60
76
  if (result.terminal)
61
77
  throw new GuardrailError(result.terminal);
62
78
  }
79
+ /**
80
+ * Compiles `guardrailPacks` config onto the existing tool interception seams: one `tool_input`
81
+ * guardrail per rule (`name = pack:<pack>/<rule>`), plus one `tool_output` recorder for packs that
82
+ * observe results. Compiled once per session — patterns are compiled here, never per tool call.
83
+ * Throws `GuardrailPackError` on malformed config (fail closed); returns `undefined` when unset.
84
+ */
85
+ export function compileGuardrailPacks(refs, registry = BUILT_IN_GUARDRAIL_PACKS) {
86
+ const packs = resolveGuardrailPacks(refs, registry);
87
+ if (packs.length === 0)
88
+ return undefined;
89
+ const toolInput = [];
90
+ const toolOutput = [];
91
+ for (const pack of packs) {
92
+ const state = {};
93
+ if (pack.observe)
94
+ toolOutput.push(observeGuardrail(pack, pack.observe, state));
95
+ for (const resolved of pack.rules)
96
+ toolInput.push(ruleGuardrail(pack, resolved, state));
97
+ }
98
+ return toolOutput.length > 0 ? { toolInput, toolOutput } : { toolInput };
99
+ }
100
+ /** Stable identity rows for the same config `compileGuardrailPacks` accepts (no state, no guardrails built). */
101
+ export function describeGuardrailPacks(refs, registry = BUILT_IN_GUARDRAIL_PACKS) {
102
+ const rows = [];
103
+ for (const pack of resolveGuardrailPacks(refs, registry)) {
104
+ if (pack.observe)
105
+ rows.push({ name: packRuleName(pack.id, OBSERVE_RULE_ID), stage: "tool_output", revision: packRevision(pack) });
106
+ for (const resolved of pack.rules)
107
+ rows.push({ name: packRuleName(pack.id, resolved.rule.id), stage: "tool_input", revision: packRevision(pack) });
108
+ }
109
+ return rows;
110
+ }
111
+ function packRevision(pack) {
112
+ return `${pack.id}@${pack.version}`;
113
+ }
114
+ function packRuleName(packId, ruleId) {
115
+ return `pack:${packId}/${ruleId}`;
116
+ }
117
+ function resolveGuardrailPacks(refs, registry) {
118
+ if (refs === undefined)
119
+ return [];
120
+ if (!Array.isArray(refs))
121
+ throw new GuardrailPackError("guardrailPacks must be an array of pack ids or pack input objects");
122
+ if (refs.length > MAX_GUARDRAIL_PACKS)
123
+ throw new GuardrailPackError(`guardrailPacks accepts at most ${MAX_GUARDRAIL_PACKS} packs`);
124
+ const seenPacks = new Set();
125
+ return refs.map((ref) => {
126
+ const input = (typeof ref === "string" ? { id: ref } : ref) ?? {};
127
+ if (typeof input.id !== "string" || !input.id.trim() || byteLength(input.id) > MAX_PACK_ID_BYTES) {
128
+ throw new GuardrailPackError(`guardrail pack ids must be non-empty strings of at most ${MAX_PACK_ID_BYTES} bytes`);
129
+ }
130
+ if (seenPacks.has(input.id))
131
+ throw new GuardrailPackError(`duplicate guardrail pack id "${input.id}"`);
132
+ seenPacks.add(input.id);
133
+ if (input.version !== undefined && (!Number.isSafeInteger(input.version) || input.version < 1)) {
134
+ throw new GuardrailPackError(`guardrail pack "${input.id}" version must be a positive integer`);
135
+ }
136
+ const definition = registry.get(input.id);
137
+ if (definition === undefined && input.rules === undefined) {
138
+ throw new GuardrailPackError(`unknown guardrail pack "${input.id}"; known packs: ${[...registry.keys()].join(", ") || "none"}`);
139
+ }
140
+ let built;
141
+ if (input.rules !== undefined) {
142
+ if (input.options !== undefined)
143
+ throw new GuardrailPackError(`inline guardrail pack "${input.id}" cannot set options`);
144
+ built = { rules: input.rules };
145
+ }
146
+ else {
147
+ built = definition.build(Object.freeze({ ...input.options }));
148
+ }
149
+ if (!built || !Array.isArray(built.rules) || built.rules.length === 0) {
150
+ throw new GuardrailPackError(`guardrail pack "${input.id}" must declare at least one rule`);
151
+ }
152
+ if (built.rules.length > MAX_GUARDRAIL_PACK_RULES) {
153
+ throw new GuardrailPackError(`guardrail pack "${input.id}" accepts at most ${MAX_GUARDRAIL_PACK_RULES} rules`);
154
+ }
155
+ if (built.observe !== undefined && typeof built.observe !== "function") {
156
+ throw new GuardrailPackError(`guardrail pack "${input.id}" observe must be a function`);
157
+ }
158
+ const seenRules = new Set();
159
+ const rules = built.rules.map((rule) => resolveRule(input.id, rule, seenRules));
160
+ if (built.observe && byteLength(packRuleName(input.id, OBSERVE_RULE_ID)) > MAX_PACK_NAME_BYTES) {
161
+ throw new GuardrailPackError(`guardrail pack "${input.id}" name exceeds ${MAX_PACK_NAME_BYTES} bytes`);
162
+ }
163
+ return {
164
+ id: input.id,
165
+ version: input.version ?? definition?.version ?? 1,
166
+ rules,
167
+ ...(built.observe ? { observe: built.observe } : {}),
168
+ };
169
+ });
170
+ }
171
+ function resolveRule(packId, rule, seenRules) {
172
+ const where = `guardrail pack "${packId}"`;
173
+ if (!rule || typeof rule.id !== "string" || !rule.id.trim() || byteLength(rule.id) > MAX_RULE_ID_BYTES) {
174
+ throw new GuardrailPackError(`${where} rule ids must be non-empty strings of at most ${MAX_RULE_ID_BYTES} bytes`);
175
+ }
176
+ if (seenRules.has(rule.id))
177
+ throw new GuardrailPackError(`${where} has a duplicate rule id "${rule.id}"`);
178
+ seenRules.add(rule.id);
179
+ const action = rule.action ?? "deny";
180
+ if (action !== "deny" && action !== "tripwire") {
181
+ throw new GuardrailPackError(`${where} rule "${rule.id}" action must be "deny" or "tripwire" ("ask" has no deterministic seam)`);
182
+ }
183
+ const hasPattern = rule.pattern !== undefined;
184
+ const hasDeny = rule.deny !== undefined;
185
+ if (hasPattern === hasDeny) {
186
+ throw new GuardrailPackError(`${where} rule "${rule.id}" requires exactly one of "pattern" or "deny"`);
187
+ }
188
+ if (hasDeny && typeof rule.deny !== "function")
189
+ throw new GuardrailPackError(`${where} rule "${rule.id}" deny must be a function`);
190
+ if (rule.reason !== undefined && (typeof rule.reason !== "string" || byteLength(rule.reason) > MAX_RULE_REASON_BYTES)) {
191
+ throw new GuardrailPackError(`${where} rule "${rule.id}" reason must be a string of at most ${MAX_RULE_REASON_BYTES} bytes`);
192
+ }
193
+ let tools;
194
+ if (rule.tool !== undefined) {
195
+ tools = typeof rule.tool === "string" ? [rule.tool] : [...rule.tool];
196
+ if (tools.length === 0 || tools.length > MAX_GUARDRAIL_PACK_RULES || tools.some((name) => typeof name !== "string" || !name.trim())) {
197
+ throw new GuardrailPackError(`${where} rule "${rule.id}" tool must be a non-empty tool name or array of names`);
198
+ }
199
+ }
200
+ if (rule.argPath !== undefined) {
201
+ const paths = typeof rule.argPath === "string" ? [rule.argPath] : [...rule.argPath];
202
+ if (paths.length === 0 || paths.length > MAX_RULE_ARG_PATHS || paths.some((path) => typeof path !== "string" || !path.trim())) {
203
+ throw new GuardrailPackError(`${where} rule "${rule.id}" argPath must be a non-empty dot path or array of paths`);
204
+ }
205
+ }
206
+ if (byteLength(packRuleName(packId, rule.id)) > MAX_PACK_NAME_BYTES) {
207
+ throw new GuardrailPackError(`${where} rule "${rule.id}" name exceeds ${MAX_PACK_NAME_BYTES} bytes`);
208
+ }
209
+ return {
210
+ rule,
211
+ action,
212
+ reason: rule.reason ?? `guardrail pack rule ${packId}/${rule.id}`,
213
+ ...(tools ? { tools } : {}),
214
+ ...(hasPattern ? { regex: compileRulePattern(packId, rule.id, rule.pattern) } : {}),
215
+ };
216
+ }
217
+ function compileRulePattern(packId, ruleId, pattern) {
218
+ const where = `guardrail pack "${packId}" rule "${ruleId}"`;
219
+ if (pattern instanceof RegExp)
220
+ return new RegExp(pattern.source, pattern.flags.replace(/[gy]/g, ""));
221
+ if (typeof pattern !== "string" || !pattern)
222
+ throw new GuardrailPackError(`${where} pattern must be a non-empty string or RegExp`);
223
+ if (byteLength(pattern) > MAX_PATTERN_BYTES)
224
+ throw new GuardrailPackError(`${where} pattern exceeds ${MAX_PATTERN_BYTES} bytes`);
225
+ try {
226
+ return new RegExp(pattern);
227
+ }
228
+ catch (error) {
229
+ throw new GuardrailPackError(`${where} has an invalid pattern`, { cause: error });
230
+ }
231
+ }
232
+ function ruleGuardrail(pack, resolved, state) {
233
+ return {
234
+ name: packRuleName(pack.id, resolved.rule.id),
235
+ revision: packRevision(pack),
236
+ stage: "tool_input",
237
+ evaluate(context) {
238
+ if (resolved.tools && !resolved.tools.includes(context.toolName ?? ""))
239
+ return { action: "allow" };
240
+ const args = context.value.arguments;
241
+ const matched = resolved.rule.deny
242
+ ? Boolean(resolved.rule.deny(args, ruleContext(context, state)))
243
+ : patternMatches(resolved.regex, argumentStrings(args, resolved.rule.argPath));
244
+ if (!matched)
245
+ return { action: "allow" };
246
+ return {
247
+ // Pack vocabulary is `deny`; the core guardrail action for a denial is `block`.
248
+ action: resolved.action === "deny" ? "block" : "tripwire",
249
+ reason: resolved.reason,
250
+ metadata: { pack: pack.id, rule: resolved.rule.id, version: pack.version },
251
+ };
252
+ },
253
+ };
254
+ }
255
+ function observeGuardrail(pack, observe, state) {
256
+ return {
257
+ name: packRuleName(pack.id, OBSERVE_RULE_ID),
258
+ revision: packRevision(pack),
259
+ stage: "tool_output",
260
+ evaluate(context) {
261
+ observe(state, context.value, ruleContext(context, state));
262
+ return { action: "allow" };
263
+ },
264
+ };
265
+ }
266
+ function ruleContext(context, state) {
267
+ return {
268
+ toolName: context.toolName ?? "",
269
+ toolCallId: context.toolCallId ?? "",
270
+ sessionId: context.sessionId,
271
+ runId: context.runId,
272
+ metadata: context.metadata,
273
+ state,
274
+ };
275
+ }
276
+ function patternMatches(regex, values) {
277
+ for (const value of values) {
278
+ if (regex.test(value.length > MAX_ARG_STRING_BYTES ? value.slice(0, MAX_ARG_STRING_BYTES) : value))
279
+ return true;
280
+ }
281
+ return false;
282
+ }
283
+ function argumentStrings(args, argPath) {
284
+ if (argPath === undefined) {
285
+ const all = [];
286
+ for (const value of Object.values(args))
287
+ pushStrings(value, all, 0);
288
+ return all;
289
+ }
290
+ const out = [];
291
+ for (const path of typeof argPath === "string" ? [argPath] : argPath) {
292
+ walkPath(args, path.split("."), out);
293
+ if (out.length >= MAX_ARG_SCAN_STRINGS)
294
+ break;
295
+ }
296
+ return out;
297
+ }
298
+ function walkPath(value, segments, out) {
299
+ if (out.length >= MAX_ARG_SCAN_STRINGS)
300
+ return;
301
+ if (segments.length === 0) {
302
+ pushStrings(value, out, 0);
303
+ return;
304
+ }
305
+ if (Array.isArray(value)) {
306
+ for (const item of value)
307
+ walkPath(item, segments, out);
308
+ return;
309
+ }
310
+ if (value && typeof value === "object") {
311
+ walkPath(value[segments[0]], segments.slice(1), out);
312
+ }
313
+ }
314
+ function pushStrings(value, out, depth) {
315
+ if (out.length >= MAX_ARG_SCAN_STRINGS || depth > MAX_ARG_SCAN_DEPTH)
316
+ return;
317
+ if (typeof value === "string") {
318
+ out.push(value);
319
+ return;
320
+ }
321
+ if (Array.isArray(value)) {
322
+ for (const item of value)
323
+ pushStrings(item, out, depth + 1);
324
+ return;
325
+ }
326
+ if (value && typeof value === "object") {
327
+ for (const item of Object.values(value))
328
+ pushStrings(item, out, depth + 1);
329
+ }
330
+ }
63
331
  function stageGuards(guardrails, stage) {
64
332
  if (!guardrails)
65
333
  return [];
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  export { resolveAgentDefinition } from "./agent-definitions.js";
2
2
  export type { AgentEventSourceErrorCode } from "./agent-event-source.js";
3
- export { AgentEventSourceError, createMemoryAgentEventSource } from "./agent-event-source.js";
3
+ export { AgentEventSourceError, createMemoryAgentEventSource, isTerminalAgentEventType } from "./agent-event-source.js";
4
4
  export { dispatchToolCallsInOrder, generateValidateReviseLoop, isAgentLoopOptions, resolveLoop, resolveToolConcurrency, singleShotLoop, } from "./agent-loops.js";
5
5
  export type { AgentRunLifecycle, AgentRunLifecycleAgent, AgentRunLifecycleOptions, AgentRunLifecycleRequest, AgentRunLifecycleStreamRequest, } from "./agent-run-lifecycle.js";
6
6
  export { createAgentRunLifecycle } from "./agent-run-lifecycle.js";
7
+ export type { CheckpointRestoreAudit, CheckpointRestoreAuditEntry, CheckpointRestoreHook, RunCheckpointRestoreHooksOptions, } from "./checkpoint-restore.js";
8
+ export { CheckpointRestoreError, DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS, runCheckpointRestoreHooks } from "./checkpoint-restore.js";
7
9
  export type { PendingToolCall, StoredAgentRunState } from "./agent-run-state.js";
8
- export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, agentFingerprint, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, loadAgentRunState, } from "./agent-run-state.js";
10
+ export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, agentFingerprint, boundCheckpointMetadata, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, loadAgentRunState, MAX_AGENT_RUN_METADATA_BYTES, readCheckpointMetadata, resolveCheckpointMetadata, } from "./agent-run-state.js";
9
11
  export { createAgent, createAgentSession, resumeAgentRun, resumeAgentRunStream } from "./agents.js";
10
12
  export type { ArtifactApproval, ArtifactApprovalState, ArtifactBodyErrorCode, ArtifactBodyPresignOptions, ArtifactBodyRef, ArtifactBodyStore, ArtifactBodyTransferOptions, ArtifactCitation, ArtifactDecisionState, ArtifactDeliveryToken, ArtifactRecord, ArtifactRevision, CitationIntegrityReason, CitationIntegrityResult, CitationLiveSource, CitationSupport, } from "./artifacts.js";
11
13
  export { ARTIFACT_BODY_ERROR_CODES, ARTIFACT_CHECKPOINT_NAMESPACE, ArtifactBodyStoreError, ArtifactError, approvalEvidenceIntact, artifactApprovalState, artifactCheckpointKey, checkCitationIntegrity, citationBindingDigest, HARD_CITATION_EXCERPT_BYTES, } from "./artifacts.js";
@@ -28,7 +30,7 @@ export { assertDeclaredMediaTypeMatches, assertMediaBlocksWithinBounds, assertMe
28
30
  export type { ContextBudget, ContextBudgetMessageGroups, ContextBudgetOmission, ContextBudgetOmissionKind, ContextBudgetReport, TokenEstimator, } from "./context-budget.js";
29
31
  export { applyContextBudget, CONTEXT_BUDGET_ERROR_CODE, CONTEXT_BUDGET_REPORT_METADATA_KEY, ContextBudgetError, DEFAULT_MAX_CONTEXT_BUDGET_OMISSIONS, estimateAssemblyTokens, estimateMessageBytes, estimateMessageTokens, estimateTextBytes, estimateTextTokens, getContextBudgetReport, HARD_MAX_CONTEXT_BUDGET_BYTES, HARD_MAX_CONTEXT_BUDGET_OMISSIONS, HARD_MAX_CONTEXT_BUDGET_TOKENS, isContextBudgetError, resolveContextBudget, } from "./context-budget.js";
30
32
  export type * from "./contracts.js";
31
- export type { ApprovalOutcome, AttentionCompiler, AttentionCompilerContext, AttentionCompilerOptions, AttentionCompilerSetting, AttentionInputCapOptions, AttentionReport, CompactionTrigger, CompactionTriggerContext, DecisionScope, NestedRunApproval, NestedRunOutcome, NestedRunRef, PendingDecision, PendingDecisionKind, ProviderResolver, RealtimeCaps, RealtimeEvent, RealtimeSession, RealtimeSessionFactory, RealtimeSessionOptions, ResolveShouldCompactInput, ResolveShouldCompactOptions, ResumeNestedRun, RunDecision, RunLimitCounters, RunLimitName, SecureAgentOptions, StickyDecision, ToolCallAuthority, ToolEffectClassifier, ToolEffectDeclaration, ToolEffectIdempotency, ToolEffectKey, ToolEffectKind, ToolEffectRecord, ToolEffectStatus, ToolEffectStore, ToolEffectTransition, ToolElicitationRequest, } from "./contracts.js";
33
+ export type { ApprovalOutcome, AttentionCompiler, AttentionCompilerContext, AttentionCompilerOptions, AttentionCompilerSetting, AttentionInputCapOptions, AttentionReport, CompactionTrigger, CompactionTriggerContext, ContextMeter, DecisionScope, ModelFamily, NestedRunApproval, NestedRunOutcome, NestedRunRef, PendingDecision, PendingDecisionKind, ProviderResolver, RealtimeCaps, RealtimeEvent, RealtimeSession, RealtimeSessionFactory, RealtimeSessionOptions, ResolveShouldCompactInput, ResolveShouldCompactOptions, ResumeNestedRun, RunDecision, RunLimitCounters, RunLimitName, SecureAgentOptions, StickyDecision, TokenEstimate, TokenEstimateConfidence, ToolCallAuthority, ToolEffectClassifier, ToolEffectDeclaration, ToolEffectIdempotency, ToolEffectKey, ToolEffectKind, ToolEffectRecord, ToolEffectStatus, ToolEffectStore, ToolEffectTransition, ToolElicitationRequest, } from "./contracts.js";
32
34
  export { AgentDecisionError, AgentDelegationSuspendedError, AgentLoopStateError, AgentRunError, AgentRunStateError, assertBatchJobsSupported, assertCompactionTrigger, assertEmbeddingsSupported, assertImageGenerationSupported, assertModerationSupported, assertSessionMetadataKey, assertSpeechSupported, assertTranscriptionSupported, assertVideoGenerationSupported, BatchJobsError, DEFAULT_MAX_PENDING_DECISIONS, DEFAULT_MAX_PENDING_STEER_BYTES, DEFAULT_MAX_PENDING_STEERS, DEFAULT_MAX_SESSION_SEARCH_CURSOR_BYTES, DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_ENTRIES, DEFAULT_MAX_SESSION_SEARCH_LINEAR_SESSIONS, DEFAULT_MAX_SESSION_SEARCH_QUERY_BYTES, DEFAULT_MAX_SESSION_SEARCH_SNIPPET_BYTES, DEFAULT_MAX_STICKY_DECISIONS, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_SNAPSHOT_CACHE_TTL_MS, EmbeddingsError, HARD_MAX_ACTION_CONSTRAINT_BYTES, HARD_MAX_ACTION_CONSTRAINTS, HARD_MAX_DECISION_REASON_BYTES, HARD_MAX_ELICITATION_BYTES, HARD_MAX_PENDING_DECISIONS, HARD_MAX_PENDING_STEER_BYTES, HARD_MAX_PENDING_STEERS, HARD_MAX_SESSION_SEARCH_CURSOR_BYTES, HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES, HARD_MAX_SESSION_SEARCH_LIMIT, HARD_MAX_SESSION_SEARCH_LINEAR_BYTES, HARD_MAX_SESSION_SEARCH_LINEAR_ENTRIES, HARD_MAX_SESSION_SEARCH_LINEAR_SESSIONS, HARD_MAX_SESSION_SEARCH_QUERY_BYTES, HARD_MAX_SESSION_SEARCH_SNIPPET_BYTES, HARD_MAX_SNAPSHOT_CACHE_TTL_MS, HARD_MAX_STICKY_DECISIONS, ImageGenerationError, isBatchJobTerminal, isSessionAppendConflict, isSessionEntryKind, isSessionMetadataConflict, isSessionSearchUnsupported, MAX_ACTION_CONSTRAINT_BYTES, MAX_ACTION_CONSTRAINTS, MAX_ATTRIBUTION_DEPTH, MAX_DECISION_REASON_BYTES, MAX_ELICITATION_BYTES, ModerationError, modelSupportsBatchJobs, modelSupportsEmbeddings, modelSupportsImageGeneration, modelSupportsModeration, modelSupportsSpeech, modelSupportsTranscription, modelSupportsVideoGeneration, pollBatch, resolveSessionSearchQuery, resolveShouldCompact, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SESSION_METADATA_CONFLICT_CODE, SESSION_SEARCH_UNSUPPORTED_CODE, SESSION_SEARCH_WORKSPACE_METADATA_KEY, SessionAppendConflictError, SessionMetadataConflictError, SessionSearchUnsupportedError, SpeechError, TranscriptionError, VideoGenerationError, } from "./contracts.js";
33
35
  export { parseAgentFile, parseSkillFile } from "./contribution-parsing.js";
34
36
  export type { ContributionRegistries, ContributionRegistriesOptions, ContributionRegistry, ContributionRegistryOptions, } from "./contributions.js";
@@ -53,8 +55,9 @@ export type { MemoryRunFeedbackStoreOptions, PrepareRunFeedbackOptions, RunFeedb
53
55
  export { createMemoryRunFeedbackStore, prepareRunFeedback, RunFeedbackError, requireRunFeedbackOwnership, runFeedbackPageLimit, } from "./feedback.js";
54
56
  export type { ApplyFieldPolicyOptions, AuditFieldRedaction, AuditFieldRedactorLike, AuditFieldRedactorOptions, FieldPolicy, FieldPolicyAction, FieldPolicyDecision, FieldPolicyInput, ProtectedFieldPolicyOptions, } from "./field-policy.js";
55
57
  export { ALLOW_FIELD_POLICY, applyFieldPolicy, createAuditFieldRedactor, createProtectedFieldPolicy, FIELD_POLICY_LIMITS, FieldPolicyError, } from "./field-policy.js";
56
- export type { GuardrailRunResult, RunGuardrailsOptions, } from "./guardrails.js";
57
- export { assertGuardrailsAllowed, GuardrailError, MAX_GUARDRAIL_CONCURRENCY, runGuardrails } from "./guardrails.js";
58
+ export type { GuardrailPackRow, GuardrailRunResult, RunGuardrailsOptions, } from "./guardrails.js";
59
+ export { assertGuardrailsAllowed, compileGuardrailPacks, describeGuardrailPacks, GuardrailError, GuardrailPackError, MAX_GUARDRAIL_CONCURRENCY, MAX_GUARDRAIL_PACK_RULES, MAX_GUARDRAIL_PACKS, runGuardrails, } from "./guardrails.js";
60
+ export { BUILT_IN_GUARDRAIL_PACK_IDS } from "./guardrail-packs/index.js";
58
61
  export type { AgentIdentity, AssertIdentityActiveOptions, IdentityLimits, IdentityVerifier, NarrowIdentityOptions, Principal, ResolvedIdentityLimits, } from "./identity.js";
59
62
  export { assertIdentityActive, assertIdentityMatchesOwnership, assertIdentityPropagation, DEFAULT_IDENTITY_LIMITS, HARD_IDENTITY_LIMITS, IdentityError, identityTelemetryAttributes, narrowIdentity, ownershipFromIdentity, resolveIdentityLimits, resolveRunIdentity, } from "./identity.js";
60
63
  export type { AgentInput, AssembleProviderInputOptions, DefaultInputBuildContext, DefaultInputBuilder, DefaultPromptBuilder, InputAttachment, PromptInstruction, PromptTemplateOptions, ResolveContextOptions, } from "./input.js";
@@ -64,8 +67,8 @@ export { resolveInstructionInjectors, runInstructionInjectors } from "./instruct
64
67
  export { createMemoryLeaseStore, LEASE_CONFLICT_CODE, LeaseConflictError } from "./leases.js";
65
68
  export type { ManifestContributionDeclaration, ManifestContributionKind, ManifestResourceDeclaration, PrismManifest } from "./manifests.js";
66
69
  export { definePrismManifest, parsePrismManifest } from "./manifests.js";
67
- export type { Middleware, MiddlewareHookName, MiddlewareNext, MiddlewareRegistry, MiddlewareRegistryOptions } from "./middleware.js";
68
- export { createMiddlewareRegistry } from "./middleware.js";
70
+ export type { BeforeProviderTurnPayload, DeterministicTurnAnswer, DeterministicTurnProvenance, Middleware, MiddlewareHookName, MiddlewareNext, MiddlewareRegistry, MiddlewareRegistryOptions, } from "./middleware.js";
71
+ export { createMiddlewareRegistry, DeterministicTurnError } from "./middleware.js";
69
72
  export type { MockProviderOptions } from "./mock-provider.js";
70
73
  export { createMockProvider } from "./mock-provider.js";
71
74
  export type { ModelRegistry, ModelRegistryOptions } from "./models.js";
@@ -75,7 +78,7 @@ export { createProviderTurnMetadata, readProviderHttpStatus } from "./observabil
75
78
  export type { ApplyRetentionInput, ApplyRetentionResult, ConsumeTenantQuotaInput, ExportUnderHoldInput, LegalHoldExportItem, LegalHoldQuery, LegalHoldRecord, PersistenceLifecycleStore, PersistenceResourceKind, PutLegalHoldInput, ReleaseLegalHoldInput, SetTenantQuotaInput, TenantQuota, } from "./persistence-lifecycle.js";
76
79
  export { createMemoryPersistenceLifecycle, DEFAULT_LIFECYCLE_PAGE_SIZE, DEFAULT_MAX_HOLD_REASON_BYTES, HARD_LIFECYCLE_PAGE_SIZE, HARD_MAX_HOLD_REASON_BYTES, isResourceHeld, PersistenceLifecycleError, } from "./persistence-lifecycle.js";
77
80
  export { boundResponse, defaultResolver, isLoopbackAddress, isLoopbackHostname, normalizeHostname, type PinnedFetchOptions, pinnedFetch, raceAbort, requestPinned, resolvePinnedAddress, } from "./pinned-fetch.js";
78
- export { providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
81
+ export { mapProviderStopReason, providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
79
82
  export { authMethodKey, defineProviderPackage, systemPromptContributionKey } from "./provider-packages.js";
80
83
  export type { ApplyDefaultProviderRequestOptionsContext, SessionCachePolicyOptions } from "./provider-request-policy.js";
81
84
  export { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions, ProviderRequirementError, } from "./provider-request-policy.js";
@@ -123,8 +126,10 @@ export { createActiveToolSet, createSearchToolsTool, createToolSearchIndex, crea
123
126
  export type { DispatchToolCallOptions, ToolArgumentValidationError, ToolArgumentValidationResult, ToolArgumentValidator, ToolFilter, ToolFilterInput, ToolParameterValidatorOptions, ToolRegistryOptions, ToolValidator, } from "./tools.js";
124
127
  export { createToolParameterValidator, createToolRegistry, dispatchToolCall, filterTools } from "./tools.js";
125
128
  export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
129
+ export type { ModelFamilyTokens } from "./usage-estimation.js";
130
+ export { MODEL_FAMILY_TOKENS, resolveModelFamily } from "./usage-estimation.js";
126
131
  export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
127
132
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
128
133
  export declare const name = "prism";
129
- export declare const version = "0.8.0";
134
+ export declare const version = "0.9.0";
130
135
  export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  export { resolveAgentDefinition } from "./agent-definitions.js";
2
- export { AgentEventSourceError, createMemoryAgentEventSource } from "./agent-event-source.js";
2
+ export { AgentEventSourceError, createMemoryAgentEventSource, isTerminalAgentEventType } from "./agent-event-source.js";
3
3
  export { dispatchToolCallsInOrder, generateValidateReviseLoop, isAgentLoopOptions, resolveLoop, resolveToolConcurrency, singleShotLoop, } from "./agent-loops.js";
4
4
  export { createAgentRunLifecycle } from "./agent-run-lifecycle.js";
5
- export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, agentFingerprint, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, loadAgentRunState, } from "./agent-run-state.js";
5
+ export { CheckpointRestoreError, DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS, runCheckpointRestoreHooks } from "./checkpoint-restore.js";
6
+ export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, agentFingerprint, boundCheckpointMetadata, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, loadAgentRunState, MAX_AGENT_RUN_METADATA_BYTES, readCheckpointMetadata, resolveCheckpointMetadata, } from "./agent-run-state.js";
6
7
  export { createAgent, createAgentSession, resumeAgentRun, resumeAgentRunStream } from "./agents.js";
7
8
  export { ARTIFACT_BODY_ERROR_CODES, ARTIFACT_CHECKPOINT_NAMESPACE, ArtifactBodyStoreError, ArtifactError, approvalEvidenceIntact, artifactApprovalState, artifactCheckpointKey, checkCitationIntegrity, citationBindingDigest, HARD_CITATION_EXCERPT_BYTES, } from "./artifacts.js";
8
9
  export { ATTENTION_BUDGET_ERROR_CODE, AttentionBudgetError, createAttentionCompiler, createAttentionTruncationTrigger, DEFAULT_ATTENTION_COMPACT_RATIO, DEFAULT_ATTENTION_KEEP_LAST, DEFAULT_ATTENTION_RESERVE_TOKENS, DEFAULT_ATTENTION_THINKING_KEEP_TURNS, DEFAULT_ATTENTION_TRIGGER_RATIO, DEFAULT_ATTENTION_TRUNCATION_THRESHOLD, isAttentionBudgetError, resolveAttentionReserveTokens, resolveInputCap, resolveRunAttentionCompiler, } from "./attention-compiler.js";
@@ -27,20 +28,21 @@ export { applyExecutionDecision, assertExecutionAllowed, checkExecution, Executi
27
28
  export { activateKernel, createExtensionEventBus, createExtensionKernel } from "./extensions.js";
28
29
  export { createMemoryRunFeedbackStore, prepareRunFeedback, RunFeedbackError, requireRunFeedbackOwnership, runFeedbackPageLimit, } from "./feedback.js";
29
30
  export { ALLOW_FIELD_POLICY, applyFieldPolicy, createAuditFieldRedactor, createProtectedFieldPolicy, FIELD_POLICY_LIMITS, FieldPolicyError, } from "./field-policy.js";
30
- export { assertGuardrailsAllowed, GuardrailError, MAX_GUARDRAIL_CONCURRENCY, runGuardrails } from "./guardrails.js";
31
+ export { assertGuardrailsAllowed, compileGuardrailPacks, describeGuardrailPacks, GuardrailError, GuardrailPackError, MAX_GUARDRAIL_CONCURRENCY, MAX_GUARDRAIL_PACK_RULES, MAX_GUARDRAIL_PACKS, runGuardrails, } from "./guardrails.js";
32
+ export { BUILT_IN_GUARDRAIL_PACK_IDS } from "./guardrail-packs/index.js";
31
33
  export { assertIdentityActive, assertIdentityMatchesOwnership, assertIdentityPropagation, DEFAULT_IDENTITY_LIMITS, HARD_IDENTITY_LIMITS, IdentityError, identityTelemetryAttributes, narrowIdentity, ownershipFromIdentity, resolveIdentityLimits, resolveRunIdentity, } from "./identity.js";
32
34
  export { assembleProviderInput, createDefaultInputBuilder, createDefaultPromptBuilder, EMPTY_TOOL_RESULT_TEXT, renderPromptTemplate, resolveContextProviders, } from "./input.js";
33
35
  export { resolveInstructionInjectors, runInstructionInjectors } from "./instruction-injection.js";
34
36
  export { createMemoryLeaseStore, LEASE_CONFLICT_CODE, LeaseConflictError } from "./leases.js";
35
37
  export { definePrismManifest, parsePrismManifest } from "./manifests.js";
36
- export { createMiddlewareRegistry } from "./middleware.js";
38
+ export { createMiddlewareRegistry, DeterministicTurnError } from "./middleware.js";
37
39
  export { createMockProvider } from "./mock-provider.js";
38
40
  export { createModelRegistry } from "./models.js";
39
41
  export { abortableSleep, pollDeviceCodeToken, redactOAuthError, throwIfAborted, } from "./oauth-device-code.js";
40
42
  export { createProviderTurnMetadata, readProviderHttpStatus } from "./observability.js";
41
43
  export { createMemoryPersistenceLifecycle, DEFAULT_LIFECYCLE_PAGE_SIZE, DEFAULT_MAX_HOLD_REASON_BYTES, HARD_LIFECYCLE_PAGE_SIZE, HARD_MAX_HOLD_REASON_BYTES, isResourceHeld, PersistenceLifecycleError, } from "./persistence-lifecycle.js";
42
44
  export { boundResponse, defaultResolver, isLoopbackAddress, isLoopbackHostname, normalizeHostname, pinnedFetch, raceAbort, requestPinned, resolvePinnedAddress, } from "./pinned-fetch.js";
43
- export { providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
45
+ export { mapProviderStopReason, providerContentDelta, providerContinuationRequired, providerDone, providerError, providerTextDelta, providerThinkingDelta, providerToolCall, providerToolCallDelta, providerUsage, toolCallContent, toolCallFromArgumentsText, } from "./provider-events.js";
44
46
  export { authMethodKey, defineProviderPackage, systemPromptContributionKey } from "./provider-packages.js";
45
47
  export { applyDefaultProviderRequestOptions, createProviderRequestPolicyChain, createSessionCachePolicy, mergeProviderRequestOptions, ProviderRequirementError, } from "./provider-request-policy.js";
46
48
  export { canonicalizeJsonSchema } from "./providers/schema.js";
@@ -67,8 +69,9 @@ export { DEFAULT_TOOL_RESULT_FOLD_MAX_SUMMARY_BYTES, DEFAULT_TOOL_RESULT_FOLD_MI
67
69
  export { createActiveToolSet, createSearchToolsTool, createToolSearchIndex, createToolSearchState, DEFAULT_MAX_TOOLS_SEARCH_QUERY_BYTES, DEFAULT_TOOLS_SEARCH_TOP_K, HARD_MAX_TOOLS_INDEX, HARD_MAX_TOOLS_SEARCH_QUERY_BYTES, HARD_MAX_TOOLS_SEARCH_TOP_K, isToolDisclosureError, resolveToolsDisclosure, SEARCH_TOOLS_TOOL_NAME, scoreTools, selectDisclosedTools, TOOL_DISCLOSURE_ERROR_CODE, ToolDisclosureError, } from "./tool-search.js";
68
70
  export { createToolParameterValidator, createToolRegistry, dispatchToolCall, filterTools } from "./tools.js";
69
71
  export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
72
+ export { MODEL_FAMILY_TOKENS, resolveModelFamily } from "./usage-estimation.js";
70
73
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
71
74
  export const name = "prism";
72
- export const version = "0.8.0";
75
+ export const version = "0.9.0";
73
76
  export const description = "Agent harness for AI providers, agents, sessions, and tools.";
74
77
  //# sourceMappingURL=index.js.map
package/dist/input.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type AttentionStickyFrontier } from "./attention-compiler.js";
1
+ import { type AttentionFoldLedger, type AttentionStickyFrontier } from "./attention-compiler.js";
2
2
  import { type ContextBudget } from "./context-budget.js";
3
3
  import type { AttentionCompiler, AttentionCompilerOptions, AttentionReport, ContentBlock, ContextBlock, ContextProvider, ContextResolutionContext, InputBuildContext, InputBuilder, InstructionInjector, JsonObject, Message, ModelConfig, PromptBuilder, PromptBuildRequest, ProviderRequest, ProviderRequestOptions, ResourceLoader, Skill, ToolDefinition, ToolResult } from "./contracts.js";
4
4
  import type { MiddlewareRegistry } from "./middleware.js";
@@ -65,6 +65,8 @@ export interface AssembleProviderInputOptions extends DefaultInputBuildContext {
65
65
  readonly skills?: readonly Skill[];
66
66
  readonly skillsDisclosure?: SkillsDisclosure;
67
67
  readonly loadedSkills?: LoadedSkillSet;
68
+ /** Run-owned append-only segments. Omit outside a session to retain existing assembly exactly. */
69
+ readonly tailSegments?: Map<string, Message>;
68
70
  readonly tools?: readonly ToolDefinition[];
69
71
  /** Tools disclosure: "search" narrows the disclosed tool list (activated ∪ top-k); default "all" is unchanged. */
70
72
  readonly toolsDisclosure?: ToolsDisclosure;
@@ -86,9 +88,14 @@ export interface AssembleProviderInputOptions extends DefaultInputBuildContext {
86
88
  readonly attentionCompiler?: AttentionCompilerOptions | AttentionCompiler;
87
89
  /** Per-session-leaf sticky frontier; omit for one-shot assemblies (no cross-turn stickiness). */
88
90
  readonly attentionSticky?: AttentionStickyFrontier;
91
+ /** Per-session folded bodies; omit to re-summarize every folded row on every turn. */
92
+ readonly attentionFold?: AttentionFoldLedger;
89
93
  /** Called once per *mutated* turn with the report, so a host can emit telemetry: under-ratio
90
94
  * turns never call it, and it runs before `input_assembly` middleware. */
91
95
  readonly onAttentionReport?: (report: AttentionReport) => void;
96
+ /** Run input tokens already charged this run; feeds the `run_input_ratio` axis projection
97
+ * (default 0). The run budget itself rides the resolved `AttentionCompiler` handle. */
98
+ readonly runInputTokens?: number;
92
99
  }
93
100
  export declare function createDefaultInputBuilder(): DefaultInputBuilder;
94
101
  export declare function resolveContextProviders(options: ResolveContextOptions): Promise<readonly ContextBlock[]>;
package/dist/input.js CHANGED
@@ -5,7 +5,7 @@ import { runInstructionInjectors } from "./instruction-injection.js";
5
5
  import { applyDefaultProviderRequestOptions } from "./provider-request-policy.js";
6
6
  import { redactMessage } from "./redaction.js";
7
7
  import { loadTextResource } from "./resources.js";
8
- import { skillMessages as buildSkillMessages } from "./skill-disclosure.js";
8
+ import { capSkillCatalog, selectSkillsForPrompt, skillHasRenderableBody, skillMessages as buildSkillMessages, } from "./skill-disclosure.js";
9
9
  import { composeSystemPrompt } from "./system-prompts.js";
10
10
  import { foldToolResultHistory, foldToolResults } from "./tool-result-fold.js";
11
11
  import { selectDisclosedTools } from "./tool-search.js";
@@ -51,11 +51,16 @@ export function createDefaultPromptBuilder() {
51
51
  // text-only (or unknown-capability) models — duplicating it doubles tool tokens per turn.
52
52
  const tools = request.model?.capabilities?.tools === true ? undefined : request.tools;
53
53
  const context = contextMessages(request.context);
54
- const skills = buildSkillMessages(request.skills, {
55
- disclosure: request.skillsDisclosure,
56
- loaded: request.loadedSkills,
57
- demotedBodies: request.demotedSkillBodies?.length ? new Set(request.demotedSkillBodies) : undefined,
58
- });
54
+ const skills = buildSkillMessages(request.skills, request.tailSkillBodies
55
+ ? {
56
+ disclosure: "progressive",
57
+ demotedBodies: request.demotedSkillBodies?.length ? new Set(request.demotedSkillBodies) : undefined,
58
+ }
59
+ : {
60
+ disclosure: request.skillsDisclosure,
61
+ loaded: request.loadedSkills,
62
+ demotedBodies: request.demotedSkillBodies?.length ? new Set(request.demotedSkillBodies) : undefined,
63
+ });
59
64
  const declarations = toolMessages(tools);
60
65
  if ((request.inputLayout ?? "cache_aware") === "legacy") {
61
66
  return [...context, ...skills, ...declarations, ...request.messages];
@@ -156,9 +161,11 @@ export async function assembleProviderInput(options) {
156
161
  tools,
157
162
  fold: options.toolResultFold,
158
163
  frontier: options.attentionSticky,
164
+ attentionFold: options.attentionFold,
159
165
  redactor: options.redactor,
160
166
  signal: options.signal,
161
167
  turn,
168
+ runInputTokens: options.runInputTokens,
162
169
  sessionId: options.sessionId,
163
170
  runId: options.runId,
164
171
  });
@@ -213,6 +220,14 @@ export async function assembleProviderInput(options) {
213
220
  ...baseContext,
214
221
  });
215
222
  }
223
+ const tailSegments = options.tailSegments;
224
+ const tailSkillBodies = tailSegments !== undefined;
225
+ if (tailSegments) {
226
+ const activeTailSegments = new Set();
227
+ messages = moveResourceMessagesToTail(messages, options, tailSegments, activeTailSegments);
228
+ appendSkillTailSegments(tailSegments, activeTailSegments, skills, options.skillsDisclosure, options.loadedSkills, demotedSkillBodies);
229
+ messages = [...messages, ...tailMessages(tailSegments, activeTailSegments)];
230
+ }
216
231
  const promptBuilder = options.promptBuilder ?? createDefaultPromptBuilder();
217
232
  const promptRequest = options.middleware
218
233
  ? await options.middleware.run("prompt_build", {
@@ -222,6 +237,7 @@ export async function assembleProviderInput(options) {
222
237
  skills,
223
238
  skillsDisclosure: options.skillsDisclosure,
224
239
  loadedSkills: options.loadedSkills,
240
+ tailSkillBodies,
225
241
  demotedSkillBodies,
226
242
  tools,
227
243
  metadata: options.metadata,
@@ -234,6 +250,7 @@ export async function assembleProviderInput(options) {
234
250
  skills,
235
251
  skillsDisclosure: options.skillsDisclosure,
236
252
  loadedSkills: options.loadedSkills,
253
+ tailSkillBodies,
237
254
  demotedSkillBodies,
238
255
  tools,
239
256
  metadata: options.metadata,
@@ -389,6 +406,51 @@ function textMessage(role, text, metadata) {
389
406
  function contextMessages(context) {
390
407
  return (context ?? []).map((block) => textMessage("system", `${block.title ? `${block.title}:\n` : "Context:\n"}${blockText(block)}`, block.metadata));
391
408
  }
409
+ function moveResourceMessagesToTail(messages, options, tailSegments, activeTailSegments) {
410
+ const resourceUris = new Set([
411
+ ...(options.resourceUris ?? []),
412
+ ...(options.attachments ?? []).flatMap((attachment) => attachment.uri !== undefined && attachment.text === undefined && attachment.content === undefined ? [attachment.uri] : []),
413
+ ]);
414
+ if (resourceUris.size === 0)
415
+ return messages;
416
+ return messages.filter((message) => {
417
+ const uri = message.metadata?.uri;
418
+ if (message.role !== "user" || typeof uri !== "string" || !resourceUris.has(uri))
419
+ return true;
420
+ appendTailSegment(tailSegments, activeTailSegments, `resource:${uri}`, message);
421
+ return false;
422
+ });
423
+ }
424
+ function appendSkillTailSegments(tailSegments, activeTailSegments, skills, disclosure, loaded, demotedSkillBodies) {
425
+ const renderContext = {
426
+ disclosure,
427
+ loaded,
428
+ demotedBodies: demotedSkillBodies?.length ? new Set(demotedSkillBodies) : undefined,
429
+ };
430
+ const selected = capSkillCatalog(selectSkillsForPrompt(skills ?? [], renderContext));
431
+ const byName = new Map(selected.map((skill) => [skill.name, skill]));
432
+ const ordered = disclosure === "eager"
433
+ ? selected
434
+ : (loaded?.list() ?? []).flatMap((name) => {
435
+ const skill = byName.get(name);
436
+ return skill === undefined ? [] : [skill];
437
+ });
438
+ for (const skill of ordered) {
439
+ if (!skillHasRenderableBody(skill, renderContext))
440
+ continue;
441
+ const message = buildSkillMessages([skill], renderContext)[0];
442
+ if (message)
443
+ appendTailSegment(tailSegments, activeTailSegments, `skill:${skill.name}`, message);
444
+ }
445
+ }
446
+ /** Map#set retains first-insertion order, so re-derivation replaces only this segment's bytes. */
447
+ function appendTailSegment(tailSegments, activeTailSegments, id, message) {
448
+ tailSegments.set(id, message);
449
+ activeTailSegments.add(id);
450
+ }
451
+ function tailMessages(tailSegments, activeTailSegments) {
452
+ return [...tailSegments].flatMap(([id, message]) => (activeTailSegments.has(id) ? [message] : []));
453
+ }
392
454
  function toolMessages(tools) {
393
455
  if (!tools?.length)
394
456
  return [];
@@ -1,5 +1,40 @@
1
- import type { ExtensionEvent } from "./contracts.js";
2
- export type MiddlewareHookName = "provider_request" | "input_assembly" | "prompt_build" | "context" | "tool_call" | "tool_result" | "retry" | "compaction" | "session_start" | "session_shutdown";
1
+ import type { ContentBlock, ExtensionEvent } from "./contracts.js";
2
+ export type MiddlewareHookName = "beforeProviderTurn" | "provider_request" | "input_assembly" | "prompt_build" | "context" | "tool_call" | "tool_result" | "retry" | "compaction" | "session_start" | "session_shutdown";
3
+ /** Provenance of a host-answered turn (plan 096). An id, never free host code. */
4
+ export interface DeterministicTurnProvenance {
5
+ /** Answering middleware id; bounded, replay-stable, and auditable. */
6
+ readonly middleware: string;
7
+ }
8
+ /** Host middleware answer that completes a turn without any provider request (plan 096). */
9
+ export interface DeterministicTurnAnswer {
10
+ /** Assistant content with provider content-block shape; tool calls are rejected (no provider ran). */
11
+ readonly content: readonly ContentBlock[];
12
+ /** Mandatory: a deterministic turn can never masquerade as model output. */
13
+ readonly provenance: DeterministicTurnProvenance;
14
+ }
15
+ /**
16
+ * Payload for the `beforeProviderTurn` hook (plan 096). Host middleware sets `answer` to complete the
17
+ * turn deterministically; leaving it absent/undefined sends the turn to the provider as usual.
18
+ */
19
+ export interface BeforeProviderTurnPayload {
20
+ readonly sessionId: string;
21
+ readonly runId: string;
22
+ readonly turn: number;
23
+ /** Concatenated text blocks of the latest user-role message in the assembled request. */
24
+ readonly userText: string;
25
+ /** Set by host middleware to answer without a provider call. */
26
+ readonly answer?: DeterministicTurnAnswer;
27
+ }
28
+ /** Host answered with a malformed deterministic turn. Fails the run closed — never falls through. */
29
+ export declare class DeterministicTurnError extends Error {
30
+ readonly code = "ERR_PRISM_DETERMINISTIC_TURN";
31
+ constructor(message: string);
32
+ }
33
+ /**
34
+ * Validate a host deterministic answer at the trust boundary: non-empty assistant-visible content and
35
+ * mandatory bounded provenance. Throws instead of degrading to a provider call.
36
+ */
37
+ export declare function validateDeterministicTurnAnswer(value: unknown): DeterministicTurnAnswer;
3
38
  export type MiddlewareNext<T> = (value: T) => Promise<T>;
4
39
  export type Middleware<T = unknown> = (value: T, next: MiddlewareNext<T>) => T | Promise<T>;
5
40
  export interface MiddlewareRegistryOptions {