@arnilo/prism 0.0.3 → 0.0.5
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 +40 -0
- package/README.md +62 -26
- package/dist/agent-loops.d.ts +8 -1
- package/dist/agent-loops.js +57 -11
- package/dist/agents.js +212 -32
- package/dist/checkpoints.d.ts +11 -0
- package/dist/checkpoints.js +144 -0
- package/dist/cli-init.d.ts +41 -0
- package/dist/cli-init.js +390 -0
- package/dist/cli-runner.d.ts +7 -1
- package/dist/cli-runner.js +13 -1
- package/dist/compaction.js +9 -1
- package/dist/content.d.ts +121 -0
- package/dist/content.js +538 -0
- package/dist/contracts.d.ts +236 -11
- package/dist/contracts.js +8 -0
- package/dist/event-multiplexer.d.ts +23 -0
- package/dist/event-multiplexer.js +136 -0
- package/dist/execution-policy.d.ts +28 -0
- package/dist/execution-policy.js +24 -0
- package/dist/feedback.d.ts +48 -0
- package/dist/feedback.js +230 -0
- package/dist/index.d.ts +20 -6
- package/dist/index.js +13 -5
- package/dist/input.js +11 -1
- package/dist/leases.d.ts +8 -0
- package/dist/leases.js +111 -0
- package/dist/node/agent-definitions.js +3 -5
- package/dist/node/config.d.ts +1 -0
- package/dist/node/config.js +5 -3
- package/dist/node/contribution-discovery.js +5 -8
- package/dist/node/session-store-jsonl.js +8 -5
- package/dist/node/settings.js +2 -2
- package/dist/node/trust.js +2 -4
- package/dist/observability.d.ts +3 -0
- package/dist/observability.js +18 -0
- package/dist/providers/media.d.ts +44 -0
- package/dist/providers/media.js +126 -0
- package/dist/providers/openai-compatible.js +18 -119
- package/dist/providers/openai-primitives.d.ts +9 -0
- package/dist/providers/openai-primitives.js +129 -0
- package/dist/providers/transport.d.ts +40 -0
- package/dist/providers/transport.js +221 -0
- package/dist/redaction.js +40 -13
- package/dist/resources.d.ts +5 -0
- package/dist/resources.js +4 -0
- package/dist/structured-output.d.ts +11 -0
- package/dist/structured-output.js +59 -0
- package/dist/testing/feedback.d.ts +6 -0
- package/dist/testing/feedback.js +37 -0
- package/dist/testing/persistence-schema.d.ts +102 -0
- package/dist/testing/persistence-schema.js +487 -0
- package/dist/testing/provider-conformance.js +10 -1
- package/dist/testing/run-ledger-conformance.d.ts +33 -0
- package/dist/testing/run-ledger-conformance.js +178 -0
- package/dist/testing/session-store-conformance.d.ts +16 -0
- package/dist/testing/session-store-conformance.js +73 -0
- package/dist/tools.d.ts +17 -0
- package/dist/tools.js +29 -2
- package/docs/a2a.md +73 -0
- package/docs/agent-events.md +17 -10
- package/docs/agent-loops.md +11 -5
- package/docs/agent-session-runtime.md +15 -16
- package/docs/cli-rpc.md +36 -5
- package/docs/coding-agent-tools.md +43 -9
- package/docs/coding-security.md +88 -0
- package/docs/compaction-observational-memory.md +2 -0
- package/docs/context-and-skills.md +1 -0
- package/docs/credential-storage.md +177 -0
- package/docs/credentials-and-redaction.md +4 -3
- package/docs/database-persistence.md +52 -7
- package/docs/evaluations.md +122 -0
- package/docs/extensions.md +2 -2
- package/docs/host-security.md +33 -2
- package/docs/index.md +46 -18
- package/docs/input-and-prompt-assembly.md +6 -5
- package/docs/mcp-tools.md +184 -0
- package/docs/middleware-hooks.md +2 -0
- package/docs/migration.md +51 -28
- package/docs/model-registry.md +5 -3
- package/docs/multimodal-content.md +156 -0
- package/docs/observability.md +171 -0
- package/docs/performance.md +249 -1
- package/docs/persistence-credentials-multimodality-primitives.md +303 -0
- package/docs/postgres-persistence.md +143 -0
- package/docs/provider-conformance.md +18 -0
- package/docs/provider-layer.md +1 -1
- package/docs/provider-packages.md +2 -0
- package/docs/provider-primitives.md +281 -0
- package/docs/providers/ai-sdk.md +113 -0
- package/docs/providers/kimi.md +1 -0
- package/docs/providers/neuralwatt.md +1 -0
- package/docs/providers/openai-compatible.md +2 -1
- package/docs/providers/openai.md +8 -1
- package/docs/providers/opencode-go.md +1 -0
- package/docs/providers/openrouter.md +1 -0
- package/docs/providers/zai.md +1 -0
- package/docs/public-contracts.md +13 -5
- package/docs/rag.md +113 -0
- package/docs/release-and-install.md +237 -30
- package/docs/resource-loading.md +14 -4
- package/docs/review-coverage-2026-07-14.md +260 -0
- package/docs/review-coverage-2026-07-15.md +193 -0
- package/docs/run-ledger-conformance.md +96 -0
- package/docs/runs-and-usage.md +43 -4
- package/docs/server.md +139 -0
- package/docs/session-store-conformance.md +16 -0
- package/docs/session-stores-and-branching.md +1 -0
- package/docs/settings-auth-trust-security.md +6 -5
- package/docs/sqlite-persistence.md +123 -0
- package/docs/structured-output.md +9 -0
- package/docs/supervisors.md +71 -0
- package/docs/tool-conformance.md +1 -0
- package/docs/tool-execution-primitives.md +374 -0
- package/docs/tools.md +39 -1
- package/docs/workflow-orchestration-primitives.md +581 -0
- package/docs/workflow-tui-primitives.md +5 -0
- package/docs/workflows.md +293 -0
- package/docs/working-and-semantic-memory.md +169 -0
- package/package.json +43 -5
- package/templates/init/README.md.tmpl +28 -0
- package/templates/init/env.example.tmpl +1 -0
- package/templates/init/gitignore.tmpl +11 -0
- package/templates/init/optional/evals-example.ts.tmpl +17 -0
- package/templates/init/optional/workflows-example.ts.tmpl +27 -0
- package/templates/init/package.json.tmpl +22 -0
- package/templates/init/providers.json +76 -0
- package/templates/init/src/agent.ts.tmpl +10 -0
- package/templates/init/src/index.ts.tmpl +12 -0
- package/templates/init/src/tests/agent.test.ts.tmpl +24 -0
- package/templates/init/tsconfig.json.tmpl +15 -0
package/dist/contracts.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { SecretRedactor } from "./redaction.js";
|
|
|
5
5
|
import type { PermissionPolicy } from "./security.js";
|
|
6
6
|
import type { ManifestContributionDeclaration } from "./manifests.js";
|
|
7
7
|
import type { ToolValidator } from "./tools.js";
|
|
8
|
+
import type { AudioContent, DocumentContent, FileContent } from "./content.js";
|
|
8
9
|
export type JsonPrimitive = string | number | boolean | null;
|
|
9
10
|
export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
10
11
|
export interface JsonObject {
|
|
@@ -16,7 +17,8 @@ export interface ErrorInfo {
|
|
|
16
17
|
readonly code?: string | number;
|
|
17
18
|
readonly cause?: unknown;
|
|
18
19
|
}
|
|
19
|
-
export type
|
|
20
|
+
export type { AudioContent, DocumentContent, FileContent } from "./content.js";
|
|
21
|
+
export type ContentBlock = TextContent | ImageContent | AudioContent | FileContent | DocumentContent | ThinkingContent | ToolCallDeltaContent | ToolCallContent | ToolResultContent;
|
|
20
22
|
export interface TextContent {
|
|
21
23
|
readonly type: "text";
|
|
22
24
|
readonly text: string;
|
|
@@ -26,6 +28,9 @@ export interface ImageContent {
|
|
|
26
28
|
readonly mimeType?: string;
|
|
27
29
|
readonly data?: string;
|
|
28
30
|
readonly url?: string;
|
|
31
|
+
readonly resourceUri?: string;
|
|
32
|
+
readonly name?: string;
|
|
33
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
29
34
|
}
|
|
30
35
|
export interface ThinkingContent {
|
|
31
36
|
readonly type: "thinking";
|
|
@@ -71,11 +76,14 @@ export interface ModelConfig {
|
|
|
71
76
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
72
77
|
}
|
|
73
78
|
export interface ModelCapabilities {
|
|
79
|
+
/** Known values include `text`, `image`, `audio`, `file`, and `document`. */
|
|
74
80
|
readonly input?: readonly string[];
|
|
75
81
|
readonly output?: readonly string[];
|
|
76
82
|
readonly reasoning?: boolean;
|
|
77
83
|
readonly tools?: boolean;
|
|
78
84
|
readonly streaming?: boolean;
|
|
85
|
+
/** Native JSON-schema structured output support for this model. */
|
|
86
|
+
readonly structuredOutput?: boolean | "json_schema";
|
|
79
87
|
}
|
|
80
88
|
export interface ModelLimits {
|
|
81
89
|
readonly contextWindow?: number;
|
|
@@ -121,6 +129,11 @@ export interface PromptCacheHints {
|
|
|
121
129
|
readonly retention?: CacheRetention;
|
|
122
130
|
readonly breakpoints?: readonly PromptCacheBreakpoint[];
|
|
123
131
|
}
|
|
132
|
+
export interface StructuredOutputOptions {
|
|
133
|
+
readonly name: string;
|
|
134
|
+
readonly schema: JsonObject;
|
|
135
|
+
readonly strict?: boolean;
|
|
136
|
+
}
|
|
124
137
|
export interface ProviderRequestOptions {
|
|
125
138
|
readonly sessionId?: string;
|
|
126
139
|
readonly cacheRetention?: CacheRetention;
|
|
@@ -135,6 +148,8 @@ export interface ProviderRequestOptions {
|
|
|
135
148
|
readonly maxRetryDelayMs?: number;
|
|
136
149
|
readonly compat?: JsonObject;
|
|
137
150
|
readonly extra?: JsonObject;
|
|
151
|
+
/** Provider-neutral JSON-schema structured output request. Requires model `capabilities.structuredOutput`. */
|
|
152
|
+
readonly structuredOutput?: StructuredOutputOptions;
|
|
138
153
|
}
|
|
139
154
|
export interface ProviderRequest {
|
|
140
155
|
readonly model: ModelConfig;
|
|
@@ -241,13 +256,7 @@ export interface AgentConfig {
|
|
|
241
256
|
readonly promptBuilder?: PromptBuilder;
|
|
242
257
|
readonly middleware?: MiddlewareRegistry;
|
|
243
258
|
readonly resourceLoader?: ResourceLoader;
|
|
244
|
-
/** Host-owned metadata only: createAgent/session.run do not load or run these extensions. */
|
|
245
|
-
readonly extensions?: readonly Extension[];
|
|
246
259
|
readonly store?: SessionStore;
|
|
247
|
-
/** Host-owned metadata only: createAgent/session.run do not read settings. */
|
|
248
|
-
readonly settings?: SettingsProvider;
|
|
249
|
-
/** Host-owned metadata only: createAgent/session.run do not resolve credentials. Pass resolvers to provider edges explicitly. */
|
|
250
|
-
readonly credentials?: CredentialResolver;
|
|
251
260
|
readonly permission?: PermissionPolicy;
|
|
252
261
|
readonly providerOptions?: ProviderRequestOptions;
|
|
253
262
|
readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
|
|
@@ -289,13 +298,42 @@ export interface SubscribeOptions {
|
|
|
289
298
|
/** What to do when `maxQueuedEvents` is reached. Defaults to `close`. */
|
|
290
299
|
readonly overflow?: SubscriberOverflowPolicy;
|
|
291
300
|
}
|
|
301
|
+
export type AgentRunStatus = "succeeded" | "failed" | "aborted";
|
|
302
|
+
/** Terminal result of `session.run()` / `session.prompt()`. Failed and aborted runs throw {@link AgentRunError} with this shape attached. */
|
|
303
|
+
export interface AgentRunResult {
|
|
304
|
+
readonly sessionId: string;
|
|
305
|
+
readonly runId: string;
|
|
306
|
+
readonly status: AgentRunStatus;
|
|
307
|
+
/** Branch leaf after the run settles. */
|
|
308
|
+
readonly leafId?: string;
|
|
309
|
+
/** Concatenated text blocks from the final assistant message, or `""` when none. */
|
|
310
|
+
readonly text: string;
|
|
311
|
+
/** Content blocks from the final assistant message, or `[]` when none. */
|
|
312
|
+
readonly content: readonly ContentBlock[];
|
|
313
|
+
/** Final assistant message when the run produced one. */
|
|
314
|
+
readonly message?: Message;
|
|
315
|
+
/** Aggregate usage across provider turns (`run_total` scope). */
|
|
316
|
+
readonly usage?: Usage;
|
|
317
|
+
/** Present when `status` is `"failed"` or when a failed attempt still produced partial output. */
|
|
318
|
+
readonly error?: ErrorInfo;
|
|
319
|
+
/** String form of the abort reason when `status` is `"aborted"`. */
|
|
320
|
+
readonly abortReason?: string;
|
|
321
|
+
}
|
|
322
|
+
export declare class AgentRunError extends Error {
|
|
323
|
+
readonly result: AgentRunResult;
|
|
324
|
+
constructor(result: AgentRunResult, options?: {
|
|
325
|
+
readonly cause?: unknown;
|
|
326
|
+
});
|
|
327
|
+
}
|
|
292
328
|
export interface AgentSession {
|
|
293
329
|
readonly id: string;
|
|
294
330
|
/** Current branch leaf entry id; advances on every append/run and is re-pointed by `checkout`.
|
|
295
331
|
* Undefined until the first entry lands (a fresh session with no history). */
|
|
296
332
|
readonly leafId: string | undefined;
|
|
297
|
-
run(input: string | Message | readonly Message[], options?: RunOptions): Promise<
|
|
298
|
-
prompt(input: string, options?: RunOptions): Promise<
|
|
333
|
+
run(input: string | Message | readonly Message[], options?: RunOptions): Promise<AgentRunResult>;
|
|
334
|
+
prompt(input: string, options?: RunOptions): Promise<AgentRunResult>;
|
|
335
|
+
/** Subscribe first, then start exactly one run and yield only that run's events until it terminates. */
|
|
336
|
+
stream(input: string | Message | readonly Message[], options?: RunOptions & SubscribeOptions): AsyncIterable<AgentEvent>;
|
|
299
337
|
compact(options?: CompactionOptions): Promise<CompactionResult>;
|
|
300
338
|
subscribe(options?: SubscribeOptions): AsyncIterable<AgentEvent>;
|
|
301
339
|
abort(reason?: unknown): void;
|
|
@@ -304,6 +342,20 @@ export interface AgentSession {
|
|
|
304
342
|
fork(options?: AgentSessionForkOptions): AgentSession;
|
|
305
343
|
clone(options?: AgentSessionCloneOptions): Promise<AgentSession>;
|
|
306
344
|
}
|
|
345
|
+
export interface ProviderTurnMetadata {
|
|
346
|
+
readonly providerId: string;
|
|
347
|
+
readonly model: ModelConfig;
|
|
348
|
+
readonly requestId?: string;
|
|
349
|
+
readonly latencyMs?: number;
|
|
350
|
+
readonly attempt?: number;
|
|
351
|
+
readonly httpStatus?: number;
|
|
352
|
+
readonly rateLimitRemaining?: number;
|
|
353
|
+
readonly rateLimitResetMs?: number;
|
|
354
|
+
}
|
|
355
|
+
export interface ToolExecutionMetadata {
|
|
356
|
+
readonly durationMs: number;
|
|
357
|
+
readonly status: ToolCallStatus;
|
|
358
|
+
}
|
|
307
359
|
export type AgentEvent = {
|
|
308
360
|
readonly type: "agent_started";
|
|
309
361
|
readonly sessionId: string;
|
|
@@ -323,6 +375,20 @@ export type AgentEvent = {
|
|
|
323
375
|
readonly sessionId: string;
|
|
324
376
|
readonly runId: string;
|
|
325
377
|
readonly turn: number;
|
|
378
|
+
} | {
|
|
379
|
+
readonly type: "provider_turn_started";
|
|
380
|
+
readonly sessionId: string;
|
|
381
|
+
readonly runId: string;
|
|
382
|
+
readonly turn: number;
|
|
383
|
+
readonly metadata: ProviderTurnMetadata;
|
|
384
|
+
} | {
|
|
385
|
+
readonly type: "provider_turn_finished";
|
|
386
|
+
readonly sessionId: string;
|
|
387
|
+
readonly runId: string;
|
|
388
|
+
readonly turn: number;
|
|
389
|
+
readonly metadata: ProviderTurnMetadata;
|
|
390
|
+
readonly usage?: Usage;
|
|
391
|
+
readonly error?: ErrorInfo;
|
|
326
392
|
} | {
|
|
327
393
|
readonly type: "message_started";
|
|
328
394
|
readonly sessionId: string;
|
|
@@ -356,12 +422,14 @@ export type AgentEvent = {
|
|
|
356
422
|
readonly sessionId: string;
|
|
357
423
|
readonly runId: string;
|
|
358
424
|
readonly result: ToolResult;
|
|
425
|
+
readonly metadata: ToolExecutionMetadata;
|
|
359
426
|
} | {
|
|
360
427
|
readonly type: "tool_execution_error";
|
|
361
428
|
readonly sessionId: string;
|
|
362
429
|
readonly runId: string;
|
|
363
430
|
readonly call: ToolCallContent;
|
|
364
431
|
readonly error: ErrorInfo;
|
|
432
|
+
readonly metadata: ToolExecutionMetadata;
|
|
365
433
|
} | {
|
|
366
434
|
readonly type: "tool_execution_blocked";
|
|
367
435
|
readonly sessionId: string;
|
|
@@ -370,6 +438,7 @@ export type AgentEvent = {
|
|
|
370
438
|
readonly name: string;
|
|
371
439
|
readonly reason: string;
|
|
372
440
|
readonly error: ErrorInfo;
|
|
441
|
+
readonly metadata: ToolExecutionMetadata;
|
|
373
442
|
} | {
|
|
374
443
|
readonly type: "queue_updated";
|
|
375
444
|
readonly sessionId: string;
|
|
@@ -442,6 +511,8 @@ export interface ToolDefinition {
|
|
|
442
511
|
readonly name: string;
|
|
443
512
|
readonly description?: string;
|
|
444
513
|
readonly parameters?: JsonObject;
|
|
514
|
+
/** Force any provider turn containing this tool to dispatch sequentially. */
|
|
515
|
+
readonly exclusive?: boolean;
|
|
445
516
|
execute(args: JsonObject, context: ToolExecutionContext): Promise<ToolResult> | ToolResult;
|
|
446
517
|
}
|
|
447
518
|
export interface ToolRegistry {
|
|
@@ -647,6 +718,8 @@ export interface OAuthLoginCallbacks {
|
|
|
647
718
|
readonly message: string;
|
|
648
719
|
readonly choices: readonly string[];
|
|
649
720
|
}): string | undefined | Promise<string | undefined>;
|
|
721
|
+
/** Aborts OAuth login flows and device-code polling when signaled. */
|
|
722
|
+
readonly signal?: AbortSignal;
|
|
650
723
|
}
|
|
651
724
|
export interface OAuthCredentials {
|
|
652
725
|
readonly access?: string;
|
|
@@ -832,6 +905,83 @@ export interface PersistenceQuery {
|
|
|
832
905
|
readonly limit?: number;
|
|
833
906
|
readonly order?: "asc" | "desc";
|
|
834
907
|
}
|
|
908
|
+
/** Generic versioned checkpoint key. Namespaces prevent consumer collisions. */
|
|
909
|
+
export interface CheckpointKey extends OwnershipScope {
|
|
910
|
+
readonly namespace: string;
|
|
911
|
+
readonly key: string;
|
|
912
|
+
readonly signal?: AbortSignal;
|
|
913
|
+
}
|
|
914
|
+
/** Input for an optimistic checkpoint write. Versions must strictly increase. */
|
|
915
|
+
export interface CheckpointSaveInput extends CheckpointKey {
|
|
916
|
+
readonly version: number;
|
|
917
|
+
/** Exact current version required before update; use 0 for create-only. */
|
|
918
|
+
readonly expectedVersion?: number;
|
|
919
|
+
/** Monotonic lease fence. Lower or absent worker fences cannot replace a fenced record. */
|
|
920
|
+
readonly fencingToken?: number;
|
|
921
|
+
readonly value: unknown;
|
|
922
|
+
readonly category?: string;
|
|
923
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
924
|
+
}
|
|
925
|
+
/** Durable generic checkpoint record. */
|
|
926
|
+
export interface CheckpointRecord extends OwnershipScope {
|
|
927
|
+
readonly namespace: string;
|
|
928
|
+
readonly key: string;
|
|
929
|
+
readonly version: number;
|
|
930
|
+
readonly fencingToken?: number;
|
|
931
|
+
readonly value: unknown;
|
|
932
|
+
readonly category?: string;
|
|
933
|
+
readonly createdAt: string;
|
|
934
|
+
readonly updatedAt: string;
|
|
935
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
936
|
+
}
|
|
937
|
+
/** Bounded checkpoint query. */
|
|
938
|
+
export interface CheckpointQuery extends PersistenceQuery, OwnershipScope {
|
|
939
|
+
readonly namespace?: string;
|
|
940
|
+
readonly keyPrefix?: string;
|
|
941
|
+
readonly category?: string | readonly string[];
|
|
942
|
+
readonly signal?: AbortSignal;
|
|
943
|
+
}
|
|
944
|
+
/** Generic versioned checkpoint capability for persistence adapters. */
|
|
945
|
+
export interface CheckpointStore {
|
|
946
|
+
saveCheckpoint(input: CheckpointSaveInput): Promise<CheckpointRecord>;
|
|
947
|
+
loadCheckpoint(input: CheckpointKey): Promise<CheckpointRecord | null>;
|
|
948
|
+
listCheckpoints(query?: CheckpointQuery): Promise<PersistencePage<CheckpointRecord>>;
|
|
949
|
+
deleteCheckpoint(input: CheckpointKey): Promise<boolean>;
|
|
950
|
+
}
|
|
951
|
+
/** Generic lease key. Ownership fields are part of the trust boundary. */
|
|
952
|
+
export interface LeaseKey extends OwnershipScope {
|
|
953
|
+
readonly namespace: string;
|
|
954
|
+
readonly key: string;
|
|
955
|
+
readonly signal?: AbortSignal;
|
|
956
|
+
}
|
|
957
|
+
export interface LeaseAcquireInput extends LeaseKey {
|
|
958
|
+
readonly ownerId: string;
|
|
959
|
+
readonly ttlMs: number;
|
|
960
|
+
}
|
|
961
|
+
export interface LeaseClaimInput extends LeaseKey {
|
|
962
|
+
readonly ownerId: string;
|
|
963
|
+
readonly token: string;
|
|
964
|
+
readonly ttlMs?: number;
|
|
965
|
+
}
|
|
966
|
+
export interface LeaseRecord extends OwnershipScope {
|
|
967
|
+
readonly namespace: string;
|
|
968
|
+
readonly key: string;
|
|
969
|
+
readonly ownerId: string;
|
|
970
|
+
readonly token: string;
|
|
971
|
+
readonly fencingToken: number;
|
|
972
|
+
readonly acquiredAt: string;
|
|
973
|
+
readonly expiresAt: string;
|
|
974
|
+
readonly updatedAt: string;
|
|
975
|
+
}
|
|
976
|
+
/** Atomic distributed lease capability. Expired rows retain fencing counters. */
|
|
977
|
+
export interface LeaseStore {
|
|
978
|
+
tryAcquireLease(input: LeaseAcquireInput): Promise<LeaseRecord | null>;
|
|
979
|
+
renewLease(input: LeaseClaimInput & {
|
|
980
|
+
readonly ttlMs: number;
|
|
981
|
+
}): Promise<LeaseRecord | null>;
|
|
982
|
+
releaseLease(input: LeaseClaimInput): Promise<boolean>;
|
|
983
|
+
getLease(input: LeaseKey): Promise<LeaseRecord | null>;
|
|
984
|
+
}
|
|
835
985
|
/** Stored session record. Does not include provider objects or credentials. */
|
|
836
986
|
export interface SessionRecord extends OwnershipScope {
|
|
837
987
|
readonly id: string;
|
|
@@ -908,12 +1058,16 @@ export interface ToolCallRecord extends OwnershipScope {
|
|
|
908
1058
|
readonly redacted: boolean;
|
|
909
1059
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
910
1060
|
}
|
|
911
|
-
|
|
1061
|
+
export type UsageScope = "provider_turn" | "run_total";
|
|
1062
|
+
/** Stored usage row. `scope` prevents provider-turn and aggregate totals from being summed together. */
|
|
912
1063
|
export interface UsageRecord extends OwnershipScope {
|
|
913
1064
|
readonly id: string;
|
|
914
1065
|
readonly sessionId: string;
|
|
915
1066
|
readonly runId?: string;
|
|
916
1067
|
readonly entryId?: string;
|
|
1068
|
+
readonly scope: UsageScope;
|
|
1069
|
+
readonly turn?: number;
|
|
1070
|
+
readonly attempt?: number;
|
|
917
1071
|
readonly usage: Usage;
|
|
918
1072
|
readonly recordedAt: string;
|
|
919
1073
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
@@ -927,6 +1081,59 @@ export interface RunLedger {
|
|
|
927
1081
|
}
|
|
928
1082
|
/** Union of records that may be handed to a {@link RunLedger}. */
|
|
929
1083
|
export type RunLedgerRecord = RunRecord | AgentEventRecord | ToolCallRecord | UsageRecord;
|
|
1084
|
+
/** Immutable human feedback linked to an existing owned run/trace and optional evaluations. */
|
|
1085
|
+
export interface RunFeedbackRecord extends OwnershipScope {
|
|
1086
|
+
readonly id: string;
|
|
1087
|
+
readonly runId: string;
|
|
1088
|
+
readonly sessionId: string;
|
|
1089
|
+
readonly traceId?: string;
|
|
1090
|
+
readonly rating?: number;
|
|
1091
|
+
readonly comment?: string;
|
|
1092
|
+
readonly tags: readonly string[];
|
|
1093
|
+
readonly scorerIds: readonly string[];
|
|
1094
|
+
readonly evaluationIds: readonly string[];
|
|
1095
|
+
readonly createdAt: string;
|
|
1096
|
+
readonly createdBy?: string;
|
|
1097
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1098
|
+
}
|
|
1099
|
+
export interface AppendRunFeedbackInput extends OwnershipScope {
|
|
1100
|
+
readonly id: string;
|
|
1101
|
+
readonly runId: string;
|
|
1102
|
+
readonly sessionId?: string;
|
|
1103
|
+
readonly traceId?: string;
|
|
1104
|
+
readonly rating?: number;
|
|
1105
|
+
readonly comment?: string;
|
|
1106
|
+
readonly tags?: readonly string[];
|
|
1107
|
+
readonly scorerIds?: readonly string[];
|
|
1108
|
+
readonly evaluationIds?: readonly string[];
|
|
1109
|
+
readonly createdAt?: string;
|
|
1110
|
+
readonly createdBy?: string;
|
|
1111
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1112
|
+
readonly signal?: AbortSignal;
|
|
1113
|
+
}
|
|
1114
|
+
/** Cursor-paginated, ownership-scoped feedback query. */
|
|
1115
|
+
export interface RunFeedbackQuery extends PersistenceQuery, OwnershipScope {
|
|
1116
|
+
readonly runId?: string;
|
|
1117
|
+
readonly sessionId?: string;
|
|
1118
|
+
readonly traceId?: string;
|
|
1119
|
+
readonly rating?: number;
|
|
1120
|
+
readonly scorerId?: string;
|
|
1121
|
+
readonly evaluationId?: string;
|
|
1122
|
+
readonly tag?: string;
|
|
1123
|
+
readonly fromCreatedAt?: string;
|
|
1124
|
+
readonly toCreatedAt?: string;
|
|
1125
|
+
readonly signal?: AbortSignal;
|
|
1126
|
+
}
|
|
1127
|
+
export interface DeleteRunFeedbackInput extends OwnershipScope {
|
|
1128
|
+
readonly id: string;
|
|
1129
|
+
readonly signal?: AbortSignal;
|
|
1130
|
+
}
|
|
1131
|
+
/** Feedback storage seam. Records are append-only; correction uses a new record and deletion is explicit. */
|
|
1132
|
+
export interface RunFeedbackStore {
|
|
1133
|
+
append(input: AppendRunFeedbackInput): Promise<RunFeedbackRecord>;
|
|
1134
|
+
query(query: RunFeedbackQuery): Promise<PersistencePage<RunFeedbackRecord>>;
|
|
1135
|
+
delete(input: DeleteRunFeedbackInput): Promise<boolean>;
|
|
1136
|
+
}
|
|
930
1137
|
/** Stored agent definition version. Does not include provider credentials/resolvers/provider instances. */
|
|
931
1138
|
export interface AgentDefinitionRecord extends OwnershipScope {
|
|
932
1139
|
readonly id: string;
|
|
@@ -1031,6 +1238,9 @@ export interface UsageQuery extends PersistenceQuery, OwnershipScope {
|
|
|
1031
1238
|
readonly sessionId?: string;
|
|
1032
1239
|
readonly runId?: string;
|
|
1033
1240
|
readonly entryId?: string;
|
|
1241
|
+
readonly scope?: UsageScope;
|
|
1242
|
+
readonly turn?: number;
|
|
1243
|
+
readonly attempt?: number;
|
|
1034
1244
|
readonly fromRecordedAt?: string;
|
|
1035
1245
|
readonly toRecordedAt?: string;
|
|
1036
1246
|
}
|
|
@@ -1058,11 +1268,17 @@ export interface MigrationQuery extends PersistenceQuery {
|
|
|
1058
1268
|
* Production database-neutral persistence store contract.
|
|
1059
1269
|
* Hosts implement this interface to provide durable, paginated storage
|
|
1060
1270
|
* for sessions, entries, runs, events, tool calls, usage, agent definitions,
|
|
1061
|
-
* and migrations. No SQL client, ORM, host file storage, or network dependency is
|
|
1271
|
+
* and migrations, with optional generic checkpoint and atomic lease capabilities. No SQL client, ORM, host file storage, or network dependency is
|
|
1062
1272
|
* required by the contract.
|
|
1063
1273
|
*/
|
|
1064
1274
|
export interface ProductionPersistenceStore {
|
|
1065
1275
|
readonly name?: string;
|
|
1276
|
+
/** Optional generic write capability for resumable consumers such as workflows. */
|
|
1277
|
+
readonly checkpoints?: CheckpointStore;
|
|
1278
|
+
/** Optional atomic distributed lease capability for coordinators and workers. */
|
|
1279
|
+
readonly leases?: LeaseStore;
|
|
1280
|
+
/** Optional immutable run/trace feedback storage capability. */
|
|
1281
|
+
readonly feedback?: RunFeedbackStore;
|
|
1066
1282
|
querySessions(query: SessionQuery): Promise<PersistencePage<SessionRecord>>;
|
|
1067
1283
|
queryBranches(query: BranchQuery): Promise<PersistencePage<BranchRecord>>;
|
|
1068
1284
|
queryEntries(query: SessionEntryQuery): Promise<PersistencePage<SessionEntry>>;
|
|
@@ -1201,9 +1417,12 @@ export interface LoopContext {
|
|
|
1201
1417
|
readonly input: AgentInput;
|
|
1202
1418
|
readonly inputMessages: readonly Message[];
|
|
1203
1419
|
readonly maxToolRounds: number;
|
|
1420
|
+
/** Maximum independent tool calls dispatched concurrently per provider turn. Default `1`. */
|
|
1421
|
+
readonly toolConcurrency: number;
|
|
1204
1422
|
assemble(nextInput: AgentInput, toolResults?: readonly ToolResult[], turn?: number): Promise<ProviderRequest>;
|
|
1205
1423
|
generate(request: ProviderRequest): Promise<ProviderTurnResult>;
|
|
1206
1424
|
dispatchToolCall(call: ToolCallContent): Promise<ToolResult>;
|
|
1425
|
+
isToolCallExclusive?(call: ToolCallContent): boolean;
|
|
1207
1426
|
appendMessage(message: Message): Promise<void>;
|
|
1208
1427
|
emit(event: AgentEvent): void;
|
|
1209
1428
|
}
|
|
@@ -1213,12 +1432,18 @@ export interface AgentLoopStrategy {
|
|
|
1213
1432
|
}
|
|
1214
1433
|
export type AgentLoopOptions = {
|
|
1215
1434
|
readonly strategy: "single-shot";
|
|
1435
|
+
/** Independent tool calls per turn run concurrently up to this limit. Default `1` (sequential). */
|
|
1436
|
+
readonly toolConcurrency?: number;
|
|
1216
1437
|
} | {
|
|
1217
1438
|
readonly strategy: "generate-validate-revise";
|
|
1218
1439
|
readonly validator: ArtifactValidator<unknown>;
|
|
1219
1440
|
readonly parser?: ArtifactParser<unknown>;
|
|
1220
1441
|
readonly repairer?: ArtifactRepairer<unknown>;
|
|
1221
1442
|
readonly maxRevisions?: number;
|
|
1443
|
+
/** Native provider JSON-schema output. Ignored when `structuredOutputMode` is `artifact-loop`. */
|
|
1444
|
+
readonly structuredOutput?: StructuredOutputOptions;
|
|
1445
|
+
/** `native` maps schema to capable providers; `artifact-loop` keeps repair turns only. */
|
|
1446
|
+
readonly structuredOutputMode?: "native" | "artifact-loop";
|
|
1222
1447
|
};
|
|
1223
1448
|
export interface ArtifactValidation {
|
|
1224
1449
|
readonly ok: boolean;
|
package/dist/contracts.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export class AgentRunError extends Error {
|
|
2
|
+
result;
|
|
3
|
+
constructor(result, options) {
|
|
4
|
+
super(result.error?.message ?? (result.status === "aborted" ? "Agent run aborted" : "Agent run failed"), options);
|
|
5
|
+
this.name = "AgentRunError";
|
|
6
|
+
this.result = result;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
1
9
|
export const SESSION_ENTRY_KINDS = [
|
|
2
10
|
"message",
|
|
3
11
|
"event",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type EventOverflowPolicy = "close" | "drop_oldest" | "drop_newest";
|
|
2
|
+
export interface EventOverflowInfo {
|
|
3
|
+
readonly droppedEvents: number;
|
|
4
|
+
readonly maxQueuedEvents: number;
|
|
5
|
+
readonly policy: EventOverflowPolicy;
|
|
6
|
+
}
|
|
7
|
+
export interface EventMultiplexerOptions<T> {
|
|
8
|
+
readonly maxQueuedEvents?: number;
|
|
9
|
+
readonly overflow?: EventOverflowPolicy;
|
|
10
|
+
readonly overflowEvent?: (info: EventOverflowInfo) => T;
|
|
11
|
+
readonly compare?: (a: T, b: T) => number;
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
export interface EventMultiplexer<T> {
|
|
15
|
+
publish(event: T): void;
|
|
16
|
+
observe<S>(source: AsyncIterable<S>, map: (event: S) => T): () => void;
|
|
17
|
+
subscribe(): AsyncIterable<T>;
|
|
18
|
+
close(): void;
|
|
19
|
+
readonly droppedEvents: number;
|
|
20
|
+
readonly closed: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Bounded single-consumer fan-in for arbitrary async event sources. */
|
|
23
|
+
export declare function createEventMultiplexer<T>(options?: EventMultiplexerOptions<T>): EventMultiplexer<T>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** Bounded single-consumer fan-in for arbitrary async event sources. */
|
|
2
|
+
export function createEventMultiplexer(options = {}) {
|
|
3
|
+
const maxQueuedEvents = Math.max(1, options.maxQueuedEvents ?? 1024);
|
|
4
|
+
const overflow = options.overflow ?? "close";
|
|
5
|
+
const queue = [];
|
|
6
|
+
const stops = new Set();
|
|
7
|
+
let waiter;
|
|
8
|
+
let isClosed = false;
|
|
9
|
+
let droppedEvents = 0;
|
|
10
|
+
let overflowNotified = false;
|
|
11
|
+
const abort = () => close();
|
|
12
|
+
if (options.signal?.aborted)
|
|
13
|
+
isClosed = true;
|
|
14
|
+
else
|
|
15
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
16
|
+
function publish(event) {
|
|
17
|
+
if (isClosed)
|
|
18
|
+
return;
|
|
19
|
+
if (waiter) {
|
|
20
|
+
const resolve = waiter;
|
|
21
|
+
waiter = undefined;
|
|
22
|
+
resolve({ value: event, done: false });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (queue.length < maxQueuedEvents) {
|
|
26
|
+
queue.push(event);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
droppedEvents += 1;
|
|
30
|
+
const notice = !overflowNotified && options.overflowEvent
|
|
31
|
+
? options.overflowEvent({ droppedEvents, maxQueuedEvents, policy: overflow })
|
|
32
|
+
: undefined;
|
|
33
|
+
overflowNotified = true;
|
|
34
|
+
if (overflow === "close") {
|
|
35
|
+
queue.length = 0;
|
|
36
|
+
if (notice !== undefined)
|
|
37
|
+
queue.push(notice);
|
|
38
|
+
options.signal?.removeEventListener("abort", abort);
|
|
39
|
+
finishSources();
|
|
40
|
+
isClosed = true;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (overflow === "drop_newest") {
|
|
44
|
+
if (notice !== undefined)
|
|
45
|
+
queue[queue.length - 1] = notice;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
queue.shift();
|
|
49
|
+
if (notice !== undefined) {
|
|
50
|
+
queue.push(notice);
|
|
51
|
+
if (queue.length >= maxQueuedEvents)
|
|
52
|
+
queue.shift();
|
|
53
|
+
}
|
|
54
|
+
queue.push(event);
|
|
55
|
+
}
|
|
56
|
+
function observe(source, map) {
|
|
57
|
+
if (isClosed)
|
|
58
|
+
return () => undefined;
|
|
59
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
60
|
+
let stopped = false;
|
|
61
|
+
const stop = () => {
|
|
62
|
+
if (stopped)
|
|
63
|
+
return;
|
|
64
|
+
stopped = true;
|
|
65
|
+
stops.delete(stop);
|
|
66
|
+
void iterator.return?.();
|
|
67
|
+
};
|
|
68
|
+
stops.add(stop);
|
|
69
|
+
void (async () => {
|
|
70
|
+
try {
|
|
71
|
+
while (!stopped && !isClosed) {
|
|
72
|
+
const next = await iterator.next();
|
|
73
|
+
if (next.done)
|
|
74
|
+
break;
|
|
75
|
+
publish(map(next.value));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Source failure ends that source; owners surface source errors separately.
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
stop();
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
return stop;
|
|
86
|
+
}
|
|
87
|
+
function finishSources() {
|
|
88
|
+
for (const stop of [...stops])
|
|
89
|
+
stop();
|
|
90
|
+
stops.clear();
|
|
91
|
+
}
|
|
92
|
+
function close() {
|
|
93
|
+
if (isClosed)
|
|
94
|
+
return;
|
|
95
|
+
isClosed = true;
|
|
96
|
+
options.signal?.removeEventListener("abort", abort);
|
|
97
|
+
finishSources();
|
|
98
|
+
queue.length = 0;
|
|
99
|
+
if (waiter) {
|
|
100
|
+
const resolve = waiter;
|
|
101
|
+
waiter = undefined;
|
|
102
|
+
resolve({ value: undefined, done: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function* subscribe() {
|
|
106
|
+
while (true) {
|
|
107
|
+
if (queue.length > 0) {
|
|
108
|
+
if (options.compare)
|
|
109
|
+
queue.sort(options.compare);
|
|
110
|
+
yield queue.shift();
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (isClosed)
|
|
114
|
+
return;
|
|
115
|
+
const next = await new Promise((resolve) => {
|
|
116
|
+
waiter = resolve;
|
|
117
|
+
});
|
|
118
|
+
if (next.done)
|
|
119
|
+
return;
|
|
120
|
+
yield next.value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
publish,
|
|
125
|
+
observe,
|
|
126
|
+
subscribe,
|
|
127
|
+
close,
|
|
128
|
+
get droppedEvents() {
|
|
129
|
+
return droppedEvents;
|
|
130
|
+
},
|
|
131
|
+
get closed() {
|
|
132
|
+
return isClosed;
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=event-multiplexer.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ExecutionRisk = "low" | "medium" | "high";
|
|
2
|
+
export interface ExecutionAction {
|
|
3
|
+
readonly kind: "shell" | "read" | "write" | "edit" | string;
|
|
4
|
+
readonly operation: string;
|
|
5
|
+
readonly paths?: readonly string[];
|
|
6
|
+
readonly command?: string;
|
|
7
|
+
readonly risk?: ExecutionRisk;
|
|
8
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
9
|
+
}
|
|
10
|
+
export interface ExecutionDecision {
|
|
11
|
+
readonly allowed: boolean;
|
|
12
|
+
readonly reason?: string;
|
|
13
|
+
readonly modified?: Partial<ExecutionAction>;
|
|
14
|
+
/** When true, tool definitions should expose `exclusive: true` for pre-dispatch serialization. */
|
|
15
|
+
readonly exclusive?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ExecutionPolicy {
|
|
18
|
+
check(action: ExecutionAction): ExecutionDecision | Promise<ExecutionDecision>;
|
|
19
|
+
}
|
|
20
|
+
export declare class ExecutionDeniedError extends Error {
|
|
21
|
+
readonly action: ExecutionAction;
|
|
22
|
+
readonly decision: ExecutionDecision;
|
|
23
|
+
readonly code = "ERR_PRISM_EXECUTION_DENIED";
|
|
24
|
+
constructor(action: ExecutionAction, decision: ExecutionDecision);
|
|
25
|
+
}
|
|
26
|
+
export declare function checkExecution(policy: ExecutionPolicy | undefined, action: ExecutionAction): Promise<ExecutionDecision>;
|
|
27
|
+
export declare function applyExecutionDecision(action: ExecutionAction, decision: ExecutionDecision): ExecutionAction;
|
|
28
|
+
export declare function assertExecutionAllowed(policy: ExecutionPolicy | undefined, action: ExecutionAction): Promise<ExecutionAction>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class ExecutionDeniedError extends Error {
|
|
2
|
+
action;
|
|
3
|
+
decision;
|
|
4
|
+
code = "ERR_PRISM_EXECUTION_DENIED";
|
|
5
|
+
constructor(action, decision) {
|
|
6
|
+
super(decision.reason ?? `Execution denied for ${action.kind}:${action.operation}`);
|
|
7
|
+
this.action = action;
|
|
8
|
+
this.decision = decision;
|
|
9
|
+
this.name = "ExecutionDeniedError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export async function checkExecution(policy, action) {
|
|
13
|
+
return policy ? await policy.check(action) : { allowed: true };
|
|
14
|
+
}
|
|
15
|
+
export function applyExecutionDecision(action, decision) {
|
|
16
|
+
return decision.modified ? { ...action, ...decision.modified } : action;
|
|
17
|
+
}
|
|
18
|
+
export async function assertExecutionAllowed(policy, action) {
|
|
19
|
+
const decision = await checkExecution(policy, action);
|
|
20
|
+
if (!decision.allowed)
|
|
21
|
+
throw new ExecutionDeniedError(action, decision);
|
|
22
|
+
return applyExecutionDecision(action, decision);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=execution-policy.js.map
|