ai-runtime-engine 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/LICENSE +15 -0
- package/README.md +489 -0
- package/dist/artifacts/artifacts.d.ts +28 -0
- package/dist/artifacts/artifacts.js +46 -0
- package/dist/benchmark/benchmark.d.ts +23 -0
- package/dist/benchmark/benchmark.js +40 -0
- package/dist/cli/cli.d.ts +6 -0
- package/dist/cli/cli.js +161 -0
- package/dist/cli/commands/cleanup.d.ts +47 -0
- package/dist/cli/commands/cleanup.js +96 -0
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.js +28 -0
- package/dist/cli/commands/doctor.d.ts +57 -0
- package/dist/cli/commands/doctor.js +86 -0
- package/dist/cli/commands/executions.d.ts +9 -0
- package/dist/cli/commands/executions.js +25 -0
- package/dist/cli/commands/info.d.ts +43 -0
- package/dist/cli/commands/info.js +53 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.js +75 -0
- package/dist/cli/commands/inspect.d.ts +16 -0
- package/dist/cli/commands/inspect.js +60 -0
- package/dist/cli/commands/phase2.d.ts +22 -0
- package/dist/cli/commands/phase2.js +83 -0
- package/dist/cli/commands/route.d.ts +14 -0
- package/dist/cli/commands/route.js +49 -0
- package/dist/cli/commands/run.d.ts +11 -0
- package/dist/cli/commands/run.js +37 -0
- package/dist/cli/commands/setup.d.ts +34 -0
- package/dist/cli/commands/setup.js +104 -0
- package/dist/cli/commands/skills.d.ts +28 -0
- package/dist/cli/commands/skills.js +48 -0
- package/dist/cli/commands/test.d.ts +7 -0
- package/dist/cli/commands/test.js +29 -0
- package/dist/cli/context.d.ts +12 -0
- package/dist/cli/context.js +16 -0
- package/dist/cli/interactive/repl.d.ts +6 -0
- package/dist/cli/interactive/repl.js +45 -0
- package/dist/cli/interactive/session.d.ts +36 -0
- package/dist/cli/interactive/session.js +356 -0
- package/dist/cli/prompt.d.ts +6 -0
- package/dist/cli/prompt.js +18 -0
- package/dist/cli/render.d.ts +7 -0
- package/dist/cli/render.js +14 -0
- package/dist/comparison/analysis.d.ts +46 -0
- package/dist/comparison/analysis.js +177 -0
- package/dist/comparison/comparator.d.ts +46 -0
- package/dist/comparison/comparator.js +270 -0
- package/dist/comparison/comparison.d.ts +140 -0
- package/dist/comparison/comparison.js +9 -0
- package/dist/comparison/render.d.ts +7 -0
- package/dist/comparison/render.js +66 -0
- package/dist/config/defaults.d.ts +52 -0
- package/dist/config/defaults.js +56 -0
- package/dist/config/load.d.ts +17 -0
- package/dist/config/load.js +50 -0
- package/dist/config/providerDefaults.d.ts +17 -0
- package/dist/config/providerDefaults.js +61 -0
- package/dist/config/schema.d.ts +9 -0
- package/dist/config/schema.js +78 -0
- package/dist/context/budget.d.ts +13 -0
- package/dist/context/budget.js +17 -0
- package/dist/context/compiler.d.ts +61 -0
- package/dist/context/compiler.js +125 -0
- package/dist/context/tokens.d.ts +19 -0
- package/dist/context/tokens.js +38 -0
- package/dist/conversations/conversations.d.ts +38 -0
- package/dist/conversations/conversations.js +64 -0
- package/dist/core/capabilities/evidence.d.ts +40 -0
- package/dist/core/capabilities/evidence.js +102 -0
- package/dist/core/capabilities/overlay.d.ts +15 -0
- package/dist/core/capabilities/overlay.js +0 -0
- package/dist/core/capabilities/taxonomy.d.ts +19 -0
- package/dist/core/capabilities/taxonomy.js +25 -0
- package/dist/core/fallback/errors.d.ts +30 -0
- package/dist/core/fallback/errors.js +80 -0
- package/dist/core/fallback/fallback.d.ts +40 -0
- package/dist/core/fallback/fallback.js +82 -0
- package/dist/core/fallback/retryPolicy.d.ts +11 -0
- package/dist/core/fallback/retryPolicy.js +14 -0
- package/dist/core/health/health.d.ts +3 -0
- package/dist/core/health/health.js +5 -0
- package/dist/core/health/monitor.d.ts +23 -0
- package/dist/core/health/monitor.js +82 -0
- package/dist/core/policies/budget.d.ts +19 -0
- package/dist/core/policies/budget.js +37 -0
- package/dist/core/registry/builtinTasks.d.ts +8 -0
- package/dist/core/registry/builtinTasks.js +54 -0
- package/dist/core/registry/registry.d.ts +18 -0
- package/dist/core/registry/registry.js +33 -0
- package/dist/core/registry/taskRegistry.d.ts +15 -0
- package/dist/core/registry/taskRegistry.js +30 -0
- package/dist/core/router/confidence.d.ts +7 -0
- package/dist/core/router/confidence.js +20 -0
- package/dist/core/router/dimensions.d.ts +16 -0
- package/dist/core/router/dimensions.js +60 -0
- package/dist/core/router/executor.d.ts +16 -0
- package/dist/core/router/executor.js +25 -0
- package/dist/core/router/filter.d.ts +34 -0
- package/dist/core/router/filter.js +113 -0
- package/dist/core/router/normalize.d.ts +30 -0
- package/dist/core/router/normalize.js +119 -0
- package/dist/core/router/request.d.ts +4 -0
- package/dist/core/router/request.js +21 -0
- package/dist/core/router/router.d.ts +32 -0
- package/dist/core/router/router.js +195 -0
- package/dist/core/router/routingPrefs.d.ts +11 -0
- package/dist/core/router/routingPrefs.js +30 -0
- package/dist/core/router/scorer.d.ts +19 -0
- package/dist/core/router/scorer.js +50 -0
- package/dist/core/router/weights.d.ts +9 -0
- package/dist/core/router/weights.js +31 -0
- package/dist/core/validation/validator.d.ts +16 -0
- package/dist/core/validation/validator.js +33 -0
- package/dist/discovery/modelCatalog.d.ts +28 -0
- package/dist/discovery/modelCatalog.js +105 -0
- package/dist/discovery/openapi.d.ts +25 -0
- package/dist/discovery/openapi.js +76 -0
- package/dist/executions/checkpoint.d.ts +26 -0
- package/dist/executions/checkpoint.js +114 -0
- package/dist/executions/execution.d.ts +51 -0
- package/dist/executions/execution.js +8 -0
- package/dist/executions/store.d.ts +52 -0
- package/dist/executions/store.js +124 -0
- package/dist/generation/generateAdapter.d.ts +17 -0
- package/dist/generation/generateAdapter.js +30 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.js +107 -0
- package/dist/learning/feedback.d.ts +9 -0
- package/dist/learning/feedback.js +18 -0
- package/dist/learning/learningStore.d.ts +68 -0
- package/dist/learning/learningStore.js +138 -0
- package/dist/learning/performanceStore.d.ts +27 -0
- package/dist/learning/performanceStore.js +0 -0
- package/dist/marketplace/presets.d.ts +24 -0
- package/dist/marketplace/presets.js +52 -0
- package/dist/mcp/mcp.d.ts +31 -0
- package/dist/mcp/mcp.js +54 -0
- package/dist/memory/bm25.d.ts +16 -0
- package/dist/memory/bm25.js +56 -0
- package/dist/memory/classifier.d.ts +14 -0
- package/dist/memory/classifier.js +17 -0
- package/dist/memory/memory.d.ts +80 -0
- package/dist/memory/memory.js +191 -0
- package/dist/orchestration/executor.d.ts +35 -0
- package/dist/orchestration/executor.js +65 -0
- package/dist/orchestration/orchestrator.d.ts +42 -0
- package/dist/orchestration/orchestrator.js +63 -0
- package/dist/orchestration/plan.d.ts +37 -0
- package/dist/orchestration/plan.js +70 -0
- package/dist/orchestration/planner.d.ts +29 -0
- package/dist/orchestration/planner.js +69 -0
- package/dist/plugin/ai.d.ts +82 -0
- package/dist/plugin/ai.js +167 -0
- package/dist/probing/probe.d.ts +25 -0
- package/dist/probing/probe.js +63 -0
- package/dist/providers/factory.d.ts +18 -0
- package/dist/providers/factory.js +54 -0
- package/dist/providers/httpClient.d.ts +34 -0
- package/dist/providers/httpClient.js +80 -0
- package/dist/providers/httpProvider.d.ts +49 -0
- package/dist/providers/httpProvider.js +135 -0
- package/dist/providers/mock/demo.d.ts +13 -0
- package/dist/providers/mock/demo.js +58 -0
- package/dist/providers/mock/mockProvider.d.ts +35 -0
- package/dist/providers/mock/mockProvider.js +121 -0
- package/dist/providers/mock/scenarios.d.ts +44 -0
- package/dist/providers/mock/scenarios.js +30 -0
- package/dist/providers/provider.d.ts +26 -0
- package/dist/providers/provider.js +11 -0
- package/dist/providers/wire/anthropicWire.d.ts +6 -0
- package/dist/providers/wire/anthropicWire.js +83 -0
- package/dist/providers/wire/openaiWire.d.ts +7 -0
- package/dist/providers/wire/openaiWire.js +81 -0
- package/dist/providers/wire/registry.d.ts +8 -0
- package/dist/providers/wire/registry.js +20 -0
- package/dist/providers/wire/types.d.ts +39 -0
- package/dist/providers/wire/types.js +24 -0
- package/dist/runtime/config.d.ts +31 -0
- package/dist/runtime/config.js +121 -0
- package/dist/runtime/context.d.ts +34 -0
- package/dist/runtime/context.js +11 -0
- package/dist/runtime/events.d.ts +99 -0
- package/dist/runtime/events.js +82 -0
- package/dist/runtime/host.d.ts +27 -0
- package/dist/runtime/host.js +7 -0
- package/dist/runtime/intent/classifier.d.ts +30 -0
- package/dist/runtime/intent/classifier.js +60 -0
- package/dist/runtime/intent/signals.d.ts +19 -0
- package/dist/runtime/intent/signals.js +46 -0
- package/dist/runtime/modes/availability.d.ts +11 -0
- package/dist/runtime/modes/availability.js +17 -0
- package/dist/runtime/modes/chat.d.ts +18 -0
- package/dist/runtime/modes/chat.js +67 -0
- package/dist/runtime/modes/modeResolver.d.ts +43 -0
- package/dist/runtime/modes/modeResolver.js +78 -0
- package/dist/runtime/policy.d.ts +72 -0
- package/dist/runtime/policy.js +59 -0
- package/dist/runtime/providerView.d.ts +62 -0
- package/dist/runtime/providerView.js +105 -0
- package/dist/runtime/routing.d.ts +26 -0
- package/dist/runtime/routing.js +65 -0
- package/dist/runtime/runtime.d.ts +191 -0
- package/dist/runtime/runtime.js +718 -0
- package/dist/runtime/types.d.ts +153 -0
- package/dist/runtime/types.js +9 -0
- package/dist/runtime/workspace/detectors.d.ts +15 -0
- package/dist/runtime/workspace/detectors.js +57 -0
- package/dist/runtime/workspace/workspace.d.ts +29 -0
- package/dist/runtime/workspace/workspace.js +116 -0
- package/dist/security/credentials.d.ts +26 -0
- package/dist/security/credentials.js +34 -0
- package/dist/security/redact.d.ts +16 -0
- package/dist/security/redact.js +57 -0
- package/dist/skills/builtins/fileAnalyzer.d.ts +7 -0
- package/dist/skills/builtins/fileAnalyzer.js +47 -0
- package/dist/skills/builtins/repositoryAnalyzer.d.ts +6 -0
- package/dist/skills/builtins/repositoryAnalyzer.js +47 -0
- package/dist/skills/discovery.d.ts +61 -0
- package/dist/skills/discovery.js +211 -0
- package/dist/skills/manifest.d.ts +30 -0
- package/dist/skills/manifest.js +75 -0
- package/dist/skills/registry.d.ts +15 -0
- package/dist/skills/registry.js +22 -0
- package/dist/skills/skill.d.ts +64 -0
- package/dist/skills/skill.js +8 -0
- package/dist/store/area.d.ts +54 -0
- package/dist/store/area.js +164 -0
- package/dist/store/paths.d.ts +15 -0
- package/dist/store/paths.js +48 -0
- package/dist/store/store.d.ts +59 -0
- package/dist/store/store.js +140 -0
- package/dist/telemetry/sinks/file.d.ts +12 -0
- package/dist/telemetry/sinks/file.js +28 -0
- package/dist/telemetry/telemetry.d.ts +36 -0
- package/dist/telemetry/telemetry.js +63 -0
- package/dist/tools/builtins/filesystem.d.ts +7 -0
- package/dist/tools/builtins/filesystem.js +53 -0
- package/dist/tools/builtins/git.d.ts +10 -0
- package/dist/tools/builtins/git.js +66 -0
- package/dist/tools/builtins/shell.d.ts +17 -0
- package/dist/tools/builtins/shell.js +91 -0
- package/dist/tools/jail.d.ts +12 -0
- package/dist/tools/jail.js +98 -0
- package/dist/tools/permissions.d.ts +25 -0
- package/dist/tools/permissions.js +24 -0
- package/dist/tools/registry.d.ts +10 -0
- package/dist/tools/registry.js +20 -0
- package/dist/tools/runner.d.ts +23 -0
- package/dist/tools/runner.js +64 -0
- package/dist/tools/tool.d.ts +53 -0
- package/dist/tools/tool.js +24 -0
- package/dist/tools/untrusted.d.ts +13 -0
- package/dist/tools/untrusted.js +30 -0
- package/dist/types.d.ts +460 -0
- package/dist/types.js +12 -0
- package/dist/util/clock.d.ts +6 -0
- package/dist/util/clock.js +4 -0
- package/dist/util/extractJson.d.ts +8 -0
- package/dist/util/extractJson.js +54 -0
- package/dist/verification/verify.d.ts +26 -0
- package/dist/verification/verify.js +67 -0
- package/docs/GUIDE.md +358 -0
- package/docs/README.md +21 -0
- package/docs/architecture.md +78 -0
- package/docs/router.md +376 -0
- package/docs/security.md +55 -0
- package/package.json +67 -0
package/docs/GUIDE.md
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# AI Runtime — a hands-on guide
|
|
2
|
+
|
|
3
|
+
A start-to-finish guide to **installing and using `ai-runtime-engine`**. It's written to be *studied*: read
|
|
4
|
+
top to bottom, run the snippets as you go, and you'll understand both **how it works** and **how to use it**.
|
|
5
|
+
|
|
6
|
+
You do **not** need an API key to follow along — a built-in mock provider lets you run everything offline.
|
|
7
|
+
|
|
8
|
+
**Naming, once:** the **product** is *AI Runtime*, the **npm package** is `ai-runtime-engine`, and the
|
|
9
|
+
**command-line tool** is `ai-runtime`. In code you use two classes: **`Runtime`** (the high-level API you'll
|
|
10
|
+
use most) and **`AI`** (the low-level router underneath it).
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Contents
|
|
15
|
+
|
|
16
|
+
1. [What you're installing](#1-what-youre-installing)
|
|
17
|
+
2. [Install](#2-install)
|
|
18
|
+
3. [Your first run (offline, no keys)](#3-your-first-run-offline-no-keys)
|
|
19
|
+
4. [How it works — the mental model](#4-how-it-works--the-mental-model)
|
|
20
|
+
5. [Using real providers](#5-using-real-providers)
|
|
21
|
+
6. [How to use it — worked examples](#6-how-to-use-it--worked-examples)
|
|
22
|
+
7. [The interactive terminal](#7-the-interactive-terminal)
|
|
23
|
+
8. [Configuration](#8-configuration)
|
|
24
|
+
9. [Safety model](#9-safety-model)
|
|
25
|
+
10. [Where to go next](#10-where-to-go-next)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. What you're installing
|
|
30
|
+
|
|
31
|
+
`ai-runtime-engine` is two things in one package:
|
|
32
|
+
|
|
33
|
+
- **A library** — `import { Runtime, AI } from 'ai-runtime-engine'` to embed the runtime in your own code.
|
|
34
|
+
- **A CLI** — the `ai-runtime` command, for an interactive terminal and one-shot runs.
|
|
35
|
+
|
|
36
|
+
The core idea: you configure whatever AI providers you have (cloud APIs, a local model, an internal
|
|
37
|
+
endpoint), and the runtime **routes each request to the best available model** and runs it — so you write
|
|
38
|
+
*what you want*, not *which provider to call*. Around that it adds modes, memory, skills, tools, planning,
|
|
39
|
+
orchestration, comparison, and learning.
|
|
40
|
+
|
|
41
|
+
Requirements: **Node.js 22+**.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. Install
|
|
46
|
+
|
|
47
|
+
As a dependency in your project (gives you the library and `npx ai-runtime`):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install ai-runtime-engine
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or globally, to get the `ai-runtime` command on your PATH:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g ai-runtime-engine
|
|
57
|
+
ai-runtime --help
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 3. Your first run (offline, no keys)
|
|
63
|
+
|
|
64
|
+
You can run the whole pipeline with a **mock provider** — no credentials, no network. Create `first.mjs`:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
import { Runtime, MockProvider, makeModel } from 'ai-runtime-engine';
|
|
68
|
+
|
|
69
|
+
// A fresh runtime with no persistence (nothing written to disk).
|
|
70
|
+
const runtime = new Runtime();
|
|
71
|
+
|
|
72
|
+
// Register one fake provider with one fake model that can "reason" and output "text".
|
|
73
|
+
runtime.ai.registerProvider(new MockProvider({
|
|
74
|
+
id: 'demo',
|
|
75
|
+
models: [makeModel({
|
|
76
|
+
providerId: 'demo',
|
|
77
|
+
id: 'demo-1',
|
|
78
|
+
caps: { intelligence: ['reasoning'], output: ['text'] },
|
|
79
|
+
})],
|
|
80
|
+
}));
|
|
81
|
+
|
|
82
|
+
const result = await runtime.run({ input: 'Say hello and explain what you are.' });
|
|
83
|
+
|
|
84
|
+
console.log('ok:', result.ok);
|
|
85
|
+
console.log('text:', result.response?.text);
|
|
86
|
+
console.log('chose:', result.routing?.selected); // which provider/model was picked
|
|
87
|
+
console.log('why:', result.routing?.ranked?.length, 'candidate(s) considered');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
node first.mjs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You'll see `ok: true`, a mock response, and a **routing trace** showing the decision. That trace is always
|
|
95
|
+
there — every run tells you *what it did and why*.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 4. How it works — the mental model
|
|
100
|
+
|
|
101
|
+
A single `run()` flows through one path. You supply the capabilities; the runtime decides how to use them.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
runtime.run({ input })
|
|
105
|
+
│
|
|
106
|
+
▼ 1. Pick a MODE — auto-detected, or you set it: chat · plan · execute · orchestrate · agent · compare · debug
|
|
107
|
+
│
|
|
108
|
+
▼ 2. Build the CONTEXT under a token budget (a one-line workspace summary, relevant memory, your request)
|
|
109
|
+
│
|
|
110
|
+
▼ 3. ROUTE to a model ──► the ONE router:
|
|
111
|
+
│ filter (capability · health · privacy · cost) → score → pick → execute → validate
|
|
112
|
+
│ → fall back to the next-best model on failure
|
|
113
|
+
│
|
|
114
|
+
▼ 4. For multi-step work: PLAN → run tools/skills → succeed a step only on EVIDENCE → replan on failure
|
|
115
|
+
│
|
|
116
|
+
▼ 5. RESULT { ok, response, routing trace, + plan / comparison / memory as relevant }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Five ideas are worth internalizing:
|
|
120
|
+
|
|
121
|
+
- **Providers are replaceable; capabilities are durable.** You route by *what a task needs* (reasoning,
|
|
122
|
+
JSON output, a big context window…), not by a provider name. Swap providers freely.
|
|
123
|
+
- **One router.** *Every* model call — chat, planning, comparison, a skill's own call — goes through the
|
|
124
|
+
same router. There is never a second, hidden selection engine.
|
|
125
|
+
- **`Runtime` vs `AI`.** `AI` is the low-level router (`ai.run({ task, input })`). `Runtime` wraps it and
|
|
126
|
+
adds modes, memory, skills, orchestration, etc. (`runtime.run({ input })`). Use `Runtime`; reach for `AI`
|
|
127
|
+
only when you want the bare router.
|
|
128
|
+
- **Modes = what kind of work.** A quick answer is `chat`; a multi-step job is `orchestrate`; comparing
|
|
129
|
+
models is `compare`. `auto` (the default) guesses from your request.
|
|
130
|
+
- **Evidence over claims.** A step "succeeds" only when there's proof — a tool returned ok, a validator
|
|
131
|
+
passed — never because a model said "done."
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 5. Using real providers
|
|
136
|
+
|
|
137
|
+
To use a real model, name a provider and put its key in `.env`. The **fastest** way is the CLI:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
ai-runtime setup # detects your project, writes .ai-runtime/config.yaml + .env.example (asks first)
|
|
141
|
+
ai-runtime doctor # tells you which providers are configured and reachable
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Then add a key to `.env`. Recommended starters:
|
|
145
|
+
|
|
146
|
+
| Provider | Type | Key env var | Get a key |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| Google Gemini | Cloud | `GEMINI_API_KEY` | https://aistudio.google.com/apikey |
|
|
149
|
+
| Groq | Cloud | `GROQ_API_KEY` | https://console.groq.com/keys |
|
|
150
|
+
| OpenRouter | Cloud (aggregator) | `OPENROUTER_API_KEY` | https://openrouter.ai/keys |
|
|
151
|
+
| Ollama | **Local, no key** | — | https://ollama.com |
|
|
152
|
+
|
|
153
|
+
A minimal config (env-var **names** only — never the value):
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
# .ai-runtime/config.yaml
|
|
157
|
+
runtime:
|
|
158
|
+
defaultMode: auto
|
|
159
|
+
providers:
|
|
160
|
+
- id: gemini
|
|
161
|
+
kind: gemini
|
|
162
|
+
apiKeyEnv: GEMINI_API_KEY
|
|
163
|
+
- id: ollama # local; no key required
|
|
164
|
+
kind: ollama
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
In code, real providers load from that config:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
import { Runtime } from 'ai-runtime-engine';
|
|
171
|
+
|
|
172
|
+
const runtime = await Runtime.load({ workspace: process.cwd() }); // reads config + .env
|
|
173
|
+
const r = await runtime.run({ input: 'Summarize what this project does.' });
|
|
174
|
+
console.log(r.response?.text);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 6. How to use it — worked examples
|
|
180
|
+
|
|
181
|
+
The examples below use the offline mock so you can run them as-is; with real providers configured, drop the
|
|
182
|
+
`registerProvider` line and use `await Runtime.load()` instead.
|
|
183
|
+
|
|
184
|
+
```js
|
|
185
|
+
import { Runtime, MockProvider, makeModel } from 'ai-runtime-engine';
|
|
186
|
+
|
|
187
|
+
function demoRuntime() {
|
|
188
|
+
const rt = new Runtime();
|
|
189
|
+
rt.ai.registerProvider(new MockProvider({
|
|
190
|
+
id: 'demo',
|
|
191
|
+
models: [makeModel({ providerId: 'demo', id: 'demo-1', caps: { intelligence: ['reasoning', 'planning'], output: ['text', 'json'] } })],
|
|
192
|
+
}));
|
|
193
|
+
return rt;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### a. Chat — a single answer
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
const rt = demoRuntime();
|
|
201
|
+
const r = await rt.run({ input: 'Explain what a race condition is.', mode: 'chat' });
|
|
202
|
+
console.log(r.response?.text);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### b. Ask for a plan (no execution)
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
const r = await rt.run({ input: 'Migrate this project off deprecated APIs', mode: 'plan' });
|
|
209
|
+
console.log(r.plan); // a structured plan; nothing is executed in `plan` mode
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### c. Preview a multi-step task with dry-run (zero changes)
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
const r = await rt.run({ input: 'Fix the failing tests', mode: 'orchestrate', dryRun: true });
|
|
216
|
+
console.log(r.response?.text); // shows the plan + what it WOULD touch, with no mutations
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
To let it actually act (write files, run shell, etc.), you grant permissions in config — everything is
|
|
220
|
+
deny-by-default (see [Safety model](#9-safety-model)).
|
|
221
|
+
|
|
222
|
+
### d. Compare models
|
|
223
|
+
|
|
224
|
+
`compare` fans the same request across several models and reports where they agree, differ, and contradict
|
|
225
|
+
each other:
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
const rt = new Runtime();
|
|
229
|
+
rt.ai.registerProvider(new MockProvider({ id: 'a', models: [makeModel({ providerId: 'a', id: 'a-1', caps: { intelligence: ['reasoning'], output: ['text'] } })], behavior: { kind: 'ok', text: 'use PostgreSQL' } }));
|
|
230
|
+
rt.ai.registerProvider(new MockProvider({ id: 'b', models: [makeModel({ providerId: 'b', id: 'b-1', caps: { intelligence: ['reasoning'], output: ['text'] } })], behavior: { kind: 'ok', text: 'use MongoDB' } }));
|
|
231
|
+
|
|
232
|
+
const cmp = await rt.compare({ goal: 'which database?', input: 'Recommend a database', pins: [{ provider: 'a' }, { provider: 'b' }] });
|
|
233
|
+
console.log(cmp.analysis.unanimous, cmp.analysis.differences);
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
If you supply a `validate` function (e.g. run the tests), the answer that *passes* wins — evidence beats a
|
|
237
|
+
judge model.
|
|
238
|
+
|
|
239
|
+
### e. Remember facts across runs
|
|
240
|
+
|
|
241
|
+
With persistence on (the default when you `Runtime.load()`), memory is durable and scoped:
|
|
242
|
+
|
|
243
|
+
```js
|
|
244
|
+
const rt = await Runtime.load();
|
|
245
|
+
rt.memory.remember({ text: 'This project uses PostgreSQL', scope: 'project' });
|
|
246
|
+
console.log(rt.memory.search('database')); // finds the fact; it's injected into future chats
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
You can also just say it in chat: *"Remember that we deploy on Fridays."*
|
|
250
|
+
|
|
251
|
+
### f. Add your own skill (no code)
|
|
252
|
+
|
|
253
|
+
Drop a manifest into `.ai-runtime/skills/` and it's auto-loaded. A skill composes the built-in tools:
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
# .ai-runtime/skills/read-readme.skill.yaml
|
|
257
|
+
id: read-readme
|
|
258
|
+
version: 1.0.0
|
|
259
|
+
name: Read README
|
|
260
|
+
description: read the project README
|
|
261
|
+
steps:
|
|
262
|
+
- tool: filesystem
|
|
263
|
+
input: { op: read, path: README.md }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Run `ai-runtime skills` to see it loaded, or `ai-runtime skills --discover` to find skill files elsewhere in
|
|
267
|
+
your repo (reported, not auto-loaded). Skills can also be shipped as npm packages — name them under
|
|
268
|
+
`skills.packages` in config.
|
|
269
|
+
|
|
270
|
+
### g. Steer which models get used
|
|
271
|
+
|
|
272
|
+
- **Exclude** = a hard filter (never selected). **Prefer** = a soft nudge. **Neither** = normal routing.
|
|
273
|
+
|
|
274
|
+
```js
|
|
275
|
+
const r = await rt.run({ input: 'anything', routing: { excludeProviders: ['a'], preferProviders: ['b'] } });
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Or via environment variables (`AI_EXCLUDE_PROVIDERS`, `AI_PREFER_MODELS`, …). Learning can nudge preferences
|
|
279
|
+
from real outcomes, but **it can never override an exclusion**.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 7. The interactive terminal
|
|
284
|
+
|
|
285
|
+
The most fun way to explore. From a project that installed the package (or globally):
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
ai-runtime # opens the interactive terminal
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Type a request in plain language, or use a slash command:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
/help list everything
|
|
295
|
+
/info /status what's configured
|
|
296
|
+
/providers providers + access state
|
|
297
|
+
/providers/all models every provider's models
|
|
298
|
+
/mode plan set the mode
|
|
299
|
+
/memory list remembered facts
|
|
300
|
+
/skills discover find skill files in the repo
|
|
301
|
+
/compare <request> compare across providers
|
|
302
|
+
/dry-run toggle "plan only, no changes"
|
|
303
|
+
/doctor /cleanup diagnostics · maintenance
|
|
304
|
+
/exit
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
For scripts and CI, the one-shot form runs a single request:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
ai-runtime run "Explain this error: TypeError: x is not a function" --json
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## 8. Configuration
|
|
316
|
+
|
|
317
|
+
Three places, and only these:
|
|
318
|
+
|
|
319
|
+
| Path | What | Commit? |
|
|
320
|
+
|---|---|---|
|
|
321
|
+
| `.ai-runtime/config.yaml` | Project config — settings + providers (env-var **names**). | ✅ yes |
|
|
322
|
+
| `.env` | The secret **values** for those env vars. | ❌ no (gitignored) |
|
|
323
|
+
| `~/.ai-runtime/` | Local state — conversations, memory, executions, cache, learning. | ❌ never |
|
|
324
|
+
|
|
325
|
+
Handy optional environment variables: `AI_DEFAULT_MODE`, `AI_CONTEXT_MAX_TOKENS`, `AI_MAX_COST_USD`,
|
|
326
|
+
`AI_MAX_CALLS`, `AI_MEMORY_ENABLED`, `AI_LEARNING_ENABLED`, `AI_EXCLUDE_*` / `AI_PREFER_*`,
|
|
327
|
+
`AI_*_RETENTION_DAYS`, `AI_RUNTIME_HOME`. All optional; unset means the default.
|
|
328
|
+
|
|
329
|
+
For the full router configuration (routing strategies, scoring weights, privacy posture, self-declared
|
|
330
|
+
providers, the `run()`/`AI` reference), see [router.md](router.md).
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 9. Safety model
|
|
335
|
+
|
|
336
|
+
The runtime is built to be safe to point at your real files and shell:
|
|
337
|
+
|
|
338
|
+
- **Deny-by-default permissions.** Reads are allowed and **jailed to your workspace**; writes, shell, git
|
|
339
|
+
commit/push, and network are **off** until you grant them under `permissions:` in config. Destructive
|
|
340
|
+
shell commands always ask.
|
|
341
|
+
- **Untrusted data.** Anything read from files, tools, the web, or MCP is treated as *data, never
|
|
342
|
+
instructions* — it can't change permissions, obtain secrets, or run commands.
|
|
343
|
+
- **Secrets** are named by env var only; an inline key is rejected, and every value is redacted from all
|
|
344
|
+
output (including the terminal).
|
|
345
|
+
|
|
346
|
+
Details in [security.md](security.md).
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 10. Where to go next
|
|
351
|
+
|
|
352
|
+
- **[../README.md](../README.md)** — the concise reference (install, CLI, config at a glance).
|
|
353
|
+
- **[router.md](router.md)** — the engine: routing strategies, scoring, providers, the `run()`/`AI` API.
|
|
354
|
+
- **[architecture.md](architecture.md)** — how the router and Runtime layers fit together.
|
|
355
|
+
- **[security.md](security.md)** — the full security model.
|
|
356
|
+
|
|
357
|
+
Happy building. Remember the through-line: **describe what you want; the runtime picks the model and proves
|
|
358
|
+
the result.**
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# AI Runtime — documentation
|
|
2
|
+
|
|
3
|
+
User-facing usage lives in the top-level [README](../README.md). These are the reference docs that ship
|
|
4
|
+
with the `ai-runtime-engine` package:
|
|
5
|
+
|
|
6
|
+
- **[GUIDE.md](GUIDE.md)** — a hands-on, study-friendly guide: install → first run → how it works → worked
|
|
7
|
+
examples (runnable offline, no API key needed).
|
|
8
|
+
- **[architecture.md](architecture.md)** — the two layers, the one-router invariant, the shared
|
|
9
|
+
abstractions, the request lifecycle, and what is frozen.
|
|
10
|
+
- **[router.md](router.md)** — the router engine reference: configuration, the `run()` API and `AI` class,
|
|
11
|
+
providers, tasks/capabilities, routing internals, reliability, and advanced features.
|
|
12
|
+
- **[security.md](security.md)** — the untrusted-data boundary, filesystem jail, shell allowlist,
|
|
13
|
+
permissions, credentials, and the learning safety rail.
|
|
14
|
+
|
|
15
|
+
Additional development records — the append-only decision log (`DECISIONS.md`), the phase-by-phase build
|
|
16
|
+
log (`PROGRESS.md`), and the release checklist (`NPM_PUBLISHING.md`) — live in the (private) source
|
|
17
|
+
repository and are not part of the published package.
|
|
18
|
+
|
|
19
|
+
Per-subsystem detail is documented at the source: each module under `src/**` opens with a doc comment
|
|
20
|
+
describing its contract and invariants, and the README's [How to use it](../README.md#how-to-use-it)
|
|
21
|
+
section covers every capability from a user's perspective.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
AI Runtime is two layers: a provider-agnostic **router** and, on top of it, a **Runtime** that turns the
|
|
4
|
+
router into an orchestration platform. This document is the map; the [README](../README.md) is the usage
|
|
5
|
+
guide. (An append-only decision log, `DECISIONS.md`, records the rationale for each load-bearing choice in
|
|
6
|
+
the source repository.)
|
|
7
|
+
|
|
8
|
+
## The one invariant
|
|
9
|
+
|
|
10
|
+
**There is exactly one selection engine.** Every model call — chat, planning, comparison, a skill's own
|
|
11
|
+
`AI.run`, everything — goes through the router (`AI.run()`). The Runtime never scores or picks models
|
|
12
|
+
itself; it decides *what kind of work* a request is and *how* to carry it out, then delegates each model
|
|
13
|
+
call to the router. This keeps routing behavior consistent and testable, and keeps the router reusable on
|
|
14
|
+
its own.
|
|
15
|
+
|
|
16
|
+
## Layering
|
|
17
|
+
|
|
18
|
+
| Layer | Question it answers | Where |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Router | Which provider/model performs this AI operation? | `src/core/**`, `src/providers/**`, `src/plugin/ai.ts` |
|
|
21
|
+
| Runtime | What is being asked; which mode handles it? | `src/runtime/**` |
|
|
22
|
+
| Planner | What sequence of steps achieves the goal? | `src/orchestration/planner.ts` |
|
|
23
|
+
| Skills | What reusable capability performs a step? | `src/skills/**` |
|
|
24
|
+
| Tools | What concrete operation executes? | `src/tools/**` |
|
|
25
|
+
| Orchestrator | What happens next; are we done; replan? | `src/orchestration/**` |
|
|
26
|
+
| Memory | What durable information is worth remembering? | `src/memory/**` |
|
|
27
|
+
| Learning | What providers/skills/plans work better? | `src/learning/**` |
|
|
28
|
+
| Comparison | How do candidates compare, by evidence? | `src/comparison/**` |
|
|
29
|
+
| Executions | How does a long run persist and resume? | `src/executions/**` |
|
|
30
|
+
|
|
31
|
+
Conversation ≠ Memory ≠ Learning ≠ Repository ≠ Execution — separate stores, separate rules.
|
|
32
|
+
|
|
33
|
+
## Three shared abstractions
|
|
34
|
+
|
|
35
|
+
These keep the architecture stable as features accrete:
|
|
36
|
+
|
|
37
|
+
- **RuntimeContext** (`src/runtime/context.ts`) — the single runtime-state container, assembled once per
|
|
38
|
+
run and passed by reference to mode resolution, the context compiler, planner, orchestrator, skills,
|
|
39
|
+
and tools. No other overlapping state object exists.
|
|
40
|
+
- **ExecutionPolicy** (`src/runtime/policy.ts`) — the single authority for autonomy, approval, dry-run,
|
|
41
|
+
execution limits, and permissions. Every layer *reads* it; none re-derives policy.
|
|
42
|
+
- **ArtifactRef** (`src/runtime/types.ts`) — large outputs are passed as references; the artifact store
|
|
43
|
+
owns the content and the context compiler decides if/when to inline it.
|
|
44
|
+
|
|
45
|
+
## Request lifecycle
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
run(input) → RuntimeContext assembled → mode + policy resolved
|
|
49
|
+
→ dispatch:
|
|
50
|
+
chat → context compiled → AI.run() → router → provider
|
|
51
|
+
plan/exec/ → planner (AI.run) → validate plan → executor (tools/skills, evidence)
|
|
52
|
+
orchestrate → observe → replan (bounded) ; persisted as an Execution, resumable
|
|
53
|
+
agent/debug → bounded loops over the same machinery
|
|
54
|
+
compare → fan out AI.run() across pins → deterministic analysis → evidence ranking
|
|
55
|
+
→ RuntimeResult (+ routing trace, memory, context, plan, execution, comparison, learning)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Security model
|
|
59
|
+
|
|
60
|
+
The runtime is authoritative; everything it reads through tools/files/web/MCP is **data, never
|
|
61
|
+
instructions**. Filesystem access is jailed to the workspace (tested against `..`, absolute paths, and
|
|
62
|
+
symlinks); shell is allowlist-first with a destructive denylist; git commit/push and network are
|
|
63
|
+
individually gated; permissions are deny-by-default. Secrets are named by env var only and redacted at
|
|
64
|
+
every egress including the terminal. See [security.md](security.md).
|
|
65
|
+
|
|
66
|
+
## What is frozen
|
|
67
|
+
|
|
68
|
+
The router core (`src/core/**` except the `filter.ts`/`scorer.ts` exclude/prefer extension points),
|
|
69
|
+
`src/plugin/ai.ts`, `src/providers/**`, `src/config/{load,defaults,schema}.ts`, `src/security/**`, and
|
|
70
|
+
`src/telemetry/**` are behavior-frozen: the Runtime is strictly additive over them, so the router stays
|
|
71
|
+
backward compatible and independently usable.
|
|
72
|
+
|
|
73
|
+
## Testing
|
|
74
|
+
|
|
75
|
+
Offline and deterministic: a `MockProvider` stands in for real adapters, and injected clocks make timing
|
|
76
|
+
reproducible. Every phase kept the full suite green (typecheck + tests + build), added regression coverage
|
|
77
|
+
for new behavior, and ran an adversarial security/logic review before merge. CI runs all three on every
|
|
78
|
+
push and PR.
|