@arnilo/prism 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +4 -2
  2. package/README.md +17 -7
  3. package/dist/agent-definitions.d.ts +12 -0
  4. package/dist/agent-definitions.js +131 -0
  5. package/dist/agent-loops.d.ts +14 -0
  6. package/dist/agent-loops.js +161 -0
  7. package/dist/agents.js +263 -76
  8. package/dist/cache-helpers.d.ts +28 -0
  9. package/dist/cache-helpers.js +73 -0
  10. package/dist/cli-runner.d.ts +38 -2
  11. package/dist/cli-runner.js +167 -5
  12. package/dist/compaction.js +2 -0
  13. package/dist/config.js +47 -12
  14. package/dist/contracts.d.ts +581 -6
  15. package/dist/contracts.js +41 -1
  16. package/dist/contribution-parsing.d.ts +19 -0
  17. package/dist/contribution-parsing.js +124 -0
  18. package/dist/contributions.d.ts +13 -3
  19. package/dist/contributions.js +96 -20
  20. package/dist/extensions.js +3 -0
  21. package/dist/index.d.ts +19 -9
  22. package/dist/index.js +10 -4
  23. package/dist/input.d.ts +7 -1
  24. package/dist/input.js +52 -11
  25. package/dist/instruction-injection.d.ts +28 -0
  26. package/dist/instruction-injection.js +55 -0
  27. package/dist/manifests.d.ts +1 -1
  28. package/dist/manifests.js +3 -3
  29. package/dist/models.d.ts +4 -1
  30. package/dist/models.js +5 -2
  31. package/dist/node/agent-definitions.d.ts +98 -0
  32. package/dist/node/agent-definitions.js +389 -0
  33. package/dist/node/contribution-discovery.d.ts +17 -0
  34. package/dist/node/contribution-discovery.js +163 -0
  35. package/dist/node/instruction-injectors.d.ts +32 -0
  36. package/dist/node/instruction-injectors.js +72 -0
  37. package/dist/node/session-store-jsonl.d.ts +1 -1
  38. package/dist/node/session-store-jsonl.js +42 -4
  39. package/dist/node/system-project-prompts.d.ts +30 -0
  40. package/dist/node/system-project-prompts.js +53 -0
  41. package/dist/provider-events.d.ts +3 -1
  42. package/dist/provider-events.js +34 -0
  43. package/dist/provider-request-policy.js +15 -1
  44. package/dist/providers/openai-compatible.js +1 -1
  45. package/dist/providers.d.ts +6 -2
  46. package/dist/providers.js +15 -1
  47. package/dist/redaction.d.ts +2 -1
  48. package/dist/redaction.js +3 -0
  49. package/dist/registry-options.d.ts +5 -0
  50. package/dist/registry-options.js +5 -0
  51. package/dist/rpc.d.ts +6 -2
  52. package/dist/rpc.js +71 -13
  53. package/dist/session-stores.d.ts +3 -1
  54. package/dist/session-stores.js +67 -6
  55. package/dist/skills.d.ts +4 -1
  56. package/dist/skills.js +3 -1
  57. package/dist/system-prompts.js +6 -2
  58. package/dist/testing/compaction-conformance.d.ts +17 -0
  59. package/dist/testing/compaction-conformance.js +61 -0
  60. package/dist/testing/extension-conformance.d.ts +26 -0
  61. package/dist/testing/extension-conformance.js +55 -0
  62. package/dist/testing/provider-conformance.d.ts +7 -0
  63. package/dist/testing/provider-conformance.js +18 -31
  64. package/dist/testing/session-store-conformance.d.ts +20 -0
  65. package/dist/testing/session-store-conformance.js +92 -0
  66. package/dist/testing/tool-conformance.d.ts +39 -0
  67. package/dist/testing/tool-conformance.js +79 -0
  68. package/dist/tools.d.ts +7 -2
  69. package/dist/tools.js +50 -13
  70. package/docs/agent-definitions.md +251 -0
  71. package/docs/agent-events.md +199 -0
  72. package/docs/agent-loops.md +217 -0
  73. package/docs/agent-session-runtime.md +20 -8
  74. package/docs/cli-rpc.md +39 -4
  75. package/docs/compaction-and-retry.md +2 -2
  76. package/docs/compaction-conformance.md +76 -0
  77. package/docs/compaction-llm.md +6 -3
  78. package/docs/compaction-observational-memory.md +4 -4
  79. package/docs/configuration-and-manifests.md +6 -1
  80. package/docs/context-and-skills.md +79 -6
  81. package/docs/contribution-discovery.md +149 -0
  82. package/docs/contribution-registries.md +9 -6
  83. package/docs/credentials-and-redaction.md +2 -0
  84. package/docs/customization.md +191 -0
  85. package/docs/database-persistence.md +407 -0
  86. package/docs/extension-authoring.md +193 -0
  87. package/docs/extension-conformance.md +80 -0
  88. package/docs/extensions.md +6 -0
  89. package/docs/host-security.md +141 -0
  90. package/docs/index.md +40 -19
  91. package/docs/input-and-prompt-assembly.md +19 -3
  92. package/docs/instruction-injection.md +183 -0
  93. package/docs/migration.md +201 -0
  94. package/docs/model-registry.md +122 -0
  95. package/docs/node-jsonl-session-store.md +5 -4
  96. package/docs/performance.md +127 -0
  97. package/docs/provider-caching.md +206 -0
  98. package/docs/provider-conformance.md +32 -5
  99. package/docs/provider-layer.md +51 -11
  100. package/docs/provider-packages.md +65 -5
  101. package/docs/provider-request-policies.md +113 -0
  102. package/docs/providers/kimi.md +22 -0
  103. package/docs/providers/neuralwatt.md +388 -0
  104. package/docs/providers/openai-compatible.md +1 -0
  105. package/docs/providers/openai.md +21 -0
  106. package/docs/providers/opencode-go.md +31 -3
  107. package/docs/providers/openrouter.md +29 -0
  108. package/docs/providers/zai.md +17 -0
  109. package/docs/public-contracts.md +87 -12
  110. package/docs/release-and-install.md +76 -26
  111. package/docs/runs-and-usage.md +236 -0
  112. package/docs/session-store-conformance.md +78 -0
  113. package/docs/session-stores-and-branching.md +10 -6
  114. package/docs/session-stores.md +126 -0
  115. package/docs/settings-auth-trust-security.md +18 -4
  116. package/docs/structured-output.md +247 -0
  117. package/docs/system-prompts.md +104 -2
  118. package/docs/tool-conformance.md +87 -0
  119. package/docs/tools.md +64 -8
  120. package/package.json +35 -2
@@ -1,7 +1,10 @@
1
+ import type { AgentInput } from "./input.js";
1
2
  import type { ContributionRegistries } from "./contributions.js";
2
3
  import type { Middleware, MiddlewareHookName, MiddlewareRegistry } from "./middleware.js";
3
4
  import type { SecretRedactor } from "./redaction.js";
4
5
  import type { PermissionPolicy } from "./security.js";
6
+ import type { ManifestContributionDeclaration } from "./manifests.js";
7
+ import type { ToolValidator } from "./tools.js";
5
8
  export type JsonPrimitive = string | number | boolean | null;
6
9
  export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
7
10
  export interface JsonObject {
@@ -13,7 +16,7 @@ export interface ErrorInfo {
13
16
  readonly code?: string | number;
14
17
  readonly cause?: unknown;
15
18
  }
16
- export type ContentBlock = TextContent | ImageContent | ThinkingContent | ToolCallContent | ToolResultContent;
19
+ export type ContentBlock = TextContent | ImageContent | ThinkingContent | ToolCallDeltaContent | ToolCallContent | ToolResultContent;
17
20
  export interface TextContent {
18
21
  readonly type: "text";
19
22
  readonly text: string;
@@ -29,6 +32,13 @@ export interface ThinkingContent {
29
32
  readonly text: string;
30
33
  readonly signature?: string;
31
34
  }
35
+ export interface ToolCallDeltaContent {
36
+ readonly type: "tool_call_delta";
37
+ readonly index: number;
38
+ readonly id?: string;
39
+ readonly name?: string;
40
+ readonly argumentsText?: string;
41
+ }
32
42
  export interface ToolCallContent {
33
43
  readonly type: "tool_call";
34
44
  readonly id: string;
@@ -55,6 +65,7 @@ export interface ModelConfig {
55
65
  readonly capabilities?: ModelCapabilities;
56
66
  readonly limits?: ModelLimits;
57
67
  readonly cost?: ModelCost;
68
+ readonly cache?: ModelCacheCapabilities;
58
69
  readonly compat?: JsonObject;
59
70
  readonly parameters?: Readonly<Record<string, unknown>>;
60
71
  readonly metadata?: Readonly<Record<string, unknown>>;
@@ -88,13 +99,39 @@ export interface Usage {
88
99
  readonly currency?: string;
89
100
  }
90
101
  export type CacheRetention = "none" | "short" | "long";
102
+ export type PromptCacheKind = "implicit" | "openai_key" | "cache_control" | "provider_specific" | "none";
103
+ export interface ModelCacheCapabilities {
104
+ readonly kind?: PromptCacheKind;
105
+ readonly maxKeyLength?: number;
106
+ readonly maxBreakpoints?: number;
107
+ readonly minCacheableTokens?: number;
108
+ readonly longRetention?: boolean;
109
+ }
110
+ export type PromptCacheMode = "auto" | "on" | "off";
111
+ export type PromptCacheBreakpointLocation = "system_prompt" | "tools" | "stable_context" | "last_stable_message" | "last_user_message" | "message_id";
112
+ export type PromptCacheBreakpointTtl = "short" | "long";
113
+ export interface PromptCacheBreakpoint {
114
+ readonly location: PromptCacheBreakpointLocation;
115
+ readonly messageId?: string;
116
+ readonly ttl?: PromptCacheBreakpointTtl;
117
+ }
118
+ export interface PromptCacheHints {
119
+ readonly mode?: PromptCacheMode;
120
+ readonly key?: string;
121
+ readonly retention?: CacheRetention;
122
+ readonly breakpoints?: readonly PromptCacheBreakpoint[];
123
+ }
91
124
  export interface ProviderRequestOptions {
92
125
  readonly sessionId?: string;
93
126
  readonly cacheRetention?: CacheRetention;
94
127
  readonly cacheKey?: string;
128
+ readonly cache?: PromptCacheHints;
95
129
  readonly headers?: Readonly<Record<string, string>>;
130
+ /** @deprecated Provider-level timeout is inert in first-party providers; pass an AbortSignal/RunOptions.signal instead. */
96
131
  readonly timeoutMs?: number;
132
+ /** @deprecated Provider-level retry is inert in first-party providers; use AgentConfig.retry/RunOptions.retry instead. */
97
133
  readonly maxRetries?: number;
134
+ /** @deprecated Provider-level retry is inert in first-party providers; use AgentConfig.retry/RunOptions.retry instead. */
98
135
  readonly maxRetryDelayMs?: number;
99
136
  readonly compat?: JsonObject;
100
137
  readonly extra?: JsonObject;
@@ -137,9 +174,12 @@ export interface AIProvider {
137
174
  readonly id: string;
138
175
  generate(request: ProviderRequest): AsyncIterable<ProviderEvent>;
139
176
  }
177
+ export type ProviderResolver = (model: ModelConfig) => AIProvider | undefined;
178
+ export type InputAssemblyLayout = "legacy" | "cache_aware";
140
179
  export interface RunOptions {
141
180
  readonly signal?: AbortSignal;
142
181
  readonly model?: ModelConfig;
182
+ readonly providerSource?: ProviderResolver;
143
183
  readonly maxToolRounds?: number;
144
184
  readonly providerOptions?: ProviderRequestOptions;
145
185
  readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
@@ -148,12 +188,44 @@ export interface RunOptions {
148
188
  readonly retry?: false | RetryOptions;
149
189
  readonly metadata?: Readonly<Record<string, unknown>>;
150
190
  readonly redactor?: SecretRedactor;
191
+ readonly runLedger?: RunLedger;
192
+ readonly ownership?: OwnershipScope;
193
+ readonly idempotencyKey?: string;
194
+ readonly validate?: ToolValidator;
195
+ readonly activeSkills?: readonly string[];
196
+ readonly skills?: readonly Skill[];
197
+ readonly instructionInjectors?: readonly InstructionInjector[];
198
+ readonly inputLayout?: InputAssemblyLayout;
199
+ readonly loop?: AgentLoopStrategy | AgentLoopOptions;
151
200
  }
152
201
  export interface AgentDefinition {
153
202
  readonly name: string;
154
203
  readonly description?: string;
155
- create(config?: AgentConfig): Promise<Agent> | Agent;
204
+ /** Direct model config, or a model id resolved from `registries.models`. */
205
+ readonly model?: ModelConfig | string;
206
+ /** Tool names to activate from the active tool registry / `registries.tools`. */
207
+ readonly tools?: readonly string[];
208
+ /** Skill names resolved through `resolveActiveSkills()`; `toolNames` enforcement applies. */
209
+ readonly skills?: readonly string[];
210
+ /** Context provider names from `registries.contextProviders`. */
211
+ readonly context?: readonly string[];
212
+ readonly systemPrompt?: SystemPromptConfig;
213
+ readonly instructions?: string;
214
+ readonly loop?: AgentLoopStrategy | AgentLoopOptions;
156
215
  readonly metadata?: Readonly<Record<string, unknown>>;
216
+ /** Optional escape hatch. When present, overrides declarative resolution. */
217
+ create?(config?: AgentConfig): Promise<Agent> | Agent;
218
+ }
219
+ /** Input to {@link resolveAgentDefinition}. All fields are optional; the host
220
+ * controls scope by which registries it passes. */
221
+ export interface AgentDefinitionResolutionContext {
222
+ readonly registries?: ContributionRegistries;
223
+ readonly providerSource?: ProviderResolver;
224
+ readonly tools?: ToolRegistry | readonly ToolDefinition[];
225
+ readonly skillsRegistry?: SkillRegistry;
226
+ /** Migration-only: omitted `tools`/`skills` activate every in-scope tool/skill. Defaults to fail-closed. */
227
+ readonly activateAllCapabilities?: true;
228
+ readonly overrides?: Partial<AgentConfig>;
157
229
  }
158
230
  export interface AgentConfig {
159
231
  readonly id?: string;
@@ -161,6 +233,7 @@ export interface AgentConfig {
161
233
  readonly instructions?: string;
162
234
  readonly model: ModelConfig;
163
235
  readonly provider?: AIProvider;
236
+ readonly providerSource?: ProviderResolver;
164
237
  readonly tools?: ToolRegistry | readonly ToolDefinition[];
165
238
  readonly context?: readonly ContextProvider[];
166
239
  readonly skills?: SkillRegistry | readonly Skill[];
@@ -168,18 +241,28 @@ export interface AgentConfig {
168
241
  readonly promptBuilder?: PromptBuilder;
169
242
  readonly middleware?: MiddlewareRegistry;
170
243
  readonly resourceLoader?: ResourceLoader;
244
+ /** Host-owned metadata only: createAgent/session.run do not load or run these extensions. */
171
245
  readonly extensions?: readonly Extension[];
172
246
  readonly store?: SessionStore;
247
+ /** Host-owned metadata only: createAgent/session.run do not read settings. */
173
248
  readonly settings?: SettingsProvider;
249
+ /** Host-owned metadata only: createAgent/session.run do not resolve credentials. Pass resolvers to provider edges explicitly. */
174
250
  readonly credentials?: CredentialResolver;
175
251
  readonly permission?: PermissionPolicy;
176
252
  readonly providerOptions?: ProviderRequestOptions;
177
253
  readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[];
178
254
  readonly systemPrompt?: SystemPromptConfig;
179
255
  readonly redactor?: SecretRedactor;
256
+ readonly runLedger?: RunLedger;
257
+ readonly ownership?: OwnershipScope;
258
+ readonly idempotencyKey?: string;
180
259
  readonly compaction?: false | CompactionOptions;
181
260
  readonly retry?: false | RetryOptions;
182
261
  readonly metadata?: Readonly<Record<string, unknown>>;
262
+ readonly validator?: ToolValidator;
263
+ readonly instructionInjectors?: readonly InstructionInjector[];
264
+ readonly inputLayout?: InputAssemblyLayout;
265
+ readonly loop?: AgentLoopStrategy | AgentLoopOptions;
183
266
  }
184
267
  export interface Agent {
185
268
  readonly config: AgentConfig;
@@ -199,12 +282,22 @@ export interface AgentSessionCloneOptions {
199
282
  readonly id?: string;
200
283
  readonly leafId?: string;
201
284
  }
285
+ export type SubscriberOverflowPolicy = "close" | "drop_oldest" | "drop_newest";
286
+ export interface SubscribeOptions {
287
+ /** Maximum queued events for a subscriber that is not actively awaiting `next()`. Defaults to 1024. */
288
+ readonly maxQueuedEvents?: number;
289
+ /** What to do when `maxQueuedEvents` is reached. Defaults to `close`. */
290
+ readonly overflow?: SubscriberOverflowPolicy;
291
+ }
202
292
  export interface AgentSession {
203
293
  readonly id: string;
294
+ /** Current branch leaf entry id; advances on every append/run and is re-pointed by `checkout`.
295
+ * Undefined until the first entry lands (a fresh session with no history). */
296
+ readonly leafId: string | undefined;
204
297
  run(input: string | Message | readonly Message[], options?: RunOptions): Promise<void>;
205
298
  prompt(input: string, options?: RunOptions): Promise<void>;
206
299
  compact(options?: CompactionOptions): Promise<CompactionResult>;
207
- subscribe(): AsyncIterable<AgentEvent>;
300
+ subscribe(options?: SubscribeOptions): AsyncIterable<AgentEvent>;
208
301
  abort(reason?: unknown): void;
209
302
  entries(): Promise<readonly SessionEntry[]>;
210
303
  checkout(leafId?: string): Promise<void>;
@@ -282,6 +375,13 @@ export type AgentEvent = {
282
375
  readonly sessionId: string;
283
376
  readonly runId: string;
284
377
  readonly size: number;
378
+ } | {
379
+ readonly type: "event_subscriber_overflow";
380
+ readonly sessionId: string;
381
+ readonly runId?: string;
382
+ readonly droppedEvents: number;
383
+ readonly maxQueuedEvents: number;
384
+ readonly overflow: SubscriberOverflowPolicy;
285
385
  } | {
286
386
  readonly type: "compaction_started";
287
387
  readonly sessionId: string;
@@ -303,6 +403,40 @@ export type AgentEvent = {
303
403
  readonly sessionId?: string;
304
404
  readonly runId?: string;
305
405
  readonly error: ErrorInfo;
406
+ } | {
407
+ readonly type: "artifact_validation_started";
408
+ readonly sessionId: string;
409
+ readonly runId: string;
410
+ readonly turn: number;
411
+ readonly attempt: number;
412
+ } | {
413
+ readonly type: "artifact_validation_finished";
414
+ readonly sessionId: string;
415
+ readonly runId: string;
416
+ readonly turn: number;
417
+ readonly attempt: number;
418
+ readonly result: ArtifactValidation;
419
+ } | {
420
+ readonly type: "artifact_revision_started";
421
+ readonly sessionId: string;
422
+ readonly runId: string;
423
+ readonly turn: number;
424
+ readonly attempt: number;
425
+ readonly failure: ArtifactValidation;
426
+ } | {
427
+ readonly type: "artifact_finished";
428
+ readonly sessionId: string;
429
+ readonly runId: string;
430
+ readonly turn: number;
431
+ readonly attempt: number;
432
+ readonly result: ArtifactValidation;
433
+ } | {
434
+ readonly type: "artifact_failed";
435
+ readonly sessionId: string;
436
+ readonly runId: string;
437
+ readonly turn: number;
438
+ readonly attempt: number;
439
+ readonly result: ArtifactValidation;
306
440
  };
307
441
  export interface ToolDefinition {
308
442
  readonly name: string;
@@ -370,12 +504,44 @@ export interface ContextResolutionContext {
370
504
  readonly metadata?: Readonly<Record<string, unknown>>;
371
505
  readonly signal?: AbortSignal;
372
506
  }
507
+ /** When an {@link InstructionInjector} contributes to the assembled provider input. */
508
+ export type InstructionTiming = "first_turn" | "every_turn" | "on_input";
509
+ /** Runtime turn scope handed to an {@link InstructionInjector}. Mirrors {@link LoopContext}
510
+ * scope using already-redacted input/history so predicates cannot recover secrets. */
511
+ export interface InstructionContext {
512
+ readonly sessionId: string;
513
+ readonly runId: string;
514
+ readonly turn: number;
515
+ readonly input: readonly Message[];
516
+ readonly history: readonly Message[];
517
+ readonly metadata: Readonly<Record<string, unknown>>;
518
+ readonly signal: AbortSignal;
519
+ }
520
+ /** Output of an {@link InstructionInjector}. Only `instructions` and `contextBlocks` are
521
+ * honored; other fields grant nothing (no tools, skills, or permissions). */
522
+ export interface InstructionContribution {
523
+ readonly instructions?: string;
524
+ readonly contextBlocks?: readonly ContextBlock[];
525
+ readonly when: InstructionTiming;
526
+ /** Used only when `when === "on_input"`; absent predicate means apply every turn. */
527
+ readonly predicate?: (ctx: InstructionContext) => boolean;
528
+ }
529
+ /** Additive instruction/context contribution that a package registers through
530
+ * {@link ExtensionAPI.registerInstructionInjector} and the host selects on
531
+ * {@link AgentConfig.instructionInjectors} / {@link RunOptions.instructionInjectors}.
532
+ * Inert until selected; cannot grant privileges beyond text/context blocks. */
533
+ export interface InstructionInjector {
534
+ readonly name: string;
535
+ readonly description?: string;
536
+ apply(ctx: InstructionContext): InstructionContribution;
537
+ }
373
538
  export interface InputBuilder {
374
539
  readonly name: string;
375
540
  build(input: string | Message | readonly Message[], context?: InputBuildContext): Promise<readonly Message[]> | readonly Message[];
376
541
  readonly metadata?: Readonly<Record<string, unknown>>;
377
542
  }
378
543
  export interface InputBuildContext {
544
+ readonly inputLayout?: InputAssemblyLayout;
379
545
  readonly sessionId?: string;
380
546
  readonly runId?: string;
381
547
  readonly metadata?: Readonly<Record<string, unknown>>;
@@ -408,6 +574,25 @@ export interface SkillRegistry {
408
574
  resolve(name: string): Skill;
409
575
  list(): readonly Skill[];
410
576
  }
577
+ /** Directory-name spelling for discovered contribution kinds. Maps to a
578
+ * {@link ManifestContributionDeclaration} kind for non-skill kinds:
579
+ * `context` → `contextProvider`, `instructions` → `systemPromptContribution`. */
580
+ export type ContributionFileKind = "skill" | "tool" | "context" | "instructions";
581
+ /** Inert envelope emitted by the host/CLI discovery scanner. Carries the
582
+ * realized {@link Skill} for skill kinds and a manifest-referenced
583
+ * {@link ManifestContributionDeclaration} for other kinds; the host owns
584
+ * any executable behavior. Contains no code, no credential. */
585
+ export interface DiscoveredContribution {
586
+ readonly kind: ContributionFileKind;
587
+ readonly name: string;
588
+ readonly origin: "global" | "workspace";
589
+ readonly path: string;
590
+ /** Present when `kind === "skill"`. */
591
+ readonly skill?: Skill;
592
+ /** Present for non-skill kinds. */
593
+ readonly declaration?: ManifestContributionDeclaration;
594
+ readonly metadata?: Readonly<Record<string, unknown>>;
595
+ }
411
596
  export type ExtensionLifecycleEventName = "resource_discovery" | "session_start" | "session_shutdown" | "before_agent_start" | "turn" | "context" | "provider_request" | "tool_call" | "tool_result" | "compaction" | "retry";
412
597
  export interface ExtensionEvent {
413
598
  readonly type: ExtensionLifecycleEventName | "extension_error" | string;
@@ -534,13 +719,19 @@ export interface ExtensionAPI {
534
719
  registerAuthMethod(method: AuthMethod): void;
535
720
  registerProviderRequestPolicy(policy: ProviderRequestPolicy): void;
536
721
  registerSystemPromptContribution(contribution: SystemPromptContribution): void;
722
+ registerInstructionInjector(injector: InstructionInjector): void;
537
723
  }
724
+ export type SessionEntryKind = "message" | "event" | "summary" | "metadata" | "model_change" | "label" | "custom" | "compaction";
725
+ export declare const SESSION_ENTRY_KINDS: readonly SessionEntryKind[];
726
+ export declare const SESSION_ENTRY_SCHEMA_VERSION = 1;
727
+ export declare function isSessionEntryKind(value: unknown): value is SessionEntryKind;
538
728
  export interface SessionEntry {
539
729
  readonly id: string;
540
730
  readonly parentId?: string;
541
731
  readonly sessionId: string;
542
732
  readonly timestamp: string;
543
- readonly kind: "message" | "event" | "summary" | "metadata" | "model_change" | "label" | "custom" | "compaction";
733
+ readonly kind: SessionEntryKind;
734
+ readonly schemaVersion?: 1;
544
735
  readonly runId?: string;
545
736
  readonly message?: Message;
546
737
  readonly event?: AgentEvent;
@@ -552,15 +743,341 @@ export interface SessionEntry {
552
743
  readonly metadata?: Readonly<Record<string, unknown>>;
553
744
  }
554
745
  export interface SessionStore {
555
- append(entry: SessionEntry): Promise<void>;
746
+ append(entry: SessionEntry, options?: SessionAppendOptions): Promise<void>;
556
747
  list(sessionId: string): Promise<readonly SessionEntry[]>;
557
748
  get?(id: string): Promise<SessionEntry | undefined>;
558
- }
749
+ /** DB-friendly branch read: return one branch's ancestor chain as a page so adapters
750
+ * avoid `list(sessionId)` (full-session scan) + in-memory rebuild. Optional — the
751
+ * built-in memory/JSONL stores omit it and the runtime falls back to `list()`. */
752
+ readBranchPath?(query: SessionBranchRead): Promise<PersistencePage<SessionEntry>>;
753
+ }
754
+ /** Query for a single branch's ancestor chain (DB-friendly: one recursive/ancestor query
755
+ * instead of a full-session scan). Honored by `SessionStore.readBranchPath` and the pure
756
+ * branch helpers' reader overload. `leafId` is optional (omit for the latest leaf). */
757
+ export interface SessionBranchRead {
758
+ readonly sessionId: string;
759
+ readonly leafId?: string;
760
+ readonly cursor?: string;
761
+ readonly limit?: number;
762
+ }
763
+ /** Database-neutral callable returning one branch's ancestor chain as a page. Implementations
764
+ * issue a single recursive CTE / ancestor walk; the pure helpers follow `nextCursor` to
765
+ * completion. Returns redacted `SessionEntry` values only (stores already persist redacted
766
+ * entries; the runtime redacts before append). */
767
+ export type BranchReader = (query: SessionBranchRead) => Promise<PersistencePage<SessionEntry>>;
768
+ /**
769
+ * Options for `SessionStore.append`. Stores that honor them reject dangling
770
+ * `expectedParentId` values and deduplicate exact retries by `idempotencyKey` +
771
+ * parent. Production stores may add stricter branch-tip CAS and report
772
+ * `currentLeafId` in `SessionAppendConflictError`. `idempotencyKey` is an opaque
773
+ * host string; stores redact it like metadata when persisted. Carries no
774
+ * credentials, credential resolvers, provider instances, or unredacted secrets.
775
+ */
776
+ export interface SessionAppendOptions {
777
+ /** Parent entry the new entry should attach to. Must exist when provided. */
778
+ readonly expectedParentId?: string;
779
+ /** Opaque host idempotency key; exact retries for one parent deduplicate. */
780
+ readonly idempotencyKey?: string;
781
+ }
782
+ /**
783
+ * Durable pointer to a branch tip. One session may own many handles (one per
784
+ * leaf). `BranchRecord.leafEntryId` is the persistence-side equivalent.
785
+ */
786
+ export interface SessionBranchHandle {
787
+ readonly sessionId: string;
788
+ readonly leafId: string;
789
+ }
790
+ /** Stable error code carried by `SessionAppendConflictError`. */
791
+ export declare const SESSION_APPEND_CONFLICT_CODE: "session_append_conflict";
792
+ /** Conflict details carried by `SessionAppendConflictError`. Carries no secrets. */
793
+ export interface SessionAppendConflict {
794
+ readonly code: typeof SESSION_APPEND_CONFLICT_CODE;
795
+ readonly expectedParentId?: string;
796
+ readonly currentLeafId?: string;
797
+ readonly idempotencyDuplicate?: boolean;
798
+ }
799
+ /**
800
+ * Thrown when `SessionStore.append` rejects an entry under `SessionAppendOptions`
801
+ * (dangling/stale `expectedParentId`, stricter adapter CAS failure, or duplicate
802
+ * idempotency key for the same parent). Recognize via the stable `code` and
803
+ * `isSessionAppendConflict`, not message text.
804
+ */
805
+ export declare class SessionAppendConflictError extends Error {
806
+ readonly conflict: SessionAppendConflict;
807
+ readonly code: "session_append_conflict";
808
+ constructor(conflict: SessionAppendConflict);
809
+ }
810
+ /** Type guard keyed off the stable `code` (works across bundles; not message text). */
811
+ export declare function isSessionAppendConflict(error: unknown): error is SessionAppendConflictError;
559
812
  export interface StoreFactory {
560
813
  readonly name: string;
561
814
  create(config?: JsonObject): Promise<SessionStore> | SessionStore;
562
815
  readonly metadata?: Readonly<Record<string, unknown>>;
563
816
  }
817
+ /** Ownership scope identifiers. Hosts may use these for multi-tenant isolation. */
818
+ export interface OwnershipScope {
819
+ readonly tenantId?: string;
820
+ readonly accountId?: string;
821
+ readonly userId?: string;
822
+ }
823
+ /** Cursor-paginated result page. */
824
+ export interface PersistencePage<T> {
825
+ readonly items: readonly T[];
826
+ readonly nextCursor?: string;
827
+ readonly total?: number;
828
+ }
829
+ /** Common query controls for cursor-based pagination. */
830
+ export interface PersistenceQuery {
831
+ readonly cursor?: string;
832
+ readonly limit?: number;
833
+ readonly order?: "asc" | "desc";
834
+ }
835
+ /** Stored session record. Does not include provider objects or credentials. */
836
+ export interface SessionRecord extends OwnershipScope {
837
+ readonly id: string;
838
+ readonly parentSessionId?: string;
839
+ readonly agentDefinitionId?: string;
840
+ readonly agentDefinitionVersion?: string;
841
+ readonly createdAt: string;
842
+ readonly updatedAt: string;
843
+ readonly expiresAt?: string;
844
+ readonly retentionPolicyId?: string;
845
+ readonly metadata?: Readonly<Record<string, unknown>>;
846
+ }
847
+ /** Stored branch handle / leaf pointer. The leaf is the current entry id for the branch. */
848
+ export interface BranchRecord {
849
+ readonly id: string;
850
+ readonly sessionId: string;
851
+ readonly name?: string;
852
+ readonly rootEntryId?: string;
853
+ readonly parentBranchId?: string;
854
+ /** Durable leaf entry id for this branch (the persistence-side branch tip). */
855
+ readonly leafEntryId?: string;
856
+ readonly createdAt: string;
857
+ readonly metadata?: Readonly<Record<string, unknown>>;
858
+ }
859
+ export type RunStatus = "queued" | "running" | "succeeded" | "failed" | "aborted";
860
+ /** Stored run record. */
861
+ export interface RunRecord extends OwnershipScope {
862
+ readonly id: string;
863
+ readonly sessionId: string;
864
+ readonly branchId?: string;
865
+ readonly agentDefinitionId?: string;
866
+ readonly agentDefinitionVersion?: string;
867
+ readonly model?: ModelConfig;
868
+ readonly provider?: string;
869
+ readonly idempotencyKey?: string;
870
+ readonly status?: RunStatus;
871
+ readonly startedAt: string;
872
+ readonly finishedAt?: string;
873
+ readonly abortReason?: string;
874
+ readonly error?: ErrorInfo;
875
+ readonly metadata?: Readonly<Record<string, unknown>>;
876
+ }
877
+ export type AgentEventType = AgentEvent["type"];
878
+ /** Stored agent event ledger row. The `event` payload should be redacted before storage when secrets are present. */
879
+ export interface AgentEventRecord extends OwnershipScope {
880
+ readonly id: string;
881
+ readonly sessionId: string;
882
+ readonly runId?: string;
883
+ readonly entryId?: string;
884
+ readonly type: AgentEventType;
885
+ readonly timestamp: string;
886
+ readonly event: AgentEvent;
887
+ readonly redacted: boolean;
888
+ readonly metadata?: Readonly<Record<string, unknown>>;
889
+ }
890
+ export type ToolCallStatus = "started" | "finished" | "error" | "blocked";
891
+ /** Stored tool-call row. The `result` payload should be redacted before storage when secrets are present. */
892
+ export interface ToolCallRecord extends OwnershipScope {
893
+ readonly id: string;
894
+ readonly sessionId: string;
895
+ readonly runId?: string;
896
+ readonly entryId?: string;
897
+ readonly toolCallId: string;
898
+ readonly name: string;
899
+ readonly arguments: JsonObject;
900
+ readonly result?: ToolResult;
901
+ readonly status?: ToolCallStatus;
902
+ readonly reason?: string;
903
+ readonly progress?: unknown;
904
+ readonly progressMetadata?: Readonly<Record<string, unknown>>;
905
+ readonly progressAt?: string;
906
+ readonly startedAt: string;
907
+ readonly finishedAt?: string;
908
+ readonly redacted: boolean;
909
+ readonly metadata?: Readonly<Record<string, unknown>>;
910
+ }
911
+ /** Stored usage row. */
912
+ export interface UsageRecord extends OwnershipScope {
913
+ readonly id: string;
914
+ readonly sessionId: string;
915
+ readonly runId?: string;
916
+ readonly entryId?: string;
917
+ readonly usage: Usage;
918
+ readonly recordedAt: string;
919
+ readonly metadata?: Readonly<Record<string, unknown>>;
920
+ }
921
+ /** Host-implemented write-side ledger for runs, events, tool calls, and usage. */
922
+ export interface RunLedger {
923
+ appendRun(record: RunRecord): Promise<void> | void;
924
+ appendEvent(record: AgentEventRecord): Promise<void> | void;
925
+ appendToolCall(record: ToolCallRecord): Promise<void> | void;
926
+ appendUsage(record: UsageRecord): Promise<void> | void;
927
+ }
928
+ /** Union of records that may be handed to a {@link RunLedger}. */
929
+ export type RunLedgerRecord = RunRecord | AgentEventRecord | ToolCallRecord | UsageRecord;
930
+ /** Stored agent definition version. Does not include provider credentials/resolvers/provider instances. */
931
+ export interface AgentDefinitionRecord extends OwnershipScope {
932
+ readonly id: string;
933
+ readonly name: string;
934
+ readonly version: string;
935
+ readonly source?: string;
936
+ readonly agentDefinition: AgentDefinition;
937
+ readonly createdAt: string;
938
+ readonly createdBy?: string;
939
+ readonly metadata?: Readonly<Record<string, unknown>>;
940
+ }
941
+ /** Stored retention policy. */
942
+ export interface RetentionPolicy extends OwnershipScope {
943
+ readonly id: string;
944
+ readonly name?: string;
945
+ readonly maxAgeDays?: number;
946
+ readonly maxEntriesPerSession?: number;
947
+ readonly maxTotalBytes?: number;
948
+ readonly archiveStore?: string;
949
+ readonly appliedKinds?: readonly SessionEntryKind[];
950
+ readonly createdAt: string;
951
+ readonly metadata?: Readonly<Record<string, unknown>>;
952
+ }
953
+ /** Stored migration record. */
954
+ export interface MigrationRecord {
955
+ readonly id: string;
956
+ readonly name: string;
957
+ readonly version: string;
958
+ readonly appliedAt: string;
959
+ readonly appliedBy?: string;
960
+ readonly checksum?: string;
961
+ readonly metadata?: Readonly<Record<string, unknown>>;
962
+ }
963
+ /** Query for sessions. */
964
+ export interface SessionQuery extends PersistenceQuery, OwnershipScope {
965
+ readonly parentSessionId?: string;
966
+ readonly agentDefinitionId?: string;
967
+ readonly agentDefinitionVersion?: string;
968
+ readonly retentionPolicyId?: string;
969
+ readonly fromCreatedAt?: string;
970
+ readonly toCreatedAt?: string;
971
+ readonly fromUpdatedAt?: string;
972
+ readonly toUpdatedAt?: string;
973
+ readonly hasExpired?: boolean;
974
+ }
975
+ /** Query for session entries. */
976
+ export interface SessionEntryQuery extends PersistenceQuery, OwnershipScope {
977
+ readonly sessionId?: string;
978
+ readonly runId?: string;
979
+ readonly parentId?: string;
980
+ /** Filter to entries on the branch ending at this leaf id. */
981
+ readonly leafId?: string;
982
+ readonly kind?: SessionEntryKind | readonly SessionEntryKind[];
983
+ readonly fromTimestamp?: string;
984
+ readonly toTimestamp?: string;
985
+ }
986
+ /** Query for branch handles/leaves. */
987
+ export interface BranchQuery extends PersistenceQuery {
988
+ readonly sessionId?: string;
989
+ readonly name?: string;
990
+ readonly parentBranchId?: string;
991
+ readonly hasLeaf?: boolean;
992
+ }
993
+ /** Query for runs. */
994
+ export interface RunQuery extends PersistenceQuery, OwnershipScope {
995
+ readonly sessionId?: string;
996
+ readonly branchId?: string;
997
+ readonly agentDefinitionId?: string;
998
+ readonly agentDefinitionVersion?: string;
999
+ readonly status?: RunStatus | readonly RunStatus[];
1000
+ readonly fromStartedAt?: string;
1001
+ readonly toStartedAt?: string;
1002
+ readonly fromFinishedAt?: string;
1003
+ readonly toFinishedAt?: string;
1004
+ readonly isFinished?: boolean;
1005
+ }
1006
+ /** Query for agent event ledger rows. */
1007
+ export interface AgentEventQuery extends PersistenceQuery, OwnershipScope {
1008
+ readonly sessionId?: string;
1009
+ readonly runId?: string;
1010
+ readonly entryId?: string;
1011
+ readonly type?: AgentEventType | readonly AgentEventType[];
1012
+ readonly fromTimestamp?: string;
1013
+ readonly toTimestamp?: string;
1014
+ readonly redacted?: boolean;
1015
+ }
1016
+ /** Query for tool-call rows. */
1017
+ export interface ToolCallQuery extends PersistenceQuery, OwnershipScope {
1018
+ readonly sessionId?: string;
1019
+ readonly runId?: string;
1020
+ readonly entryId?: string;
1021
+ readonly name?: string;
1022
+ readonly status?: ToolCallStatus | readonly ToolCallStatus[];
1023
+ readonly fromStartedAt?: string;
1024
+ readonly toStartedAt?: string;
1025
+ readonly fromFinishedAt?: string;
1026
+ readonly toFinishedAt?: string;
1027
+ readonly redacted?: boolean;
1028
+ }
1029
+ /** Query for usage rows. */
1030
+ export interface UsageQuery extends PersistenceQuery, OwnershipScope {
1031
+ readonly sessionId?: string;
1032
+ readonly runId?: string;
1033
+ readonly entryId?: string;
1034
+ readonly fromRecordedAt?: string;
1035
+ readonly toRecordedAt?: string;
1036
+ }
1037
+ /** Query for agent definition versions. */
1038
+ export interface AgentDefinitionQuery extends PersistenceQuery, OwnershipScope {
1039
+ readonly name?: string;
1040
+ readonly version?: string;
1041
+ readonly source?: string;
1042
+ readonly fromCreatedAt?: string;
1043
+ readonly toCreatedAt?: string;
1044
+ }
1045
+ /** Query for retention policies. */
1046
+ export interface RetentionPolicyQuery extends PersistenceQuery, OwnershipScope {
1047
+ readonly name?: string;
1048
+ readonly archiveStore?: string;
1049
+ }
1050
+ /** Query for migration records. */
1051
+ export interface MigrationQuery extends PersistenceQuery {
1052
+ readonly name?: string;
1053
+ readonly version?: string;
1054
+ readonly fromAppliedAt?: string;
1055
+ readonly toAppliedAt?: string;
1056
+ }
1057
+ /**
1058
+ * Production database-neutral persistence store contract.
1059
+ * Hosts implement this interface to provide durable, paginated storage
1060
+ * for sessions, entries, runs, events, tool calls, usage, agent definitions,
1061
+ * and migrations. No SQL client, ORM, host file storage, or network dependency is
1062
+ * required by the contract.
1063
+ */
1064
+ export interface ProductionPersistenceStore {
1065
+ readonly name?: string;
1066
+ querySessions(query: SessionQuery): Promise<PersistencePage<SessionRecord>>;
1067
+ queryBranches(query: BranchQuery): Promise<PersistencePage<BranchRecord>>;
1068
+ queryEntries(query: SessionEntryQuery): Promise<PersistencePage<SessionEntry>>;
1069
+ queryRuns(query: RunQuery): Promise<PersistencePage<RunRecord>>;
1070
+ queryEvents(query: AgentEventQuery): Promise<PersistencePage<AgentEventRecord>>;
1071
+ queryToolCalls(query: ToolCallQuery): Promise<PersistencePage<ToolCallRecord>>;
1072
+ queryUsage(query: UsageQuery): Promise<PersistencePage<UsageRecord>>;
1073
+ queryAgentDefinitions(query: AgentDefinitionQuery): Promise<PersistencePage<AgentDefinitionRecord>>;
1074
+ queryRetentionPolicies(query: RetentionPolicyQuery): Promise<PersistencePage<RetentionPolicy>>;
1075
+ queryMigrations(query: MigrationQuery): Promise<PersistencePage<MigrationRecord>>;
1076
+ /** DB-friendly branch read (mirrors `SessionStore.readBranchPath`): one ancestor-chain
1077
+ * query instead of `queryEntries({ sessionId })` + in-memory walk. Optional. */
1078
+ readBranchPath?(query: SessionBranchRead): Promise<PersistencePage<SessionEntry>>;
1079
+ readonly metadata?: Readonly<Record<string, unknown>>;
1080
+ }
564
1081
  export interface CompactionStrategy {
565
1082
  readonly name: string;
566
1083
  compact(context: CompactionContext): Promise<CompactionResult> | CompactionResult;
@@ -668,3 +1185,61 @@ export interface CredentialResolverSource {
668
1185
  export interface OAuthCredentialStore {
669
1186
  set(provider: string, credentials: OAuthCredentials): void | Promise<void>;
670
1187
  }
1188
+ export interface ProviderTurnResult {
1189
+ readonly content: readonly ContentBlock[];
1190
+ readonly calls: readonly ToolCallContent[];
1191
+ readonly messageId?: string;
1192
+ readonly started: boolean;
1193
+ readonly usage?: Usage;
1194
+ }
1195
+ export interface LoopContext {
1196
+ readonly sessionId: string;
1197
+ readonly runId: string;
1198
+ readonly metadata: Readonly<Record<string, unknown>>;
1199
+ readonly signal: AbortSignal;
1200
+ readonly history: Message[];
1201
+ readonly input: AgentInput;
1202
+ readonly inputMessages: readonly Message[];
1203
+ readonly maxToolRounds: number;
1204
+ assemble(nextInput: AgentInput, toolResults?: readonly ToolResult[], turn?: number): Promise<ProviderRequest>;
1205
+ generate(request: ProviderRequest): Promise<ProviderTurnResult>;
1206
+ dispatchToolCall(call: ToolCallContent): Promise<ToolResult>;
1207
+ appendMessage(message: Message): Promise<void>;
1208
+ emit(event: AgentEvent): void;
1209
+ }
1210
+ export interface AgentLoopStrategy {
1211
+ readonly name: string;
1212
+ run(ctx: LoopContext): Promise<Usage | undefined>;
1213
+ }
1214
+ export type AgentLoopOptions = {
1215
+ readonly strategy: "single-shot";
1216
+ } | {
1217
+ readonly strategy: "generate-validate-revise";
1218
+ readonly validator: ArtifactValidator<unknown>;
1219
+ readonly parser?: ArtifactParser<unknown>;
1220
+ readonly repairer?: ArtifactRepairer<unknown>;
1221
+ readonly maxRevisions?: number;
1222
+ };
1223
+ export interface ArtifactValidation {
1224
+ readonly ok: boolean;
1225
+ readonly errors?: readonly {
1226
+ readonly path?: string;
1227
+ readonly message: string;
1228
+ }[];
1229
+ readonly metadata?: Readonly<Record<string, unknown>>;
1230
+ }
1231
+ export interface ArtifactContext {
1232
+ readonly sessionId: string;
1233
+ readonly runId: string;
1234
+ readonly turn: number;
1235
+ readonly signal: AbortSignal;
1236
+ readonly metadata: Readonly<Record<string, unknown>>;
1237
+ }
1238
+ export interface ArtifactParseResult<T> {
1239
+ readonly ok: boolean;
1240
+ readonly value?: T;
1241
+ readonly error?: string;
1242
+ }
1243
+ export type ArtifactParser<T> = (text: string, ctx: ArtifactContext) => ArtifactParseResult<T> | Promise<ArtifactParseResult<T>>;
1244
+ export type ArtifactValidator<T> = (value: T, ctx: ArtifactContext) => ArtifactValidation | Promise<ArtifactValidation>;
1245
+ export type ArtifactRepairer<T> = (value: T | undefined, failure: ArtifactValidation, ctx: ArtifactContext) => AgentInput | Promise<AgentInput>;