car-runtime 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.d.ts +119 -11
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -667,12 +667,30 @@ export class CarRuntime {
667
667
  /** Set update preferences (JSON `UpdatePreferences` shape). Returns stored prefs JSON. */
668
668
  updatePrefsSet(prefsJson: string): Promise<string>;
669
669
 
670
- /** Route a prompt. Returns the routing decision as JSON. */
670
+ /**
671
+ * Route a prompt. Returns the routing decision as JSON, including
672
+ * `candidates`: the advisory ranking of every scored model
673
+ * (`{ model_id, reliability, score, selected, in_band }`) so callers can see
674
+ * why a model won and what the alternatives cost in reliability terms. Empty
675
+ * on explicit-model and cold-start paths where no ranking occurred.
676
+ */
671
677
  routeModel(prompt: string): Promise<string>;
672
678
 
673
679
  /** Per-model performance profiles. Returns JSON. */
674
680
  modelStats(): Promise<string>;
675
681
 
682
+ /**
683
+ * Persistent outcome scoreboard, folded from the durable outcome ledger.
684
+ * Returns JSON `{ rows: [{ model_id, success_count, fail_count,
685
+ * inconclusive_count, total_input_tokens, total_output_tokens, avg_quality,
686
+ * avg_latency_ms, success_rate, tokens_per_success, usd_per_success }],
687
+ * total_successes, total_failures, total_inconclusive, total_usd,
688
+ * overall_usd_per_success, model_count, receipts }`. Rows are sorted
689
+ * cheapest-correct-outcome first. The cross-session, outcome-denominated view
690
+ * (unlike `modelStats`, the live in-memory profiles).
691
+ */
692
+ outcomeScoreboard(): Promise<string>;
693
+
676
694
  // --- Execution ---
677
695
 
678
696
  /** Count of events in this runtime's execution log. */
@@ -1081,6 +1099,15 @@ export interface IntentHint {
1081
1099
  * then `prefer_quality`, then `prefer_local`.
1082
1100
  */
1083
1101
  prefer_quality?: boolean;
1102
+ /**
1103
+ * The operation is high-stakes — consequential or irreversible (e.g. the
1104
+ * session is authorized for FullAccess actions). Forces the strongest
1105
+ * quality posture regardless of task or any cost/latency preference: never
1106
+ * economize on what you can't take back. Highest precedence — wins over
1107
+ * `prefer_fast`, `prefer_quality`, and `prefer_local`. The daemon sets this
1108
+ * automatically for FullAccess-granted sessions.
1109
+ */
1110
+ high_stakes?: boolean;
1084
1111
  }
1085
1112
 
1086
1113
  // --- Voice streaming (stored-callback pattern) ---
@@ -1401,6 +1428,13 @@ export function resumeWorkflow(pausedJson: string, inputJson: string): Promise<s
1401
1428
  /** Static analysis on a workflow definition. Returns verification report JSON. */
1402
1429
  export function verifyWorkflow(workflowJson: string): string;
1403
1430
 
1431
+ /**
1432
+ * Build the external-item automation recipe (poll → dedup → per-item agent →
1433
+ * deliver) from an `AutomationSpec` JSON into a runnable workflow JSON. Hand the
1434
+ * result to `runWorkflow`, typically on a schedule. Stateless.
1435
+ */
1436
+ export function buildAutomationWorkflow(specJson: string): string;
1437
+
1404
1438
  export interface StartMeetingResponse {
1405
1439
  id: string;
1406
1440
  title: string;
@@ -1486,12 +1520,19 @@ export function reapStaleAgents(
1486
1520
  // --- car-a2a server lifecycle ---
1487
1521
  //
1488
1522
  // Expose CAR as an Agent2Agent (A2A) v1.0 peer programmatically,
1489
- // without shelling out to `car-server --a2a-bind`. Process-global
1490
- // state holds the bound listener and join handle so a later
1491
- // `stopA2aServer` / `a2aServerStatus` call reaches the right server.
1523
+ // without shelling out to `car-server --a2a-bind`. These proxy to the
1524
+ // daemon the `CarRuntime` is connected to, so each takes the runtime as
1525
+ // its first argument.
1526
+ //
1527
+ // NOTE ON NAMING: napi-rs (heck) splits at digit→letter boundaries, so
1528
+ // the Rust `start_a2a_server` camelCases to `startA2AServer` (the `a2a`
1529
+ // segment becomes `A2A`), NOT `startA2aServer`. The exported names are
1530
+ // `startA2AServer` / `stopA2AServer` / `a2AServerStatus` /
1531
+ // `sendA2AMessage` / `a2ADispatch`. (Earlier versions of this file
1532
+ // declared `…A2a…`, which did not exist at runtime — car-releases#65.)
1492
1533
 
1493
1534
  /**
1494
- * Start an A2A listener.
1535
+ * Start an A2A listener on the daemon `rt` is connected to.
1495
1536
  *
1496
1537
  * `paramsJson` shape:
1497
1538
  * ```jsonc
@@ -1510,31 +1551,49 @@ export function reapStaleAgents(
1510
1551
  * the calling `CarRuntime`'s session runtime instead of spawning a
1511
1552
  * fresh one. Tools registered on the session via
1512
1553
  * `registerToolSchema` then appear on the Agent Card's `skills`
1513
- * list, and A2A peer `message/send` calls for those tools route
1514
- * back to the handler installed via `registerToolHandler`. This is
1554
+ * list, and A2A peer `message/send` calls that carry an explicit
1555
+ * tool invocation (a `data` part `{ "tool": "...", "parameters": {...} }`)
1556
+ * route back to the handler installed via `registerToolHandler`. This is
1515
1557
  * the canonical path for host-language agents to project themselves
1516
1558
  * over A2A. Default `false` preserves the legacy fresh-Runtime
1517
1559
  * behaviour (only `register_agent_basics` tools, dispatch in Rust).
1518
1560
  *
1561
+ * A purely *conversational* `message/send` (free text, no tool `data`
1562
+ * part) is routed to the host's `agent.chat` handler — the daemon
1563
+ * reverse-calls `agent.chat` on this session, aggregates the streamed
1564
+ * reply, and returns it as the A2A agent message (car-releases#65). So
1565
+ * register an `agent.chat` handler to serve conversational turns, and/or
1566
+ * a `registerToolHandler` for explicit tool `data` parts.
1567
+ *
1519
1568
  * Returns `'{"bound":"127.0.0.1:8731"}'` on success. Errors if a
1520
1569
  * server is already running, the bind fails, `share_session_runtime`
1521
1570
  * is set but no session runtime is available (e.g. invoked from a
1522
1571
  * non-WS path), or `paramsJson` is malformed.
1523
1572
  */
1524
- export function startA2aServer(paramsJson: string): Promise<string>;
1573
+ export function startA2AServer(rt: CarRuntime, paramsJson: string): Promise<string>;
1525
1574
 
1526
1575
  /**
1527
1576
  * Stop the running A2A listener. Returns `'{"stopped":true}'` on
1528
1577
  * success. Errors if no server is running.
1529
1578
  */
1530
- export function stopA2aServer(): string;
1579
+ export function stopA2AServer(rt: CarRuntime): Promise<string>;
1531
1580
 
1532
1581
  /**
1533
1582
  * Report whether the A2A listener is up. Always returns a JSON
1534
1583
  * object — `{"running":true,"bound":"...","uptime_secs":N}` when
1535
1584
  * running, `{"running":false}` otherwise.
1536
1585
  */
1537
- export function a2aServerStatus(): string;
1586
+ export function a2AServerStatus(rt: CarRuntime): Promise<string>;
1587
+
1588
+ /**
1589
+ * Send a message to a remote A2A peer at `endpoint`.
1590
+ *
1591
+ * `paramsJson` shape: `{ endpoint, message, blocking?, ingest_a2ui?,
1592
+ * route_auth?, allow_untrusted_endpoint? }`. The daemon enforces a
1593
+ * loopback-or-explicit-allow rule on `endpoint` — non-loopback URLs
1594
+ * require `allow_untrusted_endpoint: true`.
1595
+ */
1596
+ export function sendA2AMessage(rt: CarRuntime, paramsJson: string): Promise<string>;
1538
1597
 
1539
1598
  // --- Verification (stateless) ---
1540
1599
 
@@ -1575,6 +1634,13 @@ export function optimize(proposalJson: string): string;
1575
1634
 
1576
1635
  export function equivalent(proposal1Json: string, proposal2Json: string): boolean;
1577
1636
 
1637
+ /**
1638
+ * Wire protocol version this binding speaks to the `car-server` daemon,
1639
+ * exchanged via the `server.handshake` RPC. Bumped only on a
1640
+ * backward-incompatible JSON-RPC change — independent of the package semver.
1641
+ */
1642
+ export function protocolVersion(): number;
1643
+
1578
1644
  /**
1579
1645
  * Check a proposal for transactional conflicts against the current shared
1580
1646
  * state (survey "Code as Agent Harness" §4.3/§5.2.4 — the shared
@@ -1844,6 +1910,34 @@ export function createTask(
1844
1910
  systemPrompt?: string | null,
1845
1911
  ): string;
1846
1912
 
1913
+ /**
1914
+ * Preview the durable OS-level schedule (launchd plist + crontab line) a task
1915
+ * would install, without installing it. `program` + `argsJson` (a JSON string
1916
+ * array) are the command the OS runs to execute the task once. Returns
1917
+ * `{ label, launchdPlist, launchdError, crontabLine, crontabError }`.
1918
+ */
1919
+ export function renderOsSchedule(taskJson: string, program: string, argsJson: string): string;
1920
+
1921
+ /**
1922
+ * Install a durable OS-level schedule (launchd on macOS, crontab on Linux) so
1923
+ * the task fires even when the CAR daemon is down. Idempotent. Returns the
1924
+ * installed-schedule JSON.
1925
+ */
1926
+ export function installOsSchedule(taskJson: string, program: string, argsJson: string): string;
1927
+
1928
+ /** Remove a task's OS-level schedule (full label or bare task id). Returns `{ label, removed }`. */
1929
+ export function uninstallOsSchedule(labelOrId: string): string;
1930
+
1931
+ /** List labels of all CAR-managed OS-level schedules on this host (JSON string array). */
1932
+ export function listOsSchedules(): string;
1933
+
1934
+ /**
1935
+ * Reap orphaned OS-level schedules — uninstall every CAR-managed launchd/cron
1936
+ * entry whose task is gone from `~/.car/tasks/` or whose trigger is no longer
1937
+ * schedulable. Returns the reconcile report `{ removed, kept, errors }`.
1938
+ */
1939
+ export function reconcileOsSchedules(): string;
1940
+
1847
1941
  /** Run a task once using the registered agent runner. */
1848
1942
  export function runTask(taskJson: string): Promise<string>;
1849
1943
 
@@ -1972,7 +2066,7 @@ export function visionOcr(argsJson: string): Promise<string>;
1972
2066
  * both in one process gives you two task stores (task ids are
1973
2067
  * unique per dispatcher).
1974
2068
  */
1975
- export function a2aDispatch(method: string, paramsJson: string): Promise<string>;
2069
+ export function a2ADispatch(rt: CarRuntime, method: string, paramsJson: string): Promise<string>;
1976
2070
 
1977
2071
  // --- Lifecycle-managed agents (car_registry::supervisor) ---
1978
2072
 
@@ -2077,6 +2171,20 @@ export function agentsStop(id: string, signal?: string | null): Promise<string>;
2077
2171
  */
2078
2172
  export function agentsRestart(id: string): Promise<string>;
2079
2173
 
2174
+ /**
2175
+ * Block until a managed agent reaches one of `targetsJson` (a JSON string array
2176
+ * of statuses like `["running"]` or `["stopped","errored"]`; default
2177
+ * `["running"]`) or `timeoutSecs` (default 30) elapses, polling every `pollMs`
2178
+ * (default 200). Returns the matching `ManagedAgent` JSON; rejects on timeout or
2179
+ * unknown id.
2180
+ */
2181
+ export function agentsWait(
2182
+ id: string,
2183
+ targetsJson?: string | null,
2184
+ timeoutSecs?: number | null,
2185
+ pollMs?: number | null,
2186
+ ): Promise<string>;
2187
+
2080
2188
  /**
2081
2189
  * Read a window of an agent's logs under
2082
2190
  * `~/.car/logs/<id>.{stdout,stderr}.log`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "car-runtime",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Common Agent Runtime — a deterministic execution layer for AI agents",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",