@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.
- package/CHANGELOG.md +38 -0
- package/README.md +11 -11
- package/dist/agent-approval.d.ts +11 -2
- 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 +63 -6
- package/dist/agent-run-state.d.ts +22 -2
- package/dist/agent-run-state.js +57 -5
- package/dist/agent-session/helpers.js +14 -0
- package/dist/agent-session/session/assemble.js +126 -24
- package/dist/agent-session/session/persist.d.ts +11 -0
- package/dist/agent-session/session/persist.js +37 -11
- package/dist/agent-session/session/provider-round.d.ts +14 -4
- package/dist/agent-session/session/provider-round.js +185 -19
- package/dist/agent-session/session/tool-round.js +20 -1
- package/dist/agent-session/session/types.d.ts +25 -2
- package/dist/agent-session/session.d.ts +38 -4
- package/dist/agent-session/session.js +76 -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/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 +10 -0
- package/dist/contracts-core/guardrail-packs.d.ts +41 -0
- package/dist/contracts-core/guardrail-packs.js +2 -0
- package/dist/contracts-core/provider.d.ts +25 -0
- package/dist/contracts-core/run-limits.d.ts +19 -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 +76 -2
- package/dist/contracts-run-state.d.ts +56 -1
- 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/index.d.ts +14 -9
- package/dist/index.js +9 -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 +8 -2
- package/dist/provider-events.js +60 -2
- package/dist/providers/openai-compatible.js +6 -3
- package/dist/run-bundle.js +2 -1
- 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/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/agent-events.md +68 -1
- package/docs/agent-session-runtime.md +1 -0
- package/docs/attention-compiler.md +89 -8
- package/docs/coding-agent-tools.md +1 -1
- package/docs/compaction-and-retry.md +1 -1
- package/docs/compaction-observational-memory.md +33 -6
- package/docs/durable-runs.md +42 -0
- package/docs/embeddings.md +5 -0
- package/docs/evaluations.md +5 -0
- package/docs/execution-timeline.md +78 -1
- package/docs/guardrails.md +38 -2
- package/docs/index.md +32 -13
- package/docs/input-and-prompt-assembly.md +3 -3
- package/docs/knowledge-sync.md +4 -0
- package/docs/middleware-hooks.md +38 -2
- package/docs/migrate-to-0.9.md +210 -0
- package/docs/migration.md +13 -0
- 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/options-index.md +2 -1
- package/docs/policy-and-audit.md +13 -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-packages.md +20 -20
- package/docs/public-contracts.md +2 -2
- package/docs/rag.md +101 -3
- package/docs/release-and-install.md +39 -37
- package/docs/runs-and-usage.md +43 -6
- package/docs/scoped-agent-memory.md +262 -0
- package/docs/session-store-conformance.md +1 -2
- package/docs/session-stores.md +17 -17
- package/docs/supervisors.md +32 -12
- package/docs/tools.md +17 -0
- package/docs/workflows.md +5 -0
- package/package.json +5 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { AgentLoopOptions, AgentLoopStrategy, ArtifactValidation, CompactionOptions, ContentBlock, ErrorInfo, GuardrailRecord, Guardrails, InstructionInjector, JsonObject, Message, ModelConfig, OwnershipScope, ProviderRequestOptions, ProviderRequestPolicy, ProviderResolver, RetryOptions, RunLimitBreach, RunLimits, Skill, SubscriberOverflowPolicy, SystemPromptConfig, ToolCallAuthority, ToolCallContent, TurnPolicyOptions, Usage } from "./contracts-core.js";
|
|
1
|
+
import type { AgentLoopOptions, AgentLoopStrategy, ArtifactValidation, BudgetAxisUsage, BudgetConsumedCounters, CompactionOptions, ContentBlock, ErrorInfo, GuardrailRecord, Guardrails, InstructionInjector, JsonObject, Message, ModelConfig, OwnershipScope, ProviderRequestOptions, ProviderRequestPolicy, ProviderResolver, ProviderStopReason, RetryOptions, RunLimitBreach, RunLimitName, RunLimits, Skill, SubscriberOverflowPolicy, SystemPromptConfig, ToolCallAuthority, ToolCallContent, ToolCallSummary, TurnBudgets, TurnPolicyOptions, Usage } from "./contracts-core.js";
|
|
2
|
+
import type { CacheUsageReport } from "./cache-helpers.js";
|
|
3
|
+
import type { CheckpointRestoreAudit } from "./checkpoint-restore.js";
|
|
2
4
|
import type { AgentRunInterruption, AgentRunStateOptions } from "./contracts-run-state.js";
|
|
3
5
|
import type { SecretRedactor } from "./redaction.js";
|
|
4
6
|
import type { ToolValidator } from "./tools.js";
|
|
@@ -28,6 +30,7 @@ export type ProviderEvent = {
|
|
|
28
30
|
} | {
|
|
29
31
|
readonly type: "done";
|
|
30
32
|
readonly usage?: Usage;
|
|
33
|
+
readonly stopReason?: ProviderStopReason;
|
|
31
34
|
} | {
|
|
32
35
|
readonly type: "error";
|
|
33
36
|
readonly error: ErrorInfo;
|
|
@@ -108,6 +111,10 @@ export interface RunOptions {
|
|
|
108
111
|
readonly toolNames?: readonly string[];
|
|
109
112
|
/** Tools disclosure: "all" (default) sends every active tool schema; "search" sends top-k + the generated `search_tools` tool. */
|
|
110
113
|
readonly toolsDisclosure?: import("./tool-search.js").ToolsDisclosure;
|
|
114
|
+
/** Per-turn restrictive allow-list over the run grant. Overrides `AgentConfig.toolNarrowing`. */
|
|
115
|
+
readonly toolNarrowing?: import("./contracts-core/agent.js").ToolNarrowing;
|
|
116
|
+
/** Opt-in: tools hidden this turn stay callable by name (default off). Overrides agent config. */
|
|
117
|
+
readonly allowHiddenToolCalls?: true;
|
|
111
118
|
readonly toolsSearch?: import("./tool-search.js").ToolsSearchOptions;
|
|
112
119
|
/** Opt-in projection-only fold for aged large tool results in provider view; store untouched. */
|
|
113
120
|
readonly toolResultFold?: import("./tool-result-fold.js").ToolResultFoldOptions;
|
|
@@ -140,6 +147,17 @@ export interface ProviderTurnMetadata {
|
|
|
140
147
|
readonly httpStatus?: number;
|
|
141
148
|
readonly rateLimitRemaining?: number;
|
|
142
149
|
readonly rateLimitResetMs?: number;
|
|
150
|
+
/** Why the provider turn stopped (plan 087 T1); present on `provider_turn_finished` only. */
|
|
151
|
+
readonly stopReason?: ProviderStopReason;
|
|
152
|
+
/** Effective budget state at turn end (plan 087 T1); present on `provider_turn_finished` only. */
|
|
153
|
+
readonly budgets?: TurnBudgets;
|
|
154
|
+
/** Provider-reported cache usage and derived hit rate; absent when cache usage is unknown. */
|
|
155
|
+
readonly cache?: CacheUsageReport;
|
|
156
|
+
/** Effective tool menu this turn. Names hashed in request order; never includes args. */
|
|
157
|
+
readonly tools?: {
|
|
158
|
+
readonly count: number;
|
|
159
|
+
readonly idsHash: string;
|
|
160
|
+
};
|
|
143
161
|
}
|
|
144
162
|
export interface ToolExecutionMetadata {
|
|
145
163
|
readonly durationMs: number;
|
|
@@ -177,7 +195,18 @@ export interface DelegatedAgentStep {
|
|
|
177
195
|
}
|
|
178
196
|
/** Why a run stopped cleanly. `host_policy` is a `RunOptions.turnPolicy` stop; the rest are loop ceilings (F4). */
|
|
179
197
|
export type AgentFinishReason = "turn_limit" | "token_limit" | "refusal" | "host_policy";
|
|
180
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Origin of an agent event forwarded from a delegated child (supervisor child-event passthrough).
|
|
200
|
+
* Present only on child events routed onto a parent stream; absent on a session's own events.
|
|
201
|
+
*/
|
|
202
|
+
export interface ChildEventOrigin {
|
|
203
|
+
readonly childId: string;
|
|
204
|
+
readonly delegationId: string;
|
|
205
|
+
/** Delegation depth: 1 is a direct child of the hosting supervisor. */
|
|
206
|
+
readonly depth: number;
|
|
207
|
+
}
|
|
208
|
+
/** Payload union of every agent event; the exported `AgentEvent` adds the optional child origin tag. */
|
|
209
|
+
type AgentEventPayload = {
|
|
181
210
|
readonly type: "agent_started";
|
|
182
211
|
readonly sessionId: string;
|
|
183
212
|
readonly runId: string;
|
|
@@ -201,6 +230,8 @@ export type AgentEvent = {
|
|
|
201
230
|
readonly sessionId: string;
|
|
202
231
|
readonly runId: string;
|
|
203
232
|
readonly version: number;
|
|
233
|
+
/** Plan 094 Task 3: audit of the external-state restore hooks that ran before this claim. */
|
|
234
|
+
readonly restore?: CheckpointRestoreAudit;
|
|
204
235
|
} | {
|
|
205
236
|
readonly type: "agent_denied";
|
|
206
237
|
readonly sessionId: string;
|
|
@@ -217,6 +248,17 @@ export type AgentEvent = {
|
|
|
217
248
|
readonly sessionId: string;
|
|
218
249
|
readonly runId: string;
|
|
219
250
|
readonly turn: number;
|
|
251
|
+
} | {
|
|
252
|
+
/**
|
|
253
|
+
* Host middleware completed this turn without a provider request (plan 096). No `usage` field:
|
|
254
|
+
* a deterministic turn has no provider cost, so accounting must never zero-fill one.
|
|
255
|
+
*/
|
|
256
|
+
readonly type: "deterministic_turn";
|
|
257
|
+
readonly sessionId: string;
|
|
258
|
+
readonly runId: string;
|
|
259
|
+
readonly turn: number;
|
|
260
|
+
/** Answering middleware id (provenance); ids only, never free host code. */
|
|
261
|
+
readonly middleware: string;
|
|
220
262
|
} | {
|
|
221
263
|
readonly type: "provider_turn_started";
|
|
222
264
|
readonly sessionId: string;
|
|
@@ -281,6 +323,13 @@ export type AgentEvent = {
|
|
|
281
323
|
readonly reason: string;
|
|
282
324
|
readonly error: ErrorInfo;
|
|
283
325
|
readonly metadata: ToolExecutionMetadata;
|
|
326
|
+
} | {
|
|
327
|
+
/** Host `toolNarrowing` asked for names outside the run grant; those names were dropped. */
|
|
328
|
+
readonly type: "tool_narrowing_clamped";
|
|
329
|
+
readonly sessionId: string;
|
|
330
|
+
readonly runId: string;
|
|
331
|
+
readonly turn: number;
|
|
332
|
+
readonly dropped: readonly string[];
|
|
284
333
|
} | {
|
|
285
334
|
readonly type: "guardrail_decision";
|
|
286
335
|
readonly sessionId: string;
|
|
@@ -293,6 +342,16 @@ export type AgentEvent = {
|
|
|
293
342
|
readonly sessionId: string;
|
|
294
343
|
readonly runId: string;
|
|
295
344
|
readonly breach: RunLimitBreach;
|
|
345
|
+
} | {
|
|
346
|
+
/** Terminal attribution for a run that died on a run limit (plan 087 T2): which axis fired,
|
|
347
|
+
* counters at exhaustion, how close the other axes were, and hashes of recent tool calls. */
|
|
348
|
+
readonly type: "budget_exhausted";
|
|
349
|
+
readonly sessionId: string;
|
|
350
|
+
readonly runId: string;
|
|
351
|
+
readonly limit: RunLimitName;
|
|
352
|
+
readonly consumed: BudgetConsumedCounters;
|
|
353
|
+
readonly closestOtherAxes: readonly BudgetAxisUsage[];
|
|
354
|
+
readonly recentToolCalls: readonly ToolCallSummary[];
|
|
296
355
|
} | {
|
|
297
356
|
readonly type: "queue_updated";
|
|
298
357
|
readonly sessionId: string;
|
|
@@ -383,6 +442,14 @@ export type AgentEvent = {
|
|
|
383
442
|
readonly attempt: number;
|
|
384
443
|
readonly result: ArtifactValidation;
|
|
385
444
|
};
|
|
445
|
+
/**
|
|
446
|
+
* One agent event. `child` is set only when the event was forwarded from a delegated child
|
|
447
|
+
* (e.g. supervisor `report: "stream"` passthrough), so hosts can route it onto a parent stream
|
|
448
|
+
* without per-event-type special cases. It never replaces the event's own `sessionId`/`runId`.
|
|
449
|
+
*/
|
|
450
|
+
export type AgentEvent = AgentEventPayload & {
|
|
451
|
+
readonly child?: ChildEventOrigin;
|
|
452
|
+
};
|
|
386
453
|
export type ToolEffectKind = "none" | "local_mutation" | "external_mutation";
|
|
387
454
|
export type ToolEffectIdempotency = "none" | "optional" | "required" | "tool_managed" | "unsupported";
|
|
388
455
|
/** Static or validated-argument classification of one tool call's side-effect behavior. */
|
|
@@ -688,4 +755,11 @@ export interface ProviderTurnResult {
|
|
|
688
755
|
readonly messageId?: string;
|
|
689
756
|
readonly started: boolean;
|
|
690
757
|
readonly usage?: Usage;
|
|
758
|
+
/**
|
|
759
|
+
* Provenance for turns that did not come from the provider (plan 096):
|
|
760
|
+
* `{ deterministic: { middleware } }`. Copied onto the assistant `Message.metadata`, so it
|
|
761
|
+
* serializes with the transcript and survives replay. Absent for provider turns.
|
|
762
|
+
*/
|
|
763
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
691
764
|
}
|
|
765
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { AgentSessionCloneOptions, AgentSessionForkOptions, CheckpointStore, CompactionOptions, CompactionResult, ContentBlock, ErrorInfo, JsonObject, JsonValue, Message, ModelConfig, OwnershipScope, RunLimitBreach, SessionEntry, SubscribeOptions, ToolCallContent, Usage } from "./contracts-core.js";
|
|
1
|
+
import type { AgentSessionCloneOptions, AgentSessionForkOptions, CheckpointRecord, CheckpointStore, CompactionOptions, CompactionResult, ContentBlock, ContextMeter, ErrorInfo, JsonObject, JsonValue, Message, ModelConfig, OwnershipScope, RunLimitBreach, SessionEntry, SubscribeOptions, ToolCallContent, Usage } from "./contracts-core.js";
|
|
2
2
|
import type { AgentEvent, AgentFinishReason, RunOptions, ToolEffectKind } from "./contracts-protocol.js";
|
|
3
|
+
import type { CheckpointRestoreHook } from "./checkpoint-restore.js";
|
|
3
4
|
export type AgentRunStatus = "succeeded" | "failed" | "aborted" | "suspended" | "denied";
|
|
4
5
|
export type AgentRunInterruptionKind = "input_guardrail" | "tool_approval" | "elicitation";
|
|
5
6
|
export type ApprovalOutcome = "allow_once" | "allow_for_run" | "reject_once" | "reject_for_run";
|
|
@@ -139,6 +140,15 @@ export declare const HARD_MAX_ACTION_CONSTRAINTS = 64;
|
|
|
139
140
|
export declare const MAX_ATTRIBUTION_DEPTH = 8;
|
|
140
141
|
export declare const MAX_ACTION_CONSTRAINT_BYTES: number;
|
|
141
142
|
export declare const HARD_MAX_ACTION_CONSTRAINT_BYTES: number;
|
|
143
|
+
/**
|
|
144
|
+
* Opaque host sidecar pinned to one checkpoint *record* (git commit, document version,
|
|
145
|
+
* workspace fingerprint) — never part of the run-state value, so it costs no `maxStateBytes`
|
|
146
|
+
* budget and is invisible to state parsing. Bounded to `MAX_AGENT_RUN_METADATA_BYTES` (4 KiB)
|
|
147
|
+
* and redacted like the state value at every write.
|
|
148
|
+
*/
|
|
149
|
+
export type AgentRunCheckpointMetadata = Readonly<Record<string, string>>;
|
|
150
|
+
/** Host source for checkpoint sidecar metadata: a fixed map or a live provider resolved per write. */
|
|
151
|
+
export type AgentRunCheckpointMetadataSource = AgentRunCheckpointMetadata | (() => AgentRunCheckpointMetadata | undefined);
|
|
142
152
|
export interface AgentRunStateOptions {
|
|
143
153
|
readonly checkpoints: CheckpointStore;
|
|
144
154
|
/** Host-authored immutable revision required for durable runs. */
|
|
@@ -156,6 +166,12 @@ export interface AgentRunStateOptions {
|
|
|
156
166
|
readonly checkpointPolicy?: "decision" | "every-turn";
|
|
157
167
|
/** Suspend every tool call before its side effect. */
|
|
158
168
|
readonly interruptBeforeTool?: boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Sidecar metadata written with every checkpoint of this run (and carried into a resumed
|
|
171
|
+
* run). A provider is resolved at each checkpoint write, so a host closure can pin state
|
|
172
|
+
* that moves mid-run (e.g. the current git commit). Absent = records stay byte-identical.
|
|
173
|
+
*/
|
|
174
|
+
readonly checkpointMetadata?: AgentRunCheckpointMetadataSource;
|
|
159
175
|
readonly maxStateBytes?: number;
|
|
160
176
|
readonly fencingToken?: number;
|
|
161
177
|
/** Enables sticky auto-apply when a nested suspension first surfaces during this run. */
|
|
@@ -204,6 +220,23 @@ export interface AgentRunResume {
|
|
|
204
220
|
/** Batch decision path; exactly one of decision/decisions. Applied as one atomic CAS transition. */
|
|
205
221
|
readonly decisions?: readonly RunDecision[];
|
|
206
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Checkpoint handed to a restore hook (plan 094 Task 3). `checkpoint.value` is the raw stored
|
|
225
|
+
* run-state value; `metadata` is the redacted, bounded sidecar map hosts write via
|
|
226
|
+
* `AgentRunStateOptions.checkpointMetadata`.
|
|
227
|
+
*/
|
|
228
|
+
export interface AgentCheckpointRestoreContext {
|
|
229
|
+
readonly runId: string;
|
|
230
|
+
readonly sessionId: string;
|
|
231
|
+
/** Version of the checkpoint being claimed; a hook may pass it to an external system's own CAS. */
|
|
232
|
+
readonly version: number;
|
|
233
|
+
/** State being claimed: `running` for crash recovery, `suspended` for a decision resume. */
|
|
234
|
+
readonly status: AgentRunStatus | "running";
|
|
235
|
+
readonly metadata?: AgentRunCheckpointMetadata;
|
|
236
|
+
readonly checkpoint: CheckpointRecord;
|
|
237
|
+
}
|
|
238
|
+
/** Host code restoring one external layer before a durable resume applies. */
|
|
239
|
+
export type AgentCheckpointRestoreHook = CheckpointRestoreHook<AgentCheckpointRestoreContext>;
|
|
207
240
|
export interface AgentRunResumeOptions {
|
|
208
241
|
readonly checkpoints: CheckpointStore;
|
|
209
242
|
/** Current host-authored revision; must exactly match the checkpoint. */
|
|
@@ -224,6 +257,20 @@ export interface AgentRunResumeOptions {
|
|
|
224
257
|
readonly persistSessionState?: boolean;
|
|
225
258
|
/** Opt-in (plan 018 Task 6): restore persisted loaded-skill bodies (requires `persistSessionState` too). */
|
|
226
259
|
readonly includeSkillBodies?: boolean;
|
|
260
|
+
/**
|
|
261
|
+
* Checkpoint sidecar metadata for the claim write (and the resumed run's later checkpoints).
|
|
262
|
+
* Absent = the record's existing metadata is preserved unchanged.
|
|
263
|
+
*/
|
|
264
|
+
readonly checkpointMetadata?: AgentRunCheckpointMetadataSource;
|
|
265
|
+
/**
|
|
266
|
+
* Plan 094 Task 3: external-state restore hooks. Every hook must succeed (sequentially, each
|
|
267
|
+
* within `restoreHookTimeoutMs`) before the claim write and the conversation restore apply;
|
|
268
|
+
* the first failure throws `CheckpointRestoreError` naming the hook and leaves the checkpoint
|
|
269
|
+
* suspended. Hosts that register hooks on the lifecycle instead pass them once there.
|
|
270
|
+
*/
|
|
271
|
+
readonly restoreHooks?: readonly AgentCheckpointRestoreHook[];
|
|
272
|
+
/** Per-hook restore ceiling in ms; defaults to `DEFAULT_CHECKPOINT_RESTORE_TIMEOUT_MS`. */
|
|
273
|
+
readonly restoreHookTimeoutMs?: number;
|
|
227
274
|
}
|
|
228
275
|
/** Bounded live-event options for `resumeAgentRunStream()`; `signal` is inherited from the base resume options. */
|
|
229
276
|
export interface AgentRunResumeStreamOptions extends AgentRunResumeOptions, SubscribeOptions {
|
|
@@ -235,6 +282,8 @@ export interface AgentRunRef {
|
|
|
235
282
|
export interface AgentRunStatusResult {
|
|
236
283
|
readonly state: AgentRunState;
|
|
237
284
|
readonly version: number;
|
|
285
|
+
/** Checkpoint sidecar metadata; absent when the record carries none (or carries only malformed entries). */
|
|
286
|
+
readonly metadata?: AgentRunCheckpointMetadata;
|
|
238
287
|
}
|
|
239
288
|
export declare class AgentRunStateError extends Error {
|
|
240
289
|
readonly code = "ERR_PRISM_AGENT_RUN_STATE";
|
|
@@ -319,6 +368,12 @@ export interface AgentSession {
|
|
|
319
368
|
abort(reason?: unknown): void;
|
|
320
369
|
entries(): Promise<readonly SessionEntry[]>;
|
|
321
370
|
checkout(leafId?: string): Promise<void>;
|
|
371
|
+
/**
|
|
372
|
+
* Context-fill read (plan 091 T2): latest provider turn's input tokens
|
|
373
|
+
* (reported or labeled estimate) plus the resolved per-request cap, run input
|
|
374
|
+
* budget, and used ratio. Before any provider turn it estimates stored history.
|
|
375
|
+
*/
|
|
376
|
+
contextMeter(): ContextMeter;
|
|
322
377
|
fork(options?: AgentSessionForkOptions): AgentSession;
|
|
323
378
|
clone(options?: AgentSessionCloneOptions): Promise<AgentSession>;
|
|
324
379
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { resolve as resolvePath, sep } from "node:path";
|
|
2
|
+
import { GuardrailPackError } from "./errors.js";
|
|
3
|
+
/** File-mutating prism coding tool names (plan 092 Task 1: `shell`/`read` are not mutations). */
|
|
4
|
+
const MUTATING_TOOLS = ["write", "edit", "delete", "move"];
|
|
5
|
+
const PATH_ARGS = ["path", "paths", "from", "to"];
|
|
6
|
+
const TEST_FILE_PATTERN = /(^|[\\/])(?:__tests__|tests?|specs?)[\\/]|\.(?:test|spec)\.[cm]?[jt]sx?$/;
|
|
7
|
+
const MAX_ROOTS = 16;
|
|
8
|
+
function pathStrings(args) {
|
|
9
|
+
const paths = [];
|
|
10
|
+
for (const key of PATH_ARGS) {
|
|
11
|
+
const value = args[key];
|
|
12
|
+
if (typeof value === "string")
|
|
13
|
+
paths.push(value);
|
|
14
|
+
else if (Array.isArray(value))
|
|
15
|
+
paths.push(...value.filter((item) => typeof item === "string"));
|
|
16
|
+
}
|
|
17
|
+
return paths;
|
|
18
|
+
}
|
|
19
|
+
function readRoots(value, cwd) {
|
|
20
|
+
if (value === undefined)
|
|
21
|
+
return [cwd];
|
|
22
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ROOTS) {
|
|
23
|
+
throw new GuardrailPackError(`coding-standard options.roots must be a non-empty string array (max ${MAX_ROOTS})`);
|
|
24
|
+
}
|
|
25
|
+
return value.map((root) => {
|
|
26
|
+
if (typeof root !== "string" || !root.trim())
|
|
27
|
+
throw new GuardrailPackError("coding-standard options.roots entries must be non-empty strings");
|
|
28
|
+
return resolvePath(cwd, root);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Lazy containment: no symlink resolution (a link inside a root can still point out); execution policy/sandbox remains the hard boundary. */
|
|
32
|
+
function outsideRoots(candidate, roots, cwd) {
|
|
33
|
+
const resolved = resolvePath(cwd, candidate);
|
|
34
|
+
return !roots.some((root) => resolved === root || resolved.startsWith(root.endsWith(sep) ? root : `${root}${sep}`));
|
|
35
|
+
}
|
|
36
|
+
/** Canned coding hygiene: file mutations confined to configured roots, test files read-only. */
|
|
37
|
+
export const codingStandardPack = {
|
|
38
|
+
id: "coding-standard",
|
|
39
|
+
version: 1,
|
|
40
|
+
description: "Restricts file mutation to configured workspace roots and blocks test-file rewrites.",
|
|
41
|
+
build(options) {
|
|
42
|
+
const cwd = resolvePath(typeof options.cwd === "string" ? options.cwd : process.cwd());
|
|
43
|
+
const roots = readRoots(options.roots, cwd);
|
|
44
|
+
return {
|
|
45
|
+
rules: [
|
|
46
|
+
{
|
|
47
|
+
id: "no-unrelated-file-edits",
|
|
48
|
+
tool: MUTATING_TOOLS,
|
|
49
|
+
reason: "File edits are restricted to the configured workspace roots",
|
|
50
|
+
deny: (args) => pathStrings(args).some((candidate) => outsideRoots(candidate, roots, cwd)),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "no-test-rewrites",
|
|
54
|
+
tool: MUTATING_TOOLS,
|
|
55
|
+
pattern: TEST_FILE_PATTERN,
|
|
56
|
+
argPath: PATH_ARGS,
|
|
57
|
+
reason: "Test files are read-only under this pack",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=coding-standard.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Shell commands that destroy data or history. Denies `--force-with-lease` too: both rewrite remote history. */
|
|
2
|
+
const DESTRUCTIVE_COMMANDS = [
|
|
3
|
+
{
|
|
4
|
+
id: "no-recursive-force-delete",
|
|
5
|
+
pattern: /\brm\s+(?:[^\n;&|]*?\s)?-(?=[a-z]*r)(?=[a-z]*f)[a-z]+/i,
|
|
6
|
+
reason: "Recursive force delete is not allowed",
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
id: "no-long-flag-force-delete",
|
|
10
|
+
pattern: /\brm\s+[^\n;&|]*--recursive\b[^\n;&|]*--force\b|\brm\s+[^\n;&|]*--force\b[^\n;&|]*--recursive\b/i,
|
|
11
|
+
reason: "Recursive force delete is not allowed",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "no-force-push",
|
|
15
|
+
pattern: /\bgit\s+push\b[^\n;&|]*(?:--force\b|(?:^|\s)-f(?:\s|$))/i,
|
|
16
|
+
reason: "Force push is not allowed",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "no-destructive-sql",
|
|
20
|
+
pattern: /\b(?:drop|truncate)\s+table\b/i,
|
|
21
|
+
reason: "Destructive SQL is not allowed",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "no-device-overwrite",
|
|
25
|
+
pattern: /\bmkfs(?:\.\w+)?\b|\bdd\b[^\n;&|]*\bof=\/dev\//i,
|
|
26
|
+
reason: "Raw device overwrite is not allowed",
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
/** Canned destructive shell/SQL patterns on the `shell` tool's `command` argument. */
|
|
30
|
+
export const destructiveCommandsPack = {
|
|
31
|
+
id: "destructive-commands",
|
|
32
|
+
version: 1,
|
|
33
|
+
description: "Blocks destructive shell and SQL commands (recursive force delete, force push, drop table, device overwrite).",
|
|
34
|
+
build() {
|
|
35
|
+
return {
|
|
36
|
+
rules: DESTRUCTIVE_COMMANDS.map(({ id, pattern, reason }) => ({
|
|
37
|
+
id,
|
|
38
|
+
tool: "shell",
|
|
39
|
+
pattern,
|
|
40
|
+
argPath: "command",
|
|
41
|
+
reason,
|
|
42
|
+
})),
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=destructive-commands.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Guardrail pack config/compile error (plan 092 Task 2). Config mistakes fail closed at compile time. */
|
|
2
|
+
export declare class GuardrailPackError extends Error {
|
|
3
|
+
readonly code = "ERR_PRISM_GUARDRAIL_PACK";
|
|
4
|
+
constructor(message: string, options?: {
|
|
5
|
+
readonly cause?: unknown;
|
|
6
|
+
});
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Guardrail pack config/compile error (plan 092 Task 2). Config mistakes fail closed at compile time. */
|
|
2
|
+
export class GuardrailPackError extends Error {
|
|
3
|
+
code = "ERR_PRISM_GUARDRAIL_PACK";
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
this.name = "GuardrailPackError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Built-in guardrail pack registry (plan 092 Task 2). Definitions are pure data + pure factories. */
|
|
2
|
+
import { codingStandardPack } from "./coding-standard.js";
|
|
3
|
+
import { destructiveCommandsPack } from "./destructive-commands.js";
|
|
4
|
+
import { secretsHygienePack } from "./secrets-hygiene.js";
|
|
5
|
+
import { validationRespectPack } from "./validation-respect.js";
|
|
6
|
+
const DEFINITIONS = [
|
|
7
|
+
codingStandardPack,
|
|
8
|
+
destructiveCommandsPack,
|
|
9
|
+
validationRespectPack,
|
|
10
|
+
secretsHygienePack,
|
|
11
|
+
];
|
|
12
|
+
export const BUILT_IN_GUARDRAIL_PACKS = new Map(DEFINITIONS.map((definition) => [definition.id, definition]));
|
|
13
|
+
/** Built-in pack ids, in registry order. */
|
|
14
|
+
export const BUILT_IN_GUARDRAIL_PACK_IDS = DEFINITIONS.map((definition) => definition.id);
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Known credential shapes, all quantifier-bounded so a hostile argument string cannot blow up the regex.
|
|
3
|
+
* Prism redaction matches exact known values only (plan 092 Task 1), so these patterns ship with the pack.
|
|
4
|
+
*/
|
|
5
|
+
const SECRET_PATTERN = /(?:sk-[A-Za-z0-9]{16,}|gh[pousr]_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----|eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.|xox[baprs]-[A-Za-z0-9-]{10,})/;
|
|
6
|
+
/** Canned secret hygiene: any tool argument carrying credential-shaped material is denied. */
|
|
7
|
+
export const secretsHygienePack = {
|
|
8
|
+
id: "secrets-hygiene",
|
|
9
|
+
version: 1,
|
|
10
|
+
description: "Blocks tool calls whose arguments carry secret-shaped material (API keys, tokens, private keys).",
|
|
11
|
+
build() {
|
|
12
|
+
return {
|
|
13
|
+
rules: [
|
|
14
|
+
{
|
|
15
|
+
id: "no-secret-material-in-arguments",
|
|
16
|
+
pattern: SECRET_PATTERN,
|
|
17
|
+
reason: "Tool arguments contain secret-shaped material",
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=secrets-hygiene.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Internal guardrail-pack definition types (plan 092 Task 2). Not SDK surface; hosts configure packs via `AgentSessionConfig.guardrailPacks`. */
|
|
2
|
+
import type { GuardrailRule, GuardrailRuleContext } from "../contracts-core/guardrail-packs.js";
|
|
3
|
+
import type { ToolResult } from "../contracts-protocol.js";
|
|
4
|
+
/** What a pack's `build` returns: restrictive rules plus an optional pure result observer. */
|
|
5
|
+
export interface GuardrailPackRules {
|
|
6
|
+
readonly rules: readonly GuardrailRule[];
|
|
7
|
+
/** Records tool results into pack-local state (never denies); a throw fails closed as a guardrail tripwire. */
|
|
8
|
+
readonly observe?: (state: Record<string, unknown>, result: ToolResult, context: GuardrailRuleContext) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface GuardrailPackDefinition {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly version: number;
|
|
13
|
+
readonly description: string;
|
|
14
|
+
/** Pure factory: options in, rules out. No session access, no I/O. */
|
|
15
|
+
readonly build: (options: Readonly<Record<string, unknown>>) => GuardrailPackRules;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { GuardrailPackError } from "./errors.js";
|
|
2
|
+
const MUTATING_TOOLS = ["write", "edit", "delete", "move"];
|
|
3
|
+
/** Validation-style tool names. `shell` is opt-in (`validationTools`): a non-zero shell exit is a failure signal too. */
|
|
4
|
+
const DEFAULT_VALIDATION_TOOLS = ["test", "run_tests", "validate", "validation", "lint", "typecheck", "check"];
|
|
5
|
+
const MAX_VALIDATION_TOOLS = 16;
|
|
6
|
+
/** A tool result failed when it carries an error, or reported a non-zero `exitCode` (the shell tool's shape). */
|
|
7
|
+
function resultFailed(result) {
|
|
8
|
+
if (result.error !== undefined)
|
|
9
|
+
return true;
|
|
10
|
+
const value = result.value;
|
|
11
|
+
if (!value || typeof value !== "object" || !("exitCode" in value))
|
|
12
|
+
return false;
|
|
13
|
+
const exitCode = value.exitCode;
|
|
14
|
+
return typeof exitCode === "number" && exitCode !== 0;
|
|
15
|
+
}
|
|
16
|
+
function readValidationTools(value) {
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
return DEFAULT_VALIDATION_TOOLS;
|
|
19
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_VALIDATION_TOOLS) {
|
|
20
|
+
throw new GuardrailPackError(`validation-respect options.validationTools must be a non-empty string array (max ${MAX_VALIDATION_TOOLS})`);
|
|
21
|
+
}
|
|
22
|
+
return value.map((name) => {
|
|
23
|
+
if (typeof name !== "string" || !name.trim()) {
|
|
24
|
+
throw new GuardrailPackError("validation-respect options.validationTools entries must be non-empty strings");
|
|
25
|
+
}
|
|
26
|
+
return name;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Canned "respect failed validation": once a validation tool result fails, file mutations are denied until one passes. */
|
|
30
|
+
export const validationRespectPack = {
|
|
31
|
+
id: "validation-respect",
|
|
32
|
+
version: 1,
|
|
33
|
+
description: "Denies file mutations after a failed validation tool result until a later validation passes.",
|
|
34
|
+
build(options) {
|
|
35
|
+
const validationTools = readValidationTools(options.validationTools);
|
|
36
|
+
return {
|
|
37
|
+
observe(state, result, context) {
|
|
38
|
+
if (!validationTools.includes(context.toolName))
|
|
39
|
+
return;
|
|
40
|
+
state.validationFailed = resultFailed(result) ? context.toolName : undefined;
|
|
41
|
+
},
|
|
42
|
+
rules: [
|
|
43
|
+
{
|
|
44
|
+
id: "no-mutation-after-failed-validation",
|
|
45
|
+
tool: MUTATING_TOOLS,
|
|
46
|
+
reason: "A previous validation result failed; fix it before mutating files",
|
|
47
|
+
deny: (_args, context) => context.state.validationFailed !== undefined,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=validation-respect.js.map
|
package/dist/guardrails.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type { AgentEvent, GuardrailContext, GuardrailRecord, GuardrailStage, Guardrails, GuardrailValue } from "./contracts.js";
|
|
1
|
+
import type { AgentEvent, GuardrailContext, GuardrailPackRef, GuardrailRecord, GuardrailStage, Guardrails, GuardrailValue } from "./contracts.js";
|
|
2
|
+
export { GuardrailPackError } from "./guardrail-packs/errors.js";
|
|
2
3
|
import type { SecretRedactor } from "./redaction.js";
|
|
3
4
|
export declare const MAX_GUARDRAIL_CONCURRENCY = 16;
|
|
5
|
+
/** Guardrail pack compile bounds (plan 092 Task 2). All ceilings are config-shape limits, not runtime budgets. */
|
|
6
|
+
export declare const MAX_GUARDRAIL_PACKS = 8;
|
|
7
|
+
export declare const MAX_GUARDRAIL_PACK_RULES = 64;
|
|
4
8
|
export declare class GuardrailError extends Error {
|
|
5
9
|
readonly code: string;
|
|
6
10
|
readonly record: GuardrailRecord;
|
|
@@ -23,3 +27,18 @@ export interface GuardrailRunResult {
|
|
|
23
27
|
/** Evaluate one typed stage. Default is declaration-order sequential; bounded parallel mode still reports declaration order. */
|
|
24
28
|
export declare function runGuardrails<S extends GuardrailStage>(options: RunGuardrailsOptions<S>): Promise<GuardrailRunResult>;
|
|
25
29
|
export declare function assertGuardrailsAllowed(result: GuardrailRunResult): void;
|
|
30
|
+
/** One `guardrail:<stage>` identity row of a compiled pack, for run-bundle fingerprints. */
|
|
31
|
+
export interface GuardrailPackRow {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly stage: "tool_input" | "tool_output";
|
|
34
|
+
readonly revision: string | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compiles `guardrailPacks` config onto the existing tool interception seams: one `tool_input`
|
|
38
|
+
* guardrail per rule (`name = pack:<pack>/<rule>`), plus one `tool_output` recorder for packs that
|
|
39
|
+
* observe results. Compiled once per session — patterns are compiled here, never per tool call.
|
|
40
|
+
* Throws `GuardrailPackError` on malformed config (fail closed); returns `undefined` when unset.
|
|
41
|
+
*/
|
|
42
|
+
export declare function compileGuardrailPacks(refs: readonly GuardrailPackRef[] | undefined, registry?: ReadonlyMap<string, import("./guardrail-packs/types.js").GuardrailPackDefinition>): Guardrails | undefined;
|
|
43
|
+
/** Stable identity rows for the same config `compileGuardrailPacks` accepts (no state, no guardrails built). */
|
|
44
|
+
export declare function describeGuardrailPacks(refs: readonly GuardrailPackRef[] | undefined, registry?: ReadonlyMap<string, import("./guardrail-packs/types.js").GuardrailPackDefinition>): readonly GuardrailPackRow[];
|