@basein/runner 0.3.8 → 0.3.10
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 +46 -5
- package/dist/auth/client.d.ts +15 -0
- package/dist/auth/client.js +34 -12
- package/dist/bin/bir-hooks.d.ts +1 -1
- package/dist/bin/bir-hooks.js +1 -1
- package/dist/bin/bir.d.ts +2 -0
- package/dist/bin/bir.js +60 -6
- package/dist/bin/investigate.d.ts +5 -0
- package/dist/bin/investigate.js +117 -15
- package/dist/bin/setup.d.ts +12 -0
- package/dist/bin/setup.js +185 -56
- package/dist/bin/update.d.ts +81 -0
- package/dist/bin/update.js +194 -0
- package/dist/config/adapters/claude-code.d.ts +17 -0
- package/dist/config/adapters/claude-code.js +28 -1
- package/dist/config/generate.d.ts +14 -0
- package/dist/control/daemon.d.ts +26 -1
- package/dist/control/daemon.js +53 -3
- package/dist/control/pin-guard.d.ts +6 -1
- package/dist/control/pin-guard.js +15 -1
- package/dist/control/recorder-keeper.js +2 -1
- package/dist/control/server.d.ts +200 -2
- package/dist/control/server.js +741 -48
- package/dist/control/transcript.d.ts +4 -0
- package/dist/control/transcript.js +4 -0
- package/dist/proxy/session.js +1 -0
- package/dist/record/housekeeping.d.ts +7 -1
- package/dist/record/housekeeping.js +11 -3
- package/dist/record/recorder.d.ts +34 -0
- package/dist/record/remote-recorder.d.ts +14 -0
- package/dist/record/remote-recorder.js +107 -13
- package/dist/record/switchable-recorder.js +1 -0
- package/dist/record/truncate.d.ts +11 -0
- package/dist/record/truncate.js +11 -0
- package/dist/replay/controller.d.ts +146 -4
- package/dist/replay/controller.js +340 -31
- package/dist/replay/derive.js +2 -0
- package/dist/replay/handover.d.ts +13 -1
- package/dist/replay/handover.js +19 -0
- package/dist/replay/plan.d.ts +6 -0
- package/dist/replay/plan.js +13 -3
- package/dist/replay/safety.d.ts +15 -4
- package/dist/replay/safety.js +19 -6
- package/dist/replay/source-run.js +2 -1
- package/dist/replay/types.d.ts +16 -0
- package/dist/util/service-headers.d.ts +24 -0
- package/dist/util/service-headers.js +47 -0
- package/docs/BaseInstRunner.md +115 -1
- package/docs/calculatedReplay.md +239 -27
- package/docs/calculatedReplayGuide.md +134 -12
- package/docs/installRun.md +91 -10
- package/docs/quickstart.md +64 -9
- package/package.json +1 -1
- package/production.md +81 -16
- package/scripts/install.ps1 +25 -1
package/dist/control/server.d.ts
CHANGED
|
@@ -83,7 +83,58 @@ export interface HookPayload {
|
|
|
83
83
|
* only. See {@link ControlServer.offSessions}.
|
|
84
84
|
*/
|
|
85
85
|
bir_off?: unknown;
|
|
86
|
+
/**
|
|
87
|
+
* Which host the session runs in. An adapter sends it with every request,
|
|
88
|
+
* so a recorder that restarted in the middle of a run still learns it; the
|
|
89
|
+
* session keeps the first one (see {@link hostOf}).
|
|
90
|
+
*/
|
|
91
|
+
host?: {
|
|
92
|
+
app?: unknown;
|
|
93
|
+
version?: unknown;
|
|
94
|
+
adapter?: unknown;
|
|
95
|
+
scope?: unknown;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* With `/session/prompt`: the adapter can step through a plan, and asks
|
|
99
|
+
* for one. An adapter that only records never sends it, and no plan is
|
|
100
|
+
* started for its run.
|
|
101
|
+
*/
|
|
102
|
+
replay?: unknown;
|
|
103
|
+
/** With `/session/prompt`: the host's tools whose input is run, or written into a file. */
|
|
104
|
+
sinks?: {
|
|
105
|
+
command?: unknown;
|
|
106
|
+
write?: unknown;
|
|
107
|
+
};
|
|
108
|
+
/** With `/tool/pre`: what the model wrote before the call. */
|
|
109
|
+
context?: unknown;
|
|
110
|
+
/** With `/tool/pre`: what the model reasoned before the call. */
|
|
111
|
+
thinking?: unknown;
|
|
112
|
+
/**
|
|
113
|
+
* The adapter's own call for a step of the plan, not the model's: on the
|
|
114
|
+
* `/tool/pre` that asks for the step's arguments, and on the `/tool/post`
|
|
115
|
+
* that brings its result.
|
|
116
|
+
*/
|
|
117
|
+
scripted?: unknown;
|
|
118
|
+
/** With the first scripted `/tool/pre` of a run: the tools the agent holds. */
|
|
119
|
+
tools?: unknown;
|
|
120
|
+
/** With a scripted `/tool/post`: the host stopped the step itself (`rejected`, `edited`). */
|
|
121
|
+
host_stop?: unknown;
|
|
122
|
+
/** With `/session/stop`: the run's final answer. */
|
|
123
|
+
final_answer?: unknown;
|
|
124
|
+
/** With `/session/stop`: the tokens the run's model calls used, per model, under Claude's own names. */
|
|
125
|
+
usage?: unknown;
|
|
126
|
+
/** With `/session/stop`: the run failed, and why. */
|
|
127
|
+
failed?: unknown;
|
|
128
|
+
/** With `/session/stop`: the recording is not the whole run, and why. */
|
|
129
|
+
incomplete?: unknown;
|
|
86
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* What `/health` answers as `hostFields`: how much of another host's protocol
|
|
133
|
+
* this recorder understands. An adapter reads it to know which fields it may
|
|
134
|
+
* rely on — with 1 it records; from 2 it may also ask for a plan and step
|
|
135
|
+
* through it, because the checks a replay in another host needs are here.
|
|
136
|
+
*/
|
|
137
|
+
export declare const HOST_FIELDS = 2;
|
|
87
138
|
export interface ControlServerOptions {
|
|
88
139
|
recorder: Recorder;
|
|
89
140
|
/**
|
|
@@ -296,6 +347,13 @@ export declare class ControlServer {
|
|
|
296
347
|
* SessionStart.
|
|
297
348
|
*/
|
|
298
349
|
private readonly offSessions;
|
|
350
|
+
/**
|
|
351
|
+
* Sessions of another host that named a scope the recorder cannot keep as
|
|
352
|
+
* it is (see {@link badScope}) → when last heard. Nothing of such a session
|
|
353
|
+
* is recorded or replayed: every hook of it is answered `{}`. Kept apart
|
|
354
|
+
* from {@link sessions}, so it never holds a run or takes a proxy's step.
|
|
355
|
+
*/
|
|
356
|
+
private readonly refusedSessions;
|
|
299
357
|
/**
|
|
300
358
|
* Proxy ids that registered with *this* recorder (UPG-7). A poll from any
|
|
301
359
|
* other id is a proxy from before this recorder started — a 0.2.12 proxy
|
|
@@ -434,6 +492,18 @@ export declare class ControlServer {
|
|
|
434
492
|
private sessionOff;
|
|
435
493
|
/** Mark `sessionId` off (see {@link sessionOff}), sealing whatever it had open. */
|
|
436
494
|
private markSessionOff;
|
|
495
|
+
/**
|
|
496
|
+
* Whether this hook belongs to a session of another host whose scope the
|
|
497
|
+
* recorder cannot keep as it is (see {@link badScope}), and so is answered
|
|
498
|
+
* `{}` unprocessed — every hook of it, like a session that is off. One
|
|
499
|
+
* line says so, once for the session.
|
|
500
|
+
*
|
|
501
|
+
* A session that already has a host keeps it: a later payload cannot turn
|
|
502
|
+
* a run that is being recorded into one that is not.
|
|
503
|
+
*/
|
|
504
|
+
private hostRefused;
|
|
505
|
+
/** Flag every run open right now as having lost steps (see `RunState.lossy`). */
|
|
506
|
+
private markOpenRunsLossy;
|
|
437
507
|
/** Whether `sessionId` is a session started with `BIR_OFF=1`. */
|
|
438
508
|
private isSessionOff;
|
|
439
509
|
/** The route's hook deadline, or undefined when `route` is not a hook this recorder serves. */
|
|
@@ -492,7 +562,12 @@ export declare class ControlServer {
|
|
|
492
562
|
reap(now?: number): void;
|
|
493
563
|
/** Drop a session and everything keyed on it. Its last run was sealed and drained already. */
|
|
494
564
|
private forgetSession;
|
|
495
|
-
/**
|
|
565
|
+
/**
|
|
566
|
+
* Open a run for `session`, or return the open one.
|
|
567
|
+
*
|
|
568
|
+
* `asked` is what the prompt that opens the run asked for, in a session of
|
|
569
|
+
* another host: whether its adapter wants a plan (`HookPayload.replay`).
|
|
570
|
+
*/
|
|
496
571
|
private ensureRun;
|
|
497
572
|
private runMetadata;
|
|
498
573
|
/**
|
|
@@ -589,6 +664,41 @@ export declare class ControlServer {
|
|
|
589
664
|
private refreshDeliveryTool;
|
|
590
665
|
/** `arming`, never rejecting: a broken arm is logged and is no plan at all. */
|
|
591
666
|
private armOrLog;
|
|
667
|
+
/**
|
|
668
|
+
* Whether `run` only records: a run of another host whose adapter did not
|
|
669
|
+
* ask for a plan with its prompt. Treated as a run with replay off in the
|
|
670
|
+
* three places that ask (`onPrompt`, `armFromMatch`, `tryIntentMatch`).
|
|
671
|
+
*
|
|
672
|
+
* An adapter that only records never sends `replay`. Without this the
|
|
673
|
+
* recorder would start a plan for every prompt that matches one, read the
|
|
674
|
+
* model's own calls against it, and book a replay nobody ran. A run another
|
|
675
|
+
* hook opened carries no flag either, and only records.
|
|
676
|
+
*/
|
|
677
|
+
private recordsOnly;
|
|
678
|
+
/**
|
|
679
|
+
* What {@link ReplayController.arm} is told of `session` when its host is
|
|
680
|
+
* not Claude Code, and undefined when it is.
|
|
681
|
+
*/
|
|
682
|
+
private hostContext;
|
|
683
|
+
/**
|
|
684
|
+
* The earlier tool results the reading of new values may look at: this
|
|
685
|
+
* prompt's own, from the transcript — and so none for a plan that is
|
|
686
|
+
* started at the prompt (segmented.md R-PARAM-2a).
|
|
687
|
+
*
|
|
688
|
+
* `at` is where the plan is being started, and at the prompt a transcript
|
|
689
|
+
* has nothing to give. The prompt was only just submitted, so it has no
|
|
690
|
+
* results of its own; and the transcript does not hold it yet, so what the
|
|
691
|
+
* transcript calls "this prompt's results" are still the *previous*
|
|
692
|
+
* prompt's. They used to be sent as this task's, and they answered for it:
|
|
693
|
+
* a second prompt that named one person ran on the person the first
|
|
694
|
+
* prompt's results were full of.
|
|
695
|
+
*
|
|
696
|
+
* A session of another host has no transcript, and a plan starts there at
|
|
697
|
+
* the prompt only: none either. Its adapter used to hand the conversation's
|
|
698
|
+
* earlier results over with the prompt (`recent_results`) — the same
|
|
699
|
+
* mistake, made on purpose. An adapter that still sends them is not read.
|
|
700
|
+
*/
|
|
701
|
+
private recentResultsFor;
|
|
592
702
|
/**
|
|
593
703
|
* The prompt hook answered without a directive: retire any prompt-armed plan
|
|
594
704
|
* of `run` that could still steer. `armFromMatch` arms one live only while
|
|
@@ -616,6 +726,9 @@ export declare class ControlServer {
|
|
|
616
726
|
* routinely left half-open, which is what happened in practice.
|
|
617
727
|
*
|
|
618
728
|
* Idempotent: the second caller sees `finished` and does nothing.
|
|
729
|
+
*
|
|
730
|
+
* `reason` says why the run is closed. It decides something only in a
|
|
731
|
+
* session of another host (see {@link CloseReason}).
|
|
619
732
|
*/
|
|
620
733
|
private sealRun;
|
|
621
734
|
/**
|
|
@@ -640,7 +753,14 @@ export declare class ControlServer {
|
|
|
640
753
|
* false` and zero rather than a number that is confidently wrong.
|
|
641
754
|
*/
|
|
642
755
|
private runCost;
|
|
643
|
-
/**
|
|
756
|
+
/**
|
|
757
|
+
* What a run of another host cost, from the tokens its adapter handed over
|
|
758
|
+
* with the stop. Measured only when at least one entry has tokens and every
|
|
759
|
+
* model in the list has a price; with no usage at all, not measured — and
|
|
760
|
+
* one `run.unmeasured` line says which.
|
|
761
|
+
*/
|
|
762
|
+
private hostCost;
|
|
763
|
+
/** Transcript cost since `mark`; unmeasured (and zero) without one, or with a model that has no price. */
|
|
644
764
|
private costSince;
|
|
645
765
|
private reportExecution;
|
|
646
766
|
/**
|
|
@@ -691,6 +811,68 @@ export declare class ControlServer {
|
|
|
691
811
|
* still running when the deadline passes — see {@link replayOverran}.
|
|
692
812
|
*/
|
|
693
813
|
private onToolPre;
|
|
814
|
+
/**
|
|
815
|
+
* `/tool/pre` in a session whose host is not Claude Code — a LangChain
|
|
816
|
+
* application, say (the service's integratioLangChane.md). Two kinds of
|
|
817
|
+
* request, told apart by `scripted`:
|
|
818
|
+
*
|
|
819
|
+
* - **The adapter asks for the plan's next step** (`scripted: true`). It
|
|
820
|
+
* is answering in the model's place and wants the step's arguments; the
|
|
821
|
+
* host then runs its own tool with them. See {@link onScriptedPre}.
|
|
822
|
+
* - **The model's own call.** Recorded, never pinned. See {@link onOwnPre}.
|
|
823
|
+
*
|
|
824
|
+
* ONLY A PROMPT OPENS A RUN for such a host. A hook that finds none open
|
|
825
|
+
* opens none and answers `{}`: the run failed and its adapter closed it,
|
|
826
|
+
* or the two-hour limit sealed it, or the recorder restarted under it. What
|
|
827
|
+
* arrives afterwards — the application going on from its checkpoint, a
|
|
828
|
+
* retry middleware trying the call again — must not become a second
|
|
829
|
+
* recording with an empty prompt.
|
|
830
|
+
*/
|
|
831
|
+
private onHostToolPre;
|
|
832
|
+
/**
|
|
833
|
+
* The adapter of another host asks for the plan's next step. The answer
|
|
834
|
+
* either pins the call — `allow`, with the step's computed arguments — or
|
|
835
|
+
* carries no pin, which ends the plan for the adapter. It then says why:
|
|
836
|
+
*
|
|
837
|
+
* - `noPlan`: the recorder holds no live plan for the run. It ran to its
|
|
838
|
+
* end, was handed over, or the recorder restarted while the run waited
|
|
839
|
+
* for a person. Nothing is recorded: no call follows this request.
|
|
840
|
+
* - `declined`: the plan names a tool the agent does not hold.
|
|
841
|
+
* - a refusal whose reason is the hand-over note, when the plan stopped
|
|
842
|
+
* in this very request.
|
|
843
|
+
*/
|
|
844
|
+
private onScriptedPre;
|
|
845
|
+
/**
|
|
846
|
+
* The first tool the plan will call that the agent does not hold, or
|
|
847
|
+
* undefined when it holds them all — or did not say which it holds.
|
|
848
|
+
*/
|
|
849
|
+
private missingHostTool;
|
|
850
|
+
/**
|
|
851
|
+
* The model's own call, in a session of another host: any `/tool/pre`
|
|
852
|
+
* without `scripted`.
|
|
853
|
+
*
|
|
854
|
+
* NEVER PINNED, and never answered with a bundle. In Claude Code a call to
|
|
855
|
+
* the plan's next tool is pinned, because there the model is the one who
|
|
856
|
+
* makes the plan's calls. Here the adapter makes them, so a call the model
|
|
857
|
+
* made is the model's whatever tool it names: answered with the plan's
|
|
858
|
+
* arguments, the tool would run with arguments the model never wrote, and
|
|
859
|
+
* the model would read a result that does not belong to the call it sees.
|
|
860
|
+
*
|
|
861
|
+
* A plan that is still live is handed over. The call runs as the model
|
|
862
|
+
* wrote it — the note is not given in its place — and the note goes out
|
|
863
|
+
* with this call's `/tool/post`. The recording of the model's own work
|
|
864
|
+
* after the hand-over (the fragment) opens with this very call: opened one
|
|
865
|
+
* call later, the call that left the plan would be in no recording.
|
|
866
|
+
*/
|
|
867
|
+
private onOwnPre;
|
|
868
|
+
/**
|
|
869
|
+
* What the model wrote and reasoned before a call, as its host handed it
|
|
870
|
+
* over with the call — the values {@link intentForToolUse} and
|
|
871
|
+
* {@link thinkingForToolUse} read from a transcript, under the same switch:
|
|
872
|
+
* a source `BIR_INTENT_SOURCES` turned off is not taken from the payload
|
|
873
|
+
* either. `context` is the written text only; thinking rides apart.
|
|
874
|
+
*/
|
|
875
|
+
private hostWords;
|
|
694
876
|
/** This run's plan, when it is armed, still live, and announced to the model. */
|
|
695
877
|
private livePlan;
|
|
696
878
|
/** Whether a `run_scenario` pre for `state` is still waiting for its `/scenario/run`. */
|
|
@@ -888,6 +1070,22 @@ export declare class ControlServer {
|
|
|
888
1070
|
*/
|
|
889
1071
|
private onAgent;
|
|
890
1072
|
private onStop;
|
|
1073
|
+
/**
|
|
1074
|
+
* Keep what another host handed over with its stop — on the run, not on the
|
|
1075
|
+
* session: a later prompt of the session opens a new run, which must not
|
|
1076
|
+
* inherit an answer or a cost. Returns why the run is closed.
|
|
1077
|
+
*
|
|
1078
|
+
* - `final_answer`, `usage`: the answer and the tokens (see `sealRun`,
|
|
1079
|
+
* `hostCost`).
|
|
1080
|
+
* - `incomplete`: the recording is not the whole run — the adapter lost
|
|
1081
|
+
* calls, a person changed one, or one was answered in its tool's place.
|
|
1082
|
+
* The run is flagged lossy, so its finish carries the service's mark; the
|
|
1083
|
+
* mark has no place for a text, which goes to the log only.
|
|
1084
|
+
* - `failed`: the run failed. It is closed with that text as its error
|
|
1085
|
+
* and no final answer. An exception's text can hold a password or a
|
|
1086
|
+
* user's data: it is cleaned and cut like every text that is sent.
|
|
1087
|
+
*/
|
|
1088
|
+
private noteHostStop;
|
|
891
1089
|
/**
|
|
892
1090
|
* `SessionEnd` — `/clear`, exit, logout. Answered at once: the host is
|
|
893
1091
|
* waiting on it to exit, and this process outlives the session, so the run
|