ai-runtime-engine 1.3.0 → 2.7.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.
Files changed (138) hide show
  1. package/CHANGELOG.md +578 -0
  2. package/dist/agents/admit.d.ts +69 -0
  3. package/dist/agents/admit.js +129 -0
  4. package/dist/agents/definition.d.ts +36 -0
  5. package/dist/agents/definition.js +9 -0
  6. package/dist/agents/envelope.d.ts +53 -0
  7. package/dist/agents/envelope.js +68 -0
  8. package/dist/agents/finding.d.ts +79 -0
  9. package/dist/agents/finding.js +80 -0
  10. package/dist/agents/task.d.ts +60 -0
  11. package/dist/agents/task.js +32 -0
  12. package/dist/agents/worker.d.ts +68 -0
  13. package/dist/agents/worker.js +256 -0
  14. package/dist/capabilities/capability.d.ts +117 -0
  15. package/dist/capabilities/capability.js +66 -0
  16. package/dist/capabilities/registry.d.ts +139 -0
  17. package/dist/capabilities/registry.js +413 -0
  18. package/dist/capabilities/vocabulary.d.ts +32 -0
  19. package/dist/capabilities/vocabulary.js +34 -0
  20. package/dist/cli/cli.js +55 -4
  21. package/dist/cli/commands/cleanup.js +29 -27
  22. package/dist/cli/commands/doctor.d.ts +14 -0
  23. package/dist/cli/commands/doctor.js +38 -8
  24. package/dist/cli/commands/executions.js +34 -25
  25. package/dist/cli/commands/info.d.ts +1 -0
  26. package/dist/cli/commands/info.js +11 -9
  27. package/dist/cli/commands/init.js +19 -0
  28. package/dist/cli/commands/inspect.d.ts +40 -1
  29. package/dist/cli/commands/inspect.js +157 -2
  30. package/dist/cli/commands/mcp.d.ts +45 -0
  31. package/dist/cli/commands/mcp.js +148 -0
  32. package/dist/cli/commands/route.js +21 -0
  33. package/dist/cli/commands/run.d.ts +1 -0
  34. package/dist/cli/commands/run.js +21 -2
  35. package/dist/cli/commands/skills.d.ts +2 -0
  36. package/dist/cli/commands/skills.js +29 -7
  37. package/dist/cli/interactive/ansi.d.ts +41 -0
  38. package/dist/cli/interactive/ansi.js +43 -0
  39. package/dist/cli/interactive/complete.d.ts +10 -0
  40. package/dist/cli/interactive/complete.js +19 -0
  41. package/dist/cli/interactive/repl.d.ts +3 -0
  42. package/dist/cli/interactive/repl.js +91 -13
  43. package/dist/cli/interactive/session.d.ts +8 -0
  44. package/dist/cli/interactive/session.js +73 -2
  45. package/dist/cli/render.d.ts +7 -0
  46. package/dist/cli/render.js +10 -0
  47. package/dist/cli/runtimeSession.d.ts +11 -0
  48. package/dist/cli/runtimeSession.js +17 -0
  49. package/dist/config/defaults.d.ts +3 -1
  50. package/dist/config/defaults.js +2 -0
  51. package/dist/config/schema.d.ts +1 -0
  52. package/dist/config/schema.js +2 -2
  53. package/dist/context/lossVerifier.d.ts +24 -0
  54. package/dist/context/lossVerifier.js +45 -0
  55. package/dist/context/summarize.d.ts +19 -0
  56. package/dist/context/summarize.js +53 -0
  57. package/dist/core/fallback/fallback.d.ts +5 -0
  58. package/dist/core/fallback/fallback.js +3 -1
  59. package/dist/core/router/router.d.ts +3 -0
  60. package/dist/core/router/router.js +1 -0
  61. package/dist/executions/execution.d.ts +13 -2
  62. package/dist/generation/generateAdapter.d.ts +14 -0
  63. package/dist/generation/generateAdapter.js +38 -0
  64. package/dist/generation/generateSkill.d.ts +26 -0
  65. package/dist/generation/generateSkill.js +51 -0
  66. package/dist/index.d.ts +43 -4
  67. package/dist/index.js +26 -2
  68. package/dist/mcp/client.d.ts +70 -0
  69. package/dist/mcp/client.js +221 -0
  70. package/dist/mcp/manager.d.ts +151 -0
  71. package/dist/mcp/manager.js +493 -0
  72. package/dist/mcp/protocol.d.ts +216 -0
  73. package/dist/mcp/protocol.js +149 -0
  74. package/dist/mcp/toolAdapter.d.ts +44 -0
  75. package/dist/mcp/toolAdapter.js +94 -0
  76. package/dist/mcp/transport.d.ts +109 -0
  77. package/dist/mcp/transport.js +383 -0
  78. package/dist/memory/embedders/hash.d.ts +12 -0
  79. package/dist/memory/embedders/hash.js +31 -0
  80. package/dist/memory/embedders/http.d.ts +25 -0
  81. package/dist/memory/embedders/http.js +48 -0
  82. package/dist/memory/memory.d.ts +19 -2
  83. package/dist/memory/memory.js +75 -11
  84. package/dist/memory/semantic.d.ts +17 -0
  85. package/dist/memory/semantic.js +29 -0
  86. package/dist/orchestration/budget.d.ts +30 -0
  87. package/dist/orchestration/budget.js +40 -0
  88. package/dist/orchestration/executor.d.ts +39 -1
  89. package/dist/orchestration/executor.js +64 -4
  90. package/dist/orchestration/orchestrator.d.ts +29 -1
  91. package/dist/orchestration/orchestrator.js +89 -8
  92. package/dist/orchestration/plan.d.ts +15 -1
  93. package/dist/orchestration/plan.js +23 -4
  94. package/dist/orchestration/planner.d.ts +19 -1
  95. package/dist/orchestration/planner.js +25 -5
  96. package/dist/plugin/ai.d.ts +4 -0
  97. package/dist/plugin/ai.js +9 -0
  98. package/dist/runtime/config.js +50 -6
  99. package/dist/runtime/intent/aiClassifier.d.ts +19 -0
  100. package/dist/runtime/intent/aiClassifier.js +74 -0
  101. package/dist/runtime/models/modelProfile.d.ts +61 -0
  102. package/dist/runtime/models/modelProfile.js +139 -0
  103. package/dist/runtime/planning/deriveCapabilities.d.ts +95 -0
  104. package/dist/runtime/planning/deriveCapabilities.js +146 -0
  105. package/dist/runtime/policy.d.ts +10 -0
  106. package/dist/runtime/policy.js +9 -2
  107. package/dist/runtime/runtime.d.ts +173 -0
  108. package/dist/runtime/runtime.js +705 -50
  109. package/dist/runtime/types.d.ts +88 -2
  110. package/dist/skills/manifest.d.ts +3 -0
  111. package/dist/skills/manifest.js +24 -0
  112. package/dist/skills/registry.d.ts +16 -1
  113. package/dist/skills/registry.js +21 -1
  114. package/dist/skills/skill.d.ts +6 -1
  115. package/dist/store/area.d.ts +15 -1
  116. package/dist/store/area.js +19 -8
  117. package/dist/store/crypto.d.ts +21 -0
  118. package/dist/store/crypto.js +49 -0
  119. package/dist/store/paths.d.ts +5 -1
  120. package/dist/store/paths.js +6 -0
  121. package/dist/store/store.d.ts +15 -3
  122. package/dist/store/store.js +28 -7
  123. package/dist/telemetry/sinks/otlp.d.ts +31 -0
  124. package/dist/telemetry/sinks/otlp.js +76 -0
  125. package/dist/tools/builtins/filesystem.js +1 -0
  126. package/dist/tools/builtins/git.js +1 -0
  127. package/dist/tools/builtins/shell.js +1 -0
  128. package/dist/tools/permissions.d.ts +28 -0
  129. package/dist/tools/permissions.js +72 -0
  130. package/dist/tools/registry.d.ts +18 -2
  131. package/dist/tools/registry.js +22 -2
  132. package/dist/tools/tool.d.ts +4 -0
  133. package/dist/types.d.ts +5 -1
  134. package/dist/util/flatten.d.ts +11 -0
  135. package/dist/util/flatten.js +18 -0
  136. package/dist/util/semaphore.d.ts +19 -0
  137. package/dist/util/semaphore.js +60 -0
  138. package/package.json +24 -9
@@ -3,6 +3,8 @@
3
3
  * a RuntimeContext, executes chat through `AI.run()`, and streams redacted lifecycle events. It never
4
4
  * routes or scores; all model selection stays in the one router. Unimplemented modes degrade to chat.
5
5
  */
6
+ import type { GenerateSkillResult } from '../generation/generateSkill.js';
7
+ import type { SkillManifest } from '../skills/manifest.js';
6
8
  import { AI } from '../plugin/ai.js';
7
9
  import type { AIOptions } from '../plugin/ai.js';
8
10
  import type { WorkspaceInfo } from './workspace/workspace.js';
@@ -14,8 +16,13 @@ import { ConversationStore } from '../conversations/conversations.js';
14
16
  import { MemoryStore } from '../memory/memory.js';
15
17
  import type { Tool, ToolResult } from '../tools/tool.js';
16
18
  import { resolvePermissions } from '../tools/permissions.js';
19
+ import { McpManager } from '../mcp/manager.js';
20
+ import type { McpServerStatus } from '../mcp/manager.js';
21
+ import { ActionCapabilityRegistry } from '../capabilities/registry.js';
22
+ import type { MissingCapabilityReport } from '../capabilities/capability.js';
17
23
  import type { Skill, SkillResult, SkillValidation, SkillPlan } from '../skills/skill.js';
18
24
  import type { SkillSource, LoadedSource } from '../skills/discovery.js';
25
+ import type { AgentDefinition } from '../agents/definition.js';
19
26
  import { ExecutionStore } from '../executions/store.js';
20
27
  import type { Execution } from '../executions/execution.js';
21
28
  import { ArtifactStore } from '../artifacts/artifacts.js';
@@ -23,6 +30,7 @@ import type { CompareInput } from '../comparison/comparator.js';
23
30
  import type { ComparisonResult } from '../comparison/comparison.js';
24
31
  import { LearningStore } from '../learning/learningStore.js';
25
32
  import type { FeedbackSignal } from '../learning/feedback.js';
33
+ import type { ModelProfile } from './models/modelProfile.js';
26
34
  import type { PermissionPolicy } from './policy.js';
27
35
  import type { RuntimeConfig, RuntimeResult, RuntimeRunInput, RuntimeSettings } from './types.js';
28
36
  export interface RuntimeOptions {
@@ -54,17 +62,50 @@ export declare class Runtime {
54
62
  private readonly _memory;
55
63
  private readonly _conversations;
56
64
  private readonly estimator;
65
+ /** ACTION-capability registry (Phase 3.1). Declared BEFORE the tool/skill registries so its
66
+ * ingest listeners are attached in time to capture the builtin registrations below. */
67
+ private readonly _capabilities;
68
+ /** MCP server lifecycle (Phase 3.2). Connection is LAZY: nothing is contacted until first use. */
69
+ private readonly _mcp;
70
+ private mcpConnected;
71
+ private readonly mcpToolIds;
72
+ private readonly mcpWarnings;
57
73
  private readonly _tools;
58
74
  private readonly _skills;
59
75
  private readonly _executions;
60
76
  private readonly _artifacts;
61
77
  private readonly _learning;
62
78
  private readonly workspaceRoot;
79
+ private readonly _modelProfile?;
63
80
  private readonly configPermissions;
81
+ /** The INJECTED clock. Agent deadlines are measured against it, never a real timer, so an offline
82
+ * test with a fake clock stays deterministic. */
83
+ private readonly clock;
84
+ /** Multi-agent core (Phase 3.4). False ⇒ every agent path is inert. */
85
+ private readonly agentsEnabled;
86
+ private readonly agentDefs;
87
+ /** Live runs, so a pause/cancel can abort the agent tasks actually in flight. Only ever populated
88
+ * when agents are enabled, so pause/cancel are unchanged with the flag off. */
89
+ private readonly liveRuns;
90
+ /** The config file's `budget:` ceilings, kept only so the 3.3 pre-pass can decline a model call. */
91
+ private readonly _configBudget?;
64
92
  private readonly approval?;
65
93
  private readonly _configFile?;
66
94
  private _loadedSkillSources;
67
95
  constructor(config?: RuntimeConfig, options?: RuntimeOptions, workspace?: WorkspaceInfo);
96
+ /**
97
+ * Build the memory embedder from `runtime.embedding` (Phase 14). Absent → undefined → BM25 keyword
98
+ * retrieval (the offline default). `local` = the zero-dep deterministic HashEmbedder; `openai-compatible`
99
+ * = the HTTP adapter (key by env NAME via `Credential`; a missing `baseUrl` yields no embedder → BM25).
100
+ */
101
+ private buildEmbedder;
102
+ /**
103
+ * Build the store cipher from `runtime.storage` (Phase 18). Absent / `encrypt:false` → undefined → a
104
+ * plaintext store (the default). `encrypt:true` resolves the key from the env var NAMED by `keyEnv` via
105
+ * `Credential` (never a value) and derives an AES-256 key; a missing key is a hard CONFIG error (silent
106
+ * plaintext would be a lie). The key lives only inside the returned codec — never logged or serialized.
107
+ */
108
+ private buildCipher;
68
109
  /** Build a Runtime from a workspace: load config (.ai-runtime/config.yaml > root fallback), detect workspace. */
69
110
  static load(options?: RuntimeOptions): Promise<Runtime>;
70
111
  /**
@@ -100,6 +141,15 @@ export declare class Runtime {
100
141
  * every hard gate (exclude/privacy/pin/capability/budget), which the router filter enforces.
101
142
  */
102
143
  private effectiveRouting;
144
+ /** The loaded `models.md` routing profile (per-mode/per-task model directives), or undefined if none. */
145
+ modelProfile(): ModelProfile | undefined;
146
+ /**
147
+ * Fold the `models.md` directive for this (mode, task) into the run — a soft prefer (universal, merged
148
+ * into routing), a strategy, or a hard pin (chat path, via the request escape hatch). Precedence is
149
+ * explicit per-run > models.md: the caller's own strategy/pin win, and prefer is unioned (never
150
+ * re-admitting an exclusion). No profile / no matching directive ⇒ the request is returned unchanged.
151
+ */
152
+ private applyModelProfile;
103
153
  /** Apply free-text feedback (e.g. "that worked" / "wrong root cause") to the most recent outcome. */
104
154
  feedback(text: string, opts?: {
105
155
  providerId?: string;
@@ -114,10 +164,79 @@ export declare class Runtime {
114
164
  tools(): Tool[];
115
165
  /** Register a skill. Chainable. */
116
166
  registerSkill(skill: Skill): this;
167
+ /**
168
+ * Register an agent definition (Phase 3.4). Chainable, and inert unless `runtime.agents.enabled` is
169
+ * set — registering a definition grants nothing on its own, exactly like adding an MCP server.
170
+ */
171
+ registerAgent(id: string, def: AgentDefinition): this;
172
+ /** The agent definition ids this runtime knows (registered or configured). */
173
+ agents(): string[];
174
+ /**
175
+ * This run's agent envelopes. THE ONLY call site of `narrowEnvelope` — never re-derive an inner
176
+ * catalog, a permission clamp, or a reservation anywhere else (see the header of agents/envelope.ts).
177
+ */
178
+ private agentEnvelopes;
179
+ /** The MCP server manager: `list()`, `status(id)`, `test(id)`, `addServer`, `removeServer`, `setEnabled`. */
180
+ mcp(): McpManager;
181
+ /**
182
+ * Connect every enabled MCP server, discover their tools, and register them. LAZY BY DESIGN: a one-shot
183
+ * CLI command that never touches MCP pays nothing, and a failing server records its state instead of
184
+ * breaking construction. Idempotent — the second call is a no-op.
185
+ */
186
+ connectMcp(): Promise<McpServerStatus[]>;
187
+ /** Whether any MCP server is configured at all (absent ⇒ MCP is entirely inert). */
188
+ hasMcpServers(): boolean;
189
+ /**
190
+ * Register one server's discovered tools as ordinary Runtime Tools (+ their namespaced action
191
+ * capabilities, via the tool registry's ingest listener). A generated id NEVER shadows an existing
192
+ * non-MCP tool: the collision is skipped and reported, because silently replacing `filesystem` would be
193
+ * a privilege swap.
194
+ */
195
+ private registerMcpTools;
196
+ /**
197
+ * The legacy declaration path (`AI.run({ mcp: true })`) — tools DECLARED to a model, never executed
198
+ * through here. It honors the same read/full split as execution (declaring a tool the executor would
199
+ * refuse just invites the model to plan around it) and is keyed by server id, so re-publishing with an
200
+ * empty list REVOKES it.
201
+ */
202
+ private publishMcpSource;
203
+ /** Drop a server's tools (removal / disable). */
204
+ private deregisterMcpTools;
205
+ /** Map a server's lifecycle state onto capability availability (the D7 derivation table). */
206
+ private mcpAvailability;
207
+ /** Warnings from MCP wiring (id collisions) plus the manager's own (invalid store files, etc.). */
208
+ mcpWarningsList(): string[];
209
+ /**
210
+ * Release long-lived resources — today: MCP stdio child processes. A one-shot CLI command and the REPL
211
+ * both call this on completion/exit; without it a spawned server keeps the event loop alive.
212
+ */
213
+ close(): Promise<void>;
117
214
  /** Skills whose required tools are all registered. */
118
215
  skills(): Skill[];
216
+ /**
217
+ * Scaffold a skill MANIFEST from a natural-language goal (Phase 21a). Drafts a `*.skill.yaml` via the
218
+ * model, validated by `parseManifest` + tool-membership + a dry compile. **Writes nothing** — pass the
219
+ * returned manifest to `saveScaffoldedSkill` on explicit confirm.
220
+ */
221
+ scaffoldSkill(goal: string): Promise<GenerateSkillResult>;
222
+ /**
223
+ * Write a scaffolded manifest into the consented `.ai-runtime/skills/` directory (Phase 21a). Only call
224
+ * this after the user has confirmed the drafted manifest. Returns the written path. The id was validated
225
+ * as kebab-case at generation; it is re-checked here so a hand-built manifest can't escape the skills dir.
226
+ */
227
+ saveScaffoldedSkill(manifest: SkillManifest): string;
228
+ /** The ACTION-capability registry (Phase 3.1): what this runtime can DO, and who provides it. */
229
+ capabilities(): ActionCapabilityRegistry;
119
230
  /** The resolved tool permissions for this runtime (config grants over deny-by-default defaults). */
120
231
  permissions(): ReturnType<typeof resolvePermissions>;
232
+ /**
233
+ * The ONE resolved-permission view for a run: config grants merged with a per-run override, with `mcp`
234
+ * merged by per-server MINIMUM so an override can only ever NARROW. Extracted from `toolContext`
235
+ * (Phase 3.3 / D9) so capability resolution and tool execution can never read different permissions.
236
+ * Never re-derive this merge at a call site: a plain `resolvePermissions({ ...config, ...override })`
237
+ * would let an override widen `read` to `full` and drop sibling servers.
238
+ */
239
+ private resolvedPermissions;
121
240
  private toolContext;
122
241
  /** Invoke a registered tool with the runtime's resolved permissions + host approval. */
123
242
  runTool(id: string, input: unknown, overrides?: {
@@ -128,6 +247,7 @@ export declare class Runtime {
128
247
  runSkill(id: string, input: unknown, overrides?: {
129
248
  permissions?: PermissionPolicy;
130
249
  signal?: AbortSignal;
250
+ ai?: AI;
131
251
  }): Promise<{
132
252
  plan: SkillPlan;
133
253
  result: SkillResult;
@@ -154,6 +274,52 @@ export declare class Runtime {
154
274
  /** Record an EXECUTED orchestration outcome for learning. plan-only, dry-run, and waiting states are
155
275
  * skipped — no skill ran, so there is no success/failure to learn (recording them would teach noise). */
156
276
  private recordOrchestration;
277
+ /**
278
+ * A capped, FENCED action-capability snapshot for the planner prompt (Phase 3.1, opt-in). Untrusted
279
+ * sources (anything not an in-tree builtin) have their descriptions fenced, and the block is bounded so
280
+ * a large catalog can never dominate the prompt.
281
+ */
282
+ private capabilityCatalogText;
283
+ /** Any call/cost ceiling declared in the config file's `budget:` block (router-level, not policy). */
284
+ private configBudget;
285
+ /** Deriver candidates: registry ids + one clamped label. Built by the SAME helper the CLI uses. */
286
+ private capabilityCandidates;
287
+ /**
288
+ * Derive the capabilities this goal needs and resolve them (Phase 3.3, opt-in). Offline BM25 first —
289
+ * free and deterministic — with ONE model call only when the offline rung finds nothing. ADVISORY: it
290
+ * never blocks a run and never grants anything; a gap is metadata plus a line in the planner prompt.
291
+ */
292
+ private capabilityPlanning;
293
+ /** The pre-rendered "Required capabilities" planner block (Phase 3.3) — clamped like the 3.1 catalog. */
294
+ private requiredCapabilitiesText;
295
+ /** A step's capability provider id. An MCP-backed tool ingests under `mcp:` (see the ingest hook). */
296
+ private providerIdForRef;
297
+ /**
298
+ * Resolve the capabilities the plan's OWN steps reference (Phase 3.3). ZERO model calls, purely
299
+ * additive metadata, and the only path that can surface a real `permission` gap with a concrete
300
+ * policyKey — the always-on validation path resolves namespaced MISSES, which have no providers and are
301
+ * therefore always reason 'unknown'. It never blocks: a gap here is advice, and the tool's own
302
+ * permission check remains the authority.
303
+ */
304
+ private checkPlanCapabilities;
305
+ /**
306
+ * Turn unregistered plan references into structured gaps (Phase 3.1's always-on upgrade), resolved
307
+ * against the RUN's permissions rather than the raw config (Phase 3.3 / D9) — so what resolution
308
+ * reports and what the executor will allow can never disagree.
309
+ */
310
+ private resolveMissingRefs;
311
+ /**
312
+ * The user-facing report for a set of required capability ids (Phase 3.1), against the runtime's
313
+ * CONFIGURED posture. A specific run's gaps use that run's merged permissions instead (see
314
+ * `resolveMissingRefs` and the capability-planning pre-pass); this entry point has no run in scope.
315
+ */
316
+ capabilityReport(required: string[]): MissingCapabilityReport;
317
+ /**
318
+ * Project an orchestration status onto a persisted execution status. EXHAUSTIVE on purpose (Phase
319
+ * 3.4): the previous catch-all silently persisted an unrecognized status as
320
+ * `waiting_for_clarification` — resumable, answerable with a text answer, and wrong. The mapping of
321
+ * the six existing members is unchanged.
322
+ */
157
323
  private execStatus;
158
324
  private mapOutcome;
159
325
  private resultFromExecution;
@@ -177,7 +343,14 @@ export declare class Runtime {
177
343
  approve?: boolean;
178
344
  signal?: AbortSignal;
179
345
  }): Promise<RuntimeResult>;
346
+ /**
347
+ * THE single source of step runners, used by both the fresh-run path and the resume-continue path.
348
+ * They used to drift: resume built its own pair with no agent runner, so a persisted plan containing
349
+ * an agent step would have failed every one of those steps.
350
+ */
180
351
  private orchestrateRunners;
352
+ /** Abort a run that is in flight, recording WHY so a task can tell a pause from a cancellation. */
353
+ private abortLiveRun;
181
354
  /** Mark an execution paused (it can be resumed later). */
182
355
  pauseExecution(id: string): boolean;
183
356
  /** Cancel an execution (terminal). */