@basein/runner 0.3.21 → 0.3.22

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 (48) hide show
  1. package/dist/bin/bir-hooks.d.ts +7 -16
  2. package/dist/bin/bir-hooks.js +7 -16
  3. package/dist/bin/bir-scenario.js +1 -1
  4. package/dist/bin/bir.js +1 -21
  5. package/dist/bin/investigate.d.ts +0 -9
  6. package/dist/bin/investigate.js +14 -42
  7. package/dist/bin/scenario-edit.js +13 -44
  8. package/dist/control/recorder-main.d.ts +0 -15
  9. package/dist/control/recorder-main.js +7 -39
  10. package/dist/control/server.d.ts +24 -137
  11. package/dist/control/server.js +101 -995
  12. package/dist/record/recorder.d.ts +11 -142
  13. package/dist/record/recorder.js +0 -3
  14. package/dist/record/remote-recorder.d.ts +1 -9
  15. package/dist/record/remote-recorder.js +3 -49
  16. package/dist/record/switchable-recorder.js +0 -2
  17. package/dist/replay/bundle.d.ts +2 -2
  18. package/dist/replay/bundle.js +3 -3
  19. package/dist/replay/controller.d.ts +19 -123
  20. package/dist/replay/controller.js +151 -518
  21. package/dist/replay/derive.d.ts +0 -10
  22. package/dist/replay/derive.js +0 -3
  23. package/dist/replay/handover.d.ts +2 -37
  24. package/dist/replay/handover.js +38 -106
  25. package/dist/replay/logic.d.ts +0 -11
  26. package/dist/replay/logic.js +0 -24
  27. package/dist/replay/plan.d.ts +43 -163
  28. package/dist/replay/plan.js +144 -556
  29. package/dist/replay/safety.d.ts +4 -5
  30. package/dist/replay/safety.js +7 -7
  31. package/dist/replay/source-run.d.ts +15 -24
  32. package/dist/replay/source-run.js +25 -58
  33. package/dist/replay/targets.d.ts +11 -21
  34. package/dist/replay/targets.js +30 -69
  35. package/dist/replay/types.d.ts +9 -96
  36. package/dist/replay/types.js +3 -16
  37. package/dist/util/service-headers.d.ts +1 -2
  38. package/dist/util/service-headers.js +1 -2
  39. package/docs/calculatedReplay.md +17 -74
  40. package/docs/calculatedReplayGuide.md +9 -30
  41. package/package.json +1 -1
  42. package/production.md +5 -35
  43. package/dist/replay/condition-words.d.ts +0 -28
  44. package/dist/replay/condition-words.js +0 -59
  45. package/dist/replay/flatten.d.ts +0 -161
  46. package/dist/replay/flatten.js +0 -222
  47. package/dist/replay/reads-only.d.ts +0 -29
  48. package/dist/replay/reads-only.js +0 -261
@@ -20,7 +20,6 @@
20
20
  * step to know its reach, so it can choose between the proxy, a recorded
21
21
  * output, and skipping.
22
22
  */
23
- import { type FlatEntry } from "./flatten.js";
24
23
  import type { ReplayMode } from "./coverage.js";
25
24
  import type { HandoverStopReason } from "./handover.js";
26
25
  import type { ExecutionStage, FallbackKind, ParamsSchema, SerializedScenario, SerializedScenarioStep } from "./types.js";
@@ -130,16 +129,12 @@ export interface DriveOptions {
130
129
  /**
131
130
  * Supplies a step's recorded output when its tool cannot run here (§8.1).
132
131
  *
133
- * It takes the *entry*, not the step: a step inside a called segment takes its
134
- * recorded output from that segment's own recording, within its own range
135
- * (segmented.md R-CALL-31).
136
- *
137
132
  * `leftOut`, when there, is told of every step a test left out (the service's
138
133
  * autocorrect.md AC5): one that was in the recording made its call there, and
139
134
  * its output is passed over, so the next step of its tool takes its own.
140
135
  */
141
- export type RecordedOutputFor = ((entry: FlatEntry) => Promise<string | undefined>) & {
142
- leftOut?: (entry: FlatEntry) => void;
136
+ export type RecordedOutputFor = ((step: SerializedScenarioStep) => Promise<string | undefined>) & {
137
+ leftOut?: (step: SerializedScenarioStep) => void;
143
138
  };
144
139
  /**
145
140
  * What one step did, told to the caller as it happens.
@@ -154,12 +149,6 @@ export type RecordedOutputFor = ((entry: FlatEntry) => Promise<string | undefine
154
149
  */
155
150
  export interface StepInfo {
156
151
  step: SerializedScenarioStep;
157
- /**
158
- * The flat entry this step ran as: which scenario owns it, which frame it
159
- * ran in, and where it sits in the flat order (segmented.md R-CALL-13).
160
- * Absent only where a caller builds a StepInfo by hand.
161
- */
162
- entry?: FlatEntry;
163
152
  input: Record<string, unknown>;
164
153
  /**
165
154
  * What the step's output logic was given: the tool's answer, or for
@@ -170,7 +159,7 @@ export interface StepInfo {
170
159
  /**
171
160
  * `not_taken`: the step's test said this request does not need it, and it
172
161
  * was left out on purpose (the service's autocorrect.md AC5). No call, no
173
- * output logic; a sub-task's call row left out whole is one such verdict.
162
+ * output logic.
174
163
  */
175
164
  outcome: "executed" | "recorded" | "skipped" | "failed" | "not_taken";
176
165
  /** Which part of the step broke. Only set for `failed`. */
@@ -220,19 +209,18 @@ export interface ComposeResult {
220
209
  /** Where, and why, the run stopped short of its end, when it did. */
221
210
  stopped?: PlanStop;
222
211
  /**
223
- * The flat position the walk ended at. At or past the plan's `stepCount`
224
- * when it reached the end of the planned steps — past it when a test left
225
- * out a sub-task that reaches beyond a parked step.
212
+ * The position the walk ended at. At the plan's `stepCount` when it reached
213
+ * the end of the planned steps.
226
214
  */
227
215
  endedAt: number;
228
216
  }
229
217
  /** Where, and why, a run stopped short of the chain's end (fallbk.md). */
230
218
  export interface PlanStop {
231
219
  kind: FallbackKind;
232
- /** The owning scenario's own `stepIndex` of the step it stopped at. */
220
+ /** The scenario's own `stepIndex` of the step it stopped at. */
233
221
  stepIndex: number;
234
- /** Its position in the flat list, which is what the caller indexes by. */
235
- flatIndex?: number;
222
+ /** Its position in the chain, which is what the caller indexes by. */
223
+ position?: number;
236
224
  stage?: ExecutionStage;
237
225
  error?: string;
238
226
  /**
@@ -243,21 +231,14 @@ export interface PlanStop {
243
231
  reason?: HandoverStopReason;
244
232
  /** For `other_branch`: the test in words — what the steps from here are for (AC5). */
245
233
  whenText?: string | null;
246
- /**
247
- * For `result_map`: the sub-task whose results could not go back to its
248
- * caller, after its last step was left out by its test (AC5).
249
- */
250
- subTask?: string | null;
251
234
  }
252
235
  /**
253
- * What a step's test decided at one flat position (the service's
254
- * autocorrect.md AC5).
236
+ * What a step's test decided at one position (the service's autocorrect.md
237
+ * AC5).
255
238
  *
256
239
  * - `run`: no test, or its test said yes.
257
- * - `skip`: this request does not need it — the step, or the whole sub-task
258
- * whose call row's test said no. The walk goes on at `until`. `leave` says
259
- * the step left out was the last of an entered sub-task, so the sub-task's
260
- * results still go back to its caller.
240
+ * - `skip`: this request does not need the step. The walk goes on with the
241
+ * next one.
261
242
  * - `stop`: the test said `hand_over` (this request is the other half), or
262
243
  * could not answer. `info` is the step's verdict when there is one to give.
263
244
  */
@@ -265,11 +246,9 @@ export type Gate = {
265
246
  kind: "run";
266
247
  } | {
267
248
  kind: "skip";
268
- until: number;
269
249
  info: StepInfo;
270
- entry: FlatEntry;
250
+ step: SerializedScenarioStep;
271
251
  text: string | null;
272
- tools: string[];
273
252
  } | {
274
253
  kind: "stop";
275
254
  stop: PlanStop;
@@ -277,21 +256,11 @@ export type Gate = {
277
256
  };
278
257
  /** A step left out by its test, as the steer note and the bundle name it. */
279
258
  export interface LeftOut {
280
- /** The owning scenario's own `stepIndex` — the caller's for a sub-task. */
259
+ /** The scenario's own `stepIndex`. */
281
260
  stepIndex: number;
282
- /** Its flat position. */
283
- flatIndex: number;
284
- /**
285
- * The flat position after it: past every step of a sub-task left out
286
- * whole, `flatIndex + 1` for one step.
287
- */
288
- until: number;
261
+ /** Its position in the chain. */
262
+ position: number;
289
263
  toolName: string;
290
- /**
291
- * Every tool the steps left out call — the sub-task's, for a sub-task left
292
- * out whole — so a call the model makes to any of them is known for one.
293
- */
294
- tools: string[];
295
264
  text: string | null;
296
265
  }
297
266
  export interface PlanOptions {
@@ -306,7 +275,7 @@ export interface PlanOptions {
306
275
  * What a *target* takes when the parameters settle without the derivation.
307
276
  * `null` (the default) is the rule: a target is never guessed. `samples` is
308
277
  * `bir replay`'s own contract — an operator named the scenario by id, so a
309
- * recorded sample stands in (R-CALL-37).
278
+ * recorded sample stands in.
310
279
  */
311
280
  fallbackTargets?: "null" | "samples";
312
281
  mode: ReplayMode;
@@ -318,18 +287,11 @@ export interface PlanOptions {
318
287
  */
319
288
  stopAt?: number;
320
289
  /**
321
- * The plan is a sub-task inside the agent's own task (segmented.md R-OUT-13):
322
- * it was armed by intent, not by the prompt, so its directive and its bundles
323
- * tell the agent to continue its task rather than to stop calling tools.
290
+ * The plan is a sub-task inside the agent's own task: it was armed mid-task
291
+ * by intent, not by the prompt, so its directive and its bundles tell the
292
+ * agent to continue its task rather than to stop calling tools.
324
293
  */
325
294
  subTask?: boolean;
326
- /**
327
- * The flattened chain: the steps that will really run, each with the frame it
328
- * runs in (segmented.md 10.6). A chain with no calls flattens to one frame
329
- * and behaves exactly as it did before calls existed, which is why this is
330
- * optional — a caller that does not flatten gets that same single frame.
331
- */
332
- entries?: FlatEntry[];
333
295
  }
334
296
  export declare class ScenarioReplayPlan {
335
297
  readonly scenarioId: string;
@@ -337,8 +299,8 @@ export declare class ScenarioReplayPlan {
337
299
  readonly mode: ReplayMode;
338
300
  readonly intent: string;
339
301
  private readonly scenario;
340
- /** The flat list this plan walks. One entry per step that will really run. */
341
- private readonly entries;
302
+ /** The chain this plan walks. */
303
+ private readonly steps;
342
304
  private paramsPromise;
343
305
  /** The values a step worked out in the recording ({@link FROM_STEP_MARK}). */
344
306
  private readonly fromStep;
@@ -361,65 +323,11 @@ export declare class ScenarioReplayPlan {
361
323
  private readyPromise?;
362
324
  /** Exclusive end of the planned steps. Equal to the chain length unless a step is parked. */
363
325
  private readonly stopAt;
364
- /** This plan is a sub-task inside the agent's own task (segmented.md R-OUT-13). */
326
+ /** This plan is a sub-task inside the agent's own task: it was armed mid-task by intent. */
365
327
  readonly subTask: boolean;
366
- /**
367
- * Where each called frame begins and ends, its callees' entries included:
368
- * where it is entered, its test decided and it is left, and where a
369
- * sub-task its test leaves out ends (AC5).
370
- */
371
- private readonly edges;
372
- /** Each entry's flat position. */
373
- private readonly positions;
374
- /** Every frame of the flat list, by id. */
375
- private readonly frames;
376
- /** The plan's own walk: what its cursor has entered and decided (AC5). */
328
+ /** The plan's own walk: what its cursor has decided (AC5). */
377
329
  private readonly walk;
378
330
  constructor(opts: PlanOptions);
379
- private frameById;
380
- /** The called frames that begin at flat position `flatIndex`, outermost first. */
381
- private framesStartingAt;
382
- /** The caller's own frame — the one at depth 0. */
383
- private rootFrame;
384
- /** The parameters one entry's logic runs with (segmented.md R-CALL-29). */
385
- private paramsFor;
386
- /** The accumulated values one entry's logic runs with. */
387
- private respFor;
388
- /**
389
- * Entering a called frame: build the segment's parameters from the caller's
390
- * state (R-CALL-29).
391
- *
392
- * The recipe is the dry run's, exactly (9.8 step 10): the mapping's output,
393
- * plus the segment's own recorded sample for every *setting* the mapping left
394
- * out. A mapping that omits a setting therefore cannot pass the service's
395
- * check and then run `undefined` here.
396
- */
397
- private enterFramesAt;
398
- private enterFrame;
399
- /**
400
- * Leave every called frame that ends at `flatIndex` and that `walk`
401
- * entered, innermost first: a sub-task whose chain ends with a call is left
402
- * after its callee has handed it its results.
403
- */
404
- private leaveFramesAt;
405
- /**
406
- * After a skip that ends at flat position `last`: leave every entered
407
- * sub-task that ends there — its results still go back to its caller. A
408
- * result mapping that throws ends the walk: its verdict is filed on the
409
- * call row, in the caller's chain, and the stop says the step at `last` was
410
- * left out, not run (`result_map`). Rethrown instead when `rethrow`.
411
- */
412
- private leaveAfterSkip;
413
- /**
414
- * The call row that opened `frame`, as a step of its caller's chain: where
415
- * a sub-task's test and its result mapping are filed (R-CALL-13).
416
- */
417
- private callRowOf;
418
- /**
419
- * Leaving a called frame: hand what the segment emitted back to its caller
420
- * (R-CALL-29). `out` is the frame's own accumulated `respParams`.
421
- */
422
- private leaveFrame;
423
331
  /**
424
332
  * Await the derivation, then apply `paramsLogic` — once, however many callers
425
333
  * race here. A rejected derivation settles on the fallback values
@@ -461,24 +369,12 @@ export declare class ScenarioReplayPlan {
461
369
  get currentStepIndex(): number;
462
370
  /** Steps this plan will run — the chain up to the first known-bad step. */
463
371
  get stepCount(): number;
464
- /** Every step this plan could run, planned or not. */
372
+ /** Every step in the scenario's chain, planned or not. */
465
373
  get totalSteps(): number;
466
374
  /** True when the plan ends in front of a known-bad step (fallbk.md D3). */
467
375
  stopsEarly(): boolean;
468
376
  /** The known-bad step the plan stops in front of, if any. */
469
377
  stopStep(): SerializedScenarioStep | undefined;
470
- /** The entry the plan stops in front of, with the frame that owns it. */
471
- stopEntry(): FlatEntry | undefined;
472
- /**
473
- * The flat position of the chain's decision stop (the service's
474
- * segmentsbreakdown.md SB-18), or -1 when it has none. The steps from there
475
- * on are the half the recording took, whatever stops the plan first.
476
- */
477
- decisionIndex(): number;
478
- /** Every entry in order — for the report, and for the owning scenario ids. */
479
- allEntries(): readonly FlatEntry[];
480
- /** The entry awaiting execution, or undefined when the plan is done. */
481
- currentEntry(): FlatEntry | undefined;
482
378
  /** The parameters in force. Empty until {@link ready} resolves. */
483
379
  get parameters(): Readonly<Record<string, unknown>>;
484
380
  /**
@@ -508,7 +404,7 @@ export declare class ScenarioReplayPlan {
508
404
  expectedTool(): string | undefined;
509
405
  /** True once every planned step has been applied — the plan should be retired. */
510
406
  isDone(): boolean;
511
- /** Every step in order — for the directive, and for coverage reporting. */
407
+ /** Every step in order — for the directive, the report and coverage reporting. */
512
408
  allSteps(): readonly SerializedScenarioStep[];
513
409
  /**
514
410
  * True when `toolName` is one of this scenario's own tools.
@@ -536,21 +432,16 @@ export declare class ScenarioReplayPlan {
536
432
  private inputOf;
537
433
  /** Whether the plan's cursor rests in front of the step it is parked before. */
538
434
  atStop(): boolean;
539
- /**
540
- * The test an entry runs under, in words, when it has one: its own, or that
541
- * of a sub-task beginning at it — one whose chain begins with a call begins
542
- * at its callee's first step.
543
- */
544
- onlyWhen(entry: FlatEntry): {
435
+ /** The test a step runs under, in words, when it has one. */
436
+ onlyWhen(step: SerializedScenarioStep): {
545
437
  text: string | null;
546
438
  } | undefined;
547
439
  /**
548
- * The tool names of the steps from flat position `from` to the end (or to
549
- * `until`, not included), each that runs only under a test marked so — for a
550
- * hand-over note's "remaining planned steps", which must not read as steps
551
- * this request needs.
440
+ * The tool names of the steps from position `from` to the end, each that
441
+ * runs only under a test marked so — for a hand-over note's "remaining
442
+ * planned steps", which must not read as steps this request needs.
552
443
  */
553
- remainingFrom(from: number, until?: number): string[];
444
+ remainingFrom(from: number): string[];
554
445
  /** The steps the plan's own cursor has left out so far, in order (AC5). */
555
446
  leftOut(): readonly LeftOut[];
556
447
  /** Whether any planned step runs only under a test. */
@@ -558,22 +449,16 @@ export declare class ScenarioReplayPlan {
558
449
  /** One test, answered — or the reason it could not be. Never throws. */
559
450
  private answer;
560
451
  /**
561
- * What the tests decide at flat position `flatIndex` for `walk`. Enters the
562
- * position's frame when its own test needs the frame's parameters, and
563
- * nothing else changes: the caller moves its cursor.
452
+ * What the step's test decides at `position` for `walk`. Nothing changes:
453
+ * the caller moves its cursor.
564
454
  */
565
455
  private gate;
566
- /**
567
- * A sub-task's test, decided in its caller's scope at flat position
568
- * `flatIndex`, where the sub-task begins. Undefined when it says yes.
569
- */
570
- private decideCall;
571
456
  /** What a skip the gate decided leaves out, as the notes name it. */
572
457
  private leftOutOf;
573
458
  /**
574
- * Tell a recorded-output source of the steps one skip left out — every step
575
- * of a sub-task left out whole — so its queues pass over the outputs of the
576
- * ones that were in the recording ({@link RecordedOutputFor}).
459
+ * Tell a recorded-output source of a step a test left out, so its queues
460
+ * pass over that step's output when it was in the recording
461
+ * ({@link RecordedOutputFor}).
577
462
  */
578
463
  private passOver;
579
464
  /**
@@ -581,12 +466,8 @@ export declare class ScenarioReplayPlan {
581
466
  * deciding each test as its step comes due (AC5). Stops at a step that will
582
467
  * run, at the end, or at a test that stops the plan — which it returns, with
583
468
  * the steps it left out. The observer is told each verdict as it is made.
584
- * A sub-task whose results cannot go back after its last step was left out
585
- * stops the plan too (`result_map`), its verdict filed on the call row.
586
469
  */
587
- settleTests(onStep?: StepObserver, opts?: {
588
- rethrow?: boolean;
589
- }): {
470
+ settleTests(onStep?: StepObserver): {
590
471
  stop?: PlanStop;
591
472
  left: LeftOut[];
592
473
  };
@@ -605,12 +486,11 @@ export declare class ScenarioReplayPlan {
605
486
  * The arguments each planned step will run with, where they are known before
606
487
  * any step runs — for the steer directive (see {@link steeringDirective}).
607
488
  *
608
- * Known means: the parameters are settled, the step is the caller's own
609
- * (a called segment's parameters are only built when it is entered), and
610
- * its input logic neither reads nor passes on anything an earlier step
611
- * accumulates — or it is the step at the cursor, whose accumulation is
612
- * already final. Everything else is undefined, and the directive leaves
613
- * those steps' arguments to the system.
489
+ * Known means: the parameters are settled, and the step's input logic
490
+ * neither reads nor passes on anything an earlier step accumulates — or it
491
+ * is the step at the cursor, whose accumulation is already final.
492
+ * Everything else is undefined, and the directive leaves those steps'
493
+ * arguments to the system.
614
494
  *
615
495
  * A look-ahead only: every body runs on copies, under a short limit, and a
616
496
  * body that throws or runs long just leaves its step without arguments —