car-runtime 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +36 -0
- package/README.md +63 -0
- package/index.d.ts +387 -0
- package/index.js +37 -0
- package/install.js +102 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Common Agent Runtime — Binary License
|
|
2
|
+
======================================
|
|
3
|
+
|
|
4
|
+
Copyright © 2026 Parslee AI. All rights reserved.
|
|
5
|
+
|
|
6
|
+
This package distributes pre-built binary artifacts of the Common Agent
|
|
7
|
+
Runtime (the "Binaries"). Your use of the Binaries is subject to these terms.
|
|
8
|
+
|
|
9
|
+
Subject to your agreement with these terms, Parslee AI grants you a
|
|
10
|
+
worldwide, royalty-free, non-exclusive, non-transferable license to:
|
|
11
|
+
|
|
12
|
+
(a) download, install, and use the Binaries for any lawful purpose,
|
|
13
|
+
including commercial use;
|
|
14
|
+
(b) redistribute the Binaries in their original, unmodified form,
|
|
15
|
+
provided this license is included.
|
|
16
|
+
|
|
17
|
+
You may NOT:
|
|
18
|
+
|
|
19
|
+
(c) modify, translate, adapt, or create derivative works of the Binaries;
|
|
20
|
+
(d) decompile, disassemble, reverse engineer, or otherwise attempt to
|
|
21
|
+
derive the source code of the Binaries, except to the extent that
|
|
22
|
+
applicable law expressly permits despite this limitation;
|
|
23
|
+
(e) remove, alter, or obscure any copyright, trademark, or other
|
|
24
|
+
proprietary notices on or in the Binaries;
|
|
25
|
+
(f) circumvent or disable any license-enforcement, anti-tamper, or
|
|
26
|
+
similar mechanism in the Binaries.
|
|
27
|
+
|
|
28
|
+
If you need rights beyond those granted above — including modification,
|
|
29
|
+
derivative works, source access, or a commercial redistribution agreement —
|
|
30
|
+
contact Parslee AI.
|
|
31
|
+
|
|
32
|
+
THE BINARIES ARE PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
33
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
|
|
34
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
35
|
+
PARSLEE AI BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING
|
|
36
|
+
FROM THE USE OF, INABILITY TO USE, OR DISTRIBUTION OF THE BINARIES.
|
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# car-runtime
|
|
2
|
+
|
|
3
|
+
Node.js bindings for **Common Agent Runtime** — a deterministic execution
|
|
4
|
+
layer for AI agents. Models propose; the runtime validates and executes.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install car-runtime
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The package's install script downloads the matching native binary for your
|
|
13
|
+
platform from [car-releases](https://github.com/Parslee-ai/car-releases/releases).
|
|
14
|
+
Supported platforms: macOS (14+) arm64/x64, Linux x64/arm64 glibc.
|
|
15
|
+
|
|
16
|
+
## Quickstart
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { CarRuntime, executeProposal } from 'car-runtime';
|
|
20
|
+
|
|
21
|
+
const rt = new CarRuntime();
|
|
22
|
+
|
|
23
|
+
// Register tools + policies.
|
|
24
|
+
await rt.registerTool('shell');
|
|
25
|
+
await rt.registerPolicy('no_rm', 'deny_tool_param', 'shell', 'command', 'rm -rf');
|
|
26
|
+
|
|
27
|
+
// Verify before executing.
|
|
28
|
+
const proposal = JSON.stringify({
|
|
29
|
+
actions: [{
|
|
30
|
+
id: 'a1',
|
|
31
|
+
type: 'tool_call',
|
|
32
|
+
tool: 'shell',
|
|
33
|
+
parameters: { command: 'ls' },
|
|
34
|
+
dependencies: [],
|
|
35
|
+
}],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const check = JSON.parse(await rt.verifyProposal(proposal));
|
|
39
|
+
if (!check.valid) throw new Error(`invalid: ${JSON.stringify(check.issues)}`);
|
|
40
|
+
|
|
41
|
+
// Execute with a JS tool callback.
|
|
42
|
+
const result = await executeProposal(rt, proposal, async (callJson) => {
|
|
43
|
+
const { tool, params } = JSON.parse(callJson);
|
|
44
|
+
// Dispatch to your tool implementation.
|
|
45
|
+
return JSON.stringify({ stdout: 'ok' });
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Full API reference lives in [`index.d.ts`](./index.d.ts). High-level docs and
|
|
50
|
+
examples: https://github.com/Parslee-ai/car-releases
|
|
51
|
+
|
|
52
|
+
## Environment variables
|
|
53
|
+
|
|
54
|
+
- `CAR_RUNTIME_SKIP_DOWNLOAD=1` — bypass the install-time download. Place the
|
|
55
|
+
binary in the package directory yourself.
|
|
56
|
+
- `CAR_RUNTIME_DOWNLOAD_BASE=<url>` — override the download origin (e.g.
|
|
57
|
+
internal mirror). Binary filename is appended.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
Free for any use including commercial; free to redistribute unmodified.
|
|
62
|
+
Modification, reverse engineering, and derivative works are not permitted.
|
|
63
|
+
See [`LICENSE`](./LICENSE) for the full text. Copyright © 2026 Parslee AI.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/** Common Agent Runtime — native Node.js bindings.
|
|
2
|
+
*
|
|
3
|
+
* Most methods that return structured data return a JSON-encoded string; the
|
|
4
|
+
* caller is expected to `JSON.parse` the result. This keeps the FFI surface
|
|
5
|
+
* small and avoids coupling the native binding to any specific TS shape.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Persistent runtime instance with state, memory, tools, and policies. */
|
|
9
|
+
export class CarRuntime {
|
|
10
|
+
constructor();
|
|
11
|
+
|
|
12
|
+
// --- Memory persistence ---
|
|
13
|
+
|
|
14
|
+
/** Load memory graph from a JSON file. Returns the number of facts loaded. */
|
|
15
|
+
loadMemory(path: string): number;
|
|
16
|
+
|
|
17
|
+
/** Persist memory graph to a JSON file (backward-compatible flat format). */
|
|
18
|
+
persistMemory(path: string): void;
|
|
19
|
+
|
|
20
|
+
// --- Tools & policies ---
|
|
21
|
+
|
|
22
|
+
/** Register a tool by name. */
|
|
23
|
+
registerTool(name: string): Promise<void>;
|
|
24
|
+
|
|
25
|
+
/** Register CAR's built-in agent utility tools. */
|
|
26
|
+
registerAgentBasics(): Promise<void>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Register a policy enforced in Rust on every action.
|
|
30
|
+
* `rule` is one of: "deny_tool", "deny_tool_param", "require_state".
|
|
31
|
+
*/
|
|
32
|
+
registerPolicy(
|
|
33
|
+
name: string,
|
|
34
|
+
rule: string,
|
|
35
|
+
target?: string | null,
|
|
36
|
+
key?: string | null,
|
|
37
|
+
pattern?: string | null,
|
|
38
|
+
valueJson?: string | null,
|
|
39
|
+
): Promise<void>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set replan configuration on this runtime.
|
|
43
|
+
* `maxReplans` = 0 disables replanning (default).
|
|
44
|
+
*/
|
|
45
|
+
setReplanConfig(maxReplans: number, delayMs?: number | null): Promise<void>;
|
|
46
|
+
|
|
47
|
+
// --- State ---
|
|
48
|
+
|
|
49
|
+
/** Set a state key (value must be a JSON string). */
|
|
50
|
+
stateSet(key: string, valueJson: string): void;
|
|
51
|
+
|
|
52
|
+
/** Get a state key. Returns the value as a JSON string, or `"null"`. */
|
|
53
|
+
stateGet(key: string): string;
|
|
54
|
+
|
|
55
|
+
stateExists(key: string): boolean;
|
|
56
|
+
|
|
57
|
+
/** Snapshot of all state as a JSON string. */
|
|
58
|
+
stateSnapshot(): string;
|
|
59
|
+
|
|
60
|
+
stateKeys(): string[];
|
|
61
|
+
|
|
62
|
+
// --- Memory / Facts (graph-backed) ---
|
|
63
|
+
|
|
64
|
+
/** Add a fact. `kind` is typically "pattern" or "constraint". */
|
|
65
|
+
addFact(subject: string, body: string, kind: string, confidence?: number | null): number;
|
|
66
|
+
|
|
67
|
+
/** Query facts via graph spreading activation. Returns a JSON array. */
|
|
68
|
+
queryFacts(query: string, k?: number | null): string;
|
|
69
|
+
|
|
70
|
+
factCount(): number;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Build the full 4-layer context for a query.
|
|
74
|
+
* When `modelContextWindow` is provided, dynamically sizes the budget.
|
|
75
|
+
*/
|
|
76
|
+
buildContext(query: string, modelContextWindow?: number | null): string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Build context in Fast mode for latency-sensitive paths.
|
|
80
|
+
* Skips embedding flush, skill lookup, PPR-based scoring, known unknowns.
|
|
81
|
+
*/
|
|
82
|
+
buildContextFast(query: string, modelContextWindow?: number | null): string;
|
|
83
|
+
|
|
84
|
+
/** Run memory consolidation ("dream") pass. Returns a JSON report. */
|
|
85
|
+
consolidate(): string;
|
|
86
|
+
|
|
87
|
+
// --- Skills ---
|
|
88
|
+
|
|
89
|
+
/** Save a learned skill with trigger context. Returns the node index. */
|
|
90
|
+
ingestSkill(
|
|
91
|
+
name: string,
|
|
92
|
+
code: string,
|
|
93
|
+
platform: string,
|
|
94
|
+
persona: string,
|
|
95
|
+
urlPattern: string,
|
|
96
|
+
taskKeywords: string[],
|
|
97
|
+
description: string,
|
|
98
|
+
supersedesSkill?: string | null,
|
|
99
|
+
): number;
|
|
100
|
+
|
|
101
|
+
/** Find best matching skill for context. Returns JSON or `"null"`. */
|
|
102
|
+
findSkill(
|
|
103
|
+
persona: string,
|
|
104
|
+
url: string,
|
|
105
|
+
task: string,
|
|
106
|
+
maxResults?: number | null,
|
|
107
|
+
): string;
|
|
108
|
+
|
|
109
|
+
/** Report skill execution outcome ("success" or "fail"). Returns updated stats JSON. */
|
|
110
|
+
reportOutcome(skillName: string, outcome: string): string;
|
|
111
|
+
|
|
112
|
+
/** Distill skills from execution trace events. Returns JSON array of DistilledSkill. */
|
|
113
|
+
distillSkills(eventsJson: string): Promise<string>;
|
|
114
|
+
|
|
115
|
+
/** Ingest distilled skills into the memory graph. Returns the count ingested. */
|
|
116
|
+
ingestDistilledSkills(skillsJson: string): number;
|
|
117
|
+
|
|
118
|
+
/** List skills (optionally filtered by domain). Returns JSON array. */
|
|
119
|
+
listSkills(domain?: string | null): string;
|
|
120
|
+
|
|
121
|
+
/** Domains with success rate below the given threshold (default 0.6). */
|
|
122
|
+
domainsNeedingEvolution(threshold?: number | null): string[];
|
|
123
|
+
|
|
124
|
+
/** Repair a degraded skill using local inference. Returns repaired code or null. */
|
|
125
|
+
repairSkill(skillName: string): Promise<string | null>;
|
|
126
|
+
|
|
127
|
+
/** Evolve skills for a domain based on failed events. Returns JSON array. */
|
|
128
|
+
evolveSkills(eventsJson: string, domain: string): Promise<string>;
|
|
129
|
+
|
|
130
|
+
// --- Inference ---
|
|
131
|
+
|
|
132
|
+
/** Generate text. Returns JSON: `{"text":"..."}`. */
|
|
133
|
+
infer(prompt: string, model?: string | null, maxTokens?: number | null): Promise<string>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Generate with full tracking: text, tool_calls, usage, model_used, latency_ms.
|
|
137
|
+
* Returns JSON.
|
|
138
|
+
*/
|
|
139
|
+
inferTracked(
|
|
140
|
+
prompt: string,
|
|
141
|
+
model?: string | null,
|
|
142
|
+
maxTokens?: number | null,
|
|
143
|
+
context?: string | null,
|
|
144
|
+
toolsJson?: string | null,
|
|
145
|
+
messagesJson?: string | null,
|
|
146
|
+
): Promise<string>;
|
|
147
|
+
|
|
148
|
+
/** Generate text grounded with memory context from this runtime's memgine. */
|
|
149
|
+
inferWithContext(
|
|
150
|
+
prompt: string,
|
|
151
|
+
model?: string | null,
|
|
152
|
+
maxTokens?: number | null,
|
|
153
|
+
): Promise<string>;
|
|
154
|
+
|
|
155
|
+
/** Embed texts. Returns JSON array of float arrays. */
|
|
156
|
+
embed(texts: string[], model?: string | null): Promise<string>;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Rerank documents against a query using a cross-encoder reranker.
|
|
160
|
+
* Returns JSON: `{ranked: [{index, score, document}, ...], model_used}`.
|
|
161
|
+
*/
|
|
162
|
+
rerank(
|
|
163
|
+
query: string,
|
|
164
|
+
documents: string[],
|
|
165
|
+
model?: string | null,
|
|
166
|
+
topN?: number | null,
|
|
167
|
+
instruction?: string | null,
|
|
168
|
+
): Promise<string>;
|
|
169
|
+
|
|
170
|
+
/** Classify text against labels. Returns JSON array of `{label, score}`. */
|
|
171
|
+
classify(text: string, labels: string[], model?: string | null): Promise<string>;
|
|
172
|
+
|
|
173
|
+
// --- Speech ---
|
|
174
|
+
|
|
175
|
+
/** Prepare the managed speech runtime and return its root path. */
|
|
176
|
+
prepareSpeechRuntime(): Promise<string>;
|
|
177
|
+
|
|
178
|
+
/** Transcribe a local audio file. Returns JSON `{text, model_used, language, ...}`. */
|
|
179
|
+
transcribe(
|
|
180
|
+
audioPath: string,
|
|
181
|
+
model?: string | null,
|
|
182
|
+
language?: string | null,
|
|
183
|
+
prompt?: string | null,
|
|
184
|
+
timestamps?: boolean | null,
|
|
185
|
+
): Promise<string>;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Synthesize speech to an output file. Returns JSON `{audio_path, media_type, ...}`.
|
|
189
|
+
* `referenceAudioPath`, `referenceText`, `voiceInstruction` are Qwen3-TTS-specific
|
|
190
|
+
* controls (voice cloning / voice design); other backends ignore them.
|
|
191
|
+
*/
|
|
192
|
+
synthesize(
|
|
193
|
+
text: string,
|
|
194
|
+
model?: string | null,
|
|
195
|
+
voice?: string | null,
|
|
196
|
+
language?: string | null,
|
|
197
|
+
speed?: number | null,
|
|
198
|
+
outputPath?: string | null,
|
|
199
|
+
format?: string | null,
|
|
200
|
+
referenceAudioPath?: string | null,
|
|
201
|
+
referenceText?: string | null,
|
|
202
|
+
voiceInstruction?: string | null,
|
|
203
|
+
): Promise<string>;
|
|
204
|
+
|
|
205
|
+
// --- Models ---
|
|
206
|
+
|
|
207
|
+
/** Local + built-in models. Returns JSON array. */
|
|
208
|
+
listModels(): string;
|
|
209
|
+
|
|
210
|
+
/** Download a model. Returns its local path. */
|
|
211
|
+
pullModel(name: string): Promise<string>;
|
|
212
|
+
|
|
213
|
+
/** Remove a downloaded model. */
|
|
214
|
+
removeModel(name: string): void;
|
|
215
|
+
|
|
216
|
+
/** Unified registry (local + remote). Returns JSON array. */
|
|
217
|
+
listModelsUnified(): string;
|
|
218
|
+
|
|
219
|
+
/** Register a model schema (persists to `~/.car/models.json`). */
|
|
220
|
+
registerModel(schemaJson: string): void;
|
|
221
|
+
|
|
222
|
+
/** Route a prompt. Returns the routing decision as JSON. */
|
|
223
|
+
routeModel(prompt: string): Promise<string>;
|
|
224
|
+
|
|
225
|
+
/** Per-model performance profiles. Returns JSON. */
|
|
226
|
+
modelStats(): Promise<string>;
|
|
227
|
+
|
|
228
|
+
// --- Execution ---
|
|
229
|
+
|
|
230
|
+
/** Count of events in this runtime's execution log. */
|
|
231
|
+
eventCount(): Promise<number>;
|
|
232
|
+
|
|
233
|
+
/** Verify a proposal against this runtime's state + tools. Returns JSON. */
|
|
234
|
+
verifyProposal(proposalJson: string): Promise<string>;
|
|
235
|
+
|
|
236
|
+
// --- Browser automation ---
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Run a JSON script of browser operations against a persistent Chromium
|
|
240
|
+
* session attached to this runtime instance. First call lazily launches
|
|
241
|
+
* Chromium (requires a local Chrome/Chromium binary); subsequent calls
|
|
242
|
+
* reuse the same session so element IDs from `observe` resolve across
|
|
243
|
+
* invocations.
|
|
244
|
+
*
|
|
245
|
+
* Script shape: `{operations: [{op:"navigate",url:"..."}, {op:"observe"}, ...]}`
|
|
246
|
+
* Supported ops: navigate, observe, click, type, scroll, keypress, wait.
|
|
247
|
+
* Returns JSON: `{steps:[{op,status,data,error,duration_ms}]}`. Execution
|
|
248
|
+
* short-circuits on first error.
|
|
249
|
+
*/
|
|
250
|
+
browserRun(
|
|
251
|
+
scriptJson: string,
|
|
252
|
+
width?: number | null,
|
|
253
|
+
height?: number | null,
|
|
254
|
+
): Promise<string>;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Standalone functions
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Execute a proposal through a CarRuntime with a JS tool callback.
|
|
263
|
+
* The callback receives `{"tool":"name","params":{...}}` as a JSON string
|
|
264
|
+
* and must return a JSON string.
|
|
265
|
+
*/
|
|
266
|
+
export function executeProposal(
|
|
267
|
+
rt: CarRuntime,
|
|
268
|
+
proposalJson: string,
|
|
269
|
+
toolFn: (callJson: string) => Promise<string>,
|
|
270
|
+
): Promise<string>;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Stream inference events in real time via a callback.
|
|
274
|
+
* Callback receives event JSON strings:
|
|
275
|
+
* `{"type":"text","data":"..."}`
|
|
276
|
+
* `{"type":"tool_start","name":"...","index":N}`
|
|
277
|
+
* `{"type":"tool_delta","index":N,"data":"..."}`
|
|
278
|
+
* `{"type":"done","text":"...","tool_calls":[...]}`
|
|
279
|
+
*/
|
|
280
|
+
export function inferStream(
|
|
281
|
+
rt: CarRuntime,
|
|
282
|
+
prompt: string,
|
|
283
|
+
model: string | null | undefined,
|
|
284
|
+
maxTokens: number | null | undefined,
|
|
285
|
+
context: string | null | undefined,
|
|
286
|
+
toolsJson: string | null | undefined,
|
|
287
|
+
onEvent: (eventJson: string) => void,
|
|
288
|
+
): Promise<string>;
|
|
289
|
+
|
|
290
|
+
// --- Verification (stateless) ---
|
|
291
|
+
|
|
292
|
+
export function verify(
|
|
293
|
+
proposalJson: string,
|
|
294
|
+
initialStateJson?: string | null,
|
|
295
|
+
toolNames?: string[] | null,
|
|
296
|
+
maxActions?: number | null,
|
|
297
|
+
): string;
|
|
298
|
+
|
|
299
|
+
export function simulate(
|
|
300
|
+
proposalJson: string,
|
|
301
|
+
initialStateJson?: string | null,
|
|
302
|
+
): string;
|
|
303
|
+
|
|
304
|
+
export function optimize(proposalJson: string): string;
|
|
305
|
+
|
|
306
|
+
export function equivalent(proposal1Json: string, proposal2Json: string): boolean;
|
|
307
|
+
|
|
308
|
+
// --- Multi-agent coordination ---
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Register the agent runner callback for multi-agent and scheduler functions.
|
|
312
|
+
* Call once before using `runSwarm`, `runPipeline`, `runSupervisor`, etc.
|
|
313
|
+
*
|
|
314
|
+
* `agentFn(specJson, taskJson) => Promise<AgentOutput JSON>`
|
|
315
|
+
*/
|
|
316
|
+
export function registerAgentRunner(
|
|
317
|
+
agentFn: (specJson: string, taskJson: string) => Promise<string>,
|
|
318
|
+
): Promise<void>;
|
|
319
|
+
|
|
320
|
+
/** Run a Swarm pattern. `mode` is "parallel", "sequential", or "debate". */
|
|
321
|
+
export function runSwarm(
|
|
322
|
+
mode: string,
|
|
323
|
+
agents: string,
|
|
324
|
+
task: string,
|
|
325
|
+
synthesizerSpec?: string | null,
|
|
326
|
+
): Promise<string>;
|
|
327
|
+
|
|
328
|
+
export function runPipeline(stages: string, task: string): Promise<string>;
|
|
329
|
+
|
|
330
|
+
export function runSupervisor(
|
|
331
|
+
workers: string,
|
|
332
|
+
supervisor: string,
|
|
333
|
+
task: string,
|
|
334
|
+
maxRounds: number,
|
|
335
|
+
): Promise<string>;
|
|
336
|
+
|
|
337
|
+
export function runMapReduce(
|
|
338
|
+
mapper: string,
|
|
339
|
+
reducer: string,
|
|
340
|
+
task: string,
|
|
341
|
+
items: string,
|
|
342
|
+
): Promise<string>;
|
|
343
|
+
|
|
344
|
+
export function runVote(
|
|
345
|
+
agents: string,
|
|
346
|
+
task: string,
|
|
347
|
+
synthesizerSpec?: string | null,
|
|
348
|
+
): Promise<string>;
|
|
349
|
+
|
|
350
|
+
// --- Scheduler ---
|
|
351
|
+
|
|
352
|
+
/** Create a task definition. Returns task JSON. */
|
|
353
|
+
export function createTask(
|
|
354
|
+
name: string,
|
|
355
|
+
prompt: string,
|
|
356
|
+
trigger?: string | null,
|
|
357
|
+
schedule?: string | null,
|
|
358
|
+
systemPrompt?: string | null,
|
|
359
|
+
): string;
|
|
360
|
+
|
|
361
|
+
/** Run a task once using the registered agent runner. */
|
|
362
|
+
export function runTask(taskJson: string): Promise<string>;
|
|
363
|
+
|
|
364
|
+
/** Run a task loop using the registered agent runner. */
|
|
365
|
+
export function runTaskLoop(
|
|
366
|
+
taskJson: string,
|
|
367
|
+
maxIterations?: number | null,
|
|
368
|
+
): Promise<string>;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Ensure a dream (memory consolidation) task exists in `~/.car/tasks/`.
|
|
372
|
+
* Returns true if a new task was created, false if one already existed.
|
|
373
|
+
*/
|
|
374
|
+
export function ensureDreamTask(): boolean;
|
|
375
|
+
|
|
376
|
+
// --- Planner ---
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Score and rank candidate proposals. Returns JSON array of ScoredProposal.
|
|
380
|
+
* `candidatesJson` is a JSON array of ActionProposal objects.
|
|
381
|
+
* `tools` is an optional array of registered tool names.
|
|
382
|
+
*/
|
|
383
|
+
export function rankProposals(
|
|
384
|
+
candidatesJson: string,
|
|
385
|
+
tools?: string[] | null,
|
|
386
|
+
costWeight?: number | null,
|
|
387
|
+
): string;
|
package/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Platform-aware loader. The binary is downloaded at install time by
|
|
2
|
+
// install.js — see that file for the download contract and opt-outs.
|
|
3
|
+
|
|
4
|
+
const os = require('node:os');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const platformMap = {
|
|
8
|
+
'darwin-arm64': 'darwin-arm64',
|
|
9
|
+
'darwin-x64': 'darwin-x64',
|
|
10
|
+
'linux-x64': 'linux-x64-gnu',
|
|
11
|
+
'linux-arm64': 'linux-arm64-gnu',
|
|
12
|
+
'win32-x64': 'win32-x64-msvc',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const key = `${os.platform()}-${os.arch()}`;
|
|
16
|
+
const target = platformMap[key];
|
|
17
|
+
|
|
18
|
+
if (!target) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Unsupported platform: ${key}. Supported: ${Object.keys(platformMap).join(', ')}.`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const binaryPath = path.join(__dirname, `car-runtime.${target}.node`);
|
|
25
|
+
|
|
26
|
+
let nativeModule;
|
|
27
|
+
try {
|
|
28
|
+
nativeModule = require(binaryPath);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Failed to load car-runtime native binary at ${binaryPath}. ` +
|
|
32
|
+
`Try reinstalling, or set CAR_RUNTIME_DOWNLOAD_BASE to a mirror and ` +
|
|
33
|
+
`run node install.js manually. Error: ${e.message}`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = nativeModule;
|
package/install.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Downloads the native Node.js binary matching this package's version and
|
|
3
|
+
// the host platform from the car-releases GitHub repo. Cached next to this
|
|
4
|
+
// script so `require('./car-runtime.<platform>.node')` resolves without
|
|
5
|
+
// another network round-trip.
|
|
6
|
+
|
|
7
|
+
const fs = require('node:fs');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const https = require('node:https');
|
|
10
|
+
const { pipeline } = require('node:stream/promises');
|
|
11
|
+
|
|
12
|
+
const PLATFORMS = {
|
|
13
|
+
'darwin-arm64': 'car-runtime.darwin-arm64.node',
|
|
14
|
+
'darwin-x64': 'car-runtime.darwin-x64.node',
|
|
15
|
+
'linux-x64': 'car-runtime.linux-x64-gnu.node',
|
|
16
|
+
'linux-arm64': 'car-runtime.linux-arm64-gnu.node',
|
|
17
|
+
'win32-x64': 'car-runtime.win32-x64-msvc.node',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function targetForHost() {
|
|
21
|
+
const key = `${process.platform}-${process.arch}`;
|
|
22
|
+
const name = PLATFORMS[key];
|
|
23
|
+
if (!name) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Unsupported platform ${key}. Supported: ${Object.keys(PLATFORMS).join(', ')}.`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return name;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function pkgVersion() {
|
|
32
|
+
const pkg = JSON.parse(
|
|
33
|
+
fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'),
|
|
34
|
+
);
|
|
35
|
+
return pkg.version;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function get(url) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const req = https.get(
|
|
41
|
+
url,
|
|
42
|
+
{ headers: { 'user-agent': `car-runtime-install/${pkgVersion()}` } },
|
|
43
|
+
(res) => {
|
|
44
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
45
|
+
// Follow redirect (GitHub release asset URLs redirect to S3).
|
|
46
|
+
res.resume();
|
|
47
|
+
return resolve(get(res.headers.location));
|
|
48
|
+
}
|
|
49
|
+
if (res.statusCode !== 200) {
|
|
50
|
+
res.resume();
|
|
51
|
+
return reject(new Error(`${url} → HTTP ${res.statusCode}`));
|
|
52
|
+
}
|
|
53
|
+
resolve(res);
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
req.on('error', reject);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function main() {
|
|
61
|
+
const name = targetForHost();
|
|
62
|
+
const dest = path.join(__dirname, name);
|
|
63
|
+
|
|
64
|
+
// Opt-out for air-gapped installs — user is expected to drop the .node
|
|
65
|
+
// file into this directory themselves.
|
|
66
|
+
if (process.env.CAR_RUNTIME_SKIP_DOWNLOAD === '1') {
|
|
67
|
+
console.log('[car-runtime] CAR_RUNTIME_SKIP_DOWNLOAD=1 — skipping download.');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Skip if already present (e.g. preinstalled, reinstall without cache wipe).
|
|
72
|
+
if (fs.existsSync(dest)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const version = pkgVersion();
|
|
77
|
+
const url = `https://github.com/Parslee-ai/car-releases/releases/download/v${version}/${name}`;
|
|
78
|
+
|
|
79
|
+
// Override for testing / mirrors.
|
|
80
|
+
const base = process.env.CAR_RUNTIME_DOWNLOAD_BASE;
|
|
81
|
+
const finalUrl = base ? `${base}/${name}` : url;
|
|
82
|
+
|
|
83
|
+
console.log(`[car-runtime] downloading ${finalUrl}`);
|
|
84
|
+
try {
|
|
85
|
+
const res = await get(finalUrl);
|
|
86
|
+
const tmp = `${dest}.part`;
|
|
87
|
+
await pipeline(res, fs.createWriteStream(tmp));
|
|
88
|
+
fs.renameSync(tmp, dest);
|
|
89
|
+
console.log(`[car-runtime] installed ${name}`);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error(
|
|
92
|
+
`[car-runtime] download failed: ${err.message}\n` +
|
|
93
|
+
`Place ${name} manually in ${__dirname} or set CAR_RUNTIME_SKIP_DOWNLOAD=1 ` +
|
|
94
|
+
`and ensure the binary is resolvable at require-time.`,
|
|
95
|
+
);
|
|
96
|
+
// Exit 0 so `npm install` doesn't fail the whole project — the require()
|
|
97
|
+
// in index.js will surface a clear error if the binary is missing.
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "car-runtime",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "Common Agent Runtime — a deterministic execution layer for AI agents",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ai",
|
|
9
|
+
"agent",
|
|
10
|
+
"runtime",
|
|
11
|
+
"llm",
|
|
12
|
+
"inference",
|
|
13
|
+
"napi"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/Parslee-ai/car-releases.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/Parslee-ai/car-releases",
|
|
20
|
+
"bugs": "https://github.com/Parslee-ai/car-releases/issues",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18"
|
|
23
|
+
},
|
|
24
|
+
"os": [
|
|
25
|
+
"darwin",
|
|
26
|
+
"linux",
|
|
27
|
+
"win32"
|
|
28
|
+
],
|
|
29
|
+
"cpu": [
|
|
30
|
+
"x64",
|
|
31
|
+
"arm64"
|
|
32
|
+
],
|
|
33
|
+
"files": [
|
|
34
|
+
"index.js",
|
|
35
|
+
"index.d.ts",
|
|
36
|
+
"install.js",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"install": "node install.js || true"
|
|
42
|
+
},
|
|
43
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
44
|
+
"private": false
|
|
45
|
+
}
|