ai-runtime-engine 1.3.0 → 2.8.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 +638 -0
- package/dist/agents/admit.d.ts +69 -0
- package/dist/agents/admit.js +129 -0
- package/dist/agents/definition.d.ts +36 -0
- package/dist/agents/definition.js +9 -0
- package/dist/agents/envelope.d.ts +53 -0
- package/dist/agents/envelope.js +68 -0
- package/dist/agents/finding.d.ts +79 -0
- package/dist/agents/finding.js +80 -0
- package/dist/agents/roles.d.ts +36 -0
- package/dist/agents/roles.js +44 -0
- package/dist/agents/synthesize.d.ts +44 -0
- package/dist/agents/synthesize.js +60 -0
- package/dist/agents/task.d.ts +112 -0
- package/dist/agents/task.js +48 -0
- package/dist/agents/worker.d.ts +91 -0
- package/dist/agents/worker.js +377 -0
- package/dist/capabilities/capability.d.ts +117 -0
- package/dist/capabilities/capability.js +66 -0
- package/dist/capabilities/registry.d.ts +139 -0
- package/dist/capabilities/registry.js +413 -0
- package/dist/capabilities/vocabulary.d.ts +32 -0
- package/dist/capabilities/vocabulary.js +34 -0
- package/dist/cli/cli.js +55 -4
- package/dist/cli/commands/cleanup.js +29 -27
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +38 -8
- package/dist/cli/commands/executions.js +34 -25
- package/dist/cli/commands/info.d.ts +1 -0
- package/dist/cli/commands/info.js +11 -9
- package/dist/cli/commands/init.js +19 -0
- package/dist/cli/commands/inspect.d.ts +40 -1
- package/dist/cli/commands/inspect.js +157 -2
- package/dist/cli/commands/mcp.d.ts +45 -0
- package/dist/cli/commands/mcp.js +148 -0
- package/dist/cli/commands/route.js +21 -0
- package/dist/cli/commands/run.d.ts +1 -0
- package/dist/cli/commands/run.js +21 -2
- package/dist/cli/commands/skills.d.ts +2 -0
- package/dist/cli/commands/skills.js +29 -7
- package/dist/cli/interactive/ansi.d.ts +41 -0
- package/dist/cli/interactive/ansi.js +43 -0
- package/dist/cli/interactive/complete.d.ts +10 -0
- package/dist/cli/interactive/complete.js +19 -0
- package/dist/cli/interactive/lanes.d.ts +69 -0
- package/dist/cli/interactive/lanes.js +181 -0
- package/dist/cli/interactive/repl.d.ts +3 -0
- package/dist/cli/interactive/repl.js +91 -13
- package/dist/cli/interactive/session.d.ts +8 -0
- package/dist/cli/interactive/session.js +73 -2
- package/dist/cli/render.d.ts +7 -0
- package/dist/cli/render.js +10 -0
- package/dist/cli/runtimeSession.d.ts +11 -0
- package/dist/cli/runtimeSession.js +17 -0
- package/dist/config/defaults.d.ts +3 -1
- package/dist/config/defaults.js +2 -0
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.js +2 -2
- package/dist/context/lossVerifier.d.ts +24 -0
- package/dist/context/lossVerifier.js +45 -0
- package/dist/context/summarize.d.ts +19 -0
- package/dist/context/summarize.js +53 -0
- package/dist/core/fallback/fallback.d.ts +5 -0
- package/dist/core/fallback/fallback.js +3 -1
- package/dist/core/router/router.d.ts +3 -0
- package/dist/core/router/router.js +1 -0
- package/dist/executions/agentTasks.d.ts +627 -0
- package/dist/executions/agentTasks.js +149 -0
- package/dist/executions/checkpoint.d.ts +5 -1
- package/dist/executions/checkpoint.js +13 -1
- package/dist/executions/execution.d.ts +36 -2
- package/dist/executions/store.d.ts +37 -0
- package/dist/executions/store.js +33 -0
- package/dist/generation/generateAdapter.d.ts +14 -0
- package/dist/generation/generateAdapter.js +38 -0
- package/dist/generation/generateSkill.d.ts +26 -0
- package/dist/generation/generateSkill.js +51 -0
- package/dist/index.d.ts +47 -4
- package/dist/index.js +33 -2
- package/dist/mcp/client.d.ts +70 -0
- package/dist/mcp/client.js +221 -0
- package/dist/mcp/manager.d.ts +151 -0
- package/dist/mcp/manager.js +493 -0
- package/dist/mcp/protocol.d.ts +216 -0
- package/dist/mcp/protocol.js +149 -0
- package/dist/mcp/toolAdapter.d.ts +44 -0
- package/dist/mcp/toolAdapter.js +94 -0
- package/dist/mcp/transport.d.ts +109 -0
- package/dist/mcp/transport.js +383 -0
- package/dist/memory/embedders/hash.d.ts +12 -0
- package/dist/memory/embedders/hash.js +31 -0
- package/dist/memory/embedders/http.d.ts +25 -0
- package/dist/memory/embedders/http.js +48 -0
- package/dist/memory/memory.d.ts +19 -2
- package/dist/memory/memory.js +75 -11
- package/dist/memory/semantic.d.ts +17 -0
- package/dist/memory/semantic.js +29 -0
- package/dist/orchestration/budget.d.ts +30 -0
- package/dist/orchestration/budget.js +40 -0
- package/dist/orchestration/executor.d.ts +64 -1
- package/dist/orchestration/executor.js +104 -7
- package/dist/orchestration/orchestrator.d.ts +35 -1
- package/dist/orchestration/orchestrator.js +106 -8
- package/dist/orchestration/plan.d.ts +15 -1
- package/dist/orchestration/plan.js +23 -4
- package/dist/orchestration/planner.d.ts +19 -1
- package/dist/orchestration/planner.js +25 -5
- package/dist/plugin/ai.d.ts +4 -0
- package/dist/plugin/ai.js +9 -0
- package/dist/runtime/config.js +50 -6
- package/dist/runtime/intent/aiClassifier.d.ts +19 -0
- package/dist/runtime/intent/aiClassifier.js +74 -0
- package/dist/runtime/models/modelProfile.d.ts +61 -0
- package/dist/runtime/models/modelProfile.js +139 -0
- package/dist/runtime/planning/deriveCapabilities.d.ts +95 -0
- package/dist/runtime/planning/deriveCapabilities.js +146 -0
- package/dist/runtime/policy.d.ts +10 -0
- package/dist/runtime/policy.js +9 -2
- package/dist/runtime/runtime.d.ts +233 -0
- package/dist/runtime/runtime.js +1042 -60
- package/dist/runtime/types.d.ts +88 -2
- package/dist/security/redact.js +22 -10
- package/dist/skills/manifest.d.ts +3 -0
- package/dist/skills/manifest.js +24 -0
- package/dist/skills/registry.d.ts +16 -1
- package/dist/skills/registry.js +21 -1
- package/dist/skills/skill.d.ts +6 -1
- package/dist/store/area.d.ts +15 -1
- package/dist/store/area.js +19 -8
- package/dist/store/crypto.d.ts +21 -0
- package/dist/store/crypto.js +49 -0
- package/dist/store/paths.d.ts +5 -1
- package/dist/store/paths.js +6 -0
- package/dist/store/store.d.ts +15 -3
- package/dist/store/store.js +28 -7
- package/dist/telemetry/sinks/otlp.d.ts +31 -0
- package/dist/telemetry/sinks/otlp.js +76 -0
- package/dist/tools/builtins/filesystem.js +1 -0
- package/dist/tools/builtins/git.js +1 -0
- package/dist/tools/builtins/shell.js +1 -0
- package/dist/tools/permissions.d.ts +28 -0
- package/dist/tools/permissions.js +72 -0
- package/dist/tools/registry.d.ts +18 -2
- package/dist/tools/registry.js +22 -2
- package/dist/tools/tool.d.ts +4 -0
- package/dist/types.d.ts +5 -1
- package/dist/util/flatten.d.ts +11 -0
- package/dist/util/flatten.js +18 -0
- package/dist/util/hash.d.ts +19 -0
- package/dist/util/hash.js +39 -0
- package/dist/util/semaphore.d.ts +19 -0
- package/dist/util/semaphore.js +60 -0
- package/package.json +24 -9
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted agent tasks (Phase 3.5) — the schema, and the ONE way anything reads them back.
|
|
3
|
+
*
|
|
4
|
+
* An `Execution` is a JSON file in the user's home. Invariant 21 says persisted agent state is
|
|
5
|
+
* schema-validated on read, and the reason is concrete: a record's `innerPlan` is EXECUTED on resume and
|
|
6
|
+
* its hashes decide whether completed work may be reused, so a malformed record is not a display problem
|
|
7
|
+
* — it is an execution problem. Validation is fail-closed per record: anything that does not parse is
|
|
8
|
+
* dropped whole and counted, never coerced or half-read.
|
|
9
|
+
*
|
|
10
|
+
* READING IS NOT WRITING. `parseAgentTasks` returns a filtered VIEW and never touches the stored record,
|
|
11
|
+
* so merely listing or acquiring an execution cannot destroy tasks it could not parse. The dropped count
|
|
12
|
+
* travels with the view so a silently shrinking list is visible instead of inferred.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
/** Structural only. A persisted inner plan still faces `validatePlan` against the envelope before it runs. */
|
|
16
|
+
const planStep = z
|
|
17
|
+
.object({
|
|
18
|
+
id: z.string().min(1),
|
|
19
|
+
description: z.string(),
|
|
20
|
+
skill: z.string().optional(),
|
|
21
|
+
tool: z.string().optional(),
|
|
22
|
+
agent: z.string().optional(),
|
|
23
|
+
motivatedBy: z.array(z.string()).optional(),
|
|
24
|
+
input: z.unknown().optional(),
|
|
25
|
+
dependsOn: z.array(z.string()).optional(),
|
|
26
|
+
status: z.enum(['pending', 'running', 'succeeded', 'failed', 'skipped']),
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
29
|
+
const executionPlan = z.object({ id: z.string(), goal: z.string(), version: z.number(), steps: z.array(planStep), reason: z.string().optional() }).strict();
|
|
30
|
+
const observation = z
|
|
31
|
+
.object({
|
|
32
|
+
stepId: z.string(),
|
|
33
|
+
skill: z.string().optional(),
|
|
34
|
+
tool: z.string().optional(),
|
|
35
|
+
agent: z.string().optional(),
|
|
36
|
+
agentTaskId: z.string().optional(),
|
|
37
|
+
ok: z.boolean(),
|
|
38
|
+
output: z.string().optional(),
|
|
39
|
+
error: z.string().optional(),
|
|
40
|
+
code: z.string().optional(),
|
|
41
|
+
data: z.unknown().optional(),
|
|
42
|
+
artifacts: z.array(z.unknown()).optional(),
|
|
43
|
+
callsUsed: z.number().optional(),
|
|
44
|
+
})
|
|
45
|
+
.passthrough();
|
|
46
|
+
const evidence = z.object({ kind: z.string(), ref: z.string().optional(), detail: z.string().optional(), stepId: z.string().optional() }).passthrough();
|
|
47
|
+
const finding = z
|
|
48
|
+
.object({
|
|
49
|
+
id: z.string().min(1),
|
|
50
|
+
agentId: z.string(),
|
|
51
|
+
agentTaskId: z.string(),
|
|
52
|
+
type: z.string(),
|
|
53
|
+
subject: z.string().optional(),
|
|
54
|
+
claim: z.string(),
|
|
55
|
+
verdict: z.string().optional(),
|
|
56
|
+
executionCoverage: z.number().min(0).max(1),
|
|
57
|
+
confidence: z.number().min(0).max(1),
|
|
58
|
+
evidence: z.array(evidence),
|
|
59
|
+
artifacts: z.array(z.unknown()),
|
|
60
|
+
sourceSteps: z.array(z.string()),
|
|
61
|
+
provenance: z.object({ executionId: z.string().optional(), planVersion: z.number() }).passthrough(),
|
|
62
|
+
status: z.enum(['active', 'superseded', 'contradicted']),
|
|
63
|
+
supersededBy: z.string().optional(),
|
|
64
|
+
createdAt: z.number(),
|
|
65
|
+
})
|
|
66
|
+
.passthrough();
|
|
67
|
+
const checkpoint = z
|
|
68
|
+
.object({
|
|
69
|
+
at: z.number(),
|
|
70
|
+
planVersion: z.number(),
|
|
71
|
+
gitHead: z.string().optional(),
|
|
72
|
+
fileHashes: z.record(z.string(), z.string()),
|
|
73
|
+
configHash: z.string().optional(),
|
|
74
|
+
skillVersions: z.record(z.string(), z.string()),
|
|
75
|
+
completedSteps: z.array(z.string()),
|
|
76
|
+
mcpTools: z.record(z.string(), z.string()).optional(),
|
|
77
|
+
})
|
|
78
|
+
.passthrough();
|
|
79
|
+
/** A counter read back into arithmetic: a whole number, never negative, never absurd. */
|
|
80
|
+
const count = z.number().int().min(0).max(1_000_000);
|
|
81
|
+
/** Bounds on the per-record collections, so one task cannot make an execution file unreadable. */
|
|
82
|
+
const FINDINGS_MAX = 200;
|
|
83
|
+
const DIAGNOSTICS_MAX = 200;
|
|
84
|
+
const AGENT_STATES = ['created', 'queued', 'running', 'completed', 'failed', 'cancelled', 'waiting_for_input', 'waiting_for_clarification', 'paused'];
|
|
85
|
+
/**
|
|
86
|
+
* The record schema. `v` is a LITERAL: a record written by a future, wider version is dropped rather
|
|
87
|
+
* than parsed as this shape — reinterpreting an unknown layout is how a resume executes something its
|
|
88
|
+
* author never wrote.
|
|
89
|
+
*/
|
|
90
|
+
export const persistedAgentTask = z
|
|
91
|
+
.object({
|
|
92
|
+
v: z.literal(1),
|
|
93
|
+
agentTaskId: z.string().min(1),
|
|
94
|
+
agentId: z.string().min(1),
|
|
95
|
+
stepId: z.string().min(1),
|
|
96
|
+
state: z.enum(AGENT_STATES),
|
|
97
|
+
createdAt: z.number(),
|
|
98
|
+
updatedAt: z.number(),
|
|
99
|
+
startedAt: z.number().optional(),
|
|
100
|
+
endedAt: z.number().optional(),
|
|
101
|
+
interruption: z.object({ kind: z.enum(['crash', 'pause', 'parent-cancel']), at: z.number(), detail: z.string().optional() }).strict().optional(),
|
|
102
|
+
provenance: z.object({ executionId: z.string().optional(), planVersion: z.number() }).strict(),
|
|
103
|
+
agentDefHash: z.string().min(1),
|
|
104
|
+
envelopeHash: z.string().min(1),
|
|
105
|
+
stepInputHash: z.string().min(1),
|
|
106
|
+
attempt: z.number().int().min(1),
|
|
107
|
+
innerPlanVersion: z.number().optional(),
|
|
108
|
+
innerPlan: executionPlan.optional(),
|
|
109
|
+
innerCompletedSteps: z.array(z.string()),
|
|
110
|
+
innerObservations: z.array(observation),
|
|
111
|
+
innerObservationsOmitted: z.number().int().min(0),
|
|
112
|
+
innerCheckpoint: checkpoint.optional(),
|
|
113
|
+
pendingInner: z.object({ kind: z.literal('clarification'), question: z.string(), at: z.number() }).strict().optional(),
|
|
114
|
+
// Bounded and non-negative. These are read back into budget arithmetic and into rendered status
|
|
115
|
+
// lines, so a tampered or corrupted file must not be able to inject a negative or absurd count.
|
|
116
|
+
innerSteps: z.object({ total: count, succeeded: count }).strict(),
|
|
117
|
+
callsReserved: count,
|
|
118
|
+
callsUsed: count,
|
|
119
|
+
callsRefunded: count,
|
|
120
|
+
toolCallsUsed: count,
|
|
121
|
+
findings: z.array(finding).max(FINDINGS_MAX),
|
|
122
|
+
diagnostics: z.array(z.unknown()).max(DIAGNOSTICS_MAX),
|
|
123
|
+
failure: z.object({ code: z.string(), message: z.string() }).passthrough().optional(),
|
|
124
|
+
})
|
|
125
|
+
.strict();
|
|
126
|
+
/**
|
|
127
|
+
* Validate the agent tasks on an execution. Pure: it reads, it never writes. Callers that then persist
|
|
128
|
+
* the execution are choosing to drop the unparseable records — reading alone never does.
|
|
129
|
+
*/
|
|
130
|
+
export function parseAgentTasks(exec) {
|
|
131
|
+
const raw = exec.agentTasks;
|
|
132
|
+
if (!Array.isArray(raw))
|
|
133
|
+
return { tasks: [], dropped: 0 };
|
|
134
|
+
const tasks = [];
|
|
135
|
+
let dropped = 0;
|
|
136
|
+
for (const entry of raw) {
|
|
137
|
+
const parsed = persistedAgentTask.safeParse(entry);
|
|
138
|
+
if (!parsed.success) {
|
|
139
|
+
dropped += 1;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
tasks.push(parsed.data);
|
|
143
|
+
}
|
|
144
|
+
return { tasks, dropped };
|
|
145
|
+
}
|
|
146
|
+
/** One task by id, validated — the lookup every resume path uses. */
|
|
147
|
+
export function findAgentTask(exec, agentTaskId) {
|
|
148
|
+
return parseAgentTasks(exec).tasks.find((t) => t.agentTaskId === agentTaskId);
|
|
149
|
+
}
|
|
@@ -16,6 +16,10 @@ export interface CaptureInput {
|
|
|
16
16
|
skills: Skill[];
|
|
17
17
|
completedSteps: string[];
|
|
18
18
|
clock?: Clock;
|
|
19
|
+
/** Phase 3.5: plan-referenced MCP tool id → a hash of its live declaration. An MCP server is remote
|
|
20
|
+
* and mutable: it can change a tool's schema, or drop it, while a plan sits paused. That is drift in
|
|
21
|
+
* exactly the same sense as an edited file, and it was invisible before. */
|
|
22
|
+
mcpTools?: Record<string, string>;
|
|
19
23
|
}
|
|
20
24
|
export declare function captureCheckpoint(input: CaptureInput): Checkpoint;
|
|
21
25
|
export interface Reconciliation {
|
|
@@ -23,4 +27,4 @@ export interface Reconciliation {
|
|
|
23
27
|
reasons: string[];
|
|
24
28
|
}
|
|
25
29
|
/** Recompute the fingerprint and compare to a checkpoint. Any difference is drift. */
|
|
26
|
-
export declare function reconcile(checkpoint: Checkpoint, root: string, skills: Skill[]): Reconciliation;
|
|
30
|
+
export declare function reconcile(checkpoint: Checkpoint, root: string, skills: Skill[], mcpTools?: Record<string, string>): Reconciliation;
|
|
@@ -85,10 +85,11 @@ export function captureCheckpoint(input) {
|
|
|
85
85
|
...(cfg !== undefined ? { configHash: cfg } : {}),
|
|
86
86
|
skillVersions,
|
|
87
87
|
completedSteps: [...input.completedSteps],
|
|
88
|
+
...(input.mcpTools && Object.keys(input.mcpTools).length ? { mcpTools: input.mcpTools } : {}),
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
/** Recompute the fingerprint and compare to a checkpoint. Any difference is drift. */
|
|
91
|
-
export function reconcile(checkpoint, root, skills) {
|
|
92
|
+
export function reconcile(checkpoint, root, skills, mcpTools) {
|
|
92
93
|
const reasons = [];
|
|
93
94
|
// Compare directly so an ADDITION (absent at capture, present now — e.g. git initialized, config
|
|
94
95
|
// added) also counts as drift, not just a change to something already captured.
|
|
@@ -110,5 +111,16 @@ export function reconcile(checkpoint, root, skills) {
|
|
|
110
111
|
else if (cur !== ver)
|
|
111
112
|
reasons.push(`skill ${id} version changed (${ver} → ${cur})`);
|
|
112
113
|
}
|
|
114
|
+
// Phase 3.5: an absent `mcpTools` means the checkpoint predates this dimension — "nothing to
|
|
115
|
+
// compare", never "everything changed". A tool that vanished is drift: the plan references it.
|
|
116
|
+
if (checkpoint.mcpTools) {
|
|
117
|
+
for (const [id, hash] of Object.entries(checkpoint.mcpTools)) {
|
|
118
|
+
const cur = mcpTools?.[id];
|
|
119
|
+
if (cur === undefined)
|
|
120
|
+
reasons.push(`MCP tool ${id} is no longer available`);
|
|
121
|
+
else if (cur !== hash)
|
|
122
|
+
reasons.push(`MCP tool ${id} changed shape`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
113
125
|
return { drifted: reasons.length > 0, reasons };
|
|
114
126
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { ExecutionPlan } from '../orchestration/plan.js';
|
|
8
8
|
import type { StepObservation } from '../orchestration/executor.js';
|
|
9
9
|
import type { ArtifactRef } from '../runtime/types.js';
|
|
10
|
+
import type { AgentTaskRecord } from '../agents/task.js';
|
|
10
11
|
export type ExecutionStatus = 'planned' | 'running' | 'paused' | 'waiting_for_input' | 'waiting_for_clarification' | 'completed' | 'failed' | 'cancelled';
|
|
11
12
|
/** A time-boxed claim on an execution by one process. */
|
|
12
13
|
export interface Lease {
|
|
@@ -23,12 +24,31 @@ export interface Checkpoint {
|
|
|
23
24
|
configHash?: string;
|
|
24
25
|
skillVersions: Record<string, string>;
|
|
25
26
|
completedSteps: string[];
|
|
27
|
+
/** Phase 3.5: plan-referenced MCP tool id → a hash of its declaration at plan time. A server that
|
|
28
|
+
* changed a tool's shape under a paused plan is drift, exactly like an edited file. Absent on every
|
|
29
|
+
* pre-3.5 checkpoint, which reconcile must read as "nothing to compare", never as "everything changed". */
|
|
30
|
+
mcpTools?: Record<string, string>;
|
|
26
31
|
}
|
|
27
|
-
/**
|
|
32
|
+
/** A plan's estimated vs available model-call budget (Phase 22), carried on a budget-paused execution. */
|
|
33
|
+
export interface BudgetInfo {
|
|
34
|
+
/** Estimated model calls the plan needs (its skill steps). */
|
|
35
|
+
estCalls: number;
|
|
36
|
+
/** The call budget in force (`policy.maxCalls`). */
|
|
37
|
+
maxCalls: number;
|
|
38
|
+
/** Steps already completed (0 on a notify-before-start pause). */
|
|
39
|
+
completedSteps: number;
|
|
40
|
+
totalSteps: number;
|
|
41
|
+
}
|
|
42
|
+
/** What an execution is waiting for (approval / clarification / budget), persisted so a restart resumes it. */
|
|
28
43
|
export interface PendingInput {
|
|
29
|
-
kind: 'approval' | 'clarification';
|
|
44
|
+
kind: 'approval' | 'clarification' | 'budget';
|
|
30
45
|
question?: string;
|
|
31
46
|
action?: string;
|
|
47
|
+
budget?: BudgetInfo;
|
|
48
|
+
/** Phase 3.5: set when the wait belongs to an AGENT's inner run. The answer is then routed into that
|
|
49
|
+
* task's inner resume — appending it to the OUTER goal would replan and destroy every sibling's
|
|
50
|
+
* progress. Absent ⇒ the wait is the outer run's, which is the pre-3.5 behaviour unchanged. */
|
|
51
|
+
agentTaskId?: string;
|
|
32
52
|
}
|
|
33
53
|
export interface Execution {
|
|
34
54
|
id: string;
|
|
@@ -46,6 +66,20 @@ export interface Execution {
|
|
|
46
66
|
createdAt: number;
|
|
47
67
|
updatedAt: number;
|
|
48
68
|
lease?: Lease;
|
|
69
|
+
/** Phase 3.5: budgeted step-calls charged across every run AND resume of this execution — the unit
|
|
70
|
+
* `foldCalls` counts, NOT provider requests (planning calls are deliberately outside the pool).
|
|
71
|
+
*
|
|
72
|
+
* ACCOUNTING, NOT A CAP. It is deliberately not subtracted from `maxCalls` on resume: `AI_MAX_CALLS`
|
|
73
|
+
* bounds a RUN, and "raise it and resume" is how a partially-budgeted plan makes progress (Phase 22).
|
|
74
|
+
* Treating it as a cumulative task ceiling would make `AI_MAX_CALLS=1` un-resumable — the first run
|
|
75
|
+
* spends the whole allowance and every resume gets a budget of zero. See DECISIONS D132.
|
|
76
|
+
* Optional because records written before 3.5 do not have it: always read `?? 0`. */
|
|
77
|
+
callsUsed?: number;
|
|
78
|
+
/** Phase 3.5: the agent tasks this execution owns, in creation order. Schema-validated on read. */
|
|
79
|
+
agentTasks?: AgentTaskRecord[];
|
|
80
|
+
/** Phase 3.5, diagnostic: how many persisted agent tasks failed validation on the last read. Counted
|
|
81
|
+
* so a silently shrinking list is visible; the dropped records are never rendered as content. */
|
|
82
|
+
agentTasksDropped?: number;
|
|
49
83
|
}
|
|
50
84
|
export declare const RESUMABLE: ReadonlySet<ExecutionStatus>;
|
|
51
85
|
export declare const TERMINAL: ReadonlySet<ExecutionStatus>;
|
|
@@ -21,6 +21,26 @@ export interface AcquireResult {
|
|
|
21
21
|
execution?: Execution;
|
|
22
22
|
reason?: string;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Why a mid-run progress commit was accepted or refused (Phase 3.5).
|
|
26
|
+
*
|
|
27
|
+
* Every refusal means the same thing to the caller: SOMEONE ELSE now owns this execution's fate, and
|
|
28
|
+
* this process must stop — not retry, not carry on discarding writes. A run that keeps executing after a
|
|
29
|
+
* refused commit doubles every tool side effect and every model call while another owner re-runs the
|
|
30
|
+
* same steps, so the caller is required to abort. That is why this is an enum and not a boolean: a
|
|
31
|
+
* boolean invites an ignored return value at the call site, which is exactly the bug.
|
|
32
|
+
*/
|
|
33
|
+
export type CommitOutcome = 'ok'
|
|
34
|
+
/** The record is gone from disk (deleted under us). */
|
|
35
|
+
| 'missing'
|
|
36
|
+
/** Another owner holds the lease, or ours is gone — writing would clobber a live run. */
|
|
37
|
+
| 'foreign-lease'
|
|
38
|
+
/** The lease was released out from under us. Never write leaseless: an unleased record is claimable. */
|
|
39
|
+
| 'released'
|
|
40
|
+
/** Disk reached a terminal status. TERMINAL IS STICKY — a snapshot from before it may not undo it. */
|
|
41
|
+
| 'terminal'
|
|
42
|
+
/** Someone paused us. `paused` is not terminal, but this owner cannot produce it, so it is not ours to overwrite. */
|
|
43
|
+
| 'paused';
|
|
24
44
|
export declare class ExecutionStore {
|
|
25
45
|
private readonly area;
|
|
26
46
|
readonly owner: string;
|
|
@@ -42,6 +62,23 @@ export declare class ExecutionStore {
|
|
|
42
62
|
/** Claim an execution. Fails if a DIFFERENT owner holds a live lease; steals an expired one. Re-reads
|
|
43
63
|
* after writing to detect losing a concurrent steal (best-effort — no OS lock). */
|
|
44
64
|
acquire(id: string): AcquireResult;
|
|
65
|
+
/**
|
|
66
|
+
* THE mid-run write (Phase 3.5). Every incremental commit point goes through here and nothing else
|
|
67
|
+
* writes an execution while a run is in flight, so all four ordering rules live in one place:
|
|
68
|
+
*
|
|
69
|
+
* 1. TERMINAL IS STICKY. A commit carries a snapshot taken before it was built; if the record reached
|
|
70
|
+
* `completed`/`failed`/`cancelled` in the meantime, that verdict stands. Without this, a cancel is
|
|
71
|
+
* undone by the next in-flight wave's commit milliseconds later.
|
|
72
|
+
* 2. `paused` IS NOT OURS TO OVERWRITE. A running owner never writes `paused`, so finding it on disk
|
|
73
|
+
* means someone else did — and the pre-3.5 behaviour (clobber it at end of run) is far worse here,
|
|
74
|
+
* because commits are frequent: the pause would be erased within one batch, before any heartbeat
|
|
75
|
+
* tick could observe it.
|
|
76
|
+
* 3. NEVER WRITE LEASELESS. An unleased record is claimable by any process; writing one back without
|
|
77
|
+
* a lease invites a second owner to acquire and re-run everything this owner is still doing.
|
|
78
|
+
* 4. THE DISK LEASE WINS. Lease bookkeeping belongs to acquire/heartbeat; a progress commit carries a
|
|
79
|
+
* possibly-stale copy and must not push it back.
|
|
80
|
+
*/
|
|
81
|
+
commitProgress(exec: Execution): CommitOutcome;
|
|
45
82
|
/** Write only if we still hold the lease (or it's free/expired) — never clobber a live different owner. */
|
|
46
83
|
commit(exec: Execution): boolean;
|
|
47
84
|
/** Renew this owner's lease. Returns false if we no longer hold it. */
|
package/dist/executions/store.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { hostname } from 'node:os';
|
|
11
11
|
import { systemClock } from '../util/clock.js';
|
|
12
|
+
import { TERMINAL } from './execution.js';
|
|
12
13
|
export class ExecutionStore {
|
|
13
14
|
area;
|
|
14
15
|
owner;
|
|
@@ -85,6 +86,38 @@ export class ExecutionStore {
|
|
|
85
86
|
return { ok: false, reason: 'lost the acquire race' };
|
|
86
87
|
return { ok: true, execution: confirmed };
|
|
87
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* THE mid-run write (Phase 3.5). Every incremental commit point goes through here and nothing else
|
|
91
|
+
* writes an execution while a run is in flight, so all four ordering rules live in one place:
|
|
92
|
+
*
|
|
93
|
+
* 1. TERMINAL IS STICKY. A commit carries a snapshot taken before it was built; if the record reached
|
|
94
|
+
* `completed`/`failed`/`cancelled` in the meantime, that verdict stands. Without this, a cancel is
|
|
95
|
+
* undone by the next in-flight wave's commit milliseconds later.
|
|
96
|
+
* 2. `paused` IS NOT OURS TO OVERWRITE. A running owner never writes `paused`, so finding it on disk
|
|
97
|
+
* means someone else did — and the pre-3.5 behaviour (clobber it at end of run) is far worse here,
|
|
98
|
+
* because commits are frequent: the pause would be erased within one batch, before any heartbeat
|
|
99
|
+
* tick could observe it.
|
|
100
|
+
* 3. NEVER WRITE LEASELESS. An unleased record is claimable by any process; writing one back without
|
|
101
|
+
* a lease invites a second owner to acquire and re-run everything this owner is still doing.
|
|
102
|
+
* 4. THE DISK LEASE WINS. Lease bookkeeping belongs to acquire/heartbeat; a progress commit carries a
|
|
103
|
+
* possibly-stale copy and must not push it back.
|
|
104
|
+
*/
|
|
105
|
+
commitProgress(exec) {
|
|
106
|
+
const disk = this.get(exec.id);
|
|
107
|
+
if (!disk)
|
|
108
|
+
return 'missing';
|
|
109
|
+
if (TERMINAL.has(disk.status))
|
|
110
|
+
return 'terminal';
|
|
111
|
+
if (disk.status === 'paused' && exec.status !== 'paused')
|
|
112
|
+
return 'paused';
|
|
113
|
+
if (!disk.lease)
|
|
114
|
+
return 'released';
|
|
115
|
+
if (disk.lease.owner !== this.owner)
|
|
116
|
+
return 'foreign-lease';
|
|
117
|
+
exec.lease = disk.lease;
|
|
118
|
+
this.save(exec);
|
|
119
|
+
return 'ok';
|
|
120
|
+
}
|
|
88
121
|
/** Write only if we still hold the lease (or it's free/expired) — never clobber a live different owner. */
|
|
89
122
|
commit(exec) {
|
|
90
123
|
const disk = this.get(exec.id);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type OpenApiAnalysis } from '../discovery/openapi.js';
|
|
8
8
|
import type { ProviderConfig } from '../types.js';
|
|
9
|
+
import type { AI } from '../plugin/ai.js';
|
|
9
10
|
export interface GenerateOptions {
|
|
10
11
|
id?: string;
|
|
11
12
|
apiKeyEnv?: string;
|
|
@@ -15,3 +16,16 @@ export interface GenerateOptions {
|
|
|
15
16
|
/** Turn an OpenAPI analysis into a ProviderConfig. Throws if the spec yielded no usable mapping. */
|
|
16
17
|
export declare function generateProviderConfig(analysis: OpenApiAnalysis, overrides?: GenerateOptions): ProviderConfig;
|
|
17
18
|
export declare function generateProviderConfigFromFile(specPath: string, overrides?: GenerateOptions): ProviderConfig;
|
|
19
|
+
export interface SuggestResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
config?: ProviderConfig;
|
|
22
|
+
error?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* AI-assisted adapter rung (Phase 21a) — an opt-in gap-filler on top of the DETERMINISTIC
|
|
26
|
+
* `generateProviderConfig`. When the spec doesn't enumerate models, a model proposes a likely model-id
|
|
27
|
+
* list; the OUTPUT is STILL produced by `generateProviderConfig` (a validated `ProviderConfig`, never code),
|
|
28
|
+
* so a bad suggestion can only propose model-id strings the operator then confirms — it can never inject an
|
|
29
|
+
* unvalidated config. Any model/parse failure falls back to the deterministic result (or its error).
|
|
30
|
+
*/
|
|
31
|
+
export declare function suggestProviderConfig(analysis: OpenApiAnalysis, ai: AI, overrides?: GenerateOptions): Promise<SuggestResult>;
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { AIError } from '../core/fallback/errors.js';
|
|
8
8
|
import { analyzeOpenApiFile } from '../discovery/openapi.js';
|
|
9
|
+
import { extractJson } from '../util/extractJson.js';
|
|
10
|
+
import { wrapUntrusted } from '../tools/untrusted.js';
|
|
9
11
|
/** Turn an OpenAPI analysis into a ProviderConfig. Throws if the spec yielded no usable mapping. */
|
|
10
12
|
export function generateProviderConfig(analysis, overrides = {}) {
|
|
11
13
|
const base = analysis.suggestedProviderConfig;
|
|
@@ -28,3 +30,39 @@ export function generateProviderConfig(analysis, overrides = {}) {
|
|
|
28
30
|
export function generateProviderConfigFromFile(specPath, overrides = {}) {
|
|
29
31
|
return generateProviderConfig(analyzeOpenApiFile(specPath), overrides);
|
|
30
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* AI-assisted adapter rung (Phase 21a) — an opt-in gap-filler on top of the DETERMINISTIC
|
|
35
|
+
* `generateProviderConfig`. When the spec doesn't enumerate models, a model proposes a likely model-id
|
|
36
|
+
* list; the OUTPUT is STILL produced by `generateProviderConfig` (a validated `ProviderConfig`, never code),
|
|
37
|
+
* so a bad suggestion can only propose model-id strings the operator then confirms — it can never inject an
|
|
38
|
+
* unvalidated config. Any model/parse failure falls back to the deterministic result (or its error).
|
|
39
|
+
*/
|
|
40
|
+
export async function suggestProviderConfig(analysis, ai, overrides = {}) {
|
|
41
|
+
let modelList = Array.isArray(overrides.models) ? overrides.models : [];
|
|
42
|
+
// Only consult the model when we actually have a gap to fill (no explicit models, none in the spec).
|
|
43
|
+
const specModels = analysis.suggestedProviderConfig?.models;
|
|
44
|
+
const needsModels = modelList.length === 0 && (specModels === undefined || specModels === 'auto');
|
|
45
|
+
if (needsModels) {
|
|
46
|
+
try {
|
|
47
|
+
const prompt = `An OpenAPI spec describes an AI provider. Suggest the model IDs it most likely exposes for chat/completions. ` +
|
|
48
|
+
`Reply ONLY with JSON: {"models": ["<model-id>", ...]}.\n\n` +
|
|
49
|
+
wrapUntrusted('openapi-summary', `title: ${analysis.title ?? '(unknown)'}\nbaseUrl: ${analysis.baseUrl ?? '(unknown)'}\nwireShape: ${analysis.wireShape}\nendpoints: ${analysis.endpoints.map((e) => e.path).slice(0, 20).join(', ')}`);
|
|
50
|
+
const run = await ai.run({ task: 'suggest-provider-config', input: prompt, output: { format: 'json' }, requirements: { intelligence: ['reasoning'], output: ['json'] } });
|
|
51
|
+
if (run.ok && run.response) {
|
|
52
|
+
const parsed = (run.response.json ?? extractJson(run.response.text ?? ''));
|
|
53
|
+
if (Array.isArray(parsed?.models))
|
|
54
|
+
modelList = parsed.models.filter((m) => typeof m === 'string' && m.trim().length > 0);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* a suggestion failure just falls through to the deterministic path */
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const config = generateProviderConfig(analysis, { ...overrides, ...(modelList.length && !overrides.models ? { models: modelList } : {}) });
|
|
63
|
+
return { ok: true, config };
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill scaffolding (Phase 21a) — the generative seam for skills, mirroring `generateAdapter`'s
|
|
3
|
+
* "emit validated CONFIG/manifest, never code" rule. A model drafts a `*.skill.yaml` MANIFEST (pure data,
|
|
4
|
+
* parsed by the existing `parseManifest`); we then validate it three ways before offering it:
|
|
5
|
+
* 1. `parseManifest` (shape),
|
|
6
|
+
* 2. every step names an AVAILABLE tool (a `validatePlan`-style membership check — no invented tools),
|
|
7
|
+
* 3. a dry `manifestToSkill` compile (it must not throw).
|
|
8
|
+
* Nothing is written here — the caller writes it only on explicit confirm into the consented
|
|
9
|
+
* `.ai-runtime/skills/` directory. A drafted manifest that fails any check is refused with a reason.
|
|
10
|
+
*/
|
|
11
|
+
import type { AI } from '../plugin/ai.js';
|
|
12
|
+
import { type SkillManifest } from '../skills/manifest.js';
|
|
13
|
+
export interface GenerateSkillInput {
|
|
14
|
+
goal: string;
|
|
15
|
+
/** Tool ids the drafted manifest may use (the host's registered tools). */
|
|
16
|
+
tools: string[];
|
|
17
|
+
ai: AI;
|
|
18
|
+
}
|
|
19
|
+
export interface GenerateSkillResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
manifest?: SkillManifest;
|
|
22
|
+
/** The manifest serialized as `*.skill.yaml`, ready to write on confirm. */
|
|
23
|
+
yaml?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function generateSkillManifest(input: GenerateSkillInput): Promise<GenerateSkillResult>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill scaffolding (Phase 21a) — the generative seam for skills, mirroring `generateAdapter`'s
|
|
3
|
+
* "emit validated CONFIG/manifest, never code" rule. A model drafts a `*.skill.yaml` MANIFEST (pure data,
|
|
4
|
+
* parsed by the existing `parseManifest`); we then validate it three ways before offering it:
|
|
5
|
+
* 1. `parseManifest` (shape),
|
|
6
|
+
* 2. every step names an AVAILABLE tool (a `validatePlan`-style membership check — no invented tools),
|
|
7
|
+
* 3. a dry `manifestToSkill` compile (it must not throw).
|
|
8
|
+
* Nothing is written here — the caller writes it only on explicit confirm into the consented
|
|
9
|
+
* `.ai-runtime/skills/` directory. A drafted manifest that fails any check is refused with a reason.
|
|
10
|
+
*/
|
|
11
|
+
import { stringify as toYaml } from 'yaml';
|
|
12
|
+
import { parseManifest, manifestToSkill } from '../skills/manifest.js';
|
|
13
|
+
import { wrapUntrusted } from '../tools/untrusted.js';
|
|
14
|
+
import { extractJson } from '../util/extractJson.js';
|
|
15
|
+
export async function generateSkillManifest(input) {
|
|
16
|
+
const goal = String(input.goal ?? '').trim();
|
|
17
|
+
if (!goal)
|
|
18
|
+
return { ok: false, error: 'a goal is required' };
|
|
19
|
+
const tools = input.tools ?? [];
|
|
20
|
+
if (tools.length === 0)
|
|
21
|
+
return { ok: false, error: 'no tools are available to compose a skill from' };
|
|
22
|
+
const prompt = `Draft an ai-runtime skill MANIFEST (pure data — NOT code) that achieves the goal below. ` +
|
|
23
|
+
`The manifest runs a sequence of tool steps. Use ONLY these registered tools: ${tools.join(', ')}.\n\n` +
|
|
24
|
+
`Goal:\n${wrapUntrusted('scaffold-goal', goal)}\n\n` +
|
|
25
|
+
`Reply ONLY with JSON of this exact shape: {"id":"<kebab-case-id>","version":"1.0.0","name":"<short name>",` +
|
|
26
|
+
`"description":"<one line>","runtimeCompatibility":">=1.0.0","steps":[{"tool":"<one of the tools>","description":"<what this step does>"}]}.`;
|
|
27
|
+
// The whole model round-trip is wrapped: a bad model reply (e.g. non-JSON, which makes `extractJson`
|
|
28
|
+
// throw) must surface as { ok:false }, never as a thrown error — scaffolding is an assist, not a hard op.
|
|
29
|
+
try {
|
|
30
|
+
const run = await input.ai.run({ task: 'generate-skill', input: prompt, output: { format: 'json' }, requirements: { intelligence: ['reasoning'], output: ['json'] } });
|
|
31
|
+
if (!run.ok || !run.response)
|
|
32
|
+
return { ok: false, error: `generation failed (${run.error?.category ?? 'no response'})` };
|
|
33
|
+
const raw = run.response.json ?? extractJson(run.response.text ?? '');
|
|
34
|
+
const { manifest, error } = parseManifest(raw);
|
|
35
|
+
if (!manifest)
|
|
36
|
+
return { ok: false, error: `drafted manifest is invalid: ${error ?? 'unparseable'}` };
|
|
37
|
+
// Membership: a drafted step may only name a tool the host actually has (no invented capabilities).
|
|
38
|
+
const unknown = [...new Set(manifest.steps.map((s) => s.tool).filter((t) => !tools.includes(t)))];
|
|
39
|
+
if (unknown.length)
|
|
40
|
+
return { ok: false, error: `manifest names unregistered tool(s): ${unknown.join(', ')}` };
|
|
41
|
+
// A safe, filesystem-friendly id (also the filename); reject anything that could escape the skills dir.
|
|
42
|
+
if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(manifest.id))
|
|
43
|
+
return { ok: false, error: `manifest id must be kebab-case ([a-z0-9-]): got ${JSON.stringify(manifest.id)}` };
|
|
44
|
+
// Dry compile — the manifest must produce a runnable Skill without throwing.
|
|
45
|
+
manifestToSkill(manifest, '(scaffold)');
|
|
46
|
+
return { ok: true, manifest, yaml: toYaml(manifest) };
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return { ok: false, error: `could not scaffold a skill: ${e instanceof Error ? e.message : String(e)}` };
|
|
50
|
+
}
|
|
51
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -44,14 +44,20 @@ export { analyzeOpenApi, analyzeOpenApiFile } from './discovery/openapi.js';
|
|
|
44
44
|
export type { OpenApiAnalysis } from './discovery/openapi.js';
|
|
45
45
|
export { benchmark } from './benchmark/benchmark.js';
|
|
46
46
|
export type { BenchResult, BenchTaskSpec } from './benchmark/benchmark.js';
|
|
47
|
-
export { generateProviderConfig, generateProviderConfigFromFile } from './generation/generateAdapter.js';
|
|
48
|
-
export type { GenerateOptions } from './generation/generateAdapter.js';
|
|
47
|
+
export { generateProviderConfig, generateProviderConfigFromFile, suggestProviderConfig } from './generation/generateAdapter.js';
|
|
48
|
+
export type { GenerateOptions, SuggestResult } from './generation/generateAdapter.js';
|
|
49
|
+
export { generateSkillManifest } from './generation/generateSkill.js';
|
|
50
|
+
export type { GenerateSkillInput, GenerateSkillResult } from './generation/generateSkill.js';
|
|
49
51
|
export { McpRegistry, StaticMcpSource } from './mcp/mcp.js';
|
|
50
52
|
export type { McpToolSource } from './mcp/mcp.js';
|
|
51
53
|
export { setCredentialResolver, Credential } from './security/credentials.js';
|
|
52
54
|
export type { CredentialResolver } from './security/credentials.js';
|
|
53
55
|
export { CallbackSink, MemorySink, MultiSink, NullSink } from './telemetry/telemetry.js';
|
|
54
56
|
export type { TelemetrySink } from './telemetry/telemetry.js';
|
|
57
|
+
export { FileSink } from './telemetry/sinks/file.js';
|
|
58
|
+
export { OtlpSink } from './telemetry/sinks/otlp.js';
|
|
59
|
+
export type { OtlpSinkOptions } from './telemetry/sinks/otlp.js';
|
|
60
|
+
export { KeyedSemaphore } from './util/semaphore.js';
|
|
55
61
|
export { MARKETPLACE, listPresets, findPreset, presetToConfig } from './marketplace/presets.js';
|
|
56
62
|
export type { ProviderPreset } from './marketplace/presets.js';
|
|
57
63
|
export { loadRemoteConfig, loadConfigAsync } from './config/load.js';
|
|
@@ -64,6 +70,7 @@ export { resolvePolicy, defaultAutonomyForMode } from './runtime/policy.js';
|
|
|
64
70
|
export type { ExecutionPolicy, PermissionPolicy, Autonomy, ApprovalLevel, PolicyOverrides } from './runtime/policy.js';
|
|
65
71
|
export { parseRuntimeConfig, loadRuntimeConfig, findRuntimeConfigFile } from './runtime/config.js';
|
|
66
72
|
export { HeuristicIntentClassifier } from './runtime/intent/classifier.js';
|
|
73
|
+
export { AIIntentClassifier } from './runtime/intent/aiClassifier.js';
|
|
67
74
|
export type { IntentClassifier, IntentClassification, IntentInput } from './runtime/intent/classifier.js';
|
|
68
75
|
export { detectWorkspace, summarizeWorkspace } from './runtime/workspace/workspace.js';
|
|
69
76
|
export type { WorkspaceInfo } from './runtime/workspace/workspace.js';
|
|
@@ -77,8 +84,33 @@ export type { AccessState, ProviderView, ModelView, ProviderViewSource } from '.
|
|
|
77
84
|
export { RuntimeStore, STORE_VERSION } from './store/store.js';
|
|
78
85
|
export type { RuntimeStoreOptions, StorePaths } from './store/store.js';
|
|
79
86
|
export { FileArea, NullArea } from './store/area.js';
|
|
80
|
-
export type { Area, IntegrityIssue } from './store/area.js';
|
|
81
|
-
export {
|
|
87
|
+
export type { Area, IntegrityIssue, ContentCodec } from './store/area.js';
|
|
88
|
+
export { makeCodec, deriveKey, encryptString, decryptString, ENVELOPE_PREFIX } from './store/crypto.js';
|
|
89
|
+
export { resolveHome, projectId, repositoryId, organizationId, findRepoRoot } from './store/paths.js';
|
|
90
|
+
export { deriveCapabilities, deriveCapabilitiesOffline, candidatesFrom, candidateSlate, DERIVE_MAX_CANDIDATES, DERIVE_MAX_IDS } from './runtime/planning/deriveCapabilities.js';
|
|
91
|
+
export type { CapabilityCandidate, DeriveCapabilitiesInput, DeriveCapabilitiesResult } from './runtime/planning/deriveCapabilities.js';
|
|
92
|
+
export { ActionCapabilityRegistry, capabilityReportFrom } from './capabilities/registry.js';
|
|
93
|
+
export type { ActionCapabilityQuery, CapabilityConfig, RegistryAccessors } from './capabilities/registry.js';
|
|
94
|
+
export { CURATED_VOCABULARY, curated, isCurated } from './capabilities/vocabulary.js';
|
|
95
|
+
export type { CuratedCapability, PermissionHint } from './capabilities/vocabulary.js';
|
|
96
|
+
export type { ActionCapability, ActionCapabilityDecl, ActionCapabilityEffect, ActionCapabilityProvider, ActionCapabilitySource, CapabilityGap, CapabilityGapReason, CapabilityResolution, GapSuggestion, MissingCapabilityReport, ProviderAvailability, } from './capabilities/capability.js';
|
|
97
|
+
export type { AgentDefinition } from './agents/definition.js';
|
|
98
|
+
export type { AgentEnvelope } from './agents/envelope.js';
|
|
99
|
+
export type { AgentTaskRecord, AgentTaskState } from './agents/task.js';
|
|
100
|
+
export type { Finding, FindingEvidence, FindingEvidenceKind, FindingStatus } from './agents/finding.js';
|
|
101
|
+
export type { AdmissionRejection, AdmissionResult } from './agents/admit.js';
|
|
102
|
+
export type { StepObservationCode } from './orchestration/executor.js';
|
|
103
|
+
export { PLAN_STEP_STATUSES } from './orchestration/plan.js';
|
|
104
|
+
export { parseAgentTasks, findAgentTask } from './executions/agentTasks.js';
|
|
105
|
+
export type { AgentTaskView } from './executions/agentTasks.js';
|
|
106
|
+
export { AGENT_TERMINAL, AGENT_RESUMABLE } from './agents/task.js';
|
|
107
|
+
export type { ProgressSnapshot } from './orchestration/executor.js';
|
|
108
|
+
export { mcpToolId } from './mcp/toolAdapter.js';
|
|
109
|
+
export { MCP_PROTOCOL_VERSION } from './mcp/protocol.js';
|
|
110
|
+
export type { McpServerConfig, McpServerState, McpServerStatus, McpTransportKind } from './mcp/manager.js';
|
|
111
|
+
export type { McpServerSettings } from './runtime/types.js';
|
|
112
|
+
export type { McpServerGrant } from './tools/permissions.js';
|
|
113
|
+
export { clampMcpPermissions, clampPermissions } from './tools/permissions.js';
|
|
82
114
|
export type { StoreScope } from './store/paths.js';
|
|
83
115
|
export { ConversationStore } from './conversations/conversations.js';
|
|
84
116
|
export type { ConversationTurn, ConversationMeta, TurnRole } from './conversations/conversations.js';
|
|
@@ -87,9 +119,18 @@ export type { MemoryRecord, MemoryScope, MemorySource, RememberInput, SearchOpti
|
|
|
87
119
|
export { classifyMemory } from './memory/classifier.js';
|
|
88
120
|
export type { MemoryCandidate } from './memory/classifier.js';
|
|
89
121
|
export { bm25Search, tokenize } from './memory/bm25.js';
|
|
122
|
+
export { cosineSimilarity, semanticRank } from './memory/semantic.js';
|
|
123
|
+
export type { VecDoc, RankedHit } from './memory/semantic.js';
|
|
124
|
+
export { HashEmbedder } from './memory/embedders/hash.js';
|
|
125
|
+
export { HttpEmbedder } from './memory/embedders/http.js';
|
|
126
|
+
export type { HttpEmbedderConfig } from './memory/embedders/http.js';
|
|
90
127
|
export type { MemoryTrace } from './runtime/types.js';
|
|
91
128
|
export { compileContext } from './context/compiler.js';
|
|
92
129
|
export type { ContextBlock, CompiledBlock, CompiledContext, CompileMetrics, CompileOptions, ContextValidation, RetentionLevel } from './context/compiler.js';
|
|
130
|
+
export { verifyContextLoss } from './context/lossVerifier.js';
|
|
131
|
+
export type { VerifyLossInput, LossCheck } from './context/lossVerifier.js';
|
|
132
|
+
export { summarizeOverBudget } from './context/summarize.js';
|
|
133
|
+
export type { SummarizeInput } from './context/summarize.js';
|
|
93
134
|
export { TokenEstimator, estimateTokens } from './context/tokens.js';
|
|
94
135
|
export { resolveContextBudget, DEFAULT_CONTEXT_TOKENS } from './context/budget.js';
|
|
95
136
|
export type { ContextBudgetInputs } from './context/budget.js';
|
|
@@ -141,6 +182,8 @@ export type { LearningOutcome, LearnedStat, SkillRef } from './learning/learning
|
|
|
141
182
|
export { classifyFeedback } from './learning/feedback.js';
|
|
142
183
|
export type { FeedbackSignal } from './learning/feedback.js';
|
|
143
184
|
export { resolveRoutingPrefs, withPreferredProviders } from './runtime/routing.js';
|
|
185
|
+
export { parseModelProfile, parseDirective, resolveModelDirective, directiveToOverrides, loadModelProfile } from './runtime/models/modelProfile.js';
|
|
186
|
+
export type { ModelProfile, ModelDirective } from './runtime/models/modelProfile.js';
|
|
144
187
|
export type { RoutingSources } from './runtime/routing.js';
|
|
145
188
|
export { isExcluded, isPreferred } from './core/router/routingPrefs.js';
|
|
146
189
|
export type { RoutingPreferences } from './types.js';
|