@arnilo/prism 0.0.6 → 0.0.8
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 +32 -0
- package/README.md +3 -1
- package/dist/agent-loops.js +8 -5
- package/dist/agent-run-lifecycle.d.ts +28 -0
- package/dist/agent-run-lifecycle.js +33 -0
- package/dist/agent-run-state.d.ts +53 -0
- package/dist/agent-run-state.js +127 -0
- package/dist/agents.d.ts +3 -1
- package/dist/agents.js +356 -45
- package/dist/contracts.d.ts +218 -3
- package/dist/contracts.js +4 -0
- package/dist/guardrails.d.ts +25 -0
- package/dist/guardrails.js +133 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.js +9 -3
- package/dist/input.js +2 -0
- package/dist/resources.js +2 -1
- package/dist/run-ledger.d.ts +21 -0
- package/dist/run-ledger.js +115 -0
- package/dist/run-limits.d.ts +34 -0
- package/dist/run-limits.js +163 -0
- package/dist/secure-agent.d.ts +3 -0
- package/dist/secure-agent.js +63 -0
- package/dist/tools.d.ts +10 -2
- package/dist/tools.js +54 -4
- package/docs/a2a.md +61 -42
- package/docs/agent-events.md +15 -3
- package/docs/agent-loops.md +12 -4
- package/docs/agent-session-runtime.md +34 -1
- package/docs/credential-storage.md +9 -0
- package/docs/database-persistence.md +1 -1
- package/docs/evaluations.md +26 -3
- package/docs/guardrails.md +75 -0
- package/docs/host-security.md +31 -4
- package/docs/index.md +17 -14
- package/docs/mcp-tools.md +36 -8
- package/docs/migration.md +54 -0
- package/docs/observability.md +26 -14
- package/docs/performance.md +25 -0
- package/docs/postgres-persistence.md +1 -0
- package/docs/providers/kimi.md +16 -2
- package/docs/providers/opencode-go.md +43 -2
- package/docs/release-and-install.md +73 -62
- package/docs/resource-loading.md +4 -0
- package/docs/review-coverage-2026-07-19-phase-3.md +174 -0
- package/docs/run-ledger-conformance.md +1 -0
- package/docs/runs-and-usage.md +46 -4
- package/docs/server.md +5 -2
- package/docs/sqlite-persistence.md +1 -0
- package/docs/supervisors.md +2 -2
- package/docs/tools.md +8 -2
- package/docs/web-tools.md +78 -0
- package/docs/workflows.md +2 -0
- package/package.json +2 -1
package/dist/contracts.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AgentInput } from "./input.js";
|
|
|
2
2
|
import type { ContributionRegistries } from "./contributions.js";
|
|
3
3
|
import type { Middleware, MiddlewareHookName, MiddlewareRegistry } from "./middleware.js";
|
|
4
4
|
import type { SecretRedactor } from "./redaction.js";
|
|
5
|
-
import type { PermissionPolicy } from "./security.js";
|
|
5
|
+
import type { PermissionPolicy, TrustPolicy } from "./security.js";
|
|
6
6
|
import type { ManifestContributionDeclaration } from "./manifests.js";
|
|
7
7
|
import type { ToolValidator } from "./tools.js";
|
|
8
8
|
import type { AudioContent, DocumentContent, FileContent } from "./content.js";
|
|
@@ -106,6 +106,83 @@ export interface Usage {
|
|
|
106
106
|
readonly cost?: number;
|
|
107
107
|
readonly currency?: string;
|
|
108
108
|
}
|
|
109
|
+
export interface RunLimits {
|
|
110
|
+
readonly maxTurns?: number;
|
|
111
|
+
readonly maxProviderAttempts?: number;
|
|
112
|
+
readonly maxToolRounds?: number;
|
|
113
|
+
readonly maxToolCalls?: number;
|
|
114
|
+
readonly maxWallTimeMs?: number;
|
|
115
|
+
readonly maxRequestBytes?: number;
|
|
116
|
+
readonly maxResponseBytes?: number;
|
|
117
|
+
readonly maxInputTokens?: number;
|
|
118
|
+
readonly maxOutputTokens?: number;
|
|
119
|
+
readonly maxTotalTokens?: number;
|
|
120
|
+
readonly maxCost?: {
|
|
121
|
+
readonly amount: number;
|
|
122
|
+
readonly currency: string;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export type RunLimitName = keyof Required<RunLimits>;
|
|
126
|
+
export interface RunLimitCounters {
|
|
127
|
+
readonly turns: number;
|
|
128
|
+
readonly providerAttempts: number;
|
|
129
|
+
readonly toolRounds: number;
|
|
130
|
+
readonly toolCalls: number;
|
|
131
|
+
readonly wallTimeMs: number;
|
|
132
|
+
readonly requestBytes: number;
|
|
133
|
+
readonly responseBytes: number;
|
|
134
|
+
readonly inputTokens: number;
|
|
135
|
+
readonly outputTokens: number;
|
|
136
|
+
readonly totalTokens: number;
|
|
137
|
+
readonly cost: number;
|
|
138
|
+
}
|
|
139
|
+
export interface RunLimitBreach {
|
|
140
|
+
readonly limit: RunLimitName;
|
|
141
|
+
readonly maximum: number;
|
|
142
|
+
readonly observed: number;
|
|
143
|
+
readonly currency?: string;
|
|
144
|
+
}
|
|
145
|
+
export type GuardrailStage = "input" | "output" | "tool_input" | "tool_output";
|
|
146
|
+
export type GuardrailAction = "allow" | "block" | "tripwire" | "interrupt";
|
|
147
|
+
export type GuardrailValue<S extends GuardrailStage> = S extends "input" ? readonly Message[] : S extends "output" ? ProviderTurnResult : S extends "tool_input" ? ToolCallContent : ToolResult;
|
|
148
|
+
export interface GuardrailContext<S extends GuardrailStage> {
|
|
149
|
+
readonly stage: S;
|
|
150
|
+
readonly value: GuardrailValue<S>;
|
|
151
|
+
readonly sessionId: string;
|
|
152
|
+
readonly runId: string;
|
|
153
|
+
readonly toolCallId?: string;
|
|
154
|
+
readonly toolName?: string;
|
|
155
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
156
|
+
readonly signal: AbortSignal;
|
|
157
|
+
}
|
|
158
|
+
export interface GuardrailDecision {
|
|
159
|
+
readonly action: GuardrailAction;
|
|
160
|
+
readonly reason?: string;
|
|
161
|
+
/** Public data only; Prism JSON-normalizes, bounds, and redacts it before emission. */
|
|
162
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
163
|
+
}
|
|
164
|
+
export interface Guardrail<S extends GuardrailStage = GuardrailStage> {
|
|
165
|
+
readonly name: string;
|
|
166
|
+
readonly stage: S;
|
|
167
|
+
/** Host-authored stable identity for durable definitions; unused by ordinary runs. */
|
|
168
|
+
readonly revision?: string;
|
|
169
|
+
evaluate(context: GuardrailContext<S>): GuardrailDecision | Promise<GuardrailDecision>;
|
|
170
|
+
}
|
|
171
|
+
export interface GuardrailRecord {
|
|
172
|
+
readonly guardrail: string;
|
|
173
|
+
readonly stage: GuardrailStage;
|
|
174
|
+
readonly action: GuardrailAction;
|
|
175
|
+
readonly reason?: string;
|
|
176
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
177
|
+
}
|
|
178
|
+
export interface Guardrails {
|
|
179
|
+
readonly input?: readonly Guardrail<"input">[];
|
|
180
|
+
readonly output?: readonly Guardrail<"output">[];
|
|
181
|
+
readonly toolInput?: readonly Guardrail<"tool_input">[];
|
|
182
|
+
readonly toolOutput?: readonly Guardrail<"tool_output">[];
|
|
183
|
+
/** Defaults to sequential; at most 16 stage evaluations run at once. */
|
|
184
|
+
readonly maxConcurrency?: number;
|
|
185
|
+
}
|
|
109
186
|
export type CacheRetention = "none" | "short" | "long";
|
|
110
187
|
export type PromptCacheKind = "implicit" | "openai_key" | "cache_control" | "provider_specific" | "none";
|
|
111
188
|
export interface ModelCacheCapabilities {
|
|
@@ -195,7 +272,10 @@ export interface RunOptions {
|
|
|
195
272
|
readonly signal?: AbortSignal;
|
|
196
273
|
readonly model?: ModelConfig;
|
|
197
274
|
readonly providerSource?: ProviderResolver;
|
|
275
|
+
/** @deprecated Use `limits.maxToolRounds`. */
|
|
198
276
|
readonly maxToolRounds?: number;
|
|
277
|
+
/** Run-scoped ceilings. When an agent config also sets limits, these can only narrow it. */
|
|
278
|
+
readonly limits?: RunLimits;
|
|
199
279
|
readonly providerOptions?: ProviderRequestOptions;
|
|
200
280
|
readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
|
|
201
281
|
readonly systemPrompt?: SystemPromptConfig;
|
|
@@ -212,6 +292,10 @@ export interface RunOptions {
|
|
|
212
292
|
readonly instructionInjectors?: readonly InstructionInjector[];
|
|
213
293
|
readonly inputLayout?: InputAssemblyLayout;
|
|
214
294
|
readonly loop?: AgentLoopStrategy | AgentLoopOptions;
|
|
295
|
+
/** Appended to agent-level guardrails for this run. */
|
|
296
|
+
readonly guardrails?: Guardrails;
|
|
297
|
+
/** Opt-in durable interruption/checkpointing. */
|
|
298
|
+
readonly runState?: AgentRunStateOptions;
|
|
215
299
|
}
|
|
216
300
|
export interface AgentDefinition {
|
|
217
301
|
readonly name: string;
|
|
@@ -258,6 +342,8 @@ export interface AgentConfig {
|
|
|
258
342
|
readonly resourceLoader?: ResourceLoader;
|
|
259
343
|
readonly store?: SessionStore;
|
|
260
344
|
readonly permission?: PermissionPolicy;
|
|
345
|
+
/** Optional trust check for tool and resource targets. */
|
|
346
|
+
readonly trust?: TrustPolicy;
|
|
261
347
|
readonly providerOptions?: ProviderRequestOptions;
|
|
262
348
|
readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
|
|
263
349
|
readonly systemPrompt?: SystemPromptConfig;
|
|
@@ -267,11 +353,31 @@ export interface AgentConfig {
|
|
|
267
353
|
readonly idempotencyKey?: string;
|
|
268
354
|
readonly compaction?: false | CompactionOptions;
|
|
269
355
|
readonly retry?: false | RetryOptions;
|
|
356
|
+
/** Agent-wide ceilings; per-run limits may only narrow these values. */
|
|
357
|
+
readonly limits?: RunLimits;
|
|
270
358
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
271
359
|
readonly validator?: ToolValidator;
|
|
272
360
|
readonly instructionInjectors?: readonly InstructionInjector[];
|
|
273
361
|
readonly inputLayout?: InputAssemblyLayout;
|
|
274
362
|
readonly loop?: AgentLoopStrategy | AgentLoopOptions;
|
|
363
|
+
readonly guardrails?: Guardrails;
|
|
364
|
+
/** Opt-in durable interruption/checkpointing default for this agent. */
|
|
365
|
+
readonly runState?: AgentRunStateOptions;
|
|
366
|
+
/** Internal marker set by createSecureAgent(); makes security defaults immutable per run. */
|
|
367
|
+
readonly secure?: true;
|
|
368
|
+
}
|
|
369
|
+
/** Opt-in fail-closed composition over the normal explicit AgentConfig API. */
|
|
370
|
+
export interface SecureAgentOptions extends Omit<AgentConfig, "tools" | "validator" | "redactor" | "permission" | "trust" | "ownership" | "limits" | "runState" | "secure"> {
|
|
371
|
+
readonly id: string;
|
|
372
|
+
readonly tools: readonly ToolDefinition[];
|
|
373
|
+
readonly toolArgumentValidator: import("./tools.js").ToolArgumentValidator;
|
|
374
|
+
readonly redactor: SecretRedactor;
|
|
375
|
+
readonly permission: PermissionPolicy;
|
|
376
|
+
readonly trust: TrustPolicy;
|
|
377
|
+
readonly ownership: OwnershipScope;
|
|
378
|
+
readonly limits: RunLimits;
|
|
379
|
+
readonly definitionRevision: string;
|
|
380
|
+
readonly runState: Omit<AgentRunStateOptions, "definitionRevision" | "interruptBeforeTool">;
|
|
275
381
|
}
|
|
276
382
|
export interface Agent {
|
|
277
383
|
readonly config: AgentConfig;
|
|
@@ -298,7 +404,61 @@ export interface SubscribeOptions {
|
|
|
298
404
|
/** What to do when `maxQueuedEvents` is reached. Defaults to `close`. */
|
|
299
405
|
readonly overflow?: SubscriberOverflowPolicy;
|
|
300
406
|
}
|
|
301
|
-
export type AgentRunStatus = "succeeded" | "failed" | "aborted";
|
|
407
|
+
export type AgentRunStatus = "succeeded" | "failed" | "aborted" | "suspended" | "denied";
|
|
408
|
+
export type AgentRunInterruptionKind = "input_guardrail" | "tool_approval";
|
|
409
|
+
/** Redacted safe-boundary descriptor; never contains tool arguments. */
|
|
410
|
+
export interface AgentRunInterruption {
|
|
411
|
+
readonly kind: AgentRunInterruptionKind;
|
|
412
|
+
readonly reason: string;
|
|
413
|
+
readonly toolCallId?: string;
|
|
414
|
+
readonly toolName?: string;
|
|
415
|
+
}
|
|
416
|
+
export interface AgentRunStateOptions {
|
|
417
|
+
readonly checkpoints: CheckpointStore;
|
|
418
|
+
/** Host-authored immutable revision required for durable runs. */
|
|
419
|
+
readonly definitionRevision: string;
|
|
420
|
+
/** Suspend every tool call before its side effect. */
|
|
421
|
+
readonly interruptBeforeTool?: boolean;
|
|
422
|
+
readonly maxStateBytes?: number;
|
|
423
|
+
readonly fencingToken?: number;
|
|
424
|
+
}
|
|
425
|
+
/** Versioned, redacted checkpoint payload. Treat as opaque except status/version/interruption. */
|
|
426
|
+
export interface AgentRunState {
|
|
427
|
+
readonly schemaVersion: 1;
|
|
428
|
+
readonly agentId: string;
|
|
429
|
+
readonly definitionRevision: string;
|
|
430
|
+
readonly fingerprint: string;
|
|
431
|
+
readonly runId: string;
|
|
432
|
+
readonly sessionId: string;
|
|
433
|
+
readonly leafId?: string;
|
|
434
|
+
readonly model: ModelConfig;
|
|
435
|
+
readonly status: AgentRunStatus | "running";
|
|
436
|
+
readonly interruption?: AgentRunInterruption;
|
|
437
|
+
readonly version?: number;
|
|
438
|
+
}
|
|
439
|
+
export interface AgentRunResume {
|
|
440
|
+
readonly decision: "approve" | "deny";
|
|
441
|
+
readonly expectedVersion: number;
|
|
442
|
+
}
|
|
443
|
+
export interface AgentRunResumeOptions {
|
|
444
|
+
readonly checkpoints: CheckpointStore;
|
|
445
|
+
/** Current host-authored revision; must exactly match the checkpoint. */
|
|
446
|
+
readonly definitionRevision: string;
|
|
447
|
+
readonly ownership?: OwnershipScope;
|
|
448
|
+
readonly fencingToken?: number;
|
|
449
|
+
}
|
|
450
|
+
export interface AgentRunRef {
|
|
451
|
+
readonly runId: string;
|
|
452
|
+
readonly sessionId?: string;
|
|
453
|
+
}
|
|
454
|
+
export interface AgentRunStatusResult {
|
|
455
|
+
readonly state: AgentRunState;
|
|
456
|
+
readonly version: number;
|
|
457
|
+
}
|
|
458
|
+
export declare class AgentRunStateError extends Error {
|
|
459
|
+
readonly code = "ERR_PRISM_AGENT_RUN_STATE";
|
|
460
|
+
constructor(message: string);
|
|
461
|
+
}
|
|
302
462
|
/** Terminal result of `session.run()` / `session.prompt()`. Failed and aborted runs throw {@link AgentRunError} with this shape attached. */
|
|
303
463
|
export interface AgentRunResult {
|
|
304
464
|
readonly sessionId: string;
|
|
@@ -314,10 +474,16 @@ export interface AgentRunResult {
|
|
|
314
474
|
readonly message?: Message;
|
|
315
475
|
/** Aggregate usage across provider turns (`run_total` scope). */
|
|
316
476
|
readonly usage?: Usage;
|
|
477
|
+
/** Present when the run hit a configured resource ceiling. */
|
|
478
|
+
readonly limit?: RunLimitBreach;
|
|
317
479
|
/** Present when `status` is `"failed"` or when a failed attempt still produced partial output. */
|
|
318
480
|
readonly error?: ErrorInfo;
|
|
319
481
|
/** String form of the abort reason when `status` is `"aborted"`. */
|
|
320
482
|
readonly abortReason?: string;
|
|
483
|
+
/** Present for durable suspended/terminal runs. Payload is redacted and bounded. */
|
|
484
|
+
readonly runState?: AgentRunState;
|
|
485
|
+
/** Present only while awaiting an operator decision. */
|
|
486
|
+
readonly interruption?: AgentRunInterruption;
|
|
321
487
|
}
|
|
322
488
|
export declare class AgentRunError extends Error {
|
|
323
489
|
readonly result: AgentRunResult;
|
|
@@ -365,6 +531,23 @@ export type AgentEvent = {
|
|
|
365
531
|
readonly sessionId: string;
|
|
366
532
|
readonly runId: string;
|
|
367
533
|
readonly usage?: Usage;
|
|
534
|
+
} | {
|
|
535
|
+
readonly type: "agent_suspended";
|
|
536
|
+
readonly sessionId: string;
|
|
537
|
+
readonly runId: string;
|
|
538
|
+
readonly interruption: AgentRunInterruption;
|
|
539
|
+
readonly version: number;
|
|
540
|
+
} | {
|
|
541
|
+
readonly type: "agent_resumed";
|
|
542
|
+
readonly sessionId: string;
|
|
543
|
+
readonly runId: string;
|
|
544
|
+
readonly version: number;
|
|
545
|
+
} | {
|
|
546
|
+
readonly type: "agent_denied";
|
|
547
|
+
readonly sessionId: string;
|
|
548
|
+
readonly runId: string;
|
|
549
|
+
readonly interruption: AgentRunInterruption;
|
|
550
|
+
readonly version: number;
|
|
368
551
|
} | {
|
|
369
552
|
readonly type: "turn_started";
|
|
370
553
|
readonly sessionId: string;
|
|
@@ -439,6 +622,18 @@ export type AgentEvent = {
|
|
|
439
622
|
readonly reason: string;
|
|
440
623
|
readonly error: ErrorInfo;
|
|
441
624
|
readonly metadata: ToolExecutionMetadata;
|
|
625
|
+
} | {
|
|
626
|
+
readonly type: "guardrail_decision";
|
|
627
|
+
readonly sessionId: string;
|
|
628
|
+
readonly runId: string;
|
|
629
|
+
readonly toolCallId?: string;
|
|
630
|
+
readonly toolName?: string;
|
|
631
|
+
readonly record: GuardrailRecord;
|
|
632
|
+
} | {
|
|
633
|
+
readonly type: "run_limit_exceeded";
|
|
634
|
+
readonly sessionId: string;
|
|
635
|
+
readonly runId: string;
|
|
636
|
+
readonly breach: RunLimitBreach;
|
|
442
637
|
} | {
|
|
443
638
|
readonly type: "queue_updated";
|
|
444
639
|
readonly sessionId: string;
|
|
@@ -617,6 +812,8 @@ export interface InputBuildContext {
|
|
|
617
812
|
readonly runId?: string;
|
|
618
813
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
619
814
|
readonly signal?: AbortSignal;
|
|
815
|
+
readonly permission?: PermissionPolicy;
|
|
816
|
+
readonly trust?: TrustPolicy;
|
|
620
817
|
}
|
|
621
818
|
export interface PromptBuilder {
|
|
622
819
|
readonly name: string;
|
|
@@ -1006,7 +1203,7 @@ export interface BranchRecord {
|
|
|
1006
1203
|
readonly createdAt: string;
|
|
1007
1204
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1008
1205
|
}
|
|
1009
|
-
export type RunStatus = "queued" | "running" | "succeeded" | "failed" | "aborted";
|
|
1206
|
+
export type RunStatus = "queued" | "running" | "suspended" | "denied" | "succeeded" | "failed" | "aborted";
|
|
1010
1207
|
/** Stored run record. */
|
|
1011
1208
|
export interface RunRecord extends OwnershipScope {
|
|
1012
1209
|
readonly id: string;
|
|
@@ -1081,6 +1278,21 @@ export interface RunLedger {
|
|
|
1081
1278
|
}
|
|
1082
1279
|
/** Union of records that may be handed to a {@link RunLedger}. */
|
|
1083
1280
|
export type RunLedgerRecord = RunRecord | AgentEventRecord | ToolCallRecord | UsageRecord;
|
|
1281
|
+
export type RunLedgerDurability = "write_through" | "flush_on_terminal" | "buffered";
|
|
1282
|
+
export interface RunLedgerFlushResult {
|
|
1283
|
+
readonly accepted: number;
|
|
1284
|
+
readonly flushed: number;
|
|
1285
|
+
readonly buffered: number;
|
|
1286
|
+
}
|
|
1287
|
+
/** Optional durability seam implemented by bounded ledger adapters. */
|
|
1288
|
+
export interface FlushableRunLedger extends RunLedger {
|
|
1289
|
+
readonly durability: RunLedgerDurability;
|
|
1290
|
+
flush(): Promise<RunLedgerFlushResult>;
|
|
1291
|
+
status(): RunLedgerFlushResult;
|
|
1292
|
+
dispose(options?: {
|
|
1293
|
+
readonly flush?: boolean;
|
|
1294
|
+
}): Promise<void>;
|
|
1295
|
+
}
|
|
1084
1296
|
/** Immutable human feedback linked to an existing owned run/trace and optional evaluations. */
|
|
1085
1297
|
export interface RunFeedbackRecord extends OwnershipScope {
|
|
1086
1298
|
readonly id: string;
|
|
@@ -1377,6 +1589,7 @@ export interface ResourceLoadContext {
|
|
|
1377
1589
|
readonly signal?: AbortSignal;
|
|
1378
1590
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1379
1591
|
readonly permission?: PermissionPolicy;
|
|
1592
|
+
readonly trust?: TrustPolicy;
|
|
1380
1593
|
}
|
|
1381
1594
|
export interface SettingsProvider {
|
|
1382
1595
|
get<T = unknown>(key: string): Promise<T | undefined> | T | undefined;
|
|
@@ -1420,6 +1633,8 @@ export interface LoopContext {
|
|
|
1420
1633
|
/** Maximum independent tool calls dispatched concurrently per provider turn. Default `1`. */
|
|
1421
1634
|
readonly toolConcurrency: number;
|
|
1422
1635
|
assemble(nextInput: AgentInput, toolResults?: readonly ToolResult[], turn?: number): Promise<ProviderRequest>;
|
|
1636
|
+
/** Charges a complete tool round before any call in it can start. */
|
|
1637
|
+
chargeToolRound?(calls: readonly ToolCallContent[]): void;
|
|
1423
1638
|
generate(request: ProviderRequest): Promise<ProviderTurnResult>;
|
|
1424
1639
|
dispatchToolCall(call: ToolCallContent): Promise<ToolResult>;
|
|
1425
1640
|
isToolCallExclusive?(call: ToolCallContent): boolean;
|
package/dist/contracts.js
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AgentEvent, GuardrailContext, GuardrailRecord, Guardrails, GuardrailStage, GuardrailValue } from "./contracts.js";
|
|
2
|
+
import type { SecretRedactor } from "./redaction.js";
|
|
3
|
+
export declare const MAX_GUARDRAIL_CONCURRENCY = 16;
|
|
4
|
+
export declare class GuardrailError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly record: GuardrailRecord;
|
|
7
|
+
constructor(record: GuardrailRecord);
|
|
8
|
+
}
|
|
9
|
+
export interface RunGuardrailsOptions<S extends GuardrailStage> {
|
|
10
|
+
readonly stage: S;
|
|
11
|
+
readonly guardrails?: Guardrails;
|
|
12
|
+
readonly value: GuardrailValue<S>;
|
|
13
|
+
readonly context: Omit<GuardrailContext<S>, "stage" | "value" | "signal"> & {
|
|
14
|
+
readonly signal?: AbortSignal;
|
|
15
|
+
};
|
|
16
|
+
readonly redactor?: SecretRedactor;
|
|
17
|
+
readonly emit?: (event: AgentEvent) => void | Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export interface GuardrailRunResult {
|
|
20
|
+
readonly records: readonly GuardrailRecord[];
|
|
21
|
+
readonly terminal?: GuardrailRecord;
|
|
22
|
+
}
|
|
23
|
+
/** Evaluate one typed stage. Default is declaration-order sequential; bounded parallel mode still reports declaration order. */
|
|
24
|
+
export declare function runGuardrails<S extends GuardrailStage>(options: RunGuardrailsOptions<S>): Promise<GuardrailRunResult>;
|
|
25
|
+
export declare function assertGuardrailsAllowed(result: GuardrailRunResult): void;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const MAX_GUARDRAIL_CONCURRENCY = 16;
|
|
2
|
+
const MAX_REASON_BYTES = 4 * 1024;
|
|
3
|
+
const MAX_METADATA_BYTES = 16 * 1024;
|
|
4
|
+
export class GuardrailError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
record;
|
|
7
|
+
constructor(record) {
|
|
8
|
+
super(record.action === "interrupt" ? "Guardrail interruption is unavailable" : "Guardrail blocked run");
|
|
9
|
+
this.name = "GuardrailError";
|
|
10
|
+
this.code = record.action === "interrupt"
|
|
11
|
+
? "ERR_PRISM_GUARDRAIL_INTERRUPT_UNAVAILABLE"
|
|
12
|
+
: "ERR_PRISM_GUARDRAIL_BLOCKED";
|
|
13
|
+
this.record = record;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Evaluate one typed stage. Default is declaration-order sequential; bounded parallel mode still reports declaration order. */
|
|
17
|
+
export async function runGuardrails(options) {
|
|
18
|
+
const guards = stageGuards(options.guardrails, options.stage);
|
|
19
|
+
if (guards.length === 0)
|
|
20
|
+
return { records: [] };
|
|
21
|
+
const maxConcurrency = resolveConcurrency(options.guardrails?.maxConcurrency);
|
|
22
|
+
const controller = new AbortController();
|
|
23
|
+
const signal = options.context.signal
|
|
24
|
+
? AbortSignal.any([options.context.signal, controller.signal])
|
|
25
|
+
: controller.signal;
|
|
26
|
+
const records = new Array(guards.length);
|
|
27
|
+
let next = 0;
|
|
28
|
+
let stopped = false;
|
|
29
|
+
const worker = async () => {
|
|
30
|
+
for (;;) {
|
|
31
|
+
if (stopped)
|
|
32
|
+
return;
|
|
33
|
+
const index = next++;
|
|
34
|
+
if (index >= guards.length)
|
|
35
|
+
return;
|
|
36
|
+
const record = await evaluate(guards[index], options, signal);
|
|
37
|
+
// A sibling may have reached a terminal decision while this callback was settling.
|
|
38
|
+
if (stopped)
|
|
39
|
+
return;
|
|
40
|
+
records[index] = record;
|
|
41
|
+
if (record.action !== "allow") {
|
|
42
|
+
stopped = true;
|
|
43
|
+
controller.abort(new GuardrailError(record));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
await Promise.all(Array.from({ length: Math.min(maxConcurrency, guards.length) }, worker));
|
|
48
|
+
const normalized = records.filter((record) => record !== undefined);
|
|
49
|
+
for (const record of normalized) {
|
|
50
|
+
await options.emit?.({
|
|
51
|
+
type: "guardrail_decision",
|
|
52
|
+
sessionId: options.context.sessionId,
|
|
53
|
+
runId: options.context.runId,
|
|
54
|
+
toolCallId: options.context.toolCallId,
|
|
55
|
+
toolName: options.context.toolName,
|
|
56
|
+
record,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return { records: normalized, terminal: normalized.find((record) => record.action !== "allow") };
|
|
60
|
+
}
|
|
61
|
+
export function assertGuardrailsAllowed(result) {
|
|
62
|
+
if (result.terminal)
|
|
63
|
+
throw new GuardrailError(result.terminal);
|
|
64
|
+
}
|
|
65
|
+
function stageGuards(guardrails, stage) {
|
|
66
|
+
if (!guardrails)
|
|
67
|
+
return [];
|
|
68
|
+
switch (stage) {
|
|
69
|
+
case "input": return (guardrails.input ?? []);
|
|
70
|
+
case "output": return (guardrails.output ?? []);
|
|
71
|
+
case "tool_input": return (guardrails.toolInput ?? []);
|
|
72
|
+
case "tool_output": return (guardrails.toolOutput ?? []);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function evaluate(guardrail, options, signal) {
|
|
76
|
+
if (!guardrail || typeof guardrail.name !== "string" || !guardrail.name || guardrail.name.length > 128 || guardrail.stage !== options.stage || typeof guardrail.evaluate !== "function") {
|
|
77
|
+
return record(guardrail?.name ?? "invalid", options.stage, "tripwire", "guardrail_invalid", undefined, options.redactor);
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const decision = await guardrail.evaluate({ ...options.context, stage: options.stage, value: options.value, signal });
|
|
81
|
+
if (!decision || !isAction(decision.action)) {
|
|
82
|
+
return record(guardrail.name, options.stage, "tripwire", "guardrail_invalid_decision", undefined, options.redactor);
|
|
83
|
+
}
|
|
84
|
+
return record(guardrail.name, options.stage, decision.action, decision.reason, decision.metadata, options.redactor);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return record(guardrail.name, options.stage, "tripwire", "guardrail_failed", undefined, options.redactor);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function resolveConcurrency(value) {
|
|
91
|
+
if (value === undefined)
|
|
92
|
+
return 1;
|
|
93
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_GUARDRAIL_CONCURRENCY) {
|
|
94
|
+
throw new Error(`Guardrail maxConcurrency must be a safe integer from 1 to ${MAX_GUARDRAIL_CONCURRENCY}`);
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
function isAction(value) {
|
|
99
|
+
return value === "allow" || value === "block" || value === "tripwire" || value === "interrupt";
|
|
100
|
+
}
|
|
101
|
+
function record(guardrail, stage, action, reason, metadata, redactor) {
|
|
102
|
+
return {
|
|
103
|
+
guardrail: boundText(guardrail, 128) || "invalid",
|
|
104
|
+
stage,
|
|
105
|
+
action,
|
|
106
|
+
reason: typeof reason === "string" ? boundText(redactor?.redact(reason) ?? reason, MAX_REASON_BYTES) : undefined,
|
|
107
|
+
metadata: boundedMetadata(metadata, redactor),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function boundedMetadata(value, redactor) {
|
|
111
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
112
|
+
return undefined;
|
|
113
|
+
try {
|
|
114
|
+
const json = JSON.stringify(redactor?.redact(value) ?? value);
|
|
115
|
+
if (!json || byteLength(json) > MAX_METADATA_BYTES)
|
|
116
|
+
return { truncated: true };
|
|
117
|
+
const parsed = JSON.parse(json);
|
|
118
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
119
|
+
? parsed
|
|
120
|
+
: undefined;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return { invalid: true };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function boundText(value, limit) {
|
|
127
|
+
const bytes = new TextEncoder().encode(value);
|
|
128
|
+
return bytes.length <= limit ? value : new TextDecoder().decode(bytes.subarray(0, limit));
|
|
129
|
+
}
|
|
130
|
+
function byteLength(value) {
|
|
131
|
+
return new TextEncoder().encode(value).length;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=guardrails.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
export type * from "./contracts.js";
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export type { RunLimitCounters, RunLimitName, SecureAgentOptions } from "./contracts.js";
|
|
3
|
+
export { isSessionEntryKind, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SessionAppendConflictError, isSessionAppendConflict, AgentRunError, AgentRunStateError } from "./contracts.js";
|
|
4
|
+
export { createAgent, createAgentSession, resumeAgentRun } from "./agents.js";
|
|
5
|
+
export { createBatchedRunLedger, isFlushableRunLedger, DEFAULT_LEDGER_BATCH_ENTRIES, HARD_LEDGER_BATCH_ENTRIES, DEFAULT_LEDGER_BATCH_BYTES, HARD_LEDGER_BATCH_BYTES, DEFAULT_LEDGER_BATCH_DELAY_MS, HARD_LEDGER_BATCH_DELAY_MS, } from "./run-ledger.js";
|
|
6
|
+
export type { BatchedRunLedgerOptions } from "./run-ledger.js";
|
|
7
|
+
export { createSecureAgent } from "./secure-agent.js";
|
|
4
8
|
export { createMemoryRunFeedbackStore, prepareRunFeedback, requireRunFeedbackOwnership, runFeedbackPageLimit, RunFeedbackError, } from "./feedback.js";
|
|
5
9
|
export type { MemoryRunFeedbackStoreOptions, PrepareRunFeedbackOptions, RunFeedbackLimits, RunFeedbackRun, RunFeedbackRunResolver, } from "./feedback.js";
|
|
6
10
|
export { CHECKPOINT_CONFLICT_CODE, CheckpointConflictError, createMemoryCheckpointStore } from "./checkpoints.js";
|
|
11
|
+
export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, agentFingerprint, loadAgentRunState } from "./agent-run-state.js";
|
|
12
|
+
export type { StoredAgentRunState } from "./agent-run-state.js";
|
|
13
|
+
export { createAgentRunLifecycle } from "./agent-run-lifecycle.js";
|
|
14
|
+
export type { AgentRunLifecycle, AgentRunLifecycleAgent, AgentRunLifecycleOptions, AgentRunLifecycleRequest } from "./agent-run-lifecycle.js";
|
|
7
15
|
export type { MemoryCheckpointStoreOptions } from "./checkpoints.js";
|
|
8
16
|
export { LEASE_CONFLICT_CODE, LeaseConflictError, createMemoryLeaseStore } from "./leases.js";
|
|
9
17
|
export { createEventMultiplexer } from "./event-multiplexer.js";
|
|
@@ -67,9 +75,13 @@ export type { ResolveActiveSkillsOptions, SkillRegistryOptions } from "./skills.
|
|
|
67
75
|
export { resolveInstructionInjectors, runInstructionInjectors } from "./instruction-injection.js";
|
|
68
76
|
export type { ResolveInstructionInjectorsOptions } from "./instruction-injection.js";
|
|
69
77
|
export { createToolRegistry, dispatchToolCall, filterTools, createToolParameterValidator } from "./tools.js";
|
|
78
|
+
export { assertGuardrailsAllowed, GuardrailError, MAX_GUARDRAIL_CONCURRENCY, runGuardrails } from "./guardrails.js";
|
|
79
|
+
export { createRunLimitTracker, DEFAULT_RUN_LIMITS, HARD_MAX_RUN_COST, HARD_RUN_LIMITS, RunLimitError, RunLimitTracker, resolveRunLimits } from "./run-limits.js";
|
|
80
|
+
export type { GuardrailRunResult, RunGuardrailsOptions, } from "./guardrails.js";
|
|
81
|
+
export type { RunLimitTrackerOptions, } from "./run-limits.js";
|
|
70
82
|
export type { DispatchToolCallOptions, ToolArgumentValidationError, ToolArgumentValidationResult, ToolArgumentValidator, ToolFilter, ToolFilterInput, ToolParameterValidatorOptions, ToolRegistryOptions, ToolValidator, } from "./tools.js";
|
|
71
83
|
export type { DuplicateRegistrationOptions, DuplicateRegistrationPolicy } from "./registry-options.js";
|
|
72
84
|
export { dispatchToolCallsInOrder, generateValidateReviseLoop, isAgentLoopOptions, resolveLoop, resolveToolConcurrency, singleShotLoop } from "./agent-loops.js";
|
|
73
85
|
export declare const name = "prism";
|
|
74
|
-
export declare const version = "0.0.
|
|
86
|
+
export declare const version = "0.0.8";
|
|
75
87
|
export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
export { isSessionEntryKind, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SessionAppendConflictError, isSessionAppendConflict, AgentRunError } from "./contracts.js";
|
|
2
|
-
export { createAgent, createAgentSession } from "./agents.js";
|
|
1
|
+
export { isSessionEntryKind, SESSION_APPEND_CONFLICT_CODE, SESSION_ENTRY_KINDS, SESSION_ENTRY_SCHEMA_VERSION, SessionAppendConflictError, isSessionAppendConflict, AgentRunError, AgentRunStateError } from "./contracts.js";
|
|
2
|
+
export { createAgent, createAgentSession, resumeAgentRun } from "./agents.js";
|
|
3
|
+
export { createBatchedRunLedger, isFlushableRunLedger, DEFAULT_LEDGER_BATCH_ENTRIES, HARD_LEDGER_BATCH_ENTRIES, DEFAULT_LEDGER_BATCH_BYTES, HARD_LEDGER_BATCH_BYTES, DEFAULT_LEDGER_BATCH_DELAY_MS, HARD_LEDGER_BATCH_DELAY_MS, } from "./run-ledger.js";
|
|
4
|
+
export { createSecureAgent } from "./secure-agent.js";
|
|
3
5
|
export { createMemoryRunFeedbackStore, prepareRunFeedback, requireRunFeedbackOwnership, runFeedbackPageLimit, RunFeedbackError, } from "./feedback.js";
|
|
4
6
|
export { CHECKPOINT_CONFLICT_CODE, CheckpointConflictError, createMemoryCheckpointStore } from "./checkpoints.js";
|
|
7
|
+
export { AGENT_RUN_STATE_NAMESPACE, AGENT_RUN_STATE_SCHEMA_VERSION, DEFAULT_MAX_AGENT_RUN_STATE_BYTES, HARD_MAX_AGENT_RUN_STATE_BYTES, agentFingerprint, loadAgentRunState } from "./agent-run-state.js";
|
|
8
|
+
export { createAgentRunLifecycle } from "./agent-run-lifecycle.js";
|
|
5
9
|
export { LEASE_CONFLICT_CODE, LeaseConflictError, createMemoryLeaseStore } from "./leases.js";
|
|
6
10
|
export { createEventMultiplexer } from "./event-multiplexer.js";
|
|
7
11
|
export { applyCacheControl, cacheHitRate, cacheSavings, cacheUsageReport, mapCacheRetention, sanitizeCacheKey } from "./cache-helpers.js";
|
|
@@ -37,8 +41,10 @@ export { applyExecutionDecision, assertExecutionAllowed, checkExecution, Executi
|
|
|
37
41
|
export { createSkillRegistry, resolveActiveSkills } from "./skills.js";
|
|
38
42
|
export { resolveInstructionInjectors, runInstructionInjectors } from "./instruction-injection.js";
|
|
39
43
|
export { createToolRegistry, dispatchToolCall, filterTools, createToolParameterValidator } from "./tools.js";
|
|
44
|
+
export { assertGuardrailsAllowed, GuardrailError, MAX_GUARDRAIL_CONCURRENCY, runGuardrails } from "./guardrails.js";
|
|
45
|
+
export { createRunLimitTracker, DEFAULT_RUN_LIMITS, HARD_MAX_RUN_COST, HARD_RUN_LIMITS, RunLimitError, RunLimitTracker, resolveRunLimits } from "./run-limits.js";
|
|
40
46
|
export { dispatchToolCallsInOrder, generateValidateReviseLoop, isAgentLoopOptions, resolveLoop, resolveToolConcurrency, singleShotLoop } from "./agent-loops.js";
|
|
41
47
|
export const name = "prism";
|
|
42
|
-
export const version = "0.0.
|
|
48
|
+
export const version = "0.0.8";
|
|
43
49
|
export const description = "Agent harness for AI providers, agents, sessions, and tools.";
|
|
44
50
|
//# sourceMappingURL=index.js.map
|
package/dist/input.js
CHANGED
|
@@ -189,6 +189,8 @@ async function resourceMessage(uri, context, attachment) {
|
|
|
189
189
|
const text = await loadTextResource(context.resourceLoader, uri, {
|
|
190
190
|
signal: context.signal,
|
|
191
191
|
metadata: context.metadata,
|
|
192
|
+
permission: context.permission,
|
|
193
|
+
trust: context.trust,
|
|
192
194
|
});
|
|
193
195
|
const label = attachment?.name ?? uri;
|
|
194
196
|
return textMessage("user", `Resource ${label}:\n${text}`, attachmentMetadata({ ...attachment, uri }));
|
package/dist/resources.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { parsePrismManifest } from "./manifests.js";
|
|
2
2
|
import { assertJsonObject } from "./config.js";
|
|
3
3
|
import { DEFAULT_MAX_MEDIA_ITEM_BYTES, loadBoundedBinaryResource, } from "./content.js";
|
|
4
|
-
import { assertPermission } from "./security.js";
|
|
4
|
+
import { assertPermission, assertTrusted } from "./security.js";
|
|
5
5
|
export async function loadTextResource(loader, uri, context) {
|
|
6
|
+
await assertTrusted(context?.trust, { kind: "resource", target: uri, capability: "load", metadata: context?.metadata });
|
|
6
7
|
await assertPermission(context?.permission, { kind: "resource", action: "load", target: uri, metadata: context?.metadata });
|
|
7
8
|
const resource = await loader.load(uri, context);
|
|
8
9
|
if (resource.text !== undefined)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FlushableRunLedger, RunLedger, RunLedgerDurability } from "./contracts.js";
|
|
2
|
+
export declare const DEFAULT_LEDGER_BATCH_ENTRIES = 128;
|
|
3
|
+
export declare const HARD_LEDGER_BATCH_ENTRIES = 4096;
|
|
4
|
+
export declare const DEFAULT_LEDGER_BATCH_BYTES: number;
|
|
5
|
+
export declare const HARD_LEDGER_BATCH_BYTES: number;
|
|
6
|
+
export declare const DEFAULT_LEDGER_BATCH_DELAY_MS = 25;
|
|
7
|
+
export declare const HARD_LEDGER_BATCH_DELAY_MS = 60000;
|
|
8
|
+
export interface BatchedRunLedgerOptions {
|
|
9
|
+
readonly maxBatchEntries?: number;
|
|
10
|
+
readonly maxBatchBytes?: number;
|
|
11
|
+
readonly maxBufferedEntries?: number;
|
|
12
|
+
readonly maxBufferedBytes?: number;
|
|
13
|
+
readonly maxDelayMs?: number;
|
|
14
|
+
readonly durability?: RunLedgerDurability;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Wrap any RunLedger with one bounded FIFO. Inputs must already be redacted, as required by RunLedger.
|
|
18
|
+
* `buffered` may lose accepted records on process crash; call `flush()` for acknowledgement.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createBatchedRunLedger(target: RunLedger, options?: BatchedRunLedgerOptions): FlushableRunLedger;
|
|
21
|
+
export declare function isFlushableRunLedger(ledger: RunLedger): ledger is FlushableRunLedger;
|