car-runtime 0.46.0 → 0.47.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/index.d.ts +218 -10
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -59,6 +59,14 @@ export interface CoderStartOptions {
|
|
|
59
59
|
* hypothesis, the other buys a retry.
|
|
60
60
|
*/
|
|
61
61
|
transientRetries?: number | undefined | null;
|
|
62
|
+
/**
|
|
63
|
+
* A `coder.discuss` conversation this run was distilled from. Its agreed
|
|
64
|
+
* constraints ride into contract derivation, so a rule stated once in the
|
|
65
|
+
* discussion does not have to be restated in the intent, and the session
|
|
66
|
+
* records the provenance. An unknown id is a clear error — never a silently
|
|
67
|
+
* ungrounded run.
|
|
68
|
+
*/
|
|
69
|
+
discussionId?: string | undefined | null;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
export class CarRuntime {
|
|
@@ -937,9 +945,93 @@ export class CarRuntime {
|
|
|
937
945
|
*/
|
|
938
946
|
coderApproveMerge(sessionId: string, approve: boolean): Promise<string>;
|
|
939
947
|
|
|
940
|
-
/**
|
|
948
|
+
/**
|
|
949
|
+
* Cancel a session: stop the loop, abandon, remove the worktree. Returns
|
|
950
|
+
* `{state, already_terminal, message}`.
|
|
951
|
+
*
|
|
952
|
+
* An already-finished session **succeeds** rather than rejecting: `state`
|
|
953
|
+
* keeps its pre-existing name and type, `already_terminal` is `true`, and
|
|
954
|
+
* `message` names what already happened. Callers that cancel unconditionally
|
|
955
|
+
* on shutdown depend on that — rejecting would turn a quiet exit into a
|
|
956
|
+
* protocol error whenever the session raced to terminal first.
|
|
957
|
+
*/
|
|
941
958
|
coderCancel(sessionId: string): Promise<string>;
|
|
942
959
|
|
|
960
|
+
/**
|
|
961
|
+
* The current session list AND registration for `coder.session_changed` on
|
|
962
|
+
* this connection, atomically (registered under the same lock the list is
|
|
963
|
+
* snapshotted under, so nothing slips through the gap). Notifications are
|
|
964
|
+
* WebSocket-only, same contract as `coder.subscribe`.
|
|
965
|
+
*
|
|
966
|
+
* Each row carries the full summary: the pre-existing
|
|
967
|
+
* `{session_id, state, intent, repo, engine, iterations, updated_at, live,
|
|
968
|
+
* error}` plus `needs_you` (`"contract" | "question" | "approval" | "auth" |
|
|
969
|
+
* null`), `needs_you_label` (the daemon-owned wording, so every client says
|
|
970
|
+
* the same thing), `question_prompt`, `auth_message`, `auth_wait_secs`,
|
|
971
|
+
* `failure_kind` (`"budget_exhausted" | "auth_required" | "error"` when
|
|
972
|
+
* failed), `worktree` (only when it still exists on disk), `project`,
|
|
973
|
+
* `result_branch`, `model`, `discussion_id`, and `next_seq` (live only —
|
|
974
|
+
* the `coder.subscribe` cursor).
|
|
975
|
+
*
|
|
976
|
+
* Pass `renew: true` for the lease-renewal form: it re-registers and answers
|
|
977
|
+
* `{ was_registered }` — `false` means this connection had been shed and
|
|
978
|
+
* should take a full snapshot — and builds NO summaries, so it is cheap
|
|
979
|
+
* enough to call on a timer. The default form is unchanged.
|
|
980
|
+
*/
|
|
981
|
+
coderWatch(renew?: boolean | undefined | null): Promise<string>;
|
|
982
|
+
|
|
983
|
+
/** Stop receiving `coder.session_changed` on this connection. */
|
|
984
|
+
coderUnwatch(): Promise<string>;
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Redraft a PROPOSED outcome contract from a plain-English request (e.g.
|
|
988
|
+
* "also verify the Windows path"). Legal only in `contract_proposed`;
|
|
989
|
+
* nothing executes and the session stays at the gate either way. Unlimited
|
|
990
|
+
* rounds.
|
|
991
|
+
*
|
|
992
|
+
* Returns `{state, revised, contract, baseline, baseline_gates_nothing,
|
|
993
|
+
* message}`. **Check `revised` before trusting `contract`**: on a redraft
|
|
994
|
+
* that does not validate, the previous contract comes back byte-identical
|
|
995
|
+
* with `revised: false` and a `message` explaining why, and the daemon emits
|
|
996
|
+
* a `contract_revision_rejected` event.
|
|
997
|
+
*/
|
|
998
|
+
coderReviseContract(sessionId: string, request: string): Promise<string>;
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Open a repo-grounded, strictly **read-only** discussion — a thinking
|
|
1002
|
+
* surface for working out what a change should be, before a run exists.
|
|
1003
|
+
* Bound at `PermissionTier::ReadOnly` with every write/shell escalation
|
|
1004
|
+
* auto-denied, so it can never touch the repo. Returns
|
|
1005
|
+
* `{discussion_id, repo, repo_summary}`; a non-git path is a clear error.
|
|
1006
|
+
*/
|
|
1007
|
+
coderDiscussStart(repo: string): Promise<string>;
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Send one operator message. Returns `{ok, seq}` where `seq` is the first
|
|
1011
|
+
* event this turn emits; the reply streams as `coder.discuss.event`
|
|
1012
|
+
* (WebSocket-only, same contract as `coder.event`).
|
|
1013
|
+
*/
|
|
1014
|
+
coderDiscussSend(discussionId: string, text: string): Promise<string>;
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Distill the discussion into `{discussion_id, proposed_intent,
|
|
1018
|
+
* constraints}`. **Starts nothing** — no worktree, no branch, no session.
|
|
1019
|
+
* The caller shows `proposed_intent` (never the transcript) for the operator
|
|
1020
|
+
* to edit, then passes it to `coderStart` with `discussion_id` so the agreed
|
|
1021
|
+
* constraints reach contract derivation. Callable repeatedly.
|
|
1022
|
+
*/
|
|
1023
|
+
coderDiscussPromote(discussionId: string): Promise<string>;
|
|
1024
|
+
|
|
1025
|
+
/** Free an in-memory discussion. Discussions do not survive a daemon restart. */
|
|
1026
|
+
coderDiscussClose(discussionId: string): Promise<string>;
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* Open discussions: `{discussions: [{discussion_id, repo, created_at,
|
|
1030
|
+
* turns}]}`. Also the capability probe — a daemon predating this surface
|
|
1031
|
+
* answers JSON-RPC `-32601`.
|
|
1032
|
+
*/
|
|
1033
|
+
coderDiscussList(): Promise<string>;
|
|
1034
|
+
|
|
943
1035
|
/**
|
|
944
1036
|
* Managed projects + in-daemon declarative agents (the non-developer path).
|
|
945
1037
|
*
|
|
@@ -1942,6 +2034,30 @@ export function resumeWorkflow(pausedJson: string, inputJson: string): Promise<s
|
|
|
1942
2034
|
* resumable runs after a restart. */
|
|
1943
2035
|
export function listPausedWorkflows(runsDir: string): string;
|
|
1944
2036
|
|
|
2037
|
+
/** Bind (or clear) the memory namespace for subsequent daemon connections
|
|
2038
|
+
* (car-releases#81). Returns the namespace now in effect, or `null` for the
|
|
2039
|
+
* daemon's shared graph.
|
|
2040
|
+
*
|
|
2041
|
+
* Prefer this over setting `CAR_MEMORY_NAMESPACE` when the namespace is
|
|
2042
|
+
* per-project. An env var cannot carry a per-project value: the host learns
|
|
2043
|
+
* which project it is *after* the process starts, and on **bun** a JS-side
|
|
2044
|
+
* `process.env` write never reaches the C `environ` this library reads — the
|
|
2045
|
+
* write is silently ignored and the session falls back to the shared graph.
|
|
2046
|
+
*
|
|
2047
|
+
* Blank or `null` clears the override, falling back to `CAR_MEMORY_NAMESPACE`
|
|
2048
|
+
* and then the shared graph.
|
|
2049
|
+
*
|
|
2050
|
+
* **Takes effect on the next connection.** The namespace is negotiated during
|
|
2051
|
+
* `session.auth`, so an already-established connection keeps the graph it
|
|
2052
|
+
* bound. Call this before your first CAR call, or disconnect afterwards to
|
|
2053
|
+
* force a rebind — otherwise you keep writing to the previous project's
|
|
2054
|
+
* graph. */
|
|
2055
|
+
export function setMemoryNamespace(namespace?: string | null): string | null;
|
|
2056
|
+
|
|
2057
|
+
/** The memory namespace currently in effect — the explicit override if set,
|
|
2058
|
+
* otherwise `CAR_MEMORY_NAMESPACE`, otherwise `null` (shared graph). */
|
|
2059
|
+
export function getMemoryNamespace(): string | null;
|
|
2060
|
+
|
|
1945
2061
|
/** NLP (F4): identify the dominant language of `text`. Returns
|
|
1946
2062
|
* `{language, backend}` JSON (Apple NaturalLanguage on macOS, pure-Rust
|
|
1947
2063
|
* fallback elsewhere). */
|
|
@@ -2145,10 +2261,25 @@ export function sendA2AMessage(rt: CarRuntime, paramsJson: string): Promise<stri
|
|
|
2145
2261
|
* `{ valid, issues, simulated_state, execution_levels, conflicts,
|
|
2146
2262
|
* evidence }`. `evidence` is the verifier's declared scope (survey
|
|
2147
2263
|
* "Code as Agent Harness" §5.2.2): `{ checks: [{ name, ran, verifies,
|
|
2148
|
-
* cannot_verify, findings }], assumptions, untested_regions,
|
|
2264
|
+
* cannot_verify, findings, tier }], assumptions, untested_regions,
|
|
2149
2265
|
* residual_risks, confidence }` — so a `valid: true` verdict can be read
|
|
2150
2266
|
* with its scope (what was checked, what was not, coverage confidence)
|
|
2151
2267
|
* rather than as a blanket guarantee.
|
|
2268
|
+
*
|
|
2269
|
+
* Each issue is `{ action_id, severity, message, tier }`. `tier` is the
|
|
2270
|
+
* **evidence tier** — `"decision_procedure" | "heuristic" | "sampled"` —
|
|
2271
|
+
* naming which kind of check produced the finding, so you don't have to
|
|
2272
|
+
* pattern-match the message to tell them apart. All of `verify`'s
|
|
2273
|
+
* findings are `decision_procedure` (set membership, the STRIPS-style
|
|
2274
|
+
* forward walk, write-conflict detection) except the
|
|
2275
|
+
* repeated-identical-call rule, which is `heuristic`: the count is
|
|
2276
|
+
* exact, "runaway loop" is a proxy, and a legitimate 3× poll trips it.
|
|
2277
|
+
* The tier is orthogonal to `severity` (how bad, not how derived), and
|
|
2278
|
+
* `decision_procedure` is not a proof or a soundness claim — it means
|
|
2279
|
+
* the check decides the property it reports over the inputs it was
|
|
2280
|
+
* given, which for the state-dependent checks is a forward model built
|
|
2281
|
+
* only from *declared* effects. Each `CheckRecord` carries the same
|
|
2282
|
+
* `tier` as the findings it contributed.
|
|
2152
2283
|
*/
|
|
2153
2284
|
export function verify(
|
|
2154
2285
|
proposalJson: string,
|
|
@@ -2652,8 +2783,13 @@ export function cascadeDecide(
|
|
|
2652
2783
|
*
|
|
2653
2784
|
* `statsJson` is aggregate counters (parsed by serde — keys are snake_case):
|
|
2654
2785
|
* `{ total_facts, structured_facts, total_edges, total_retrievals,
|
|
2655
|
-
* helpful_retrievals, conflicts_resolved,
|
|
2656
|
-
* facts_superseded }` (omitted fields
|
|
2786
|
+
* total_proactive_injections, helpful_retrievals, conflicts_resolved,
|
|
2787
|
+
* outstanding_outdated, facts_created, facts_superseded }` (omitted fields
|
|
2788
|
+
* default to 0). `total_retrievals` counts DELIBERATE recalls only;
|
|
2789
|
+
* harness-initiated proactive injections are reported separately as
|
|
2790
|
+
* `total_proactive_injections` and never feed ranking (car#816).
|
|
2791
|
+
* `helpful_retrievals` is always 0 today — `record_fact_helpful` has no
|
|
2792
|
+
* production caller — so read a 0 there as "not wired", not "nothing helped". Returns the report JSON:
|
|
2657
2793
|
* `{ representation_fidelity, retrieval_precision, update_correctness,
|
|
2658
2794
|
* long_horizon_stability, overall }` (each 0..1), `bottleneck` (one of
|
|
2659
2795
|
* `"representation" | "retrieval" | "update_correctness" |
|
|
@@ -2849,11 +2985,76 @@ export function evolutionApply(
|
|
|
2849
2985
|
// (read_only | sandbox_edit | full_access), gate it against the session's
|
|
2850
2986
|
// granted standing tier, and record human-in-the-loop approvals as durable,
|
|
2851
2987
|
// auditable state (a JSONL ledger keyed by a stable action fingerprint).
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2988
|
+
//
|
|
2989
|
+
// Two axes, not one. The tier answers "who may authorize this?" and says
|
|
2990
|
+
// nothing about whether the effect can be undone — a `git push`, a production
|
|
2991
|
+
// INSERT, and a charged card are all `full_access` with three different
|
|
2992
|
+
// rollback contracts. Every row below therefore carries a `reversibility`
|
|
2993
|
+
// alongside its `required_tier`.
|
|
2994
|
+
//
|
|
2995
|
+
// The matching Action IR fields (any `proposalJson` this package accepts, and
|
|
2996
|
+
// the full spec in docs/agent-ir-spec.md):
|
|
2997
|
+
//
|
|
2998
|
+
// "reversibility": "reversible" | "compensable" | "irreversible"
|
|
2999
|
+
// Optional. The rollback contract for this action's effects.
|
|
3000
|
+
// `reversible` is undone by restoring the scope it ran in;
|
|
3001
|
+
// `compensable` needs a compensating action run against it;
|
|
3002
|
+
// `irreversible` cannot be undone once it reaches the world.
|
|
3003
|
+
// **Defaults to "irreversible"** when omitted — deliberately, because
|
|
3004
|
+
// the default decides what the runtime believes about an unclassified
|
|
3005
|
+
// action and the two directions fail asymmetrically. Guessing
|
|
3006
|
+
// "reversible" wrongly means silently believing a sent email can be
|
|
3007
|
+
// unsent; guessing "irreversible" wrongly means over-asking for an
|
|
3008
|
+
// approval on something recoverable, which is annoying, visible, and
|
|
3009
|
+
// fixed locally by annotating the action.
|
|
3010
|
+
//
|
|
3011
|
+
// "compensation": { "type": "tool", "tool": string, "parameters"?: object }
|
|
3012
|
+
// | { "type": "action_ref", "action_id": string }
|
|
3013
|
+
// Optional. How to undo the action once it has run — the action-level
|
|
3014
|
+
// analogue of car-workflow's saga CompensationHandler. Meaningful only
|
|
3015
|
+
// with `"reversibility": "compensable"`; omitted from the serialized
|
|
3016
|
+
// form when absent, so older consumers see the payload they saw before.
|
|
3017
|
+
// Declaring one is a *claim*: nothing checks that the named tool is a
|
|
3018
|
+
// true inverse, exactly as nothing checks `expected_effects`.
|
|
3019
|
+
//
|
|
3020
|
+
// Nothing in the runtime enforces on either field yet — they are typed,
|
|
3021
|
+
// classified, and audited. Do not read `"reversible"` as a promise that the
|
|
3022
|
+
// runtime will undo anything for you: rollback restores the state map and
|
|
3023
|
+
// leaves whatever a tool wrote to disk where it is. See
|
|
3024
|
+
// docs/proposals/shepherd-substrate-adoption.md.
|
|
3025
|
+
|
|
3026
|
+
/**
|
|
3027
|
+
* Classify each action in a proposal on both authorization-adjacent axes.
|
|
3028
|
+
* Returns a JSON array of `{ action_id, tool, required_tier, reversibility,
|
|
3029
|
+
* missing_compensation }`. The keys live inside a JSON string, so they stay
|
|
3030
|
+
* snake_case — napi-rs camelCases function and parameter names, not payload
|
|
3031
|
+
* contents.
|
|
3032
|
+
*
|
|
3033
|
+
* - `required_tier` — **who may authorize this**: `"read_only" |
|
|
3034
|
+
* "sandbox_edit" | "full_access"`.
|
|
3035
|
+
* - `reversibility` — **can this be undone**: `"reversible" | "compensable" |
|
|
3036
|
+
* "irreversible"`. Independent of the tier and not derived from it:
|
|
3037
|
+
* `read_secret` is `full_access` and perfectly reversible (a read leaves
|
|
3038
|
+
* nothing to undo), while `send_email` and `deploy_service` are both
|
|
3039
|
+
* `full_access` and differ completely. This is the classifier's answer from
|
|
3040
|
+
* the tool name and flattened parameters — **not** an echo of the action's
|
|
3041
|
+
* declared `reversibility` field, which defaults to `"irreversible"` and so
|
|
3042
|
+
* would tell you only what you sent. It is a keyword heuristic: an
|
|
3043
|
+
* unrecognized tool comes back `"irreversible"`, deliberately.
|
|
3044
|
+
* - `missing_compensation` — the action **declared** `"compensable"` and
|
|
3045
|
+
* supplied no `compensation`, the one incoherent combination the IR cannot
|
|
3046
|
+
* exclude by construction. Keyed off the declared field, so it stays `false`
|
|
3047
|
+
* for proposals that never opted into the axis.
|
|
3048
|
+
*
|
|
3049
|
+
* Severity ascends `"reversible" < "compensable" < "irreversible"`, so the
|
|
3050
|
+
* rollback contract of a whole batch is the worst row — a plan is only as
|
|
3051
|
+
* recoverable as its least recoverable step. (The daemon's `permission.classify`
|
|
3052
|
+
* returns that roll-up precomputed as `declared_rollback_contract`, over the
|
|
3053
|
+
* *declared* fields; this function returns a bare array with nowhere to hang
|
|
3054
|
+
* it, so compute it from the column you care about.)
|
|
3055
|
+
*
|
|
3056
|
+
* Nothing in the runtime gates on the second axis yet — it is typed,
|
|
3057
|
+
* classified, and audited, not enforced.
|
|
2857
3058
|
*/
|
|
2858
3059
|
export function permissionClassify(proposalJson: string): string;
|
|
2859
3060
|
|
|
@@ -2861,10 +3062,17 @@ export function permissionClassify(proposalJson: string): string;
|
|
|
2861
3062
|
* Evaluate each action against a granted standing tier, consulting the
|
|
2862
3063
|
* durable approval ledger JSONL at `ledgerPath` when supplied. Returns a
|
|
2863
3064
|
* JSON array of per-action decisions, each `{ decision, required, granted,
|
|
2864
|
-
* action_id, fingerprint, ... }` where `decision` is `"allow" |
|
|
3065
|
+
* action_id, fingerprint, reversibility, ... }` where `decision` is `"allow" |
|
|
2865
3066
|
* "needs_approval" | "deny"`. A `needs_approval` decision means autonomy is
|
|
2866
3067
|
* suspended pending a human decision; resolve it with
|
|
2867
3068
|
* {@link permissionRecordForFingerprint}.
|
|
3069
|
+
*
|
|
3070
|
+
* `reversibility` is orthogonal to `decision` and rides on **every** row, the
|
|
3071
|
+
* `allow`s included: the gate's verdict says whether the action may run, not
|
|
3072
|
+
* whether it could be taken back afterwards, and a caller that only learns the
|
|
3073
|
+
* rollback contract of the actions it was stopped on is missing exactly the
|
|
3074
|
+
* rows an incident review reads first. Same field, labels, and classifier as
|
|
3075
|
+
* the `PermissionDecision` event the engine writes to its audit log.
|
|
2868
3076
|
*/
|
|
2869
3077
|
export function permissionEvaluate(
|
|
2870
3078
|
proposalJson: string,
|