@basein/runner 0.3.0 → 0.3.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/README.md CHANGED
@@ -417,7 +417,7 @@ what to do when they register, so there is one switch and no second copy of it:
417
417
  | `BIR_DERIVE_API_KEY` | **Optional.** Working out what a new request is about — which fleet, which file, which date — is done for you by the service on its own key, as long as you are signed in. Set this (an Anthropic key) only to keep that reading on your machine, on your key. Signed out *and* unset, a scenario whose values change between requests is declined rather than replayed on stale ones. |
418
418
  | `ANTHROPIC_API_KEY` | Not used by the background recorder, which has Claude Code's environment and would bill your own key — unless `BIR_USE_ANTHROPIC_API_KEY=1`. A `bir-hooks` run by hand in a terminal uses that terminal's key. |
419
419
  | `BIR_DERIVE_MODEL` | Derivation model, when you set a key of your own (default `claude-haiku-4-5-20251001`). |
420
- | `BIR_MATCH_BUDGET_MS` | How long the prompt hook waits for a match (default `1500`). After a match slower than `BIR_MATCH_SLOW_MS` (default `800`), or one that timed out, prompts stop waiting for 5 min, doubling up to 30 min; a fast match ends that. |
420
+ | `BIR_MATCH_BUDGET_MS` | How long the prompt hook waits for a match (default `3000`). After a match slower than `BIR_MATCH_SLOW_MS` (default `2000`), or one that timed out, prompts stop waiting for 5 min, doubling up to 30 min; a fast match ends that. |
421
421
  | `BIR_DERIVE_BUDGET_MS` / `BIR_HOOK_DERIVE_BUDGET_MS` | How long a direct run, and a hook, waits for parameters (default `8000` / `4000`; a hook waits the smaller). |
422
422
  | `BIR_PRETOOL_REPLAY_BUDGET_MS` | Everything replay does inside one `PreToolUse` (default `9000`, at most `10000`). |
423
423
  | `BIR_REPLAY_BUDGET_MS` / `BIR_STEP_TIMEOUT_MS` | Whole-plan and per-step ceilings for direct execution (default `100000` / `60000`; `BIR_REPLAY_PLAN_BUDGET_MS` also sets the first). A direct run's parameter wait plus its plan are held under 270 s. |
@@ -77,7 +77,7 @@
77
77
  * `bir-hooks` run by hand in a terminal uses that
78
78
  * terminal's ANTHROPIC_API_KEY as it always did
79
79
  * BIR_DERIVE_MODEL derivation model (default claude-haiku-4-5-…)
80
- * BIR_MATCH_BUDGET_MS prompt-hook match wait (default 1500)
80
+ * BIR_MATCH_BUDGET_MS prompt-hook match wait (default 3000)
81
81
  * BIR_DERIVE_BUDGET_MS derivation wait before a direct run (default 8000);
82
82
  * inside a hook it is at most BIR_HOOK_DERIVE_BUDGET_MS
83
83
  * (default 4000)
@@ -77,7 +77,7 @@
77
77
  * `bir-hooks` run by hand in a terminal uses that
78
78
  * terminal's ANTHROPIC_API_KEY as it always did
79
79
  * BIR_DERIVE_MODEL derivation model (default claude-haiku-4-5-…)
80
- * BIR_MATCH_BUDGET_MS prompt-hook match wait (default 1500)
80
+ * BIR_MATCH_BUDGET_MS prompt-hook match wait (default 3000)
81
81
  * BIR_DERIVE_BUDGET_MS derivation wait before a direct run (default 8000);
82
82
  * inside a hook it is at most BIR_HOOK_DERIVE_BUDGET_MS
83
83
  * (default 4000)
@@ -23,10 +23,10 @@
23
23
  import { ControlServer } from "./server.js";
24
24
  /**
25
25
  * What a prompt waits for its scenario match by default (`BIR_MATCH_BUDGET_MS`).
26
- * Past it the prompt goes on without one (K5): the service answering in 1-2 s
27
- * must not add that to every prompt.
26
+ * Past it the prompt goes on without one (K5): a service slower than 3 s must
27
+ * not add that to every prompt.
28
28
  */
29
- export declare const DEFAULT_MATCH_BUDGET_MS = 1500;
29
+ export declare const DEFAULT_MATCH_BUDGET_MS = 3000;
30
30
  /**
31
31
  * `BIR_CORRELATION_DECISION`, passed on only when it was set to `allow` or
32
32
  * `ask`. Unset, nothing is passed and the control server decides — and by
@@ -40,10 +40,10 @@ const SHUTDOWN_CLOSE_MS = 3_000;
40
40
  const SHUTDOWN_HARD_MS = 5_000;
41
41
  /**
42
42
  * What a prompt waits for its scenario match by default (`BIR_MATCH_BUDGET_MS`).
43
- * Past it the prompt goes on without one (K5): the service answering in 1-2 s
44
- * must not add that to every prompt.
43
+ * Past it the prompt goes on without one (K5): a service slower than 3 s must
44
+ * not add that to every prompt.
45
45
  */
46
- export const DEFAULT_MATCH_BUDGET_MS = 1_500;
46
+ export const DEFAULT_MATCH_BUDGET_MS = 3_000;
47
47
  /** How often records of dead recorders are swept from the control directory. */
48
48
  const SWEEP_EVERY_MS = 24 * 60 * 60 * 1000;
49
49
  /**
@@ -140,13 +140,14 @@ const DELIVERY_HELLO_TTL_MS = 30 * 60_000;
140
140
  /** At most this many `bir-scenario` processes are remembered, newest kept. */
141
141
  const DELIVERY_HELLO_MAX = 256;
142
142
  /*
143
- * `slowMs` is 800: a healthy service answers the create-and-match in about
144
- * 300-450 ms (a cold TLS connection adds ~250 ms), so an answer past 800 ms is
145
- * a degraded service, and waiting on it would add that much to every prompt.
143
+ * `slowMs` is 2000: a healthy service answers the create-and-match in about
144
+ * 300-450 ms (a cold TLS connection adds ~250 ms), but a service that is only
145
+ * somewhat slow should keep replay on, so only an answer past 2 s counts as a
146
+ * degraded one, and waiting on it would add that much to every prompt.
146
147
  * A false trip costs only replay for one hold, never latency.
147
148
  */
148
149
  const DEFAULT_MATCH_GATE = {
149
- slowMs: 800,
150
+ slowMs: 2_000,
150
151
  holdMs: 5 * 60_000,
151
152
  maxHoldMs: 30 * 60_000,
152
153
  };
@@ -57,7 +57,7 @@ export const DEFAULT_BUDGETS = {
57
57
  // task; a match that has not answered by then is a turn run normally. The
58
58
  // control server stops waiting at all for a while after one that answered
59
59
  // slowly (`BIR_MATCH_SLOW_MS`). `BIR_MATCH_BUDGET_MS` in the recorder.
60
- matchMs: 1_500,
60
+ matchMs: 3_000,
61
61
  deriveMs: 8_000,
62
62
  planMs: 100_000,
63
63
  stepMs: 60_000,
@@ -760,7 +760,7 @@ The hook is on the user's critical path. Every await here is a stall the user wa
760
760
 
761
761
  | Moment | Route | Hook timeout | Answered by | What may be awaited | Budget |
762
762
  |---|---|---|---|---|---|
763
- | `UserPromptSubmit` | `/session/prompt` | 10 s | 7 s | the match; for a scenario with a target, its derivation; a steer plan's argument preview | match `BIR_MATCH_BUDGET_MS` = **1500**; match and arming together ≤ **6 s**; derivation ≤ `BIR_HOOK_DERIVE_BUDGET_MS` = **4000** |
763
+ | `UserPromptSubmit` | `/session/prompt` | 10 s | 7 s | the match; for a scenario with a target, its derivation; a steer plan's argument preview | match `BIR_MATCH_BUDGET_MS` = **3000**; match and arming together ≤ **6 s**; derivation ≤ `BIR_HOOK_DERIVE_BUDGET_MS` = **4000** |
764
764
  | `PreToolUse` | `/tool/pre` | 15 s | 12 s | `plan.ready()` (derivation); on a divergence, the remaining steps | derivation ≤ min(`BIR_DERIVE_BUDGET_MS`, `BIR_HOOK_DERIVE_BUDGET_MS`) = **4000**; all replay work ≤ `BIR_PRETOOL_REPLAY_BUDGET_MS` = **9000** (held at ≤ 10 000) |
765
765
  | `run_scenario` | `/scenario/run` | `bir-scenario`'s own, **290 s** (`BIR_SCENARIO_RUN_TIMEOUT_MS`) | — | `ready()` + N steps | derivation `BIR_DERIVE_BUDGET_MS` = **8000**; plan `BIR_REPLAY_PLAN_BUDGET_MS` = **100000** (`BIR_REPLAY_BUDGET_MS` overrides it where set); per step `BIR_STEP_TIMEOUT_MS` = **60000**, clipped to what the plan has left |
766
766
  | `PostToolUse` | `/tool/post` | 5 s | 2 s | nothing | — |
@@ -794,9 +794,9 @@ minutes, while its steps keep starting. `bir replay` is not held to the ceiling.
794
794
 
795
795
  **Budget expiry is never an error.** Match budget expired → no plan, ordinary turn, one
796
796
  `replay.decision` line (`match_timeout`). **The match gate:** a match that answered slower than
797
- `BIR_MATCH_SLOW_MS` (**800**), or not at all, also makes prompts stop waiting on the match for 5
797
+ `BIR_MATCH_SLOW_MS` (**2000**), or not at all, also makes prompts stop waiting on the match for 5
798
798
  minutes, doubling up to 30 while the service stays slow; a fast match ends the hold
799
- (`replay.match_gate`). A healthy service answers in 300–450 ms, so past 800 ms waiting would add
799
+ (`replay.match_gate`). A healthy service answers in 300–450 ms, so past 2 s waiting would add
800
800
  that much to every prompt. The match is still asked meanwhile, so a hit still stops the recording. Derivation budget expired →
801
801
  settings take their recorded `sampleValue`s and targets stay `null`, never `{}`; a plan that needs a
802
802
  missing target, or whose `paramsLogic` throws, hands over instead of running (in steer mode the
@@ -345,7 +345,7 @@ so there is exactly one switch and it cannot get out of step with itself.
345
345
  | `BIR_MIN_STEER_SIMILARITY` | `0.92` | Below this a match is detected but not replayed (§8) |
346
346
  | `BIR_DERIVE_API_KEY` | *(unset)* | **Not required.** Derivation — reading what this request acts on — is done by the service on its key for a signed-in runner. Set this to keep the reading on this machine instead: the prompt then never leaves it, and it is one round trip faster. Signed out *and* unset, only a scenario with nothing to work out replays. A recorder running in the background (started by the SessionStart hook, `bir up` or `bir setup`) ignores `ANTHROPIC_API_KEY` (usually Claude Code's own, and billed) unless `BIR_USE_ANTHROPIC_API_KEY=1`; a `bir-hooks` you run in a terminal uses it |
347
347
  | `BIR_DERIVE_MODEL` | `claude-haiku-4-5-20251001` | The derivation model, when this machine does the reading |
348
- | `BIR_MATCH_BUDGET_MS` | `1500` | How long the prompt hook waits for a match before giving up. After a match slower than `BIR_MATCH_SLOW_MS` (`800`), prompts stop waiting for one for 5 minutes, doubling up to 30 while the service stays slow |
348
+ | `BIR_MATCH_BUDGET_MS` | `3000` | How long the prompt hook waits for a match before giving up. After a match slower than `BIR_MATCH_SLOW_MS` (`2000`), prompts stop waiting for one for 5 minutes, doubling up to 30 while the service stays slow |
349
349
  | `BIR_DERIVE_BUDGET_MS` | `8000` | How long `run_scenario` waits for parameters |
350
350
  | `BIR_HOOK_DERIVE_BUDGET_MS` | `4000` | How long a hook waits for them: the prompt, for a scenario with a target, and the first `PreToolUse` (never longer than `BIR_DERIVE_BUDGET_MS`) |
351
351
  | `BIR_PRETOOL_REPLAY_BUDGET_MS` | `9000` | All replay work inside one `PreToolUse`, a divergence's steps included. At most 10 000 |
@@ -548,7 +548,7 @@ first prompt that states the task plainly.
548
548
  |---|---|---|
549
549
  | No `run.matched`, ever | Prompt below the server's `SIMILARITY_THRESHOLD` | Rephrase closer, or lower it server-side. Confirm the original run is in the list — a sub-`RECORDING_MIN_ACTIONS` run is never embedded |
550
550
  | `run.matched` but no `plan.armed` | A gate declined | Read the `replay.decision` line's `why=`. Ranked by frequency: replay off — `bir replay off`, `BIR_REPLAY=0`, or never switched on here (a `bir install` without `--replay`; `bir replay status` says which) · scenario not `ready` · similarity below threshold · no step is executable |
551
- | `replay.decision … code=match_timeout` or `code=service_unhealthy` on many prompts | The service answered the match slower than `BIR_MATCH_BUDGET_MS` (1.5 s), or is failing and in its cool-down | Nothing breaks: those turns run normally, and after a slow match prompts stop waiting on it for a while by themselves (`replay.match_gate`). `bir doctor` shows the service's state. Raise `BIR_MATCH_BUDGET_MS` only if the service is reliably just over it — every prompt pays it |
551
+ | `replay.decision … code=match_timeout` or `code=service_unhealthy` on many prompts | The service answered the match slower than `BIR_MATCH_BUDGET_MS` (3 s), or is failing and in its cool-down | Nothing breaks: those turns run normally, and after a slow match prompts stop waiting on it for a while by themselves (`replay.match_gate`). `bir doctor` shows the service's state. Raise `BIR_MATCH_BUDGET_MS` only if the service is reliably just over it — every prompt pays it |
552
552
  | `replay.decision … code=no_delivery_tool` | A direct plan, and no running `bir` server has told the recorder it serves `run_scenario`: the server is missing, disabled or failed in `/mcp`, was not added (a subdirectory or worktree of a repository), or the session was started with `BIR_OFF=1` | `/mcp` shows whether `bir` is connected. `bir install --replay` adds it, in the project's own directory; then start a new session |
553
553
  | `replay.vetoed … the model's first call was …, not run_scenario` | A direct plan, and the model reached for another tool first — usually because it has no `run_scenario` | As for `no_delivery_tool`. Nothing ran; the model did the task |
554
554
  | `replay.pin_declined` on most steered turns | The model's calls to the expected tool are not the step — another command, another file — so nothing is pinned; if it then moves on, `replay.pin_abandoned` retires the plan | Harmless for those calls, which ran as the model wrote them. Persistent declines on one step usually mean its arguments cannot be shown in the directive (they depend on an earlier step's output, or the command runs to several lines), and the model writes its own |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basein/runner",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A recording MCP proxy: sits between any MCP client and its MCP servers, executes each call on the client's behalf, and records the run as a reusable BaseIn scenario.",
5
5
  "type": "module",
6
6
  "license": "MIT",