car-runtime 0.5.1 → 0.6.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/index.d.ts +534 -19
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
3
3
|
* Most methods that return structured data return a JSON-encoded string; the
|
|
4
4
|
* caller is expected to `JSON.parse` the result. This keeps the FFI surface
|
|
5
5
|
* small and avoids coupling the native binding to any specific TS shape.
|
|
6
|
+
*
|
|
7
|
+
* ## Runtime modes (closes #139's cross-process admission gap)
|
|
8
|
+
*
|
|
9
|
+
* `new CarRuntime()` runs in one of two modes, selected at construction:
|
|
10
|
+
*
|
|
11
|
+
* - **`daemon` (default)** — talks to the singleton car-server daemon over
|
|
12
|
+
* WebSocket JSON-RPC. Methods that touch shared resources (inference,
|
|
13
|
+
* embeddings, state, verification) proxy to the daemon — preserving the
|
|
14
|
+
* process-wide admission semaphore so two Node consumers don't double-load
|
|
15
|
+
* models or oversubscribe the GPU.
|
|
16
|
+
* - **`embedded`** — explicit opt-in via `CAR_FFI_MODE=embedded`. Every
|
|
17
|
+
* method runs in-process. Useful for notebooks, offline dev, or single-
|
|
18
|
+
* process deployments where the caller knows they own the machine.
|
|
19
|
+
* Production embedders generally don't want this.
|
|
20
|
+
*
|
|
21
|
+
* Some methods are **embedded-only by design** because their callback
|
|
22
|
+
* surface (`ThreadsafeFunction` for tools, streaming events) doesn't
|
|
23
|
+
* survive a network boundary cleanly. Those throw in `daemon` mode with a
|
|
24
|
+
* clear message: `executeProposal`, `inferStream`. For streaming inference
|
|
25
|
+
* under the singleton-daemon contract, talk to `ws://127.0.0.1:9100/`
|
|
26
|
+
* directly.
|
|
27
|
+
*
|
|
28
|
+
* Daemon URL override: `CAR_DAEMON_URL=ws://...` (default
|
|
29
|
+
* `ws://127.0.0.1:9100`).
|
|
6
30
|
*/
|
|
7
31
|
|
|
8
32
|
/** Persistent runtime instance with state, memory, tools, and policies. */
|
|
@@ -61,19 +85,40 @@ export class CarRuntime {
|
|
|
61
85
|
|
|
62
86
|
// --- Memory / Facts (graph-backed) ---
|
|
63
87
|
|
|
64
|
-
/**
|
|
65
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Add a fact. `kind` is typically "pattern" or "constraint".
|
|
90
|
+
*
|
|
91
|
+
* In Daemon mode, rejects with the daemon-unreachable error
|
|
92
|
+
* instead of silently returning 0 (#146).
|
|
93
|
+
*/
|
|
94
|
+
addFact(
|
|
95
|
+
subject: string,
|
|
96
|
+
body: string,
|
|
97
|
+
kind: string,
|
|
98
|
+
confidence?: number | null,
|
|
99
|
+
): Promise<number>;
|
|
66
100
|
|
|
67
101
|
/** Query facts via graph spreading activation. Returns a JSON array. */
|
|
68
102
|
queryFacts(query: string, k?: number | null): string;
|
|
69
103
|
|
|
70
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Total valid fact count.
|
|
106
|
+
*
|
|
107
|
+
* In Daemon mode, hits the daemon's per-session memgine — the
|
|
108
|
+
* embedded fallback memgine stays empty by design and would
|
|
109
|
+
* silently return 0 (#146). Rejects with the daemon-unreachable
|
|
110
|
+
* error instead.
|
|
111
|
+
*/
|
|
112
|
+
factCount(): Promise<number>;
|
|
71
113
|
|
|
72
114
|
/**
|
|
73
115
|
* Build the full 4-layer context for a query.
|
|
74
116
|
* When `modelContextWindow` is provided, dynamically sizes the budget.
|
|
117
|
+
*
|
|
118
|
+
* In Daemon mode, rejects with the daemon-unreachable error
|
|
119
|
+
* instead of silently returning "" (#146).
|
|
75
120
|
*/
|
|
76
|
-
buildContext(query: string, modelContextWindow?: number | null): string
|
|
121
|
+
buildContext(query: string, modelContextWindow?: number | null): Promise<string>;
|
|
77
122
|
|
|
78
123
|
/**
|
|
79
124
|
* Build context in Fast mode for latency-sensitive paths.
|
|
@@ -86,7 +131,14 @@ export class CarRuntime {
|
|
|
86
131
|
|
|
87
132
|
// --- Skills ---
|
|
88
133
|
|
|
89
|
-
/**
|
|
134
|
+
/**
|
|
135
|
+
* Save a learned skill with trigger context. Returns the node
|
|
136
|
+
* index.
|
|
137
|
+
*
|
|
138
|
+
* In Daemon mode, rejects with the daemon-unreachable error
|
|
139
|
+
* (or a parse error if the response is malformed) instead of
|
|
140
|
+
* silently returning 0 (#146).
|
|
141
|
+
*/
|
|
90
142
|
ingestSkill(
|
|
91
143
|
name: string,
|
|
92
144
|
code: string,
|
|
@@ -96,7 +148,7 @@ export class CarRuntime {
|
|
|
96
148
|
taskKeywords: string[],
|
|
97
149
|
description: string,
|
|
98
150
|
supersedesSkill?: string | null,
|
|
99
|
-
): number
|
|
151
|
+
): Promise<number>;
|
|
100
152
|
|
|
101
153
|
/** Find best matching skill for context. Returns JSON or `"null"`. */
|
|
102
154
|
findSkill(
|
|
@@ -129,12 +181,33 @@ export class CarRuntime {
|
|
|
129
181
|
|
|
130
182
|
// --- Inference ---
|
|
131
183
|
|
|
132
|
-
/**
|
|
133
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Generate text. Returns JSON: `{"text":"..."}`.
|
|
186
|
+
*
|
|
187
|
+
* `intentJson` is an optional serialized {@link IntentHint} —
|
|
188
|
+
* caller-facing routing hints (task, prefer_local, require). Omit to
|
|
189
|
+
* preserve the existing adaptive vs. pinned-model behavior.
|
|
190
|
+
*/
|
|
191
|
+
infer(
|
|
192
|
+
prompt: string,
|
|
193
|
+
model?: string | null,
|
|
194
|
+
maxTokens?: number | null,
|
|
195
|
+
intentJson?: string | null,
|
|
196
|
+
): Promise<string>;
|
|
134
197
|
|
|
135
198
|
/**
|
|
136
|
-
* Generate with full tracking
|
|
137
|
-
*
|
|
199
|
+
* Generate with full tracking. Returns JSON with `text`, `tool_calls`,
|
|
200
|
+
* `usage`, `model_used`, `latency_ms`, `time_to_first_token_ms`,
|
|
201
|
+
* `trace_id`. `time_to_first_token_ms` is wall-clock to the first
|
|
202
|
+
* sampled token (populated by local Candle/MLX paths; `null` for
|
|
203
|
+
* non-streaming remote calls).
|
|
204
|
+
*
|
|
205
|
+
* **Note:** intent is not exposed on the tracked path until the
|
|
206
|
+
* positional argument list is converted to an options object —
|
|
207
|
+
* this method already takes 8 positional parameters and adding a
|
|
208
|
+
* 9th would push call sites past readability. For new code, use
|
|
209
|
+
* {@link inferTrackedWithRequest} which takes a JSON-stringified
|
|
210
|
+
* `GenerateRequest` and exposes every field including `intent`.
|
|
138
211
|
*/
|
|
139
212
|
inferTracked(
|
|
140
213
|
prompt: string,
|
|
@@ -147,11 +220,24 @@ export class CarRuntime {
|
|
|
147
220
|
parallelToolCalls?: boolean | null,
|
|
148
221
|
): Promise<string>;
|
|
149
222
|
|
|
150
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Generate with full tracking, options-object form.
|
|
225
|
+
* `requestJson` is a `JSON.stringify`d `GenerateRequest` (every
|
|
226
|
+
* field optional except `prompt`). Exposes every field on the
|
|
227
|
+
* Rust struct including `intent`. Same pattern as
|
|
228
|
+
* {@link verifyProposal}. Closes #107.
|
|
229
|
+
*/
|
|
230
|
+
inferTrackedWithRequest(requestJson: string): Promise<string>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Generate text grounded with memory context from this runtime's
|
|
234
|
+
* memgine. `intentJson` works the same as on {@link infer}.
|
|
235
|
+
*/
|
|
151
236
|
inferWithContext(
|
|
152
237
|
prompt: string,
|
|
153
238
|
model?: string | null,
|
|
154
239
|
maxTokens?: number | null,
|
|
240
|
+
intentJson?: string | null,
|
|
155
241
|
): Promise<string>;
|
|
156
242
|
|
|
157
243
|
/** Embed texts. Returns JSON array of float arrays. */
|
|
@@ -172,6 +258,20 @@ export class CarRuntime {
|
|
|
172
258
|
/** Classify text against labels. Returns JSON array of `{label, score}`. */
|
|
173
259
|
classify(text: string, labels: string[], model?: string | null): Promise<string>;
|
|
174
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Encode `text` via the named local model's tokenizer. Returns a JSON
|
|
263
|
+
* array of u32 token IDs, raw (no chat-template wrapping, no BOS).
|
|
264
|
+
* Pair with `detokenize` for byte-identical round-trip. Remote models
|
|
265
|
+
* are not supported — call rejects with an error there.
|
|
266
|
+
*/
|
|
267
|
+
tokenize(model: string, text: string): Promise<string>;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Decode token IDs back to text via the named local model's tokenizer.
|
|
271
|
+
* Inverse of `tokenize` for the round-trip property.
|
|
272
|
+
*/
|
|
273
|
+
detokenize(model: string, tokens: number[]): Promise<string>;
|
|
274
|
+
|
|
175
275
|
// --- Speech ---
|
|
176
276
|
|
|
177
277
|
/** Prepare the managed speech runtime and return its root path. */
|
|
@@ -215,7 +315,14 @@ export class CarRuntime {
|
|
|
215
315
|
/** Remove a downloaded model. */
|
|
216
316
|
removeModel(name: string): void;
|
|
217
317
|
|
|
218
|
-
/**
|
|
318
|
+
/**
|
|
319
|
+
* Unified registry (local + remote). Returns JSON array of
|
|
320
|
+
* `{ id, name, provider, capabilities, param_count, size_mb,
|
|
321
|
+
* context_length, available, is_local, public_benchmarks }`.
|
|
322
|
+
* `public_benchmarks` is `[{ name, score, harness?, source_url?,
|
|
323
|
+
* measured_at? }]` with score on a 0.0–1.0 scale; ships empty in
|
|
324
|
+
* the built-in catalog and is populated via curated registry data.
|
|
325
|
+
*/
|
|
219
326
|
listModelsUnified(): string;
|
|
220
327
|
|
|
221
328
|
/** Register a model schema (persists to `~/.car/models.json`). */
|
|
@@ -248,12 +355,167 @@ export class CarRuntime {
|
|
|
248
355
|
* Supported ops: navigate, observe, click, type, scroll, keypress, wait.
|
|
249
356
|
* Returns JSON: `{steps:[{op,status,data,error,duration_ms}]}`. Execution
|
|
250
357
|
* short-circuits on first error.
|
|
358
|
+
*
|
|
359
|
+
* `headed`: when `true`, launches a visible Chromium window
|
|
360
|
+
* instead of headless mode — for interactive flows like
|
|
361
|
+
* first-time auth (LinkedIn / OAuth / SSO / 2FA / captcha).
|
|
362
|
+
* Honoured only on the *first* call that launches the session;
|
|
363
|
+
* subsequent calls reuse the existing browser regardless. To
|
|
364
|
+
* switch modes, call `browserClose()` first.
|
|
365
|
+
*
|
|
366
|
+
* `extraArgs`: extra Chromium command-line flags appended
|
|
367
|
+
* verbatim to argv at launch (#112). Use cases: the Google
|
|
368
|
+
* Meet bot needing `--use-fake-ui-for-media-stream`,
|
|
369
|
+
* `--autoplay-policy=no-user-gesture-required`, and the
|
|
370
|
+
* container-friendly `--no-sandbox` /
|
|
371
|
+
* `--disable-dev-shm-usage` / `--disable-setuid-sandbox`. Like
|
|
372
|
+
* `headed`, honoured only on the launch call.
|
|
251
373
|
*/
|
|
252
374
|
browserRun(
|
|
253
375
|
scriptJson: string,
|
|
254
376
|
width?: number | null,
|
|
255
377
|
height?: number | null,
|
|
378
|
+
headed?: boolean | null,
|
|
379
|
+
extraArgs?: string[] | null,
|
|
256
380
|
): Promise<string>;
|
|
381
|
+
|
|
382
|
+
/** Close any persistent browser session attached to this runtime. */
|
|
383
|
+
browserClose(): Promise<void>;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Register a tool with a full JSON-serialized `ToolSchema`.
|
|
387
|
+
* `verifyProposal` validates `Action.parameters` against the schema's
|
|
388
|
+
* `parameters` field — catching type mismatches like `{path: 42}` for a
|
|
389
|
+
* tool wanting `{path: string}` before dispatch. The schema also carries
|
|
390
|
+
* idempotency, cache TTL, and rate-limit hints that the engine wires up
|
|
391
|
+
* automatically.
|
|
392
|
+
*
|
|
393
|
+
* Tools registered via the schemaless `registerTool(name)` bypass type
|
|
394
|
+
* validation; this is the opt-in upgrade path.
|
|
395
|
+
*
|
|
396
|
+
* `schemaJson` matches:
|
|
397
|
+
* ```json
|
|
398
|
+
* {
|
|
399
|
+
* "name": "read_file",
|
|
400
|
+
* "description": "...",
|
|
401
|
+
* "parameters": {"type":"object","properties":{"path":{"type":"string"}},"required":["path"]},
|
|
402
|
+
* "returns": null,
|
|
403
|
+
* "idempotent": true,
|
|
404
|
+
* "cache_ttl_secs": 60,
|
|
405
|
+
* "rate_limit": {"max_calls": 100, "interval_secs": 60}
|
|
406
|
+
* }
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
registerToolSchema(schemaJson: string): Promise<void>;
|
|
410
|
+
|
|
411
|
+
// -------------------------------------------------------------------------
|
|
412
|
+
// OS-native secret store (Keychain / Credential Manager / Secret Service)
|
|
413
|
+
// -------------------------------------------------------------------------
|
|
414
|
+
|
|
415
|
+
/** Returns JSON `{available: boolean, reason?: string}`. */
|
|
416
|
+
secretAvailable(): string;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Store a secret. Returns JSON `{ok: true}` on success. Throws if the
|
|
420
|
+
* backend is unavailable. `service` defaults to the runtime-wide bundle id.
|
|
421
|
+
*/
|
|
422
|
+
secretPut(key: string, value: string, service?: string | null): string;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Retrieve a secret. Returns JSON `{value: string}`. Throws `not_found`
|
|
426
|
+
* if the secret does not exist.
|
|
427
|
+
*/
|
|
428
|
+
secretGet(key: string, service?: string | null): string;
|
|
429
|
+
|
|
430
|
+
/** Delete a secret (idempotent). Returns JSON `{ok: true}`. */
|
|
431
|
+
secretDelete(key: string, service?: string | null): string;
|
|
432
|
+
|
|
433
|
+
/** Returns JSON `{exists: boolean, key, service}` without exposing the value. */
|
|
434
|
+
secretStatus(key: string, service?: string | null): string;
|
|
435
|
+
|
|
436
|
+
// -------------------------------------------------------------------------
|
|
437
|
+
// OS permission preflight
|
|
438
|
+
// -------------------------------------------------------------------------
|
|
439
|
+
|
|
440
|
+
/** Returns JSON `{domains: [...]}` listing every permission domain CAR knows. */
|
|
441
|
+
permissionDomains(): string;
|
|
442
|
+
|
|
443
|
+
/** Returns JSON `{status: "granted"|"denied"|"prompt"|"unsupported", ...}`. */
|
|
444
|
+
permissionStatus(domain: string, targetBundleId?: string | null): string;
|
|
445
|
+
|
|
446
|
+
/** Triggers the OS permission prompt; returns the resulting status. */
|
|
447
|
+
permissionRequest(domain: string, targetBundleId?: string | null): string;
|
|
448
|
+
|
|
449
|
+
/** Returns JSON describing what the permission unlocks and how to revoke it. */
|
|
450
|
+
permissionExplain(domain: string, targetBundleId?: string | null): string;
|
|
451
|
+
|
|
452
|
+
// -------------------------------------------------------------------------
|
|
453
|
+
// Native account discovery (system Settings → Internet Accounts on macOS)
|
|
454
|
+
// -------------------------------------------------------------------------
|
|
455
|
+
|
|
456
|
+
/** Returns JSON array of accounts known to the OS. */
|
|
457
|
+
accountsList(): string;
|
|
458
|
+
|
|
459
|
+
/** Open the OS's native account-management UI for an account or the root pane. */
|
|
460
|
+
accountsOpen(accountId?: string | null): string;
|
|
461
|
+
|
|
462
|
+
// -------------------------------------------------------------------------
|
|
463
|
+
// Calendar / Contacts / Mail integrations (delegated to OS providers)
|
|
464
|
+
// -------------------------------------------------------------------------
|
|
465
|
+
|
|
466
|
+
/** Returns JSON array of calendars discovered through the OS provider. */
|
|
467
|
+
calendarList(): string;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Returns JSON array of events in the [start, end] window. Times are
|
|
471
|
+
* RFC3339; `calendarIdsCsv` is an optional comma-separated filter.
|
|
472
|
+
*/
|
|
473
|
+
calendarEvents(
|
|
474
|
+
startRfc3339: string,
|
|
475
|
+
endRfc3339: string,
|
|
476
|
+
calendarIdsCsv?: string | null,
|
|
477
|
+
): string;
|
|
478
|
+
|
|
479
|
+
/** Returns JSON array of contact containers (sources). */
|
|
480
|
+
contactsContainers(): string;
|
|
481
|
+
|
|
482
|
+
/** Returns JSON array of contacts matching `query`. */
|
|
483
|
+
contactsFind(
|
|
484
|
+
query: string,
|
|
485
|
+
limit?: number | null,
|
|
486
|
+
containerIdsCsv?: string | null,
|
|
487
|
+
): string;
|
|
488
|
+
|
|
489
|
+
/** Returns JSON array of mail accounts known to the OS provider. */
|
|
490
|
+
mailAccounts(): string;
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Returns JSON inbox snapshot. `accountIdsCsv` is an optional
|
|
494
|
+
* comma-separated filter; omit to query all known accounts.
|
|
495
|
+
*/
|
|
496
|
+
mailInbox(accountIdsCsv?: string | null): string;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Send mail. `sendRequestJson` is `{to, subject, body, ...}` per the
|
|
500
|
+
* provider contract. Returns JSON `{ok, message_id?}`.
|
|
501
|
+
*/
|
|
502
|
+
mailSend(sendRequestJson: string): string;
|
|
503
|
+
|
|
504
|
+
// -------------------------------------------------------------------------
|
|
505
|
+
// Wearable / activity (HealthKit + Fitbit/Garmin/Oura/etc.)
|
|
506
|
+
// -------------------------------------------------------------------------
|
|
507
|
+
|
|
508
|
+
/** Returns JSON `{available, reason?, providers?}`. */
|
|
509
|
+
healthStatus(): string;
|
|
510
|
+
|
|
511
|
+
/** Times are RFC3339. Returns JSON array of sleep sessions. */
|
|
512
|
+
healthSleep(startRfc3339: string, endRfc3339: string): string;
|
|
513
|
+
|
|
514
|
+
/** Times are RFC3339. Returns JSON array of workouts. */
|
|
515
|
+
healthWorkouts(startRfc3339: string, endRfc3339: string): string;
|
|
516
|
+
|
|
517
|
+
/** Dates are YYYY-MM-DD. Returns JSON array of daily activity summaries. */
|
|
518
|
+
healthActivity(startYmd: string, endYmd: string): string;
|
|
257
519
|
}
|
|
258
520
|
|
|
259
521
|
// ---------------------------------------------------------------------------
|
|
@@ -278,19 +540,90 @@ export function executeProposal(
|
|
|
278
540
|
* `{"type":"tool_start","name":"...","index":N}`
|
|
279
541
|
* `{"type":"tool_delta","index":N,"data":"..."}`
|
|
280
542
|
* `{"type":"done","text":"...","tool_calls":[...]}`
|
|
543
|
+
*
|
|
544
|
+
* **Breaking change in 0.5.x:** the prior 9-positional signature
|
|
545
|
+
* has been replaced with an options-object form. Migration: build
|
|
546
|
+
* the request object and `JSON.stringify` it as `requestJson`. The
|
|
547
|
+
* options object exposes every `GenerateRequest` field including
|
|
548
|
+
* `intent` (closes #107). The replacement (rather than addition of
|
|
549
|
+
* a sibling) is forced by napi-rs's 3-standalone-TSF cap — see the
|
|
550
|
+
* project rules for the rationale.
|
|
281
551
|
*/
|
|
282
552
|
export function inferStream(
|
|
283
553
|
rt: CarRuntime,
|
|
284
|
-
|
|
285
|
-
model: string | null | undefined,
|
|
286
|
-
maxTokens: number | null | undefined,
|
|
287
|
-
context: string | null | undefined,
|
|
288
|
-
toolsJson: string | null | undefined,
|
|
554
|
+
requestJson: string,
|
|
289
555
|
onEvent: (eventJson: string) => void,
|
|
290
|
-
toolChoice?: string | null,
|
|
291
|
-
parallelToolCalls?: boolean | null,
|
|
292
556
|
): Promise<string>;
|
|
293
557
|
|
|
558
|
+
// --- Caller-facing routing intent (parslee-ai/car-releases#18) ---
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Coarse-grained task hint the adaptive router maps to its internal
|
|
562
|
+
* `InferenceTask`. A closed set so adding a new task type is a
|
|
563
|
+
* deliberate, FFI-visible change rather than a silent fallback.
|
|
564
|
+
*/
|
|
565
|
+
export type TaskHint =
|
|
566
|
+
| 'chat'
|
|
567
|
+
| 'classify'
|
|
568
|
+
| 'summarize'
|
|
569
|
+
| 'reasoning'
|
|
570
|
+
| 'code'
|
|
571
|
+
| 'extract';
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Hard model-capability filters the router enforces in addition to
|
|
575
|
+
* any prompt-derived requirements. Mirrors `ModelCapability` in the
|
|
576
|
+
* registry; values must be one of these snake_case strings.
|
|
577
|
+
*/
|
|
578
|
+
export type ModelCapabilityRequirement =
|
|
579
|
+
| 'generate'
|
|
580
|
+
| 'embed'
|
|
581
|
+
| 'rerank'
|
|
582
|
+
| 'classify'
|
|
583
|
+
| 'code'
|
|
584
|
+
| 'reasoning'
|
|
585
|
+
| 'summarize'
|
|
586
|
+
| 'tool_use'
|
|
587
|
+
| 'multi_tool_call'
|
|
588
|
+
| 'vision'
|
|
589
|
+
| 'video_understanding'
|
|
590
|
+
| 'audio_understanding'
|
|
591
|
+
| 'grounding'
|
|
592
|
+
| 'speech_to_text'
|
|
593
|
+
| 'text_to_speech'
|
|
594
|
+
| 'image_generation'
|
|
595
|
+
| 'video_generation';
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Caller-facing routing intent — express requirements, not model IDs.
|
|
599
|
+
*
|
|
600
|
+
* All fields are optional. An IntentHint with no fields set is
|
|
601
|
+
* equivalent to omitting the hint entirely (adaptive routing as today).
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* await rt.infer(
|
|
605
|
+
* prompt,
|
|
606
|
+
* null,
|
|
607
|
+
* null,
|
|
608
|
+
* JSON.stringify({ task: 'chat', prefer_local: true } satisfies IntentHint),
|
|
609
|
+
* );
|
|
610
|
+
*/
|
|
611
|
+
export interface IntentHint {
|
|
612
|
+
/** What the caller is doing. Maps to `InferenceTask` server-side. */
|
|
613
|
+
task?: TaskHint;
|
|
614
|
+
/**
|
|
615
|
+
* Hard filter — every required capability must be present on the
|
|
616
|
+
* candidate before scoring runs.
|
|
617
|
+
*/
|
|
618
|
+
require?: ModelCapabilityRequirement[];
|
|
619
|
+
/**
|
|
620
|
+
* Bias the score profile toward local on-device models. Maps to a
|
|
621
|
+
* dedicated `RoutingWorkload::LocalPreferred` weight profile —
|
|
622
|
+
* quality-aware with a strong local_bonus so the hint wins ties.
|
|
623
|
+
*/
|
|
624
|
+
prefer_local?: boolean;
|
|
625
|
+
}
|
|
626
|
+
|
|
294
627
|
// --- Voice streaming (stored-callback pattern) ---
|
|
295
628
|
|
|
296
629
|
export type AudioSourceSpec =
|
|
@@ -363,6 +696,20 @@ export function transcribeStreamPush(
|
|
|
363
696
|
|
|
364
697
|
export function listVoiceSessions(rt: CarRuntime): string;
|
|
365
698
|
|
|
699
|
+
/**
|
|
700
|
+
* Voice providers (STT + TTS) compiled into this build.
|
|
701
|
+
*
|
|
702
|
+
* Returns a JSON-encoded array of objects with shape:
|
|
703
|
+
* `{ id: string, kind: "stt" | "tts", available: boolean, description: string }`.
|
|
704
|
+
*
|
|
705
|
+
* `available` reflects build-time presence (cfg-target, build features) —
|
|
706
|
+
* runtime readiness (API key set, permission granted, model downloaded)
|
|
707
|
+
* surfaces via per-provider error paths when you actually use them.
|
|
708
|
+
*
|
|
709
|
+
* Stateless; safe to call before constructing a `CarRuntime`.
|
|
710
|
+
*/
|
|
711
|
+
export function listVoiceProviders(): string;
|
|
712
|
+
|
|
366
713
|
// --- Meeting capture ---
|
|
367
714
|
|
|
368
715
|
export interface StartMeetingRequest {
|
|
@@ -454,6 +801,103 @@ export function getMeeting(
|
|
|
454
801
|
rootOverride?: string | null,
|
|
455
802
|
): string;
|
|
456
803
|
|
|
804
|
+
// --- Agent registry (file-based, no daemon) ---
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Register or replace an agent's entry in the user-default registry
|
|
808
|
+
* (`~/.car/registry/`) or at the path supplied as `registryPath`.
|
|
809
|
+
*
|
|
810
|
+
* `entryJson` is a JSON-serialised `AgentEntry`:
|
|
811
|
+
* ```json
|
|
812
|
+
* {
|
|
813
|
+
* "name": "trader-paper",
|
|
814
|
+
* "dashboard_url": "http://127.0.0.1:8731",
|
|
815
|
+
* "status": "running",
|
|
816
|
+
* "display_name": "Trader (paper)",
|
|
817
|
+
* "port": 8731,
|
|
818
|
+
* "pid": 12345
|
|
819
|
+
* }
|
|
820
|
+
* ```
|
|
821
|
+
* `name` and `dashboard_url` are required; the rest are optional.
|
|
822
|
+
* Returns `"null"` on success.
|
|
823
|
+
*/
|
|
824
|
+
export function registerAgent(
|
|
825
|
+
entryJson: string,
|
|
826
|
+
registryPath?: string | null,
|
|
827
|
+
): string;
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Bump `last_heartbeat_at` for the named agent. Returns
|
|
831
|
+
* `'{"refreshed": true}'` if the agent was registered, or
|
|
832
|
+
* `'{"refreshed": false}'` if the caller should re-register.
|
|
833
|
+
*/
|
|
834
|
+
export function agentHeartbeat(
|
|
835
|
+
name: string,
|
|
836
|
+
registryPath?: string | null,
|
|
837
|
+
): string;
|
|
838
|
+
|
|
839
|
+
/** Remove an agent's entry. Idempotent. */
|
|
840
|
+
export function unregisterAgent(
|
|
841
|
+
name: string,
|
|
842
|
+
registryPath?: string | null,
|
|
843
|
+
): string;
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* List all currently-registered agents. Returns a JSON array of
|
|
847
|
+
* `AgentEntry` objects, sorted by name.
|
|
848
|
+
*/
|
|
849
|
+
export function listAgents(registryPath?: string | null): string;
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Reap entries whose last heartbeat is older than `maxAgeSecs`.
|
|
853
|
+
* Returns a JSON array of names that were reaped.
|
|
854
|
+
*/
|
|
855
|
+
export function reapStaleAgents(
|
|
856
|
+
maxAgeSecs: number,
|
|
857
|
+
registryPath?: string | null,
|
|
858
|
+
): string;
|
|
859
|
+
|
|
860
|
+
// --- car-a2a server lifecycle ---
|
|
861
|
+
//
|
|
862
|
+
// Expose CAR as an Agent2Agent (A2A) v1.0 peer programmatically,
|
|
863
|
+
// without shelling out to `car-server --a2a-bind`. Process-global
|
|
864
|
+
// state holds the bound listener and join handle so a later
|
|
865
|
+
// `stopA2aServer` / `a2aServerStatus` call reaches the right server.
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Start an A2A listener.
|
|
869
|
+
*
|
|
870
|
+
* `paramsJson` shape:
|
|
871
|
+
* ```jsonc
|
|
872
|
+
* {
|
|
873
|
+
* "bind": "127.0.0.1:8731", // required
|
|
874
|
+
* "public_url": "https://...", // optional; defaults to http://<bound>
|
|
875
|
+
* "agent_name": "...", // optional
|
|
876
|
+
* "agent_description": "...", // optional
|
|
877
|
+
* "organization": "...", // optional
|
|
878
|
+
* "organization_url": "..." // optional
|
|
879
|
+
* }
|
|
880
|
+
* ```
|
|
881
|
+
*
|
|
882
|
+
* Returns `'{"bound":"127.0.0.1:8731"}'` on success. Errors if a
|
|
883
|
+
* server is already running, the bind fails, or `paramsJson` is
|
|
884
|
+
* malformed.
|
|
885
|
+
*/
|
|
886
|
+
export function startA2aServer(paramsJson: string): Promise<string>;
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Stop the running A2A listener. Returns `'{"stopped":true}'` on
|
|
890
|
+
* success. Errors if no server is running.
|
|
891
|
+
*/
|
|
892
|
+
export function stopA2aServer(): string;
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Report whether the A2A listener is up. Always returns a JSON
|
|
896
|
+
* object — `{"running":true,"bound":"...","uptime_secs":N}` when
|
|
897
|
+
* running, `{"running":false}` otherwise.
|
|
898
|
+
*/
|
|
899
|
+
export function a2aServerStatus(): string;
|
|
900
|
+
|
|
457
901
|
// --- Verification (stateless) ---
|
|
458
902
|
|
|
459
903
|
export function verify(
|
|
@@ -552,3 +996,74 @@ export function rankProposals(
|
|
|
552
996
|
tools?: string[] | null,
|
|
553
997
|
costWeight?: number | null,
|
|
554
998
|
): string;
|
|
999
|
+
|
|
1000
|
+
// --- macOS automation (car-automation) ---
|
|
1001
|
+
//
|
|
1002
|
+
// AppleScript / JXA / Shortcuts bridges. Subprocess-backed so the
|
|
1003
|
+
// surface is uniform across binding layers. On non-macOS hosts each
|
|
1004
|
+
// call rejects with a PlatformUnsupported error.
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Run an AppleScript or JXA snippet via `osascript`.
|
|
1008
|
+
*
|
|
1009
|
+
* `argsJson` shape:
|
|
1010
|
+
* ```jsonc
|
|
1011
|
+
* {
|
|
1012
|
+
* "script": "return 1 + 2",
|
|
1013
|
+
* "language": "applescript" | "javascript", // optional, default applescript
|
|
1014
|
+
* "args": ["positional", "args"], // optional
|
|
1015
|
+
* "timeout_ms": 5000 // optional
|
|
1016
|
+
* }
|
|
1017
|
+
* ```
|
|
1018
|
+
*
|
|
1019
|
+
* Returns JSON `{stdout, stderr, exit_code}`. Rejects with the
|
|
1020
|
+
* subprocess stderr on non-zero exit.
|
|
1021
|
+
*/
|
|
1022
|
+
export function runApplescript(argsJson: string): Promise<string>;
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* Enumerate Shortcuts (user-authored *and* AppShortcuts donated by
|
|
1026
|
+
* apps via the App Intents framework). Returns an array of
|
|
1027
|
+
* `{name, identifier?, tool_slug, tool_description, parameters_schema}`,
|
|
1028
|
+
* suitable for registering each as a runtime tool.
|
|
1029
|
+
*
|
|
1030
|
+
* `argsJson` shape: `{ folder?: string, with_identifiers?: boolean }`.
|
|
1031
|
+
*/
|
|
1032
|
+
export function listShortcuts(argsJson: string): Promise<string>;
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Invoke a Shortcut by name or UUID. `argsJson` shape:
|
|
1036
|
+
* ```jsonc
|
|
1037
|
+
* {
|
|
1038
|
+
* "name_or_id": "Shazam shortcut" | "43E9-...",
|
|
1039
|
+
* "input": "optional text input", // optional
|
|
1040
|
+
* "output_type": "public.plain-text", // optional UTI
|
|
1041
|
+
* "timeout_ms": 30000 // optional
|
|
1042
|
+
* }
|
|
1043
|
+
* ```
|
|
1044
|
+
* Returns JSON `{stdout, stderr, exit_code}`.
|
|
1045
|
+
*/
|
|
1046
|
+
export function runShortcut(argsJson: string): Promise<string>;
|
|
1047
|
+
|
|
1048
|
+
// --- Vision OCR (car-vision) ---
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Apple Vision-framework on-device text recognition.
|
|
1052
|
+
*
|
|
1053
|
+
* `argsJson` shape:
|
|
1054
|
+
* ```jsonc
|
|
1055
|
+
* {
|
|
1056
|
+
* "image_path": "/path/to/screen.png",
|
|
1057
|
+
* "fast_path": false, // optional; true = .fast vs .accurate
|
|
1058
|
+
* "languages": ["en-US"], // optional BCP-47 hints
|
|
1059
|
+
* "language_correction": true, // optional, default true
|
|
1060
|
+
* "minimum_text_height": 0.0 // optional, normalized; floors tiny noise
|
|
1061
|
+
* }
|
|
1062
|
+
* ```
|
|
1063
|
+
*
|
|
1064
|
+
* Returns JSON `{available, observations}`. `available` is `false`
|
|
1065
|
+
* when the Vision shim wasn't built into this binary (non-macOS or
|
|
1066
|
+
* skipped Swift compile); in that case `observations` is an empty
|
|
1067
|
+
* array rather than an error.
|
|
1068
|
+
*/
|
|
1069
|
+
export function visionOcr(argsJson: string): Promise<string>;
|