@arnilo/prism 0.0.1

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 (106) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +139 -0
  4. package/dist/agents.d.ts +5 -0
  5. package/dist/agents.js +439 -0
  6. package/dist/cli-runner.d.ts +33 -0
  7. package/dist/cli-runner.js +167 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +10 -0
  10. package/dist/compaction.d.ts +9 -0
  11. package/dist/compaction.js +67 -0
  12. package/dist/config.d.ts +17 -0
  13. package/dist/config.js +69 -0
  14. package/dist/contracts.d.ts +670 -0
  15. package/dist/contracts.js +2 -0
  16. package/dist/contributions.d.ts +35 -0
  17. package/dist/contributions.js +47 -0
  18. package/dist/credentials.d.ts +22 -0
  19. package/dist/credentials.js +63 -0
  20. package/dist/extensions.d.ts +25 -0
  21. package/dist/extensions.js +131 -0
  22. package/dist/index.d.ts +47 -0
  23. package/dist/index.js +28 -0
  24. package/dist/input.d.ts +57 -0
  25. package/dist/input.js +225 -0
  26. package/dist/manifests.d.ts +28 -0
  27. package/dist/manifests.js +108 -0
  28. package/dist/middleware.d.ts +15 -0
  29. package/dist/middleware.js +49 -0
  30. package/dist/mock-provider.d.ts +6 -0
  31. package/dist/mock-provider.js +14 -0
  32. package/dist/models.d.ts +8 -0
  33. package/dist/models.js +25 -0
  34. package/dist/node/config.d.ts +9 -0
  35. package/dist/node/config.js +51 -0
  36. package/dist/node/session-store-jsonl.d.ts +17 -0
  37. package/dist/node/session-store-jsonl.js +134 -0
  38. package/dist/node/settings.d.ts +7 -0
  39. package/dist/node/settings.js +26 -0
  40. package/dist/node/trust.d.ts +13 -0
  41. package/dist/node/trust.js +56 -0
  42. package/dist/provider-events.d.ts +15 -0
  43. package/dist/provider-events.js +30 -0
  44. package/dist/provider-packages.d.ts +4 -0
  45. package/dist/provider-packages.js +12 -0
  46. package/dist/provider-request-policy.d.ts +9 -0
  47. package/dist/provider-request-policy.js +49 -0
  48. package/dist/providers/openai-compatible.d.ts +9 -0
  49. package/dist/providers/openai-compatible.js +197 -0
  50. package/dist/providers.d.ts +8 -0
  51. package/dist/providers.js +25 -0
  52. package/dist/redaction.d.ts +11 -0
  53. package/dist/redaction.js +68 -0
  54. package/dist/resources.d.ts +5 -0
  55. package/dist/resources.js +30 -0
  56. package/dist/retry.d.ts +11 -0
  57. package/dist/retry.js +48 -0
  58. package/dist/rpc.d.ts +18 -0
  59. package/dist/rpc.js +187 -0
  60. package/dist/security.d.ts +51 -0
  61. package/dist/security.js +60 -0
  62. package/dist/session-stores.d.ts +25 -0
  63. package/dist/session-stores.js +116 -0
  64. package/dist/settings.d.ts +3 -0
  65. package/dist/settings.js +26 -0
  66. package/dist/skills.d.ts +8 -0
  67. package/dist/skills.js +34 -0
  68. package/dist/system-prompts.d.ts +6 -0
  69. package/dist/system-prompts.js +47 -0
  70. package/dist/testing/provider-conformance.d.ts +36 -0
  71. package/dist/testing/provider-conformance.js +164 -0
  72. package/dist/tools.d.ts +25 -0
  73. package/dist/tools.js +109 -0
  74. package/docs/agent-session-runtime.md +167 -0
  75. package/docs/api-page-template.md +32 -0
  76. package/docs/cli-rpc.md +140 -0
  77. package/docs/compaction-and-retry.md +177 -0
  78. package/docs/compaction-llm.md +108 -0
  79. package/docs/compaction-observational-memory.md +123 -0
  80. package/docs/configuration-and-manifests.md +142 -0
  81. package/docs/context-and-skills.md +113 -0
  82. package/docs/contribution-registries.md +118 -0
  83. package/docs/credentials-and-redaction.md +122 -0
  84. package/docs/extensions.md +139 -0
  85. package/docs/index.md +56 -0
  86. package/docs/input-and-prompt-assembly.md +168 -0
  87. package/docs/middleware-hooks.md +123 -0
  88. package/docs/node-filesystem-config.md +85 -0
  89. package/docs/node-jsonl-session-store.md +81 -0
  90. package/docs/provider-conformance.md +109 -0
  91. package/docs/provider-layer.md +172 -0
  92. package/docs/provider-packages.md +171 -0
  93. package/docs/providers/kimi.md +110 -0
  94. package/docs/providers/openai-compatible.md +125 -0
  95. package/docs/providers/openai.md +131 -0
  96. package/docs/providers/opencode-go.md +103 -0
  97. package/docs/providers/openrouter.md +105 -0
  98. package/docs/providers/zai.md +108 -0
  99. package/docs/public-contracts.md +375 -0
  100. package/docs/release-and-install.md +141 -0
  101. package/docs/resource-loading.md +97 -0
  102. package/docs/session-stores-and-branching.md +119 -0
  103. package/docs/settings-auth-trust-security.md +73 -0
  104. package/docs/system-prompts.md +116 -0
  105. package/docs/tools.md +151 -0
  106. package/package.json +93 -0
@@ -0,0 +1,375 @@
1
+ # Public contracts
2
+
3
+ ## What it does
4
+
5
+ The root `@arnilo/prism` export provides TypeScript contracts for host-owned agent systems plus small runtime helpers as phases land. These contracts describe data shapes and extension points; they do not create providers, stores, credentials, tools, or network calls by themselves.
6
+
7
+ Current contract groups:
8
+
9
+ - JSON/data: `JsonPrimitive`, `JsonValue`, `JsonObject`, `ErrorInfo`
10
+ - Content/messages: `ContentBlock`, `TextContent`, `ImageContent`, `ThinkingContent`, `ToolCallContent`, `ToolResultContent`, `Message`
11
+ - Providers/models/auth: `ModelConfig`, `ModelCapabilities`, `ModelLimits`, `ModelCost`, `Usage`, `CacheRetention`, `ProviderRequestOptions`, `ProviderRequest`, `ProviderEvent`, `AIProvider`, `ProviderPackage`, `ProviderPackageAPI`, `ProviderPackageDocs`, `AuthMethod`, `ApiKeyAuthMethod`, `OAuthAuthMethod`, `CustomAuthMethod`, `OAuthLoginCallbacks`, `OAuthCredentials`, `OAuthProvider`, `CredentialResolverSource`, `OAuthCredentialStore`, `ProviderRequestPolicy`, `ProviderRequestPolicyContext`, `ProviderRequestPolicyResult`, `SystemPromptContribution`, `SystemPromptMode`, `SystemPromptSource`, `SystemPromptConfig`
12
+ - Agents/sessions: `AgentConfig`, `AgentDefinition`, `Agent`, `AgentSessionConfig`, `AgentSessionForkOptions`, `AgentSessionCloneOptions`, `AgentSession`, `RunOptions`, `AgentEvent`
13
+ - Tools/commands: `ToolDefinition`, `ToolRegistry`, `ToolExecutionContext`, `ToolResult`, `CommandDefinition`, `CommandExecutionContext`, `CommandResult`
14
+ - Input/prompt/context/skills: `InputBuilder`, `InputBuildContext`, `AgentInput`, `DefaultInputBuilder`, `DefaultInputBuildContext`, `InputAttachment`, `PromptInstruction`, `PromptBuilder`, `PromptBuildRequest`, `ContextBlock`, `ContextProvider`, `ContextResolutionContext`, `Skill`, `SkillRegistry`
15
+ - Extensions/middleware: `ExtensionLifecycleEventName`, `ExtensionEvent`, `Extension`, `ExtensionAPI`, `MiddlewareHookName`, `Middleware`, `MiddlewareNext`, `MiddlewareRegistry`
16
+ - Configuration/manifests: `ConfigProvider`, `ConfigLayer`, `ConfigLoadContext`, `PrismManifest`, `ManifestContributionDeclaration`, `ManifestResourceDeclaration`, `ManifestContributionKind`
17
+ - Stores/resources/settings/credentials/compaction/retry: `SessionEntry`, `SessionStore`, `StoreFactory`, `Resource`, `ResourceLoader`, `ResourceLoadContext`, `SettingsProvider`, `CredentialRequest`, `Credential`, `CredentialResolver`, `CompactionStrategy`, `CompactionContext`, `CompactionResult`, `CompactionOptions`, `CompactionMiddlewarePayload`, `CompactionEntryData`, `DefaultCompactionStrategyOptions`, `RetryPolicy`, `RetryContext`, `RetryDecision`, `RetryOptions`, `RetryMiddlewarePayload`, `DefaultRetryPolicyOptions`
18
+
19
+ ## When to use it
20
+
21
+ Use these contracts when a host app or external package needs to type Prism-compatible providers, tools, context providers, skills, extensions, sessions, stores, resources, settings, or credential resolvers.
22
+
23
+ Do not use a contract as proof that every behavior exists. The agent/session runtime, tool loops, persistence adapters, config helpers, compaction helpers, and retry helpers now exist; CLI/RPC is implemented in later phases.
24
+
25
+ ## Inputs / request
26
+
27
+ Public contracts are imported from the root package:
28
+
29
+ ```ts
30
+ import type {
31
+ AgentConfig,
32
+ AgentDefinition,
33
+ AIProvider,
34
+ AuthMethod,
35
+ CommandDefinition,
36
+ CompactionStrategy,
37
+ ConfigLayer,
38
+ ConfigProvider,
39
+ ContextProvider,
40
+ CredentialResolver,
41
+ OAuthProvider,
42
+ ProviderRequestOptions,
43
+ DefaultInputBuildContext,
44
+ Extension,
45
+ InputBuilder,
46
+ ManifestContributionDeclaration,
47
+ ManifestResourceDeclaration,
48
+ Message,
49
+ Middleware,
50
+ ModelConfig,
51
+ PrismManifest,
52
+ PromptBuilder,
53
+ PromptTemplateOptions,
54
+ ProviderPackage,
55
+ ProviderRequestPolicy,
56
+ ResourceLoader,
57
+ SettingsProvider,
58
+ Skill,
59
+ StoreFactory,
60
+ SystemPromptContribution,
61
+ SystemPromptConfig,
62
+ ToolDefinition,
63
+ } from "@arnilo/prism";
64
+ ```
65
+
66
+ Important request shapes:
67
+
68
+ | Contract | Purpose |
69
+ | --- | --- |
70
+ | `ModelConfig` | Provider/model id plus optional display name, capabilities, limits, cost/cache pricing, opaque compat JSON, parameters, and metadata. |
71
+ | `ProviderPackage` | Inert provider package definition with docs metadata and explicit `setup(api)` registration. |
72
+ | `ProviderRequest` | Normalized provider input: `model`, `messages`, optional `tools`, `context`, generic `options`, `metadata`, and `signal`. |
73
+ | `ProviderRequestOptions` | Generic provider adapter hints: session/cache identifiers, cache retention, headers, timeout/retry hints, compat, and opaque `extra`. |
74
+ | `ProviderRequestPolicy` | Ordered pre-provider hook that can patch the request and return exact secrets for provider-error redaction. |
75
+ | `ToolRegistry` | Host active tool registry shape: `register()`, `get()`, `resolve()`, and `list()`. |
76
+ | `ToolExecutionContext` | Host tool execution context: session/run ids, tool call id, optional abort signal, metadata, and progress callback. |
77
+ | `ContextResolutionContext` | Context provider input: messages plus optional session/run ids, metadata, and signal. |
78
+ | `DefaultInputBuildContext` | Optional default input assembly context: instructions, history, summaries, attachments, explicit resources, tool results, middleware, ids, metadata, and signal. |
79
+ | `ResolveContextOptions` | Ordered context resolution input: selected providers, messages, ids, metadata, signal, and optional middleware. |
80
+ | `AssembleProviderInputOptions` | Provider input assembly input: model, input, optional builders, selected context providers/skills, active tools, metadata, and signal. |
81
+ | `PromptTemplateOptions` | Missing-variable behavior for tiny `renderPromptTemplate()` substitutions. |
82
+ | `SkillRegistry` | Host active skill registry shape: `register()`, `get()`, `resolve()`, and `list()`. |
83
+ | `CredentialRequest` | Credential lookup request: credential `name`, optional provider id, and metadata. |
84
+ | `OAuthProvider` | Host/package OAuth callbacks for login, optional refresh, and conversion to a `Credential`. |
85
+ | `AgentSessionConfig` | Session creation input: optional id, agent, store, leaf id, and metadata. |
86
+ | `RunOptions` | Per-run overrides: optional abort signal, model, max tool rounds, provider options/request policies, system prompt layers, compaction, retry, and metadata. |
87
+ | `SystemPromptContribution` | Explicit caller-selected prompt layer with source, mode, text, and metadata. |
88
+ | `ConfigLayer` | Named JSON config layer consumed by `mergeConfigLayers()`. |
89
+ | `PrismManifest` | Data-only package manifest with config defaults, contribution declarations, and resource declarations. |
90
+
91
+ ## Outputs / response / events
92
+
93
+ Important output/event shapes:
94
+
95
+ | Contract | Output |
96
+ | --- | --- |
97
+ | `ProviderEvent` | Provider stream events: message start, content delta, tool-call delta, final tool call, usage, done, or error. |
98
+ | `AgentEvent` | Session/runtime events: agent/turn/message/tool/queue/compaction/retry/error events, including tool started/progress/finished/error/blocked. |
99
+ | `ToolResult` | Host tool output with optional content, value, error, and metadata. |
100
+ | `ContextBlock` | Context text or content blocks with optional title, priority, and metadata. |
101
+ | `SessionEntry` | Branch-aware store entry for messages, events, summaries, metadata, model changes, labels, custom data, or compaction markers. |
102
+ | `Resource` | Loaded resource with URI, media type, text, binary data, and metadata. |
103
+ | `Credential` | Host-resolved credential value returned only to the caller that requested it. |
104
+
105
+ ## Request/response example
106
+
107
+ ```json
108
+ {
109
+ "model": { "provider": "mock", "model": "demo" },
110
+ "messages": [
111
+ {
112
+ "role": "user",
113
+ "content": [{ "type": "text", "text": "Hello" }]
114
+ }
115
+ ]
116
+ }
117
+ ```
118
+
119
+ Example provider event:
120
+
121
+ ```json
122
+ {
123
+ "type": "content_delta",
124
+ "content": { "type": "text", "text": "Hello" }
125
+ }
126
+ ```
127
+
128
+ ## Implementation example
129
+
130
+ ```ts
131
+ import type {
132
+ AgentConfig,
133
+ AgentDefinition,
134
+ AIProvider,
135
+ AssembleProviderInputOptions,
136
+ CommandDefinition,
137
+ CompactionStrategy,
138
+ ConfigLayer,
139
+ ConfigProvider,
140
+ ContextProvider,
141
+ CredentialResolver,
142
+ DefaultInputBuildContext,
143
+ Extension,
144
+ InputBuilder,
145
+ ManifestContributionDeclaration,
146
+ ManifestResourceDeclaration,
147
+ Middleware,
148
+ PrismManifest,
149
+ PromptBuilder,
150
+ PromptTemplateOptions,
151
+ ResourceLoader,
152
+ SettingsProvider,
153
+ Skill,
154
+ StoreFactory,
155
+ ToolDefinition,
156
+ } from "@arnilo/prism";
157
+ import { assembleProviderInput, createDefaultInputBuilder, createDefaultPromptBuilder, createSkillRegistry, renderPromptTemplate, resolveActiveSkills, resolveContextProviders } from "@arnilo/prism";
158
+
159
+ const provider: AIProvider = {
160
+ id: "mock",
161
+ async *generate() {
162
+ yield { type: "done" };
163
+ },
164
+ };
165
+
166
+ const context: ContextProvider = {
167
+ name: "demo-context",
168
+ resolve() {
169
+ return [{ title: "Demo", content: "Public contract example." }];
170
+ },
171
+ };
172
+
173
+ const tool: ToolDefinition = {
174
+ name: "echo",
175
+ parameters: { type: "object" },
176
+ execute(_args, ctx) {
177
+ return { toolCallId: ctx.toolCallId, name: "echo", value: "ok" };
178
+ },
179
+ };
180
+
181
+ const skill: Skill = {
182
+ name: "brief",
183
+ instructions: "Answer briefly.",
184
+ toolNames: ["echo"],
185
+ };
186
+
187
+ const command: CommandDefinition = {
188
+ name: "say",
189
+ execute() {
190
+ return { name: "say", value: "ok" };
191
+ },
192
+ };
193
+
194
+ const inputBuilder: InputBuilder = {
195
+ name: "plain-text",
196
+ build(input) {
197
+ return typeof input === "string" ? [{ role: "user", content: [{ type: "text", text: input }] }] : [];
198
+ },
199
+ };
200
+
201
+ const defaultInputContext: DefaultInputBuildContext = {
202
+ systemInstructions: "Follow host policy.",
203
+ attachments: [{ name: "notes.md", text: "notes" }],
204
+ toolResults: [{ toolCallId: "call_1", name: "echo", value: "ok" }],
205
+ };
206
+
207
+ const templateOptions: PromptTemplateOptions = { missing: "throw" };
208
+ const renderedPrompt = renderPromptTemplate("Hello {{name}}", { name: "world" }, templateOptions);
209
+ const defaultMessages = await createDefaultInputBuilder().build(renderedPrompt, defaultInputContext);
210
+
211
+ const assemblyOptions: AssembleProviderInputOptions = {
212
+ model: { provider: "mock", model: "demo-model" },
213
+ input: "Hello",
214
+ contextProviders: [context],
215
+ promptBuilder: createDefaultPromptBuilder(),
216
+ tools: [tool],
217
+ skills: [skill],
218
+ };
219
+
220
+ const skillRegistry = createSkillRegistry([skill]);
221
+ const activeSkills = resolveActiveSkills({ registry: skillRegistry, names: ["brief"], tools: [tool] });
222
+ const resolvedContext = await resolveContextProviders({ providers: [context], messages: defaultMessages });
223
+ const providerInput = await assembleProviderInput({ ...assemblyOptions, skills: activeSkills });
224
+
225
+ const promptBuilder: PromptBuilder = {
226
+ name: "default-prompt",
227
+ build(request) {
228
+ return request.messages;
229
+ },
230
+ };
231
+
232
+ const providerRequestMiddleware: Middleware<{ metadata?: Record<string, unknown> }> = (request) => ({
233
+ ...request,
234
+ metadata: { ...request.metadata, source: "demo" },
235
+ });
236
+
237
+ const compaction: CompactionStrategy = {
238
+ name: "simple-summary",
239
+ compact() {
240
+ return { summary: "Summary placeholder." };
241
+ },
242
+ };
243
+
244
+ const configLayer: ConfigLayer = { name: "runtime", config: { demo: { enabled: true } } };
245
+ const configProvider: ConfigProvider = { name: "host", load: () => configLayer.config };
246
+ const manifestContribution: ManifestContributionDeclaration = {
247
+ kind: "tool",
248
+ name: "demo.echo",
249
+ module: "./tool.js",
250
+ };
251
+ const manifestResource: ManifestResourceDeclaration = {
252
+ uri: "package://demo/prompt.md",
253
+ purpose: "prompt",
254
+ };
255
+ const manifest: PrismManifest = {
256
+ name: "demo-package",
257
+ configDefaults: configLayer.config,
258
+ contributions: [manifestContribution],
259
+ resources: [manifestResource],
260
+ };
261
+
262
+ const agentDefinition: AgentDefinition = {
263
+ name: "demo-agent",
264
+ create() {
265
+ throw new Error("Agent runtime is implemented in a later phase.");
266
+ },
267
+ };
268
+
269
+ const config: AgentConfig = {
270
+ id: "demo-agent",
271
+ model: { provider: "mock", model: "demo-model" },
272
+ provider,
273
+ context: [context],
274
+ skills: [skill],
275
+ tools: [tool],
276
+ compaction: { strategy: compaction, thresholdEntries: 40, keepRecentEntries: 8 },
277
+ retry: { maxAttempts: 3, baseDelayMs: 50 },
278
+ };
279
+
280
+ const extension: Extension = {
281
+ name: "demo-extension",
282
+ setup(api) {
283
+ api.registerProvider(provider);
284
+ api.registerContextProvider(context);
285
+ api.registerSkill(skill);
286
+ api.registerTool(tool);
287
+ },
288
+ };
289
+
290
+ const resources: ResourceLoader = {
291
+ async load(uri) {
292
+ return { uri, mediaType: "text/plain", text: "example" };
293
+ },
294
+ };
295
+
296
+ const storeFactory: StoreFactory = {
297
+ name: "memory",
298
+ create() {
299
+ return { append: async () => undefined, list: async () => [] };
300
+ },
301
+ };
302
+
303
+ const settings: SettingsProvider = {
304
+ get<T>(key: string) {
305
+ return key === "demo.enabled" ? (true as T) : undefined;
306
+ },
307
+ };
308
+
309
+ const credentials: CredentialResolver = {
310
+ resolve() {
311
+ return undefined;
312
+ },
313
+ };
314
+
315
+ void config;
316
+ void command;
317
+ void inputBuilder;
318
+ void renderedPrompt;
319
+ void defaultMessages;
320
+ void activeSkills;
321
+ void resolvedContext;
322
+ void providerInput;
323
+ void promptBuilder;
324
+ void compaction;
325
+ void configProvider;
326
+ void manifest;
327
+ void providerRequestMiddleware;
328
+ void agentDefinition;
329
+ void extension;
330
+ void resources;
331
+ void storeFactory;
332
+ void settings;
333
+ void credentials;
334
+ ```
335
+
336
+ ## Extension and configuration notes
337
+
338
+ - Contracts are host-owned and package-friendly. External packages can implement `AIProvider`, `ToolDefinition`, `CommandDefinition`, `AgentDefinition`, `InputBuilder`, `PromptBuilder`, `Middleware`, `ContextProvider`, `Skill`, `Extension`, config providers, data-only manifests, compaction strategies, store factories, resource loaders, settings providers, and credential resolvers.
339
+ - `ExtensionAPI` is implemented by the extension kernel. It exposes explicit registries, ordered middleware registration, ordered event subscription/emission, and registration methods for Phase 2 contribution categories.
340
+ - `AgentConfig.provider` can hold a direct provider instance for simple host wiring. Hosts that need config-driven selection should use `ModelConfig.provider` with explicit `createProviderRegistry()` / `createModelRegistry()` objects; Prism does not create a hidden global provider registry.
341
+ - `SettingsProvider` and `CredentialResolver` are explicit dependencies. Prism must not hide global settings or credentials behind these contracts, and `CredentialResolver` should be passed only to the edge that needs a credential.
342
+ - `PrismManifest` is data-only. It can describe contribution modules/resources and config defaults, but parsing it does not import modules, execute package code, or mutate registries.
343
+ - Resource helper functions decode resources from a caller-provided `ResourceLoader`; Prism does not include filesystem, network, package, or URI router loaders.
344
+ - `createDefaultInputBuilder()` is a small default implementation of `InputBuilder`. It is replaceable and only loads explicit URI resources through a caller-provided `ResourceLoader`.
345
+ - `resolveContextProviders()`, `createDefaultPromptBuilder()`, `assembleProviderInput()`, `createSkillRegistry()`, `resolveActiveSkills()`, and `renderPromptTemplate()` are replaceable Phase 5 helpers. They do not execute tools, evaluate template code, or grant tool permissions.
346
+ - `createAgent()` and `createAgentSession()` implement the session runtime. They use explicit providers only; no hidden provider registry is created. Store-backed sessions use explicit `SessionStore` values and branch methods on `AgentSession`. `AgentSession.compact()` and `AgentConfig`/`RunOptions.compaction` provide manual and opt-in auto-compaction. `AgentConfig`/`RunOptions.retry` provide bounded provider-turn retry before observable output.
347
+ - `createMemorySessionStore()` is the built-in in-memory `SessionStore`. Node hosts can opt into file durability with `@arnilo/prism/node/session-store-jsonl`. `createSessionEntry()`, `getSessionBranchEntries()`, `listSessionBranches()`, and `rebuildSessionContext()` are pure helpers for branch-aware session entries. `rebuildSessionContext()` understands compaction entries produced by `createDefaultCompactionStrategy()`, reducing provider-context messages while keeping raw entries. They do not read files or call providers.
348
+
349
+ ## Security and performance notes
350
+
351
+ - Type-only imports have no runtime side effects.
352
+ - Contracts do not create clients, stores, registries, background work, config discovery, package imports, or network calls.
353
+ - Host apps own credentials. Do not put secrets in messages, prompts, provider events, agent events, session entries, tool results, logs, or docs examples. Pass known secret strings to compaction options when summaries may include sensitive text.
354
+ - Use `unknown`/metadata fields for host data, but validate at trust boundaries before executing tools or loading resources.
355
+ - App-specific tool categories and business domains do not belong in public contracts.
356
+
357
+ ## Related APIs
358
+
359
+ - [Input and prompt assembly](input-and-prompt-assembly.md): prompt template expansion and default input builder for strings, messages, history, attachments, resources, summaries, and tool results.
360
+ - [Context and skills](context-and-skills.md): ordered context resolution, skill registry, and progressive disclosure.
361
+ - [Configuration and manifests](configuration-and-manifests.md): in-memory config merge helpers and data-only package manifest validation.
362
+ - [Resource loading](resource-loading.md): text, JSON, and manifest helpers over caller-provided resource loaders.
363
+ - [Extension kernel and event bus](extensions.md): runtime implementation of `ExtensionAPI`, ordered events, and extension error isolation.
364
+ - [Middleware hooks](middleware-hooks.md): ordered hook registry for runtime boundaries.
365
+ - [Contribution registries](contribution-registries.md): explicit registries for contribution contracts.
366
+ - [Tools](tools.md): active tool registry and exact allow/deny filtering built on `ToolDefinition`.
367
+ - [Agent/session runtime](agent-session-runtime.md): `createAgent()` / `createAgentSession()` runtime, `AgentSession.compact()`, and auto-compaction config built on these contracts.
368
+ - [Session stores and branching](session-stores-and-branching.md): branch-aware `SessionEntry` helpers and context rebuild.
369
+ - [Compaction and retry policies](compaction-and-retry.md): default compaction strategy, default retry policy, runtime compaction/retry options, middleware payloads, and compaction entry data.
370
+ - [Provider layer](provider-layer.md): runtime registries, provider event helpers, and mock provider built on these contracts.
371
+ - [Provider conformance](provider-conformance.md): testing subpath for network-free provider adapter checks.
372
+ - [Credentials and redaction](credentials-and-redaction.md): helpers for resolving host-owned credentials, explicit resolver order, OAuth refresh, env-object lookup, and redacting known secret values.
373
+ - [OpenAI-compatible provider](providers/openai-compatible.md): optional provider adapter implementing `AIProvider`.
374
+
375
+ Phase 10 public helpers include `createStaticSettingsProvider`, `createChainedSettingsProvider`, `createMemoryCredentialStore`, `createChainedCredentialResolver`, `createStaticTrustPolicy`, `assertTrusted`, `createStaticPermissionPolicy`, `assertPermission`, and `createSecretRedactor`. Phase 11 auth/request/prompt helpers include `createExplicitCredentialResolver`, `createEnvCredentialResolver`, `refreshOAuthCredential`, `createProviderRequestPolicyChain`, `createSessionCachePolicy`, `mergeProviderRequestOptions`, `composeSystemPrompt`, and `mergeSystemPromptConfig`; they do not read env vars, persist OAuth tokens, create cache stores, discover prompt files, or load packages unless the host supplies that behavior. `@arnilo/prism/testing/provider-conformance` exports network-free provider assertion helpers. Node subpaths `@arnilo/prism/node/settings` and `@arnilo/prism/node/trust` are explicit filesystem/path helpers.
@@ -0,0 +1,141 @@
1
+ # Release and install
2
+
3
+ ## What it does
4
+
5
+ Prism is published as one core package plus seven first-party workspace packages and three umbrella convenience packages. This page describes how they are packed, what each tarball contains, how to install them, the required `@arnilo/prism` peer dependency, the release workflow, and the offline test budget.
6
+
7
+ Core package:
8
+
9
+ - `@arnilo/prism` — the runtime, contracts, registries, streaming events, CLI, and the `/docs` hub. `files`: `dist` (with `!dist/__tests__` and `!dist/**/*.map` negations), `docs`, `CHANGELOG.md`. `bin`: `prism` -> `./dist/cli.js`. `sideEffects`: `["dist/cli.js"]`.
10
+
11
+ First-party workspace packages (each `peerDependencies: { "@arnilo/prism": "0.0.1" }`, non-optional; `sideEffects: false`):
12
+
13
+ - `@arnilo/prism-provider-openai`, `@arnilo/prism-provider-openrouter`, `@arnilo/prism-provider-kimi`, `@arnilo/prism-provider-zai`, `@arnilo/prism-provider-opencode-go` — provider adapters.
14
+ - `@arnilo/prism-compaction-llm` — optional LLM-backed compaction strategy.
15
+ - `@arnilo/prism-compaction-observational-memory` — optional source-backed observational memory.
16
+
17
+ Umbrella packages (pure manifests, no code, no `dist`; ship only `README.md`; use hard `dependencies` to transitively install their family):
18
+
19
+ - `@arnilo/prism-providers` — depends on all 5 `@arnilo/prism-provider-*` packages.
20
+ - `@arnilo/prism-compaction` — depends on both `@arnilo/prism-compaction-*` packages.
21
+ - `@arnilo/prism-all` — depends on `@arnilo/prism` + `@arnilo/prism-providers` + `@arnilo/prism-compaction` (the full kit in one install).
22
+
23
+ Each code package's `files` array is `["dist", "!dist/__tests__", "!dist/**/*.map", "README.md", "CHANGELOG.md"]`; `README.md`, `LICENSE`, and `CHANGELOG.md` ship in every code-package tarball, the core tarball also ships the `docs/` directory, and umbrella tarballs ship only `README.md` + `package.json`.
24
+
25
+ ## When to use it
26
+
27
+ Use this page when installing Prism into a host app, when adding a first-party package, when cutting a release, or when investigating why a tarball contains (or excludes) a file.
28
+
29
+ Consumers install the core package for the runtime and add first-party packages for provider adapters or compaction strategies. Each first-party package requires the `@arnilo/prism` peer at its declared version; install `@arnilo/prism` alongside them or npm will report an unmet peer.
30
+
31
+ ## Inputs / request
32
+
33
+ | Operation | Command |
34
+ | --- | --- |
35
+ | Install core only | `npm install @arnilo/prism` |
36
+ | Install core + all providers | `npm install @arnilo/prism @arnilo/prism-providers` |
37
+ | Install core + compaction | `npm install @arnilo/prism @arnilo/prism-compaction` |
38
+ | Install everything (core + providers + compaction) | `npm install @arnilo/prism-all` |
39
+ | Install core + a single provider | `npm install @arnilo/prism @arnilo/prism-provider-openai` |
40
+ | Build everything (core + workspaces) | `npm run build` |
41
+ | Run the default (network-free) test suite | `npm test` |
42
+ | Dry-run pack core + every package | `npm run pack:dry-run` |
43
+ | Local mirror of the release verify gate | `npm run release:dry-run` |
44
+
45
+ Public core import specifiers (from the root `exports` map):
46
+
47
+ | Specifier | Resolves to |
48
+ | --- | --- |
49
+ | `@arnilo/prism` | `dist/index.js` / `dist/index.d.ts` |
50
+ | `@arnilo/prism/providers/openai-compatible` | `dist/providers/openai-compatible.{js,d.ts}` |
51
+ | `@arnilo/prism/testing/provider-conformance` | `dist/testing/provider-conformance.{js,d.ts}` |
52
+ | `@arnilo/prism/node/config` | `dist/node/config.{js,d.ts}` |
53
+ | `@arnilo/prism/node/settings` | `dist/node/settings.{js,d.ts}` |
54
+ | `@arnilo/prism/node/trust` | `dist/node/trust.{js,d.ts}` |
55
+ | `@arnilo/prism/node/session-store-jsonl` | `dist/node/session-store-jsonl.{js,d.ts}` |
56
+
57
+ ## Outputs / response / events
58
+
59
+ A packed tarball contains only public compiled output and release files:
60
+
61
+ - `dist/**` compiled `.js` and `.d.ts` for every exported subpath.
62
+ - `README.md`, `LICENSE`, `CHANGELOG.md` in every package.
63
+ - The core tarball additionally ships the full `docs/` directory (the docs hub).
64
+ - `dist/cli.js` and the `bin` link in core.
65
+ - **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.0.1.tgz`; first-party packages produce `arnilo-prism-provider-<name>-0.0.1.tgz` / `arnilo-prism-compaction-<name>-0.0.1.tgz`; umbrella packages produce `arnilo-prism-providers-0.0.1.tgz` / `arnilo-prism-compaction-0.0.1.tgz` / `arnilo-prism-all-0.0.1.tgz`. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
66
+
67
+ Excluded from every tarball by `files` negation:
68
+
69
+ - `dist/__tests__/` — compiled tests and the meta-tests (`packaging.test.js`, `install-smoke.test.js`, `docs.test.js`, `network-free-guard.test.js`, and the phase boundary tests).
70
+ - `dist/**/*.map` — source maps. Source maps are still emitted locally (`tsconfig` `sourceMap: true`) for debugging; the `!dist/**/*.map` line is the **map-retention knob**: remove that negation to ship source maps in releases.
71
+ - `src/`, `plans/`, `.agents/`, `.github/`, `tsconfig*.json`, `roadmap.md`, and `package-lock.json` are never packed (outside the `files` whitelist and/or explicitly ignored).
72
+
73
+ `sideEffects` is `false` for every first-party package (their entrypoints export only types and declarations). Core sets `sideEffects: ["dist/cli.js"]` because `src/cli.ts` runs the CLI and sets `process.exitCode` at import time; every other core entrypoint is side-effect-free.
74
+
75
+ ## Request/response example
76
+
77
+ ```json
78
+ {
79
+ "name": "host-app",
80
+ "type": "module",
81
+ "dependencies": {
82
+ "@arnilo/prism": "0.0.1",
83
+ "@arnilo/prism-provider-openai": "0.0.1",
84
+ "@arnilo/prism-compaction-observational-memory": "0.0.1"
85
+ }
86
+ }
87
+ ```
88
+
89
+ Installing the provider/compaction packages without `@arnilo/prism` present produces an unmet-peer error (the `@arnilo/prism` peer is required, not optional):
90
+
91
+ ```text
92
+ npm error code ERESOLVE
93
+ npm error Could not resolve dependency:
94
+ npm error peer @arnilo/prism@"0.0.1" from @arnilo/prism-provider-openai@0.0.1
95
+ ```
96
+
97
+ ## Implementation example
98
+
99
+ ```ts
100
+ // Core runtime
101
+ import { createAgent, createAgentSession } from "@arnilo/prism";
102
+ // OpenAI-compatible provider subpath
103
+ import { createOpenAICompatibleProvider } from "@arnilo/prism/providers/openai-compatible";
104
+ // Node filesystem config loader
105
+ import { loadConfigFile } from "@arnilo/prism/node/config";
106
+
107
+ const agent = createAgent({ provider: createOpenAICompatibleProvider({ /* ... */ }) });
108
+ const session = createAgentSession(agent, { /* session store, etc. */ });
109
+ ```
110
+
111
+ Local release dry-run mirrors the GitHub Actions `verify` job (build + tests + packaging/install-smoke guards + pack dry-run):
112
+
113
+ ```bash
114
+ npm run release:dry-run
115
+ ```
116
+
117
+ ## Extension and configuration notes
118
+
119
+ - **Required `@arnilo/prism` peer.** Every first-party package declares `peerDependencies: { "@arnilo/prism": "0.0.1" }` with no `peerDependenciesMeta` (non-optional). The range stays pinned to `0.0.1` for the 0.x series and will widen to `^1.0.0` at the 1.x stable release. Inside the workspace each package also declares `"@arnilo/prism": "file:../.."` in `devDependencies` so `npm install` resolves the peer locally; that devDependency is stripped from consumer installs and is not a runtime dependency.
120
+ - **Public access.** All 11 manifests (8 code packages + 3 umbrellas) declare `"publishConfig": { "access": "public" }` so a manual `npm publish` of a scoped `@arnilo/prism-*` package defaults to public rather than `restricted` (paid). The `release.yml` flags (`npm publish --access public` + `npm publish --workspaces --access public`) are belt-and-suspenders backups.
121
+ - **Map retention knob.** Source maps are emitted locally but stripped from tarballs by `!dist/**/*.map`. Removing that `files` negation ships maps in releases (larger tarballs, better consumer stack traces).
122
+ - **Release workflow.** `.github/workflows/release.yml` has two jobs. `verify` runs on push (main/master, `v*` tags) and pull requests: `npm ci`, `npm test` (builds core + workspaces first, then runs the packaging and install-smoke guards), and `npm run pack:dry-run`. `publish` runs only on `refs/tags/v*` after `verify` succeeds: `npm run build`, then `npm publish --access public` for core (first, because packages require the `@arnilo/prism` peer on the registry) and `npm publish --workspaces --access public`. With no `NPM_TOKEN` secret it runs `--dry-run` instead of a real publish. `permissions.id-token: write` is set so `--provenance` can be added later without re-architecting permissions.
123
+ - **Adding a package.** New workspace packages are picked up automatically by `npm run build --workspaces`, `npm test --workspaces`, `npm run pack:dry-run`, the packaging guard (`src/__tests__/packaging.test.ts`), and the install-smoke test (`src/__tests__/install-smoke.test.ts`) via the workspace glob; add the package to both tests' config arrays for explicit per-package assertions.
124
+
125
+ ## Security and performance notes
126
+
127
+ - **No secrets or fixtures in tarballs.** Tests, fixtures, `src/`, `plans/`, `.agents/`, `roadmap.md`, and `tsconfig` files are excluded. The `docs avoid real-looking secret examples` docs check and the packaging guard's deny list prevent secret-bearing fixtures from shipping.
128
+ - **Live tests stay opt-in.** The default `npm test` is network-free by construction and never sets these vars. Three opt-in gate vars exist, each gating a different set of placeholder live smoke tests; none is set by default, in CI, or during release verification. Every gated live test is currently an empty placeholder awaiting provider-specific/worker checks in a later phase.
129
+ - `PRISM_LIVE_PROVIDER_TESTS=1` — gates the five provider packages' `src/__tests__/live.test.ts` (`@arnilo/prism-provider-openai`, `provider-opencode-go`, `provider-openrouter`, `provider-zai`, `provider-kimi`).
130
+ - `PRISM_LIVE_COMPACTION_TESTS=1` — gates `@arnilo/prism-compaction-llm`'s live summary-provider smoke test.
131
+ - `PRISM_LIVE_OBSERVATIONAL_MEMORY_TESTS=1` — gates `@arnilo/prism-compaction-observational-memory`'s live worker/provider checks.
132
+ - These guards use fake-safe names and carry no real credentials; the gated bodies intentionally do not read `OPENAI_API_KEY` or any provider key — they are placeholders. Itemize any provider-specific key env here only when a future phase adds a real live check that reads it.
133
+ - Enforced by `network-free-guard.test.ts` (default suite stays network-free) and by source-scanning meta-tests that assert each `live.test.ts` keeps its `skip:` guard.
134
+ - **Install smoke is offline.** The install-smoke test packs core + every package into a temp dir and installs the tarballs with `--offline --no-audit --no-fund` into a fresh temp project; zero registry fetches happen because Prism has no runtime dependencies.
135
+ - **Offline test budget.** The default `npm test` (no `PRISM_LIVE_PROVIDER_TESTS`) is pinned at **< 30s on Node 20** with a measured baseline of ~22s (build ~12.5s + tests ~9.5s, tests parallelized). The `npm test` CI step has `timeout-minutes: 3` as a hang backstop. If a future change pushes the CI median over 30s, raise it here and in `roadmap.md` Phase 17 with rationale rather than silently regressing.
136
+
137
+ ## Related APIs
138
+
139
+ - [`docs/provider-packages.md`](provider-packages.md): first-party provider package layout and setup.
140
+ - [`docs/cli-rpc.md`](cli-rpc.md): the `prism` CLI bin and RPC protocol shipped as `dist/cli.js`.
141
+ - [`docs/configuration-and-manifests.md`](configuration-and-manifests.md): package manifest merging and validation.
@@ -0,0 +1,97 @@
1
+ # Resource loading
2
+
3
+ ## What it does
4
+
5
+ Resource helpers decode text, JSON objects, and Prism manifests through a caller-provided `ResourceLoader`.
6
+
7
+ APIs:
8
+
9
+ - `loadTextResource()`
10
+ - `loadJsonResource()`
11
+ - `loadManifestResource()`
12
+ - `ResourceLoader`, `Resource`, `ResourceLoadContext`
13
+
14
+ ## When to use it
15
+
16
+ Use these helpers when a host already has a resource loader and wants small decoding helpers for prompts, skills, manifests, or package resources.
17
+
18
+ Do not use them for filesystem access, network access, package discovery, URI routing, caching, trust policy, dynamic imports, or agent/session runtime startup. The host-provided loader owns all I/O and trust decisions.
19
+
20
+ ## Inputs / request
21
+
22
+ ```ts
23
+ loadTextResource(loader, uri, context?)
24
+ loadJsonResource(loader, uri, context?)
25
+ loadManifestResource(loader, uri, context?)
26
+ ```
27
+
28
+ Inputs:
29
+
30
+ | Field | Type | Purpose |
31
+ | --- | --- | --- |
32
+ | `loader` | `ResourceLoader` | Host-owned loader called once for the requested URI. |
33
+ | `uri` | `string` | Resource identifier chosen by the host/package. |
34
+ | `context` | `ResourceLoadContext` | Optional abort signal and metadata forwarded to the loader. |
35
+
36
+ ## Outputs / response / events
37
+
38
+ - `loadTextResource()` returns `resource.text` or decodes `resource.data` with `TextDecoder`.
39
+ - `loadJsonResource()` parses text as JSON and returns a JSON object.
40
+ - `loadManifestResource()` parses a JSON object and validates it with `parsePrismManifest()`.
41
+ - No events are emitted and no registries are modified.
42
+
43
+ ## Request/response example
44
+
45
+ ```json
46
+ {
47
+ "uri": "package://demo/prism.manifest.json",
48
+ "resource": {
49
+ "mediaType": "application/json",
50
+ "text": "{\"name\":\"demo-package\"}"
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Implementation example
56
+
57
+ ```ts
58
+ import { loadManifestResource, loadTextResource, type ResourceLoader } from "@arnilo/prism";
59
+
60
+ const loader: ResourceLoader = {
61
+ async load(uri, context) {
62
+ context?.signal?.throwIfAborted();
63
+ if (uri.endsWith("prism.manifest.json")) {
64
+ return { uri, mediaType: "application/json", text: '{"name":"demo-package"}' };
65
+ }
66
+ return { uri, mediaType: "text/markdown", text: "Prompt text" };
67
+ },
68
+ };
69
+
70
+ const manifest = await loadManifestResource(loader, "package://demo/prism.manifest.json");
71
+ const prompt = await loadTextResource(loader, "package://demo/prompt.md");
72
+
73
+ console.log(manifest.name, prompt);
74
+ ```
75
+
76
+ ## Extension and configuration notes
77
+
78
+ - Manifest `resources` entries can reference prompts, skills, manifests, and package resources by URI.
79
+ - Helpers do not choose a loader by URI scheme. Hosts can use contribution registries or their own routing when they need that.
80
+ - Helpers do not execute loaded text or imported modules. Package activation remains a host decision.
81
+ - `loadManifestResource()` only validates manifest data; it does not register manifest contributions.
82
+
83
+ ## Security and performance notes
84
+
85
+ - The caller-provided loader owns URI trust, permissions, filesystem/network access, and credential boundaries.
86
+ - Node hosts can use `@arnilo/prism/node/trust` (`createPathTrustPolicy`) to guard filesystem paths. It resolves symlinks on the trusted root and target and rejects paths whose realpath escapes the root; missing roots or realpath errors fail closed.
87
+ - Helpers call `loader.load()` once per helper call and do not cache, scan, list, watch, poll, or discover packages.
88
+ - JSON parsing fails closed for invalid JSON or non-object JSON.
89
+ - Do not put resolved credential values, tokens, headers, or executable code in loaded config, manifests, prompts, skills, or metadata.
90
+
91
+ ## Related APIs
92
+
93
+ - [Configuration and manifests](configuration-and-manifests.md): data-only manifests and manifest resource declarations.
94
+ - [Contribution registries](contribution-registries.md): host-owned registries can store resource loaders.
95
+ - [Public contracts](public-contracts.md): base `ResourceLoader`, `Resource`, and `ResourceLoadContext` contracts.
96
+
97
+ `ResourceLoadContext.permission` checks `resource:<uri>:load` before calling the loader. Prism still does no resource discovery, package discovery, or trust prompts; hosts own those decisions. See [Security/auth/trust](settings-auth-trust-security.md).