@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.
- package/CHANGELOG.md +73 -0
- package/README.md +12 -11
- package/dist/agent-approval.d.ts +15 -2
- package/dist/agent-approval.js +5 -1
- package/dist/agent-event-source.d.ts +9 -1
- package/dist/agent-event-source.js +10 -3
- package/dist/agent-loops.js +7 -4
- package/dist/agent-run-lifecycle.d.ts +15 -1
- package/dist/agent-run-lifecycle.js +91 -10
- package/dist/agent-run-state.d.ts +34 -2
- package/dist/agent-run-state.js +68 -6
- package/dist/agent-session/helpers.js +20 -1
- package/dist/agent-session/session/assemble.js +250 -27
- package/dist/agent-session/session/persist.d.ts +27 -0
- package/dist/agent-session/session/persist.js +94 -12
- package/dist/agent-session/session/provider-round.d.ts +14 -4
- package/dist/agent-session/session/provider-round.js +197 -25
- package/dist/agent-session/session/tool-round.js +24 -2
- package/dist/agent-session/session/types.d.ts +36 -2
- package/dist/agent-session/session.d.ts +40 -4
- package/dist/agent-session/session.js +78 -5
- package/dist/attention-compiler.d.ts +51 -2
- package/dist/attention-compiler.js +282 -21
- package/dist/cache-helpers.d.ts +4 -2
- package/dist/cache-helpers.js +8 -6
- package/dist/checkpoint-restore.d.ts +45 -0
- package/dist/checkpoint-restore.js +54 -0
- package/dist/checkpoints.js +7 -11
- package/dist/context-budget.d.ts +2 -1
- package/dist/context-budget.js +24 -2
- package/dist/contracts-core/agent.d.ts +30 -0
- package/dist/contracts-core/attention.d.ts +95 -0
- package/dist/contracts-core/content.d.ts +15 -0
- package/dist/contracts-core/guardrail-packs.d.ts +41 -0
- package/dist/contracts-core/guardrail-packs.js +2 -0
- package/dist/contracts-core/loop.d.ts +42 -0
- package/dist/contracts-core/provider.d.ts +25 -0
- package/dist/contracts-core/run-limits.d.ts +21 -0
- package/dist/contracts-core/session.d.ts +23 -5
- package/dist/contracts-core/session.js +21 -2
- package/dist/contracts-core/usage.d.ts +40 -0
- package/dist/contracts-core/usage.js +8 -0
- package/dist/contracts-core.d.ts +2 -0
- package/dist/contracts-core.js +2 -0
- package/dist/contracts-protocol.d.ts +90 -4
- package/dist/contracts-run-state.d.ts +82 -6
- package/dist/evidence-grounding.d.ts +29 -0
- package/dist/evidence-grounding.js +162 -0
- package/dist/guardrail-packs/coding-standard.d.ts +3 -0
- package/dist/guardrail-packs/coding-standard.js +63 -0
- package/dist/guardrail-packs/destructive-commands.d.ts +3 -0
- package/dist/guardrail-packs/destructive-commands.js +46 -0
- package/dist/guardrail-packs/errors.d.ts +7 -0
- package/dist/guardrail-packs/errors.js +9 -0
- package/dist/guardrail-packs/index.d.ts +4 -0
- package/dist/guardrail-packs/index.js +15 -0
- package/dist/guardrail-packs/secrets-hygiene.d.ts +3 -0
- package/dist/guardrail-packs/secrets-hygiene.js +23 -0
- package/dist/guardrail-packs/types.d.ts +16 -0
- package/dist/guardrail-packs/types.js +2 -0
- package/dist/guardrail-packs/validation-respect.d.ts +3 -0
- package/dist/guardrail-packs/validation-respect.js +53 -0
- package/dist/guardrails.d.ts +20 -1
- package/dist/guardrails.js +268 -0
- package/dist/host-composition.d.ts +13 -0
- package/dist/host-composition.js +33 -2
- package/dist/index.d.ts +19 -10
- package/dist/index.js +11 -6
- package/dist/input.d.ts +8 -1
- package/dist/input.js +68 -6
- package/dist/middleware.d.ts +37 -2
- package/dist/middleware.js +41 -0
- package/dist/node/session-store-jsonl.js +18 -3
- package/dist/observability.js +6 -0
- package/dist/provider-events.d.ts +11 -3
- package/dist/provider-events.js +62 -4
- package/dist/providers/openai-compatible.js +6 -3
- package/dist/providers/transport.d.ts +3 -1
- package/dist/providers/transport.js +36 -0
- package/dist/redaction.js +18 -2
- package/dist/run-bundle.d.ts +89 -0
- package/dist/run-bundle.js +150 -0
- package/dist/run-limits.d.ts +11 -1
- package/dist/run-limits.js +46 -0
- package/dist/session-stores.d.ts +12 -1
- package/dist/session-stores.js +21 -4
- package/dist/testing/agent-event-source-conformance.js +41 -2
- package/dist/testing/prefix-stability-conformance.d.ts +30 -0
- package/dist/testing/prefix-stability-conformance.js +104 -0
- package/dist/testing/session-store-conformance.d.ts +3 -2
- package/dist/testing/session-store-conformance.js +48 -0
- package/dist/testing/state-concurrency-conformance.js +5 -12
- package/dist/tools.d.ts +5 -0
- package/dist/tools.js +11 -3
- package/dist/usage-estimation.d.ts +29 -0
- package/dist/usage-estimation.js +79 -0
- package/docs/ag-ui.md +5 -0
- package/docs/agent-events.md +68 -1
- package/docs/agent-loops.md +33 -0
- package/docs/agent-session-runtime.md +5 -3
- package/docs/attention-compiler.md +89 -8
- package/docs/coding-agent-tools.md +1 -1
- package/docs/coding-security.md +1 -0
- package/docs/coding-tools.md +0 -1
- package/docs/compaction-and-retry.md +1 -1
- package/docs/compaction-observational-memory.md +34 -7
- package/docs/connected-apps.md +116 -0
- package/docs/context-and-skills.md +13 -0
- package/docs/core.md +1 -1
- package/docs/diagrams.md +6 -6
- package/docs/document-reader.md +9 -9
- package/docs/documents.md +32 -11
- package/docs/durable-runs.md +129 -0
- package/docs/embeddings.md +5 -0
- package/docs/enterprise-postgres-state.md +4 -0
- package/docs/evaluations.md +5 -0
- package/docs/execution-timeline.md +84 -1
- package/docs/guardrails.md +71 -2
- package/docs/history/079-messaging-primitive-review.md +391 -0
- package/docs/history/080-messaging-followon-primitive-review.md +234 -0
- package/docs/history/081-connected-apps-primitive-review.md +74 -0
- package/docs/history/083-prism-work-primitive-review.md +84 -0
- package/docs/history/084-primitive-review.md +96 -0
- package/docs/history/085-honesty-and-cut-primitive-review.md +91 -0
- package/docs/history/README.md +5 -0
- package/docs/history/release-handoffs.md +38 -0
- package/docs/host-compositions.md +8 -6
- package/docs/host-security.md +2 -2
- package/docs/index.md +66 -29
- package/docs/input-and-prompt-assembly.md +3 -3
- package/docs/knowledge-sync.md +4 -0
- package/docs/live-testing.md +5 -3
- package/docs/mcp-tools.md +1 -0
- package/docs/messaging-channel-operations.md +166 -0
- package/docs/messaging-channels.md +150 -0
- package/docs/middleware-hooks.md +38 -2
- package/docs/migrate-to-0.8.md +124 -0
- package/docs/migrate-to-0.9.md +210 -0
- package/docs/migration.md +43 -0
- package/docs/model-registry.md +12 -2
- package/docs/multi-agent-patterns.md +25 -2
- package/docs/node-jsonl-session-store.md +7 -1
- package/docs/observability.md +7 -3
- package/docs/openapi-tools.md +1 -1
- package/docs/operations.md +1 -3
- package/docs/options-index.md +36 -3
- package/docs/peer-dependencies.md +6 -6
- package/docs/policy-and-audit.md +13 -1
- package/docs/postgres-persistence.md +1 -1
- package/docs/prefix-stability-conformance.md +93 -0
- package/docs/provider-caching.md +4 -4
- package/docs/provider-conformance.md +16 -0
- package/docs/provider-layer.md +2 -2
- package/docs/provider-packages.md +20 -20
- package/docs/providers/neuralwatt.md +5 -1
- package/docs/public-contracts.md +2 -2
- package/docs/rag.md +102 -4
- package/docs/release-and-install.md +55 -47
- package/docs/run-bundle.md +92 -0
- package/docs/runs-and-usage.md +57 -6
- package/docs/scoped-agent-memory.md +262 -0
- package/docs/server.md +2 -0
- package/docs/session-store-conformance.md +1 -2
- package/docs/session-stores.md +17 -17
- package/docs/sheets.md +9 -9
- package/docs/signal-channel.md +112 -0
- package/docs/speech.md +5 -1
- package/docs/sqlite-persistence.md +1 -1
- package/docs/supervisors.md +32 -12
- package/docs/telegram-channel.md +157 -0
- package/docs/testing.md +2 -2
- package/docs/tools.md +17 -0
- package/docs/wiki.md +1 -1
- package/docs/work-artifacts-and-review.md +1 -1
- package/docs/work-connectors.md +9 -9
- package/docs/work-sandbox.md +115 -0
- package/docs/work-tools.md +38 -16
- package/docs/workflows.md +5 -0
- package/package.json +9 -3
- package/templates/business-worker/manifest.json +2 -1
- package/templates/business-worker/src/agent.ts.tmpl +1 -1
- package/templates/business-worker/src/tests/agent.test.ts.tmpl +1 -1
package/dist/context-budget.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { capSkillCatalog, selectSkillsForPrompt, skillHasRenderableBody, skillPromptText, } from "./skill-disclosure.js";
|
|
2
|
+
import { estimateTextTokensForFamily, MODEL_FAMILY_TOKENS, resolveModelFamily } from "./usage-estimation.js";
|
|
2
3
|
export const CONTEXT_BUDGET_REPORT_METADATA_KEY = "contextBudgetReport";
|
|
3
4
|
export const HARD_MAX_CONTEXT_BUDGET_TOKENS = 2_000_000;
|
|
4
5
|
export const HARD_MAX_CONTEXT_BUDGET_BYTES = 32 * 1024 * 1024;
|
|
@@ -22,8 +23,29 @@ export function estimateTextTokens(text) {
|
|
|
22
23
|
export function estimateTextBytes(text) {
|
|
23
24
|
return Buffer.byteLength(text, "utf8");
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Single message → flattened text → estimator (budget accounting, never billing).
|
|
28
|
+
*
|
|
29
|
+
* Plan 091 Task 1 overload: a message array plus a model id, provider id, or
|
|
30
|
+
* family name returns a labeled {@link TokenEstimate}. It reuses this same
|
|
31
|
+
* per-message flattening and adds the family's per-message chat-template
|
|
32
|
+
* overhead; `unknown` families fall back to the conservative table with
|
|
33
|
+
* `lowConfidence: true`.
|
|
34
|
+
*/
|
|
35
|
+
export function estimateMessageTokens(input, estimatorOrFamily) {
|
|
36
|
+
if (isMessageArray(input)) {
|
|
37
|
+
const family = resolveModelFamily(estimatorOrFamily);
|
|
38
|
+
const table = MODEL_FAMILY_TOKENS[family];
|
|
39
|
+
let tokens = table.perMessageOverhead * input.length;
|
|
40
|
+
for (const message of input)
|
|
41
|
+
tokens += estimateTextTokensForFamily(messageText(message), family);
|
|
42
|
+
return { tokens, confidence: table.confidence, lowConfidence: table.confidence === "low" };
|
|
43
|
+
}
|
|
44
|
+
const estimateTokens = typeof estimatorOrFamily === "function" ? estimatorOrFamily : estimateTextTokens;
|
|
45
|
+
return estimateTokens(messageText(input));
|
|
46
|
+
}
|
|
47
|
+
function isMessageArray(value) {
|
|
48
|
+
return Array.isArray(value);
|
|
27
49
|
}
|
|
28
50
|
export function estimateMessageBytes(message) {
|
|
29
51
|
return estimateTextBytes(messageText(message));
|
|
@@ -10,6 +10,7 @@ import type { ToolValidator } from "../tools.js";
|
|
|
10
10
|
import type { CompactionOptions, RetryOptions } from "./compaction.js";
|
|
11
11
|
import type { ContentBlock, ErrorInfo, JsonObject, Message, ModelConfig } from "./content.js";
|
|
12
12
|
import type { ProviderRequestPolicy, SystemPromptConfig } from "./extensions.js";
|
|
13
|
+
import type { GuardrailPackRef } from "./guardrail-packs.js";
|
|
13
14
|
import type { AgentLoopOptions, AgentLoopStrategy } from "./loop.js";
|
|
14
15
|
import type { OwnershipScope } from "./persistence.js";
|
|
15
16
|
import type { AIProvider, ProviderRequestOptions, ProviderResolver } from "./provider.js";
|
|
@@ -47,6 +48,17 @@ export interface AgentDefinitionResolutionContext {
|
|
|
47
48
|
readonly activateAllCapabilities?: true;
|
|
48
49
|
readonly overrides?: Partial<AgentConfig>;
|
|
49
50
|
}
|
|
51
|
+
/** Per-turn tool menu. Called at `loopCtx.assemble` before each provider request. */
|
|
52
|
+
export interface ToolNarrowingContext {
|
|
53
|
+
/** 1-based provider turn this assemble precedes. */
|
|
54
|
+
readonly turn: number;
|
|
55
|
+
/** Text of the latest assistant message, when any. */
|
|
56
|
+
readonly lastAssistantText?: string;
|
|
57
|
+
/** Run-grant tool names (R11 snapshot, including generated `search_tools` when disclosure is search). */
|
|
58
|
+
readonly toolIds: readonly string[];
|
|
59
|
+
}
|
|
60
|
+
/** Host callback: return a subset of `toolIds`. Superset names are clamped; throw fails the turn. */
|
|
61
|
+
export type ToolNarrowing = (ctx: ToolNarrowingContext) => readonly string[] | Promise<readonly string[]>;
|
|
50
62
|
export interface AgentConfig {
|
|
51
63
|
readonly id?: string;
|
|
52
64
|
readonly name?: string;
|
|
@@ -64,11 +76,21 @@ export interface AgentConfig {
|
|
|
64
76
|
/** Tools disclosure: "all" (default) sends every active tool schema; "search" sends top-k + the generated `search_tools` tool. */
|
|
65
77
|
readonly toolsDisclosure?: import("../tool-search.js").ToolsDisclosure;
|
|
66
78
|
readonly toolsSearch?: import("../tool-search.js").ToolsSearchOptions;
|
|
79
|
+
/** Per-turn restrictive allow-list over the run grant. RunOptions override. */
|
|
80
|
+
readonly toolNarrowing?: ToolNarrowing;
|
|
81
|
+
/** Opt-in: tools hidden this turn stay callable by name (default off). */
|
|
82
|
+
readonly allowHiddenToolCalls?: true;
|
|
67
83
|
/** Opt-in projection-only fold for aged large tool results in provider view; store untouched. */
|
|
68
84
|
readonly toolResultFold?: import("../tool-result-fold.js").ToolResultFoldOptions;
|
|
69
85
|
/** Opt-in attention compiler (plan 074): `true` for defaults, an object to tune ratios/depth.
|
|
70
86
|
* Omitted keeps today's request bytes; per-run options may only relax this setting. */
|
|
71
87
|
readonly attentionCompiler?: import("./attention.js").AttentionCompilerSetting;
|
|
88
|
+
/**
|
|
89
|
+
* Missing-usage fallback (plan 091 T2): `"fallback"` (default) records a labeled
|
|
90
|
+
* estimate when a provider turn reports no usage; `"off"` leaves usage absent —
|
|
91
|
+
* never zero. Estimates are marked `Usage.estimated` and are never priced.
|
|
92
|
+
*/
|
|
93
|
+
readonly usageEstimation?: "fallback" | "off";
|
|
72
94
|
readonly inputBuilder?: InputBuilder;
|
|
73
95
|
readonly promptBuilder?: PromptBuilder;
|
|
74
96
|
readonly middleware?: MiddlewareRegistry;
|
|
@@ -134,6 +156,12 @@ export interface AgentSessionConfig {
|
|
|
134
156
|
readonly store?: SessionStore;
|
|
135
157
|
readonly leafId?: string;
|
|
136
158
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
159
|
+
/**
|
|
160
|
+
* Restrictive-only guardrail packs compiled once per session onto the existing tool interception
|
|
161
|
+
* seams (plan 092). Built-in ids are versioned; an input object with `rules` is an inline pack.
|
|
162
|
+
* Compiled rules can only deny or tripwire — they never grant permissions.
|
|
163
|
+
*/
|
|
164
|
+
readonly guardrailPacks?: readonly GuardrailPackRef[];
|
|
137
165
|
/**
|
|
138
166
|
* TTL of the in-memory `session.snapshot()` branch cache in milliseconds.
|
|
139
167
|
* Default `DEFAULT_SNAPSHOT_CACHE_TTL_MS`; `0` disables the cache (every snapshot read
|
|
@@ -277,6 +305,8 @@ export interface PromptBuildRequest {
|
|
|
277
305
|
readonly skills?: readonly Skill[];
|
|
278
306
|
readonly skillsDisclosure?: import("../skill-disclosure.js").SkillsDisclosure;
|
|
279
307
|
readonly loadedSkills?: import("../skill-disclosure.js").LoadedSkillSet;
|
|
308
|
+
/** Loaded skill bodies already appended to `messages` by the session tail allocator; render catalog entries only. */
|
|
309
|
+
readonly tailSkillBodies?: boolean;
|
|
280
310
|
/** Tools disclosure: "all" (default) sends every active tool schema; "search" sends top-k + the generated `search_tools` tool. */
|
|
281
311
|
readonly toolsDisclosure?: import("../tool-search.js").ToolsDisclosure;
|
|
282
312
|
readonly toolsSearch?: import("../tool-search.js").ToolsSearchOptions;
|
|
@@ -12,9 +12,75 @@ export interface AttentionInputCapOptions {
|
|
|
12
12
|
/** Output + next-turn headroom subtracted from the window (default 1024). */
|
|
13
13
|
readonly reserveTokens?: number;
|
|
14
14
|
}
|
|
15
|
+
/** Fold axes (plan 086 T2). `input_ratio` is the legacy `triggerRatio` axis; the rest are new. */
|
|
16
|
+
export type AttentionTriggerKind = "input_ratio" | "run_input_ratio" | "token_floor" | "predicate";
|
|
17
|
+
/** Per-turn inputs an axis reads. Frozen before a `predicate` sees it; estimates and ids only. */
|
|
18
|
+
export interface AttentionTriggerState {
|
|
19
|
+
/** Estimated tokens of the request this turn will send — what the ratio axes compare. */
|
|
20
|
+
readonly estimatedInputTokens: number;
|
|
21
|
+
/** Resolved per-request input cap (`resolveInputCap`). */
|
|
22
|
+
readonly inputCapTokens: number;
|
|
23
|
+
/** Cumulative run input budget when the run limits declare one; absent falls back to `inputCapTokens`. */
|
|
24
|
+
readonly runInputBudgetTokens?: number;
|
|
25
|
+
/** Run input tokens already charged by provider usage this run (0 when unknown). */
|
|
26
|
+
readonly runInputTokens: number;
|
|
27
|
+
/** 1-based provider turn index. */
|
|
28
|
+
readonly turn: number;
|
|
29
|
+
}
|
|
30
|
+
/** Host predicate axis. Runs host-supplied code under the same trust as `CompactionTrigger.custom`. */
|
|
31
|
+
export type AttentionTriggerFunction = (state: AttentionTriggerState) => boolean;
|
|
32
|
+
/** One fold gate. An array is any-of; the first axis that fires is the one attributed. */
|
|
33
|
+
export type AttentionTrigger =
|
|
34
|
+
/** Legacy axis: fires when the assembled request reaches `ratio` of the per-request input cap. */
|
|
35
|
+
{
|
|
36
|
+
readonly kind: "input_ratio";
|
|
37
|
+
readonly ratio: number;
|
|
38
|
+
}
|
|
39
|
+
/** Cumulative axis: fires when `runInputTokens + estimatedInputTokens` reaches `ratio` of the run
|
|
40
|
+
* input budget, so a run capped below the window folds before the cap kills it. Falls back to
|
|
41
|
+
* the `input_ratio` comparison when the run limits declare no input budget. */
|
|
42
|
+
| {
|
|
43
|
+
readonly kind: "run_input_ratio";
|
|
44
|
+
readonly ratio: number;
|
|
45
|
+
}
|
|
46
|
+
/** Absolute axis: fires when the assembled request reaches `tokens`, whatever the cap. */
|
|
47
|
+
| {
|
|
48
|
+
readonly kind: "token_floor";
|
|
49
|
+
readonly tokens: number;
|
|
50
|
+
}
|
|
51
|
+
/** Host axis: fires when `shouldFold` returns `true`. Called once per turn; must be synchronous. */
|
|
52
|
+
| {
|
|
53
|
+
readonly kind: "predicate";
|
|
54
|
+
readonly shouldFold: AttentionTriggerFunction;
|
|
55
|
+
};
|
|
56
|
+
/** Accepted `trigger` value: one axis, one predicate, or an any-of array of either. */
|
|
57
|
+
export type AttentionTriggerInput = AttentionTrigger | AttentionTriggerFunction | readonly (AttentionTrigger | AttentionTriggerFunction)[];
|
|
58
|
+
/** Result of evaluating the axes once against one turn's state. */
|
|
59
|
+
export interface AttentionTriggerDecision {
|
|
60
|
+
readonly shouldFold: boolean;
|
|
61
|
+
/** First axis that fired, in configured order (plan 087 attribution). */
|
|
62
|
+
readonly firedAxis?: AttentionTriggerKind;
|
|
63
|
+
/** Estimated-token target the sticky stages fold to; absent = fold every eligible row. */
|
|
64
|
+
readonly targetTokens?: number;
|
|
65
|
+
/** `true` when folding this request can settle the fired axis, so a still-firing axis after every
|
|
66
|
+
* eligible row throws `AttentionBudgetError`. Cumulative `run_input_ratio` axes are `false`: the
|
|
67
|
+
* spend is already booked, folding only slows the counter, and the run limit owns the cap. */
|
|
68
|
+
readonly failsClosed: boolean;
|
|
69
|
+
}
|
|
15
70
|
export interface AttentionCompilerOptions extends AttentionInputCapOptions {
|
|
16
71
|
/** Fraction of `inputCap` that triggers mutation; in `(0, 1)` (default 0.75). */
|
|
17
72
|
readonly triggerRatio?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Fold axes (plan 086 T2). Omitted keeps the `triggerRatio` axis alone, so requests gate
|
|
75
|
+
* exactly as before. Given, it **replaces** the `triggerRatio` axis: the gate is the any-of of
|
|
76
|
+
* the listed axes, and `triggerRatio` stays the input-ratio reference for `compactRatio` and
|
|
77
|
+
* the report. A run overlay may not set it (the gate is agent-config only).
|
|
78
|
+
*
|
|
79
|
+
* Predicate axes execute host-supplied code, trusted exactly like `CompactionTrigger.custom`:
|
|
80
|
+
* the function runs once per turn with a frozen `AttentionTriggerState` and must return a
|
|
81
|
+
* boolean synchronously (a `Promise` return fails closed with a `TypeError`).
|
|
82
|
+
*/
|
|
83
|
+
readonly trigger?: AttentionTriggerInput;
|
|
18
84
|
/** Where compaction should fire relative to `triggerRatio`; must exceed it (default 0.9). */
|
|
19
85
|
readonly compactRatio?: number;
|
|
20
86
|
/** Newest thinking-bearing assistant turns kept intact (default 1). */
|
|
@@ -23,6 +89,17 @@ export interface AttentionCompilerOptions extends AttentionInputCapOptions {
|
|
|
23
89
|
readonly keepLast?: number;
|
|
24
90
|
/** Tool names whose results are never stubbed, whatever the ratio. */
|
|
25
91
|
readonly excludeTools?: readonly string[];
|
|
92
|
+
/**
|
|
93
|
+
* Durable folding (plan 086 T3): persist the fold ledger and its sticky frontier into the
|
|
94
|
+
* run's checkpoint at each fold, and restore them before the first turn after a resume.
|
|
95
|
+
* Requires a durable run (`runState` with a checkpoint store); independent of
|
|
96
|
+
* `persistSessionState`, which governs skill/tool session state instead.
|
|
97
|
+
*
|
|
98
|
+
* Off by default: durable folding costs one extra checkpoint write per fold (never per turn)
|
|
99
|
+
* and stores the folded bodies — already redacted, capped by `maxSummaryBytes` — so a resumed
|
|
100
|
+
* request carries the same folded rows a live run would. A run overlay may not set it.
|
|
101
|
+
*/
|
|
102
|
+
readonly durable?: boolean;
|
|
26
103
|
}
|
|
27
104
|
/** Where the compiler is switched on: `true` uses the defaults, an object tunes them, `false`
|
|
28
105
|
* (or omitted) leaves requests byte-for-byte as they are without the compiler. On
|
|
@@ -34,6 +111,10 @@ export interface AttentionCompilerContext {
|
|
|
34
111
|
readonly model?: Pick<ModelConfig, "limits">;
|
|
35
112
|
/** Validated at create so an unknown trigger type fails at config time, not on turn one. */
|
|
36
113
|
readonly compactionTrigger?: CompactionTrigger;
|
|
114
|
+
/** Cumulative run input budget the `run_input_ratio` axis folds against (the resolved
|
|
115
|
+
* `RunLimits.maxInputTokens`); `null`/omitted means no run budget, so that axis falls back to
|
|
116
|
+
* the per-request input cap. Distinct from `maxInputTokens`, which caps one request. */
|
|
117
|
+
readonly runInputBudget?: number | null;
|
|
37
118
|
}
|
|
38
119
|
/** Validated, frozen configuration returned by `createAttentionCompiler`. */
|
|
39
120
|
export interface AttentionCompiler {
|
|
@@ -44,6 +125,14 @@ export interface AttentionCompiler {
|
|
|
44
125
|
readonly thinkingKeepTurns: number;
|
|
45
126
|
readonly keepLast: number;
|
|
46
127
|
readonly excludeTools: readonly string[];
|
|
128
|
+
/** Normalized, frozen fold axes in evaluation order: the `input_ratio` default when no
|
|
129
|
+
* `trigger` was configured, otherwise exactly the configured axes. */
|
|
130
|
+
readonly trigger: readonly AttentionTrigger[];
|
|
131
|
+
/** Run input budget resolved at create; absent when the run limits declare none. */
|
|
132
|
+
readonly runInputBudget?: number;
|
|
133
|
+
/** Durable folding resolved at create (plan 086 T3); `true` opts the run's fold state into
|
|
134
|
+
* checkpoint persistence, so `assembleProviderInput` callers should pass the ledger. */
|
|
135
|
+
readonly durable: boolean;
|
|
47
136
|
}
|
|
48
137
|
/** One mutated turn. Under-ratio turns emit nothing and produce no report (C14). */
|
|
49
138
|
export interface AttentionReport {
|
|
@@ -53,12 +142,18 @@ export interface AttentionReport {
|
|
|
53
142
|
readonly usedAfter: number;
|
|
54
143
|
readonly inputCap: number;
|
|
55
144
|
readonly triggerRatio: number;
|
|
145
|
+
/** Axis that opened the gate on this turn, when one did (plan 087 attribution). */
|
|
146
|
+
readonly firedAxis?: AttentionTriggerKind;
|
|
56
147
|
/** Thinking turns absent from this request; rows re-applied from the sticky frontier count again. */
|
|
57
148
|
readonly droppedThinkingTurns: number;
|
|
58
149
|
/** Tool results stubbed in this request; rows re-applied from the sticky frontier count again. */
|
|
59
150
|
readonly stubbedToolResults: number;
|
|
60
151
|
/** Payload bytes the stubs took out of this request (never the stub text itself). */
|
|
61
152
|
readonly stubbedBytes: number;
|
|
153
|
+
/** Folded bodies this turn added to the ledger — the summarize calls a cache saved, and the
|
|
154
|
+
* signal that a durable fold has new state to checkpoint (plan 086 T3). Zero on a turn that
|
|
155
|
+
* only re-applied bodies the ledger already held. */
|
|
156
|
+
readonly newFoldedBodies: number;
|
|
62
157
|
/** True when the gate stopped with eligible rows left: the sticky frontier is partial. */
|
|
63
158
|
readonly truncated: boolean;
|
|
64
159
|
readonly runId?: string;
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
* Moved verbatim from contracts-core.ts; public surface unchanged behind the barrel. */
|
|
3
3
|
import type { AudioContent, DocumentContent, FileContent } from "../content.js";
|
|
4
4
|
import type { ModelCacheCapabilities } from "./provider.js";
|
|
5
|
+
import type { TokenEstimateConfidence } from "./usage.js";
|
|
5
6
|
export type JsonPrimitive = string | number | boolean | null;
|
|
6
7
|
export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
7
8
|
export interface JsonObject {
|
|
8
9
|
readonly [key: string]: JsonValue;
|
|
9
10
|
}
|
|
11
|
+
export type ProviderFailureClass = "quota" | "auth" | "rate_limited" | "transient" | "permanent" | "unknown";
|
|
10
12
|
export interface ErrorInfo {
|
|
11
13
|
readonly name?: string;
|
|
12
14
|
readonly message: string;
|
|
13
15
|
readonly code?: string | number;
|
|
16
|
+
/** Advisory classification stamped only for provider failures; it never changes retry behavior. */
|
|
17
|
+
readonly failureClass?: ProviderFailureClass;
|
|
14
18
|
/** Provider backpressure hint (e.g. from a `Retry-After` header); retry policies
|
|
15
19
|
* honor it capped at their own `maxDelayMs`. */
|
|
16
20
|
readonly retryAfterMs?: number;
|
|
@@ -102,6 +106,8 @@ export interface ModelCapabilities {
|
|
|
102
106
|
readonly output?: readonly string[];
|
|
103
107
|
readonly reasoning?: boolean;
|
|
104
108
|
readonly tools?: boolean;
|
|
109
|
+
/** Advisory, conformance-derived tool-call behavior. Absent means unknown; it never changes runtime tool validation. */
|
|
110
|
+
readonly toolCallStrictness?: "strict" | "lenient" | "legacy";
|
|
105
111
|
readonly streaming?: boolean;
|
|
106
112
|
/** Native JSON-schema structured output support for this model. */
|
|
107
113
|
readonly structuredOutput?: boolean | "json_schema";
|
|
@@ -172,6 +178,15 @@ export interface Usage {
|
|
|
172
178
|
readonly cacheWriteTokens?: number;
|
|
173
179
|
readonly cost?: number;
|
|
174
180
|
readonly currency?: string;
|
|
181
|
+
/**
|
|
182
|
+
* True when these token counts are a harness estimate, never provider truth
|
|
183
|
+
* (plan 091 T2). Estimated usage is never priced, and every accounting export
|
|
184
|
+
* (ledger rows, run totals, turn events) keeps this flag so a billing surface
|
|
185
|
+
* can always tell an estimate from a report. Absent means reported.
|
|
186
|
+
*/
|
|
187
|
+
readonly estimated?: boolean;
|
|
188
|
+
/** Confidence label of an estimated usage; absent on reported usage. */
|
|
189
|
+
readonly confidence?: TokenEstimateConfidence;
|
|
175
190
|
}
|
|
176
191
|
/**
|
|
177
192
|
* Host-supplied pricing adapter (plan 062): quotes cost rates per model id. Core
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guardrail packs (plan 092 Task 2): config-declared, restrictive-only rule sets compiled once per
|
|
3
|
+
* session onto the existing tool interception seams (`tool_input` / `tool_output`). Packs can only
|
|
4
|
+
* deny or tripwire — they never grant permissions, widen arguments, or add a stage.
|
|
5
|
+
*/
|
|
6
|
+
import type { JsonObject } from "./content.js";
|
|
7
|
+
export type GuardrailRuleAction = "deny" | "tripwire";
|
|
8
|
+
/** Read-only identity view handed to a pack rule predicate (never carries a raw argument echo). */
|
|
9
|
+
export interface GuardrailRuleContext {
|
|
10
|
+
readonly toolName: string;
|
|
11
|
+
readonly toolCallId: string;
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
readonly runId: string;
|
|
14
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
15
|
+
/** Pack-local state shared with the pack's result observer; treat as read-only. */
|
|
16
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
export interface GuardrailRule {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** Tool names this rule applies to; omitted matches every tool. */
|
|
21
|
+
readonly tool?: string | readonly string[];
|
|
22
|
+
/** Regex source, compiled once; tested against matched argument strings. Exactly one of `pattern` / `deny`. */
|
|
23
|
+
readonly pattern?: string | RegExp;
|
|
24
|
+
/** Dot path(s) of arguments to test (e.g. `command`, `["from", "to"]`); omitted deep-scans argument strings. */
|
|
25
|
+
readonly argPath?: string | readonly string[];
|
|
26
|
+
/** Typed predicate escape hatch (host-trusted like all host code); deny when it returns true. Exactly one of `pattern` / `deny`. */
|
|
27
|
+
readonly deny?: (args: JsonObject, context: GuardrailRuleContext) => boolean;
|
|
28
|
+
/** Defaults to `deny`; `tripwire` also rejects the enclosing run. `ask` has no deterministic seam (plan 092 Task 1). */
|
|
29
|
+
readonly action?: GuardrailRuleAction;
|
|
30
|
+
/** Bounded, redacted record reason; defaults to the pack/rule id. */
|
|
31
|
+
readonly reason?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Built-in pack selection by `id` (optional `options`), or an inline pack when `rules` is present. */
|
|
34
|
+
export interface GuardrailPackInput {
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly version?: number;
|
|
37
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
38
|
+
readonly rules?: readonly GuardrailRule[];
|
|
39
|
+
}
|
|
40
|
+
/** A session's `guardrailPacks` entry: built-in pack id, or an inline/built-in pack input object. */
|
|
41
|
+
export type GuardrailPackRef = string | GuardrailPackInput;
|
|
@@ -4,6 +4,48 @@ import type { AgentEvent, AgentFinishReason, ProviderTurnResult, ToolResult } fr
|
|
|
4
4
|
import type { AgentInput } from "../input.js";
|
|
5
5
|
import type { JsonValue, Message, ToolCallContent, Usage } from "./content.js";
|
|
6
6
|
import type { ProviderRequest, StructuredOutputOptions } from "./provider.js";
|
|
7
|
+
/**
|
|
8
|
+
* Metadata-only view of a run at a provider-turn boundary (plan 084 Task 2). Hosts branch on
|
|
9
|
+
* counters, never content: tool arguments, prompts, and tool results are not fields.
|
|
10
|
+
*/
|
|
11
|
+
export interface TurnBoundaryContext {
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
readonly runId: string;
|
|
14
|
+
/** 1-based index of the provider turn this boundary precedes. */
|
|
15
|
+
readonly turn: number;
|
|
16
|
+
/** Provider turns already completed in this run (`turn - 1`; 0 at the first boundary). */
|
|
17
|
+
readonly turns: number;
|
|
18
|
+
/** Host tool calls dispatched so far in this run. */
|
|
19
|
+
readonly toolCalls: number;
|
|
20
|
+
/** Run-total usage so far, when the provider reported any. */
|
|
21
|
+
readonly usage?: Usage;
|
|
22
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
23
|
+
}
|
|
24
|
+
/** Synchronous decision at a turn boundary. `stop` ends the run cleanly; `continue` runs the turn. */
|
|
25
|
+
export type TurnStopDecision = {
|
|
26
|
+
readonly action: "continue";
|
|
27
|
+
} | {
|
|
28
|
+
readonly action: "stop";
|
|
29
|
+
readonly reason: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Host turn policy (plan 084 Task 2). Evaluated before every provider request, at the same
|
|
33
|
+
* boundary a `checkpointPolicy: "every-turn"` checkpoint is written. Omit it and the run keeps
|
|
34
|
+
* its exact 0.8.x turn structure (no callback, no reads).
|
|
35
|
+
*/
|
|
36
|
+
export interface TurnPolicyOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Clean turn cap. Reaching it stops the run (`stopReason: "turn_limit"`) instead of failing it
|
|
39
|
+
* with a limit breach. A run overlay may only narrow `limits.maxTurns`; widening throws.
|
|
40
|
+
*/
|
|
41
|
+
readonly maxTurns?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Consulted before every provider request. Returning `stop` ends the run cleanly with
|
|
44
|
+
* `stopReason: "host_policy"` and a resumable checkpoint (`decision: "continue"` resumes it).
|
|
45
|
+
* Must be synchronous and must not throw; a throw fails the run with `ERR_PRISM_TURN_POLICY`.
|
|
46
|
+
*/
|
|
47
|
+
readonly stop?: (context: TurnBoundaryContext) => TurnStopDecision;
|
|
48
|
+
}
|
|
7
49
|
export interface LoopContext {
|
|
8
50
|
readonly sessionId: string;
|
|
9
51
|
readonly runId: string;
|
|
@@ -62,6 +62,31 @@ export interface AIProvider {
|
|
|
62
62
|
readonly id: string;
|
|
63
63
|
generate(request: ProviderRequest): AsyncIterable<ProviderEvent>;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Closed taxonomy for why a provider turn stopped (plan 087 T1). Adapters map native wire
|
|
67
|
+
* reasons (`finish_reason`, `stop_reason`, `finishReason`, Converse `stopReason`) through the
|
|
68
|
+
* shared `mapProviderStopReason` table; `unknown` is the escape hatch for a new wire value.
|
|
69
|
+
*/
|
|
70
|
+
export type ProviderStopReason = "end_turn" | "tool_calls" | "max_output_tokens" | "content_filter" | "abort" | "provider_error" | "unknown";
|
|
71
|
+
/**
|
|
72
|
+
* Effective budget snapshot at provider-turn end (plan 087 T1): current-turn input tokens
|
|
73
|
+
* against the per-request input cap, cumulative run input against its budget, and the turn
|
|
74
|
+
* axis, so a host can see which limit was closest without instrumenting the session.
|
|
75
|
+
*/
|
|
76
|
+
export interface TurnBudgets {
|
|
77
|
+
/** Provider-reported input tokens for this turn; absent when the provider reported none. */
|
|
78
|
+
readonly inputTokens?: number;
|
|
79
|
+
/** Resolved per-request input cap (attention compiler when enabled); absent when no cap derivable. */
|
|
80
|
+
readonly inputCap?: number;
|
|
81
|
+
/** Cumulative run input budget (`RunLimits.maxInputTokens`); absent when the axis is disabled. */
|
|
82
|
+
readonly runInputBudget?: number;
|
|
83
|
+
/** Cumulative input tokens charged this run (all provider turns). */
|
|
84
|
+
readonly runInputUsed: number;
|
|
85
|
+
/** Provider turns started this run (1-based current turn at turn end). */
|
|
86
|
+
readonly turns: number;
|
|
87
|
+
/** Resolved clean turn cap; `null` when disabled. */
|
|
88
|
+
readonly maxTurns: number | null;
|
|
89
|
+
}
|
|
65
90
|
export type ProviderResolver = (model: ModelConfig) => AIProvider | undefined;
|
|
66
91
|
/** Realtime audio/session event. Realtime is a bidirectional session, not a request/response
|
|
67
92
|
* stream, so it is a separate neutral seam from `AIProvider.generate()`. Credentials are
|
|
@@ -60,6 +60,25 @@ export interface RunLimitBreach {
|
|
|
60
60
|
readonly observed: number;
|
|
61
61
|
readonly currency?: string;
|
|
62
62
|
}
|
|
63
|
+
/** One dispatched host tool call, bounded to id + name + argument hash (plan 087 T2). */
|
|
64
|
+
export interface ToolCallSummary {
|
|
65
|
+
readonly id: string;
|
|
66
|
+
readonly name: string;
|
|
67
|
+
/** `sha256:<64 hex>` over the canonicalized arguments; raw arguments never enter events. */
|
|
68
|
+
readonly argHash: string;
|
|
69
|
+
}
|
|
70
|
+
/** One run-limit axis and how close it came to its cap: `used / cap` in [0, 1] (plan 087 T2). */
|
|
71
|
+
export interface BudgetAxisUsage {
|
|
72
|
+
readonly axis: RunLimitName;
|
|
73
|
+
readonly usedRatio: number;
|
|
74
|
+
}
|
|
75
|
+
/** Run counters at exhaustion (plan 087 T2): the axes a host reads first when attributing a death. */
|
|
76
|
+
export interface BudgetConsumedCounters {
|
|
77
|
+
readonly turns: number;
|
|
78
|
+
readonly inputTokens: number;
|
|
79
|
+
readonly providerAttempts: number;
|
|
80
|
+
readonly requestBytes: number;
|
|
81
|
+
}
|
|
63
82
|
export type GuardrailStage = "input" | "output" | "tool_input" | "tool_output";
|
|
64
83
|
export type GuardrailAction = "allow" | "block" | "tripwire" | "interrupt";
|
|
65
84
|
export type GuardrailValue<S extends GuardrailStage> = S extends "input" ? readonly Message[] : S extends "output" ? ProviderTurnResult : S extends "tool_input" ? ToolCallContent : ToolResult;
|
|
@@ -70,6 +89,8 @@ export interface GuardrailContext<S extends GuardrailStage> {
|
|
|
70
89
|
readonly runId: string;
|
|
71
90
|
readonly toolCallId?: string;
|
|
72
91
|
readonly toolName?: string;
|
|
92
|
+
/** Same-run completed host tool results, available only at the output stage. */
|
|
93
|
+
readonly toolResults?: S extends "output" ? readonly ToolResult[] : never;
|
|
73
94
|
readonly metadata: Readonly<Record<string, unknown>>;
|
|
74
95
|
readonly signal: AbortSignal;
|
|
75
96
|
}
|
|
@@ -35,8 +35,8 @@ export interface SessionStore {
|
|
|
35
35
|
/**
|
|
36
36
|
* Optional bounded session search. Prefer implementing this **or** returning a companion
|
|
37
37
|
* `SessionIndex` from the adapter factory — hosts must not need both. Call
|
|
38
|
-
* `resolveSessionSearchQuery` before scan/query. Memory
|
|
39
|
-
* search (`sessionSearchMode: "unsupported"` throws)
|
|
38
|
+
* `resolveSessionSearchQuery` before scan/query. Memory and JSONL default to capped linear
|
|
39
|
+
* search (memory `sessionSearchMode: "unsupported"` throws); DB adapters index.
|
|
40
40
|
*/
|
|
41
41
|
searchSessions?(query: SessionSearchQuery): Promise<PersistencePage<SessionSearchHit>>;
|
|
42
42
|
}
|
|
@@ -58,11 +58,18 @@ export declare const DEFAULT_MAX_SESSION_SEARCH_LINEAR_BYTES: number;
|
|
|
58
58
|
export declare const HARD_MAX_SESSION_SEARCH_LINEAR_BYTES: number;
|
|
59
59
|
export declare const DEFAULT_MAX_SESSION_SEARCH_FTS_CANDIDATES = 1000;
|
|
60
60
|
export declare const HARD_MAX_SESSION_SEARCH_FTS_CANDIDATES = 5000;
|
|
61
|
+
/** Entry-kind filter for `SessionSearchQuery.kind`; `"any"` (the default) matches every kind. */
|
|
62
|
+
export type SessionSearchKind = SessionEntryKind | "any";
|
|
61
63
|
/** Bounded session search filters. Workspace matches host-written `metadata.workspaceRoot`. */
|
|
62
64
|
export interface SessionSearchQuery extends PersistenceQuery, OwnershipScope {
|
|
63
65
|
readonly workspaceRoot?: string;
|
|
64
66
|
/** Optional full-text / message+summary query (adapter-defined matching). */
|
|
65
67
|
readonly query?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Restrict the text `query` to entries of these kinds (one kind or a list). Omitted or `"any"`
|
|
70
|
+
* matches every kind. Annotation search is `kind: ["label", "summary", "metadata", "custom"]`.
|
|
71
|
+
*/
|
|
72
|
+
readonly kind?: SessionSearchKind | readonly SessionSearchKind[];
|
|
66
73
|
readonly provider?: string;
|
|
67
74
|
readonly model?: string;
|
|
68
75
|
readonly label?: string;
|
|
@@ -73,11 +80,20 @@ export interface SessionSearchQuery extends PersistenceQuery, OwnershipScope {
|
|
|
73
80
|
}
|
|
74
81
|
/**
|
|
75
82
|
* Safe search hit for resume/checkout. Never includes credentials or raw full transcripts.
|
|
76
|
-
* `leafId` is the branch tip for `session.checkout` when known
|
|
83
|
+
* `leafId` is the branch tip for `session.checkout` when known; when a text `query` matched,
|
|
84
|
+
* `entryId`/`runId`/`turn`/`score` point at the matched entry and `snippet` is its matched text.
|
|
77
85
|
*/
|
|
78
86
|
export interface SessionSearchHit {
|
|
79
87
|
readonly sessionId: string;
|
|
80
88
|
readonly leafId?: string;
|
|
89
|
+
/** Transcript entry that matched the text `query` (absent for filter-only searches). */
|
|
90
|
+
readonly entryId?: string;
|
|
91
|
+
/** Run that wrote the matched entry. */
|
|
92
|
+
readonly runId?: string;
|
|
93
|
+
/** 1-based position of the matched entry in the session transcript (`(timestamp, id)` order). */
|
|
94
|
+
readonly turn?: number;
|
|
95
|
+
/** Matched-entry relevance from the store's full-text index; higher is better (0 is a valid score). */
|
|
96
|
+
readonly score?: number;
|
|
81
97
|
readonly updatedAt?: string;
|
|
82
98
|
readonly label?: string;
|
|
83
99
|
readonly summary?: string;
|
|
@@ -89,10 +105,12 @@ export interface SessionSearchHit {
|
|
|
89
105
|
export interface SessionIndex {
|
|
90
106
|
search(query: SessionSearchQuery): Promise<PersistencePage<SessionSearchHit>>;
|
|
91
107
|
}
|
|
92
|
-
/** Validated search query with finite `limit` / `order` filled in. */
|
|
108
|
+
/** Validated search query with finite `limit` / `order` filled in and `kind` normalized. */
|
|
93
109
|
export interface ResolvedSessionSearchQuery extends SessionSearchQuery {
|
|
94
110
|
readonly limit: number;
|
|
95
111
|
readonly order: "asc" | "desc";
|
|
112
|
+
/** Concrete kinds to match, or `undefined` for "any". */
|
|
113
|
+
readonly kind?: readonly SessionEntryKind[];
|
|
96
114
|
}
|
|
97
115
|
/**
|
|
98
116
|
* O(1) validation before any scan/query. Applies default page limit; rejects NaN,
|
|
@@ -100,7 +118,7 @@ export interface ResolvedSessionSearchQuery extends SessionSearchQuery {
|
|
|
100
118
|
*/
|
|
101
119
|
export declare function resolveSessionSearchQuery(query: SessionSearchQuery): ResolvedSessionSearchQuery;
|
|
102
120
|
export declare const SESSION_SEARCH_UNSUPPORTED_CODE: "session_search_unsupported";
|
|
103
|
-
/** Thrown when a store opts out of `searchSessions` (memory `unsupported
|
|
121
|
+
/** Thrown when a store opts out of `searchSessions` (memory `sessionSearchMode: "unsupported"`). */
|
|
104
122
|
export declare class SessionSearchUnsupportedError extends Error {
|
|
105
123
|
readonly code: "session_search_unsupported";
|
|
106
124
|
constructor(message?: string);
|
|
@@ -56,7 +56,26 @@ export function resolveSessionSearchQuery(query) {
|
|
|
56
56
|
assertSearchStringBytes(query.userId, "userId", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
57
57
|
assertSearchStringBytes(query.fromUpdatedAt, "fromUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
58
58
|
assertSearchStringBytes(query.toUpdatedAt, "toUpdatedAt", HARD_MAX_SESSION_SEARCH_QUERY_BYTES);
|
|
59
|
-
return { ...query, limit, order };
|
|
59
|
+
return { ...query, limit, order, kind: resolveSessionSearchKinds(query.kind) };
|
|
60
|
+
}
|
|
61
|
+
/** Normalize `kind` to concrete entry kinds (`undefined` = any). Unknown or mixed `"any"` fails closed. */
|
|
62
|
+
function resolveSessionSearchKinds(kind) {
|
|
63
|
+
if (kind === undefined || kind === "any")
|
|
64
|
+
return undefined;
|
|
65
|
+
const values = typeof kind === "string" ? [kind] : kind;
|
|
66
|
+
const kinds = [];
|
|
67
|
+
for (const value of values) {
|
|
68
|
+
if (value === "any")
|
|
69
|
+
throw new TypeError('SessionSearchQuery.kind cannot mix "any" with entry kinds');
|
|
70
|
+
if (!isSessionEntryKind(value)) {
|
|
71
|
+
throw new TypeError(`SessionSearchQuery.kind must be a session entry kind or "any"; got ${JSON.stringify(value)}`);
|
|
72
|
+
}
|
|
73
|
+
if (!kinds.includes(value))
|
|
74
|
+
kinds.push(value);
|
|
75
|
+
}
|
|
76
|
+
if (kinds.length === 0)
|
|
77
|
+
throw new TypeError("SessionSearchQuery.kind must name at least one entry kind");
|
|
78
|
+
return kinds;
|
|
60
79
|
}
|
|
61
80
|
function assertSearchStringBytes(value, name, hardMax) {
|
|
62
81
|
if (value === undefined)
|
|
@@ -71,7 +90,7 @@ function assertSearchStringBytes(value, name, hardMax) {
|
|
|
71
90
|
}
|
|
72
91
|
}
|
|
73
92
|
export const SESSION_SEARCH_UNSUPPORTED_CODE = "session_search_unsupported";
|
|
74
|
-
/** Thrown when a store opts out of `searchSessions` (memory `unsupported
|
|
93
|
+
/** Thrown when a store opts out of `searchSessions` (memory `sessionSearchMode: "unsupported"`). */
|
|
75
94
|
export class SessionSearchUnsupportedError extends Error {
|
|
76
95
|
code = SESSION_SEARCH_UNSUPPORTED_CODE;
|
|
77
96
|
constructor(message = "session search is unsupported by this store") {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Contracts-core usage family (plan 091 Task 1): labeled token-estimation types.
|
|
2
|
+
*
|
|
3
|
+
* Estimation exists for the "missing usage is never zero usage" accounting rule:
|
|
4
|
+
* when a provider reports no usage, a host may show a labeled approximation. An
|
|
5
|
+
* estimate is never provider truth — reported usage always wins and is never
|
|
6
|
+
* overwritten by one of these. */
|
|
7
|
+
/** Model families with a chars/token table (`MODEL_FAMILY_TOKENS`). `unknown`
|
|
8
|
+
* is the conservative fallback used when a model id/name matches no family. */
|
|
9
|
+
export type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "openrouter-generic" | "mistral" | "unknown";
|
|
10
|
+
/** Confidence label on an estimated token count. `high` is reserved for a real
|
|
11
|
+
* tokenizer (Prism ships none); the calibrated family tables are `medium`, and
|
|
12
|
+
* the unknown-family fallback is `low`. */
|
|
13
|
+
export type TokenEstimateConfidence = "high" | "medium" | "low";
|
|
14
|
+
/** Labeled token estimate. Never conflate with `Usage`: estimates are
|
|
15
|
+
* approximations for context metering and labeling, reported usage is provider
|
|
16
|
+
* truth for billing. */
|
|
17
|
+
export interface TokenEstimate {
|
|
18
|
+
readonly tokens: number;
|
|
19
|
+
readonly confidence: TokenEstimateConfidence;
|
|
20
|
+
/** Coarse `confidence === "low"` flag for UI badges and host-side labeling. */
|
|
21
|
+
readonly lowConfidence: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Context-fill read for hosts (plan 091 Task 2): the latest provider turn's input
|
|
25
|
+
* tokens with their provenance, plus the cap/budget resolved the same way the
|
|
26
|
+
* turn-budget snapshot resolves them. `source: "reported"` means the provider
|
|
27
|
+
* reported those tokens; `"estimated"` means they are a labeled approximation
|
|
28
|
+
* (never billing, never conflated with reported usage). Cap/budget/ratio are
|
|
29
|
+
* absent when the model or run cannot derive them.
|
|
30
|
+
*/
|
|
31
|
+
export interface ContextMeter {
|
|
32
|
+
readonly inputTokens: number;
|
|
33
|
+
readonly source: "reported" | "estimated";
|
|
34
|
+
/** Per-request input cap from the model window and `attentionCompiler` reserve. */
|
|
35
|
+
readonly inputCap?: number;
|
|
36
|
+
/** Cumulative run input budget (`RunLimits.maxInputTokens`); absent without run limits. */
|
|
37
|
+
readonly runInputBudget?: number;
|
|
38
|
+
/** `inputTokens / inputCap`; absent when no cap is derivable. */
|
|
39
|
+
readonly usedRatio?: number;
|
|
40
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Contracts-core usage family (plan 091 Task 1): labeled token-estimation types.
|
|
2
|
+
*
|
|
3
|
+
* Estimation exists for the "missing usage is never zero usage" accounting rule:
|
|
4
|
+
* when a provider reports no usage, a host may show a labeled approximation. An
|
|
5
|
+
* estimate is never provider truth — reported usage always wins and is never
|
|
6
|
+
* overwritten by one of these. */
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=usage.js.map
|
package/dist/contracts-core.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./contracts-core/compaction.js";
|
|
|
9
9
|
export * from "./contracts-core/content.js";
|
|
10
10
|
export * from "./contracts-core/embeddings.js";
|
|
11
11
|
export * from "./contracts-core/extensions.js";
|
|
12
|
+
export * from "./contracts-core/guardrail-packs.js";
|
|
12
13
|
export * from "./contracts-core/images.js";
|
|
13
14
|
export * from "./contracts-core/loop.js";
|
|
14
15
|
export * from "./contracts-core/moderation.js";
|
|
@@ -19,4 +20,5 @@ export * from "./contracts-core/run-limits.js";
|
|
|
19
20
|
export * from "./contracts-core/session.js";
|
|
20
21
|
export * from "./contracts-core/speech.js";
|
|
21
22
|
export * from "./contracts-core/transcription.js";
|
|
23
|
+
export * from "./contracts-core/usage.js";
|
|
22
24
|
export * from "./contracts-core/video.js";
|
package/dist/contracts-core.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./contracts-core/compaction.js";
|
|
|
5
5
|
export * from "./contracts-core/content.js";
|
|
6
6
|
export * from "./contracts-core/embeddings.js";
|
|
7
7
|
export * from "./contracts-core/extensions.js";
|
|
8
|
+
export * from "./contracts-core/guardrail-packs.js";
|
|
8
9
|
export * from "./contracts-core/images.js";
|
|
9
10
|
export * from "./contracts-core/loop.js";
|
|
10
11
|
export * from "./contracts-core/moderation.js";
|
|
@@ -15,5 +16,6 @@ export * from "./contracts-core/run-limits.js";
|
|
|
15
16
|
export * from "./contracts-core/session.js";
|
|
16
17
|
export * from "./contracts-core/speech.js";
|
|
17
18
|
export * from "./contracts-core/transcription.js";
|
|
19
|
+
export * from "./contracts-core/usage.js";
|
|
18
20
|
export * from "./contracts-core/video.js";
|
|
19
21
|
//# sourceMappingURL=contracts-core.js.map
|