car-runtime 0.23.0 → 0.24.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.
Files changed (2) hide show
  1. package/index.d.ts +241 -13
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -57,6 +57,33 @@ export class CarRuntime {
57
57
  */
58
58
  persistMemory(path: string): Promise<number>;
59
59
 
60
+ // --- Foreman ---
61
+
62
+ /**
63
+ * Decompose a coding `goal` into a footprint-annotated, scheduled subtask
64
+ * plan. `repo` defaults to the daemon's cwd. Returns a JSON
65
+ * `ForemanPlanReport` (`schema_version`, `valid`, `prefer_single_session`,
66
+ * `levels`, `subtasks[]` with declared `writes`/`reads`).
67
+ */
68
+ foremanPlan(goal: string, repo?: string, maxAttempts?: number): Promise<string>;
69
+
70
+ /**
71
+ * Plan a coding `goal`, then farm the subtasks to an external coding CLI
72
+ * (`adapter`, default `"claude-code"`) in isolated git worktrees, gating each
73
+ * worktree and the integrated union. `verifyCommand` is the per-worktree
74
+ * **regression** check; `unionVerifyCommand` is the integrated-union **goal**
75
+ * check (falls back to `verifyCommand` when omitted). **Spends real agent
76
+ * quota.** Returns JSON `{ plan, ran, run? }`.
77
+ */
78
+ foremanRun(
79
+ goal: string,
80
+ repo?: string,
81
+ adapter?: string,
82
+ verifyCommand?: Array<string>,
83
+ unionVerifyCommand?: Array<string>,
84
+ maxAttempts?: number
85
+ ): Promise<string>;
86
+
60
87
  // --- Tools & policies ---
61
88
 
62
89
  /** Register a tool by name. */
@@ -74,11 +101,13 @@ export class CarRuntime {
74
101
  * `run_id`.
75
102
  *
76
103
  * `paramsJson` is a serialized request object:
77
- * `{ intent, agent_id?, agent_name?, outcome_description? }`. When
78
- * `agent_id` is omitted the daemon resolves it from the session's
104
+ * `{ intent, agent_id?, agent_name?, outcome_description?, idempotency_key? }`.
105
+ * When `agent_id` is omitted the daemon resolves it from the session's
79
106
  * `agent_id` binding, then `CAR_AGENT_ID`, then a deterministic id
80
- * synthesized from `agent_name`. Returns `{ run_id, agent_id }` as a
81
- * JSON string.
107
+ * synthesized from `agent_name`. An `idempotency_key`, when supplied,
108
+ * becomes the `run_id` and makes the start dedup: if a run with that id
109
+ * already exists the existing run is returned instead of a duplicate.
110
+ * Returns `{ run_id, agent_id }` as a JSON string.
82
111
  */
83
112
  runsStart(paramsJson: string): Promise<string>;
84
113
 
@@ -131,8 +160,14 @@ export class CarRuntime {
131
160
  /**
132
161
  * Set replan configuration on this runtime.
133
162
  * `maxReplans` = 0 disables replanning (default).
163
+ * `replanOnRejected` (default false): when true, validator/policy/capability
164
+ * rejections (not just runtime failures) also trigger rollback + replan.
134
165
  */
135
- setReplanConfig(maxReplans: number, delayMs?: number | null): Promise<void>;
166
+ setReplanConfig(
167
+ maxReplans: number,
168
+ delayMs?: number | null,
169
+ replanOnRejected?: boolean | null,
170
+ ): Promise<void>;
136
171
 
137
172
  // --- State ---
138
173
 
@@ -297,9 +332,17 @@ export class CarRuntime {
297
332
  /**
298
333
  * Generate with full tracking. Returns JSON with `text`, `tool_calls`,
299
334
  * `usage`, `model_used`, `latency_ms`, `time_to_first_token_ms`,
300
- * `trace_id`. `time_to_first_token_ms` is wall-clock to the first
301
- * sampled token (populated by local Candle/MLX paths; `null` for
302
- * non-streaming remote calls).
335
+ * `trace_id`, `stop_reason`. `time_to_first_token_ms` is wall-clock to
336
+ * the first sampled token (populated by local Candle/MLX paths; `null`
337
+ * for non-streaming remote calls). `stop_reason` is the raw provider
338
+ * termination reason (OpenAI `finish_reason`, Anthropic `stop_reason`,
339
+ * Google `finishReason`); `null` for local backends or providers that
340
+ * don't report one. A value of `"length"`/`"max_tokens"`/`"MAX_TOKENS"`
341
+ * means the output was truncated at the token cap. On local Qwen3
342
+ * hybrid-thinking models it is also set to `"thinking_recovered"` when
343
+ * reasoning consumed the whole token budget and the runtime retried
344
+ * with reasoning suppressed to produce a direct answer, or
345
+ * `"thinking_truncated"` when even that retry was empty (car-releases#60).
303
346
  *
304
347
  * **Note:** intent is not exposed on the tracked path until the
305
348
  * positional argument list is converted to an options object —
@@ -390,6 +433,22 @@ export class CarRuntime {
390
433
  */
391
434
  detokenize(model: string, tokens: number[]): Promise<string>;
392
435
 
436
+ // --- Web search ---
437
+
438
+ /**
439
+ * Web search. The daemon resolves the backend: the signed-in Parslee
440
+ * account's hosted search when available, else a bring-your-own
441
+ * `TAVILY_API_KEY`. Returns JSON `{ query, source, results: [{title, url,
442
+ * snippet, score, published_date}] }`.
443
+ */
444
+ search(query: string, maxResults?: number | null): Promise<string>;
445
+
446
+ /**
447
+ * Fetch a URL and extract readable text (keyless; companion to `search`).
448
+ * Returns JSON `{ url, status, content_type, title?, text }`.
449
+ */
450
+ webFetch(url: string): Promise<string>;
451
+
393
452
  // --- Speech ---
394
453
 
395
454
  /** Prepare the managed speech runtime and return its root path. */
@@ -436,7 +495,10 @@ export class CarRuntime {
436
495
  /**
437
496
  * Unified registry (local + remote). Returns JSON array of
438
497
  * `{ id, name, provider, capabilities, param_count, size_mb,
439
- * context_length, available, is_local, public_benchmarks }`.
498
+ * context_length, available, is_local, max_output_tokens,
499
+ * public_benchmarks }`. `max_output_tokens` is the registry-declared
500
+ * per-model output ceiling (`null` when the entry omits it; callers
501
+ * then fall back to a fraction of `context_length`).
440
502
  * `public_benchmarks` is `[{ name, score, harness?, source_url?,
441
503
  * measured_at? }]` with score on a 0.0–1.0 scale; ships empty in
442
504
  * the built-in catalog and is populated via curated registry data.
@@ -469,6 +531,121 @@ export class CarRuntime {
469
531
  */
470
532
  recommend(useCase: string, tier: string, cloudOk: boolean): Promise<string>;
471
533
 
534
+ /**
535
+ * Coder — built-in coding agent (`coder.*` daemon namespace). Sessions
536
+ * live in the daemon and are visible in CarHost. Live `coder.event`
537
+ * streaming is WebSocket-only: call `coder.subscribe` on the daemon's
538
+ * WS directly (same contract as `infer.stream`).
539
+ *
540
+ * Start a session: provisions an isolated git worktree of `repo` and
541
+ * derives a verifiable outcome contract from `intent`. `engine` is
542
+ * `"auto" | "native" | "external[:agent_id]"` (default auto). Returns
543
+ * `{session_id, state, engine, worktree, contract}` JSON.
544
+ */
545
+ coderStart(
546
+ repo: string,
547
+ intent: string,
548
+ engine?: string | undefined | null,
549
+ maxIterations?: number | undefined | null,
550
+ ): Promise<string>;
551
+
552
+ /**
553
+ * Confirm the proposed outcome contract (optionally replacing it with
554
+ * the edited `contractJson`) and start the work loop.
555
+ */
556
+ coderConfirmContract(
557
+ sessionId: string,
558
+ contractJson?: string | undefined | null,
559
+ ): Promise<string>;
560
+
561
+ /** List coder sessions (live and persisted), newest first. */
562
+ coderList(): Promise<string>;
563
+
564
+ /** Full session detail, including contract and check results. */
565
+ coderGet(sessionId: string): Promise<string>;
566
+
567
+ /**
568
+ * Answer a `user_input_requested` event (reserved — neither engine
569
+ * requests mid-session input yet).
570
+ */
571
+ coderRespond(sessionId: string, text: string): Promise<string>;
572
+
573
+ /**
574
+ * Approve (publish the `car/coder/<id>` branch in the repo) or deny
575
+ * (abandon) a session awaiting merge approval.
576
+ */
577
+ coderApproveMerge(sessionId: string, approve: boolean): Promise<string>;
578
+
579
+ /** Cancel a session: stop the loop, abandon, remove the worktree. */
580
+ coderCancel(sessionId: string): Promise<string>;
581
+
582
+ /**
583
+ * Managed projects + in-daemon declarative agents (the non-developer path).
584
+ *
585
+ * Create (or load) a CAR-managed git-backed project under
586
+ * `~/.car/projects/`. `kind` is `"app"` (code) or `"agent"` (an in-daemon
587
+ * declarative agent). Returns the `CoderProject` JSON.
588
+ */
589
+ projectCreate(name: string, kind?: string | undefined | null): Promise<string>;
590
+ /** List managed projects, newest first. */
591
+ projectList(): Promise<string>;
592
+ /** One project's metadata by slug. */
593
+ projectGet(slug: string): Promise<string>;
594
+
595
+ /**
596
+ * Discover what the signed-in Parslee account can do — identity, m365
597
+ * product entitlements, and Studio reachability. Read-only. Returns JSON.
598
+ */
599
+ parsleeCapabilities(): Promise<string>;
600
+ /**
601
+ * Generate a Word document from a natural-language brief, saved to the
602
+ * user's connected drive. Gated on the `aie` entitlement. `documentType`
603
+ * defaults to `Report`. Returns JSON `{ file_id, web_url, ... }`.
604
+ */
605
+ parsleeM365GenerateDocument(contentBrief: string, outputFilePath: string, documentType?: string | undefined | null, title?: string | undefined | null, author?: string | undefined | null): Promise<string>;
606
+
607
+ /** List registered in-daemon declarative agents. */
608
+ declagentList(): Promise<string>;
609
+ /** One declarative agent's spec by id. */
610
+ declagentGet(id: string): Promise<string>;
611
+ /** Unregister a declarative agent. */
612
+ declagentRemove(id: string): Promise<string>;
613
+ /** Enable or disable a declarative agent. */
614
+ declagentSetEnabled(id: string, enabled: boolean): Promise<string>;
615
+ /**
616
+ * Run a declarative agent on an input, in-daemon (no external process).
617
+ * Returns `{ output, turns, tool_calls, error? }` JSON.
618
+ */
619
+ declagentInvoke(id: string, input: string): Promise<string>;
620
+ /**
621
+ * Route a need to the best-matching declarative agent by capability
622
+ * similarity. Returns `{ chosen, candidates, next_visited, invoked, result? }`
623
+ * JSON. With `invoke: true`, the top agent is run on `need` and its result is
624
+ * included. Network-entry case only; multi-hop Forward chaining (`from` /
625
+ * `visited`) is WS-only.
626
+ */
627
+ declagentRoute(need: string, invoke: boolean): Promise<string>;
628
+ /**
629
+ * Split a composite need into subtasks and route each to its best-matching
630
+ * agent. Returns `{ subtasks: [{ subtask, chosen, score, result? }], count,
631
+ * invoked }` JSON. `maxSubtasks` caps the split (clamped to [1, 10]; null =
632
+ * default 5). With `invoke: true`, each subtask's chosen agent runs.
633
+ */
634
+ declagentRouteSplit(need: string, invoke: boolean, maxSubtasks?: number | undefined | null): Promise<string>;
635
+ /**
636
+ * Read-only view of the learned routing topology: per-agent success stats
637
+ * and directed agent→agent edge weights. Returns `{ agents, edges }` JSON.
638
+ */
639
+ declagentRoutingStats(): Promise<string>;
640
+ /**
641
+ * AgentDNS-style discovery: resolve a natural-language need into ranked
642
+ * CAR-local services, each named under `agentdns://org/category/name`.
643
+ * Returns `{ services: [{ identifier, name, kind, protocol, score,
644
+ * similarity }], count }` JSON. `limit` caps results (clamped to [1, 50];
645
+ * null = default 5).
646
+ */
647
+ discoveryResolve(need: string, limit?: number | undefined | null): Promise<string>;
648
+
472
649
  /**
473
650
  * Build a concrete onboarding plan (machine summary, top pick, alternatives,
474
651
  * needs-more-memory, note) as JSON.
@@ -895,6 +1072,15 @@ export interface IntentHint {
895
1072
  * `prefer_local` if both are set.
896
1073
  */
897
1074
  prefer_fast?: boolean;
1075
+ /**
1076
+ * Bias the score profile toward the most capable model — quality
1077
+ * dominates, latency and cost near-floor (maps to
1078
+ * `RoutingWorkload::Quality`). For quality-critical, infrequent work
1079
+ * (building/verifying an agent, deriving a contract, structured
1080
+ * extraction) where a weak model fails. Precedence: `prefer_fast` wins,
1081
+ * then `prefer_quality`, then `prefer_local`.
1082
+ */
1083
+ prefer_quality?: boolean;
898
1084
  }
899
1085
 
900
1086
  // --- Voice streaming (stored-callback pattern) ---
@@ -1006,6 +1192,27 @@ export function registerToolHandler(
1006
1192
  */
1007
1193
  export function unregisterToolHandler(): void;
1008
1194
 
1195
+ /**
1196
+ * Register the callback fired when a tool callback is reaped
1197
+ * (Parslee-ai/car#264). When a `tools.execute` callback exceeds its budget the
1198
+ * daemon emits a `tools.cancel` notification; this callback receives the
1199
+ * reaped call's `requestId` (the same `request_id` surfaced on the originating
1200
+ * `tools.execute` call_json) so the host can abort the in-flight child it
1201
+ * registered under that id (e.g. `AbortController.abort()` / `child.kill()`).
1202
+ *
1203
+ * Fire-and-forget — no return value. Process-wide setter; re-calling
1204
+ * overwrites. Pair with `unregisterToolCancelHandler` to clear.
1205
+ */
1206
+ export function registerToolCancelHandler(
1207
+ handlerFn: (requestId: string) => void,
1208
+ ): void;
1209
+
1210
+ /**
1211
+ * Clear the registered `tools.cancel` handler. Subsequent reaps are no longer
1212
+ * routed to the host (the daemon has already abandoned the call regardless).
1213
+ */
1214
+ export function unregisterToolCancelHandler(): void;
1215
+
1009
1216
  export function transcribeStream(
1010
1217
  rt: CarRuntime,
1011
1218
  sessionId: string,
@@ -1717,11 +1924,32 @@ export function agentsStop(id: string, signal?: string | null): Promise<string>;
1717
1924
  export function agentsRestart(id: string): Promise<string>;
1718
1925
 
1719
1926
  /**
1720
- * Read the last `n` lines from the agent's combined stdout +
1721
- * stderr log under `~/.car/logs/<id>.{stdout,stderr}.log`.
1722
- * Defaults to 100 lines. Returns JSON `{lines: string[]}`.
1927
+ * Read a window of an agent's logs under
1928
+ * `~/.car/logs/<id>.{stdout,stderr}.log`.
1929
+ *
1930
+ * - `n` caps lines per included stream (default 100; `0` ⇒ whole file,
1931
+ * still bounded by the tail byte ceiling below).
1932
+ * - `stream` selects `"stdout"`, `"stderr"`, or `"combined"` (default).
1933
+ * Each stream is tailed independently, so a long stale stderr can no
1934
+ * longer bury live stdout (Parslee-ai/car#273).
1935
+ * - `offset` pages back: skip this many lines from the end of each
1936
+ * stream before taking the window (`offset = n` ⇒ previous page).
1937
+ * Combined-view paging is not order-preserving — page within a single
1938
+ * stream to scroll back.
1939
+ *
1940
+ * Each stream is read via a bounded backward seek (at most an 8 MiB
1941
+ * tail), not a whole-file slurp, since agent logs are append-only and
1942
+ * never rotated. A log larger than the ceiling is truncated to its last
1943
+ * 8 MiB and `more` is forced `true`.
1944
+ *
1945
+ * Returns JSON `{ lines: string[], stdout: string[], stderr: string[],
1946
+ * stdoutTotal: number, stderrTotal: number, stdoutPath: string,
1947
+ * stderrPath: string, more: boolean }`. `lines` keeps the legacy
1948
+ * stdout-then-stderr combined view for back-compat. `stdoutTotal` /
1949
+ * `stderrTotal` count lines in the scanned tail (exact within the
1950
+ * ceiling).
1723
1951
  */
1724
- export function agentsTailLog(id: string, n?: number | null): Promise<string>;
1952
+ export function agentsTailLog(id: string, n?: number | null, stream?: string | null, offset?: number | null): Promise<string>;
1725
1953
 
1726
1954
  // --- External-agent detection (car-external-agents) ---
1727
1955
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "car-runtime",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "description": "Common Agent Runtime — a deterministic execution layer for AI agents",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",