pi-harness-runtime 1.1.452 → 1.1.454
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/AGENTS.md +32 -3
- package/CHANGELOG.md +57 -0
- package/index.ts +76 -0
- package/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/dist/batch-plan.d.ts +150 -0
- package/packages/jev-judge/dist/batch-plan.d.ts.map +1 -0
- package/packages/jev-judge/dist/batch-plan.js +192 -0
- package/packages/jev-judge/dist/batch-plan.js.map +1 -0
- package/packages/jev-judge/dist/delegation-harness.d.ts +20 -0
- package/packages/jev-judge/dist/delegation-harness.d.ts.map +1 -1
- package/packages/jev-judge/dist/delegation-harness.js +64 -2
- package/packages/jev-judge/dist/delegation-harness.js.map +1 -1
- package/packages/jev-judge/dist/delegation-observer.d.ts +98 -0
- package/packages/jev-judge/dist/delegation-observer.d.ts.map +1 -0
- package/packages/jev-judge/dist/delegation-observer.js +152 -0
- package/packages/jev-judge/dist/delegation-observer.js.map +1 -0
- package/packages/jev-judge/dist/index.d.ts +4 -0
- package/packages/jev-judge/dist/index.d.ts.map +1 -1
- package/packages/jev-judge/dist/index.js +4 -0
- package/packages/jev-judge/dist/index.js.map +1 -1
- package/packages/jev-judge/dist/pilot.d.ts +127 -0
- package/packages/jev-judge/dist/pilot.d.ts.map +1 -0
- package/packages/jev-judge/dist/pilot.js +178 -0
- package/packages/jev-judge/dist/pilot.js.map +1 -0
- package/packages/jev-judge/dist/validation-plan.d.ts +18 -0
- package/packages/jev-judge/dist/validation-plan.d.ts.map +1 -1
- package/packages/jev-judge/dist/validation-plan.js +93 -4
- package/packages/jev-judge/dist/validation-plan.js.map +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/jev-judge/src/batch-plan.ts +273 -0
- package/packages/jev-judge/src/delegation-harness.ts +83 -2
- package/packages/jev-judge/src/delegation-observer.ts +181 -0
- package/packages/jev-judge/src/index.ts +36 -0
- package/packages/jev-judge/src/pilot.ts +257 -0
- package/packages/jev-judge/src/validation-plan.ts +110 -4
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/tooling-preference/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/two-phase-review/dist/classify.d.ts +4 -0
- package/packages/two-phase-review/dist/classify.d.ts.map +1 -1
- package/packages/two-phase-review/dist/classify.js +5 -0
- package/packages/two-phase-review/dist/classify.js.map +1 -1
- package/packages/two-phase-review/dist/rules.d.ts +32 -2
- package/packages/two-phase-review/dist/rules.d.ts.map +1 -1
- package/packages/two-phase-review/dist/rules.js +56 -14
- package/packages/two-phase-review/dist/rules.js.map +1 -1
- package/packages/two-phase-review/dist/runtime.d.ts +8 -0
- package/packages/two-phase-review/dist/runtime.d.ts.map +1 -1
- package/packages/two-phase-review/dist/runtime.js +56 -7
- package/packages/two-phase-review/dist/runtime.js.map +1 -1
- package/packages/two-phase-review/package.json +1 -1
- package/packages/two-phase-review/src/classify.ts +9 -0
- package/packages/two-phase-review/src/rules.ts +77 -13
- package/packages/two-phase-review/src/runtime.ts +65 -6
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/write-review/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -46,8 +46,21 @@ A task with a cheap tier and an expensive tier MUST use the cheap tier while the
|
|
|
46
46
|
{
|
|
47
47
|
"metadata": {
|
|
48
48
|
"validationPlan": {
|
|
49
|
-
"fast": {
|
|
50
|
-
|
|
49
|
+
"fast": {
|
|
50
|
+
"command": "bun test tests/fast",
|
|
51
|
+
"expectedDurationMs": 18000,
|
|
52
|
+
"datasetSize": 100,
|
|
53
|
+
"owner": "the agent that runs the validation",
|
|
54
|
+
"passCriteria": ["every record is written once", "the counts of source and target match"],
|
|
55
|
+
"failureAction": "stop the job and report the failure of the pilot"
|
|
56
|
+
},
|
|
57
|
+
"full": {
|
|
58
|
+
"command": "bun test tests/full",
|
|
59
|
+
"expectedDurationMs": 2400000,
|
|
60
|
+
"datasetSize": 10000,
|
|
61
|
+
"owner": "the agent that runs the validation",
|
|
62
|
+
"scaleUpFrom": "fast"
|
|
63
|
+
},
|
|
51
64
|
"budgetMinutes": 90,
|
|
52
65
|
"finalTierRequired": true
|
|
53
66
|
}
|
|
@@ -57,6 +70,8 @@ A task with a cheap tier and an expensive tier MUST use the cheap tier while the
|
|
|
57
70
|
|
|
58
71
|
The harness never guesses a tier from a command string. Without a declared plan the current behaviour is unchanged.
|
|
59
72
|
|
|
73
|
+
A tier that declares `scaleUpFrom: "fast"` is the scale-up of a large job: it only counts when the fast tier passed. The fast tier of such a plan is the representative pilot and declares `"representative": true`.
|
|
74
|
+
|
|
60
75
|
2. **Iterate on the fast tier.** After every code edit, rerun the fast tier plus the focused unit/type checks the edit touches.
|
|
61
76
|
|
|
62
77
|
3. **Run the full tier once.** Run the full tier as the final acceptance check, when the implementation and the fast tier are stable.
|
|
@@ -71,7 +86,9 @@ A task with a cheap tier and an expensive tier MUST use the cheap tier while the
|
|
|
71
86
|
|
|
72
87
|
8. **The fast tier must be representative.** A small fixture keeps the shape of the data (optional fields, relations, uniqueness, boundary values, aggregates under test), not just the row count. Use deterministic data with cleanup so repeated runs do not accumulate rows.
|
|
73
88
|
|
|
74
|
-
9. **
|
|
89
|
+
9. **A large job starts with a measured pilot.** The pilot is the fast tier: it runs over a representative subset (100 records when that is safe) and it is measured, not assumed. The scale-up only starts when the pilot passed, the pilot ran on the declared number of records, and the run stayed inside the budget. A pilot that fails stops the job: report the finding instead of scaling up. The batches of a scale-up are bounded and explicit (`packages/jev-judge/src/batch-plan.ts`), a failed batch is retried instead of restarting the job, and the concurrency limit is always a declared number.
|
|
90
|
+
|
|
91
|
+
10. **Record every tier run in the ledger.** The harness never runs the tests, so the run is recorded by whoever knows the result:
|
|
75
92
|
|
|
76
93
|
```bash
|
|
77
94
|
bun scripts/validation-run.ts --item 12 --tier fast --status passed --duration 18s --dataset 100
|
|
@@ -83,6 +100,8 @@ A task with a cheap tier and an expensive tier MUST use the cheap tier while the
|
|
|
83
100
|
**What the harness does with the plan:**
|
|
84
101
|
|
|
85
102
|
- The continuation message carries the plan, the recorded tier state and the remaining budget, so the agent never re-runs a tier that already passed.
|
|
103
|
+
- A scale-up that ran before its pilot passed does not count: the final tier stays pending and the task stays open.
|
|
104
|
+
- The status line names the phase, the progress, the validation state and the children that really ran.
|
|
86
105
|
- When `budgetMinutes` is spent, the item pauses at a safe boundary: nothing is dispatched, the work stays open, and the reason is reported.
|
|
87
106
|
- When a todo with `finalTierRequired` is marked complete while that tier is pending or failed, the completion report is suppressed and the item is named instead. A todo may not be reported as done on the strength of an unreported run.
|
|
88
107
|
|
|
@@ -353,6 +372,16 @@ todo create "Replace Film icon with themed icon"
|
|
|
353
372
|
|
|
354
373
|
**IMPORTANT**: The `todo` tool and `bd` commands are DIFFERENT systems. Use `todo` for local task tracking.
|
|
355
374
|
|
|
375
|
+
**Who owns the todo list.** The **agent** creates the todos, the harness
|
|
376
|
+
only reads them. Two consequences:
|
|
377
|
+
|
|
378
|
+
- The kind of a todo is read from `metadata.kind` first and from the title
|
|
379
|
+
prefix second. An explicit kind is more reliable than a prefix, and the
|
|
380
|
+
agent can always set it.
|
|
381
|
+
- When the todo provider is not available, the harness says so: the status
|
|
382
|
+
line reads `[?] TODOS unavailable` and the agent is told that the phase
|
|
383
|
+
gate is not active. The harness never claims a gate it cannot enforce.
|
|
384
|
+
|
|
356
385
|
---
|
|
357
386
|
|
|
358
387
|
## Phase Model: Implementation, Review, Validation (CRITICAL)
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.1.454](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.448...v1.1.454) (2026-10-27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **delegation:** a child is only a child when it really ran ([ac4e678](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ac4e6782d7d4bc4941e458425c8a9f38a51fc9d4))
|
|
11
|
+
* **delegation:** the scope of a request is measured before it is judged ([684b6a5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/684b6a55184f63d3be24c48dcecfb0b13410dc15))
|
|
12
|
+
* **jev:** the pending question carries the ask and the answer ([a792133](https://github.com/ManotLuijiu/pi-harness-runtime/commit/a792133e517fb8c12d3363e98942f3af30270f27))
|
|
13
|
+
* **merge:** a manual run can leave the merge to the pull request event ([b3d1950](https://github.com/ManotLuijiu/pi-harness-runtime/commit/b3d1950b5941c78ccd56951acdafd1d4afbe1bff))
|
|
14
|
+
* **phase:** the agent owns the todo list and the harness says so ([c489370](https://github.com/ManotLuijiu/pi-harness-runtime/commit/c489370bd7926aece8cb1a77aa20ca2d2672f1fb))
|
|
15
|
+
* **review:** the review starts on its own when the implementation is done ([04f51f5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/04f51f599cd3222b6c74dd8fadb1373bd72d9bd7))
|
|
16
|
+
* **status:** the status line names the phase, the progress and the children ([0167bf3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/0167bf396a0b987c1d44f3b869351976a951dd65))
|
|
17
|
+
* **test:** the task waits for the final tier of the validation plan ([fa147db](https://github.com/ManotLuijiu/pi-harness-runtime/commit/fa147dbf7d50d56e6ea48c6d8fbb4fcb190caf8a))
|
|
18
|
+
* **validation:** a large job starts with a measured pilot ([425964b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/425964b04a3d4fa02adfabed47ff62c5ec2b9c28))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **hooks:** a tag is checked through the commit behind it ([c823e8e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/c823e8e1f6973c62b5449a97c101759a4d5cbba5))
|
|
24
|
+
* **jev:** the alternatives of a question are parsed without a quadratic pattern ([63016a3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/63016a3f0488acb801990dd46770c00d382b5858))
|
|
25
|
+
* **keys:** the key directory is audited as a tree ([081cc75](https://github.com/ManotLuijiu/pi-harness-runtime/commit/081cc75ac8ceff36b0d619c3f76371dc08459d3c))
|
|
26
|
+
* **merge:** the boolean input is read as a boolean ([971b716](https://github.com/ManotLuijiu/pi-harness-runtime/commit/971b7169a43db382dbdeb6bb9bab02ab56e0351c))
|
|
27
|
+
* **merge:** the manual job needs the right of the merge ([7ba685e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/7ba685ec43d815f90aa35b742579e87e76c69209))
|
|
28
|
+
* **merge:** the merge of the pull request is the GraphQL mutation ([972bab4](https://github.com/ManotLuijiu/pi-harness-runtime/commit/972bab4b0f7faf1b0047f3bb767ef6db3de4b2fa))
|
|
29
|
+
* **merge:** the workflow merges the pull request the gates cleared ([d7639ec](https://github.com/ManotLuijiu/pi-harness-runtime/commit/d7639ec9b83723510acb4a5c4e23d5d6167c3af6))
|
|
30
|
+
* **release:** a manual release keeps the version of its manifest ([122e661](https://github.com/ManotLuijiu/pi-harness-runtime/commit/122e661ea48cb8aff14c71dbd0221a4cf0ba4c8e))
|
|
31
|
+
* **release:** the release pull request names the version of its branch ([a846e83](https://github.com/ManotLuijiu/pi-harness-runtime/commit/a846e83e6de6e529f4bca05e869db0b5eebb37c5))
|
|
32
|
+
* **release:** the release scans the tree of the commit it publishes ([7d47a0b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/7d47a0b5406480a1e1d3a52623a76aabd1e2d0ba))
|
|
33
|
+
|
|
34
|
+
### [1.1.453](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.448...v1.1.453) (2026-10-27)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
* **delegation:** a child is only a child when it really ran ([ac4e678](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ac4e6782d7d4bc4941e458425c8a9f38a51fc9d4))
|
|
40
|
+
* **delegation:** the scope of a request is measured before it is judged ([684b6a5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/684b6a55184f63d3be24c48dcecfb0b13410dc15))
|
|
41
|
+
* **jev:** the pending question carries the ask and the answer ([a792133](https://github.com/ManotLuijiu/pi-harness-runtime/commit/a792133e517fb8c12d3363e98942f3af30270f27))
|
|
42
|
+
* **merge:** a manual run can leave the merge to the pull request event ([b3d1950](https://github.com/ManotLuijiu/pi-harness-runtime/commit/b3d1950b5941c78ccd56951acdafd1d4afbe1bff))
|
|
43
|
+
* **phase:** the agent owns the todo list and the harness says so ([c489370](https://github.com/ManotLuijiu/pi-harness-runtime/commit/c489370bd7926aece8cb1a77aa20ca2d2672f1fb))
|
|
44
|
+
* **review:** the review starts on its own when the implementation is done ([04f51f5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/04f51f599cd3222b6c74dd8fadb1373bd72d9bd7))
|
|
45
|
+
* **status:** the status line names the phase, the progress and the children ([0167bf3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/0167bf396a0b987c1d44f3b869351976a951dd65))
|
|
46
|
+
* **test:** the task waits for the final tier of the validation plan ([fa147db](https://github.com/ManotLuijiu/pi-harness-runtime/commit/fa147dbf7d50d56e6ea48c6d8fbb4fcb190caf8a))
|
|
47
|
+
* **validation:** a large job starts with a measured pilot ([425964b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/425964b04a3d4fa02adfabed47ff62c5ec2b9c28))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* **hooks:** a tag is checked through the commit behind it ([c823e8e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/c823e8e1f6973c62b5449a97c101759a4d5cbba5))
|
|
53
|
+
* **jev:** the alternatives of a question are parsed without a quadratic pattern ([63016a3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/63016a3f0488acb801990dd46770c00d382b5858))
|
|
54
|
+
* **keys:** the key directory is audited as a tree ([081cc75](https://github.com/ManotLuijiu/pi-harness-runtime/commit/081cc75ac8ceff36b0d619c3f76371dc08459d3c))
|
|
55
|
+
* **merge:** the boolean input is read as a boolean ([971b716](https://github.com/ManotLuijiu/pi-harness-runtime/commit/971b7169a43db382dbdeb6bb9bab02ab56e0351c))
|
|
56
|
+
* **merge:** the manual job needs the right of the merge ([7ba685e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/7ba685ec43d815f90aa35b742579e87e76c69209))
|
|
57
|
+
* **merge:** the merge of the pull request is the GraphQL mutation ([972bab4](https://github.com/ManotLuijiu/pi-harness-runtime/commit/972bab4b0f7faf1b0047f3bb767ef6db3de4b2fa))
|
|
58
|
+
* **merge:** the workflow merges the pull request the gates cleared ([d7639ec](https://github.com/ManotLuijiu/pi-harness-runtime/commit/d7639ec9b83723510acb4a5c4e23d5d6167c3af6))
|
|
59
|
+
* **release:** a manual release keeps the version of its manifest ([122e661](https://github.com/ManotLuijiu/pi-harness-runtime/commit/122e661ea48cb8aff14c71dbd0221a4cf0ba4c8e))
|
|
60
|
+
* **release:** the release scans the tree of the commit it publishes ([7d47a0b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/7d47a0b5406480a1e1d3a52623a76aabd1e2d0ba))
|
|
61
|
+
|
|
5
62
|
### [1.1.452](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.448...v1.1.452) (2026-10-27)
|
|
6
63
|
|
|
7
64
|
|
package/index.ts
CHANGED
|
@@ -557,11 +557,35 @@ async function initTwoPhaseReview(pi: ExtensionAPI): Promise<void> {
|
|
|
557
557
|
return { available: true, pendingFinalTier, failedFinalTier, incompletePlan };
|
|
558
558
|
};
|
|
559
559
|
|
|
560
|
+
/**
|
|
561
|
+
* The delegation state of the session.
|
|
562
|
+
*
|
|
563
|
+
* The numbers are the observed ones: the children that really ran and
|
|
564
|
+
* the groups the harness measured. A plan that was never dispatched
|
|
565
|
+
* shows zero dispatched children.
|
|
566
|
+
*/
|
|
567
|
+
const readDelegation = () => {
|
|
568
|
+
const harness = sharedState.delegationHarness as
|
|
569
|
+
| import("./packages/jev-judge/dist/delegation-harness.js").DelegationHarness
|
|
570
|
+
| null
|
|
571
|
+
| undefined;
|
|
572
|
+
if (!harness) return undefined;
|
|
573
|
+
try {
|
|
574
|
+
const receipt = harness.getReceipt();
|
|
575
|
+
const groups = receipt?.decision.workGroups?.length ?? 0;
|
|
576
|
+
const dispatched = harness.getChildren().length;
|
|
577
|
+
return { groups, dispatched };
|
|
578
|
+
} catch {
|
|
579
|
+
return undefined;
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
|
|
560
583
|
try {
|
|
561
584
|
await mod.initTwoPhaseReview({
|
|
562
585
|
pi,
|
|
563
586
|
readTodos,
|
|
564
587
|
readValidation,
|
|
588
|
+
readDelegation,
|
|
565
589
|
workspaceRoot: () => {
|
|
566
590
|
try {
|
|
567
591
|
return realpathSync(process.cwd());
|
|
@@ -903,6 +927,58 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
|
903
927
|
logToFile("[Delegation]", "The delegation steer failed:", oneLineError(error));
|
|
904
928
|
}
|
|
905
929
|
}
|
|
930
|
+
|
|
931
|
+
// The children of a delegation are observed, not assumed. The
|
|
932
|
+
// harness does not dispatch anything: the agent sends the measured
|
|
933
|
+
// groups to the sub-agent tool, and the tool events are the proof
|
|
934
|
+
// that a child really ran.
|
|
935
|
+
pi.on("tool_execution_start", (event) => {
|
|
936
|
+
try {
|
|
937
|
+
const toolEvent = event as {
|
|
938
|
+
toolCallId?: string;
|
|
939
|
+
toolName?: string;
|
|
940
|
+
args?: unknown;
|
|
941
|
+
};
|
|
942
|
+
const child = sharedState.delegationHarness?.observeToolStart?.({
|
|
943
|
+
toolCallId: String(toolEvent.toolCallId ?? ""),
|
|
944
|
+
toolName: String(toolEvent.toolName ?? ""),
|
|
945
|
+
args: toolEvent.args,
|
|
946
|
+
});
|
|
947
|
+
if (child) {
|
|
948
|
+
logToFile(
|
|
949
|
+
"[Delegation]",
|
|
950
|
+
`A child was dispatched: ${child.toolName} (${child.groupId ?? "no group"})`,
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
} catch (error) {
|
|
954
|
+
logToFile("[Delegation]", "The child could not be recorded:", oneLineError(error));
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
pi.on("tool_execution_end", (event) => {
|
|
959
|
+
try {
|
|
960
|
+
const toolEvent = event as {
|
|
961
|
+
toolCallId?: string;
|
|
962
|
+
toolName?: string;
|
|
963
|
+
result?: unknown;
|
|
964
|
+
isError?: boolean;
|
|
965
|
+
};
|
|
966
|
+
const child = sharedState.delegationHarness?.observeToolEnd?.({
|
|
967
|
+
toolCallId: String(toolEvent.toolCallId ?? ""),
|
|
968
|
+
toolName: String(toolEvent.toolName ?? ""),
|
|
969
|
+
result: toolEvent.result,
|
|
970
|
+
isError: toolEvent.isError === true,
|
|
971
|
+
});
|
|
972
|
+
if (child) {
|
|
973
|
+
logToFile(
|
|
974
|
+
"[Delegation]",
|
|
975
|
+
`The child ended: ${child.toolName} (${child.status})${child.model ? `, model ${child.model}` : ""}`,
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
} catch (error) {
|
|
979
|
+
logToFile("[Delegation]", "The child could not be closed:", oneLineError(error));
|
|
980
|
+
}
|
|
981
|
+
});
|
|
906
982
|
let _sessionId = Date.now().toString(36); // Track session for cancellation
|
|
907
983
|
let _lastNotifiedQuestion = ""; // Track last question to prevent repeat notifications
|
|
908
984
|
let _completedNotifiedFor: string | null = null; // Track completion notification deduplication
|
package/package.json
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The batches of a large job.
|
|
3
|
+
*
|
|
4
|
+
* A large job does not run in one piece. It starts with a measured pilot
|
|
5
|
+
* and continues in bounded batches, and the state of every batch is kept
|
|
6
|
+
* so a failure resumes instead of restarting.
|
|
7
|
+
*
|
|
8
|
+
* Every number here is either given or measured. The harness never
|
|
9
|
+
* estimates a duration from a number it invented: an estimate needs a
|
|
10
|
+
* measured cost per record, and without one the estimate is unknown.
|
|
11
|
+
*/
|
|
12
|
+
/** The kind of a batch. */
|
|
13
|
+
export type BatchKind = "pilot" | "scale-up";
|
|
14
|
+
/** The state of a batch. */
|
|
15
|
+
export type BatchStatus = "pending" | "running" | "done" | "failed";
|
|
16
|
+
/**
|
|
17
|
+
* One batch of a large job.
|
|
18
|
+
*/
|
|
19
|
+
export interface Batch {
|
|
20
|
+
/** The id of the batch. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** The kind of the batch. */
|
|
23
|
+
kind: BatchKind;
|
|
24
|
+
/** The first record of the batch (inclusive). */
|
|
25
|
+
from: number;
|
|
26
|
+
/** The last record of the batch (inclusive). */
|
|
27
|
+
to: number;
|
|
28
|
+
/** The number of records of the batch. */
|
|
29
|
+
records: number;
|
|
30
|
+
/** The state of the batch. */
|
|
31
|
+
status: BatchStatus;
|
|
32
|
+
/** How often the batch was tried. */
|
|
33
|
+
attempts: number;
|
|
34
|
+
/** The measured duration of the batch. */
|
|
35
|
+
durationMs?: number;
|
|
36
|
+
/** The reason of a failure. */
|
|
37
|
+
failure?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The plan of a large job.
|
|
41
|
+
*
|
|
42
|
+
* The limits are explicit: the size of the pilot, the size of a batch,
|
|
43
|
+
* the number of batches that may run at the same time and the budget.
|
|
44
|
+
*/
|
|
45
|
+
export interface BatchPlan {
|
|
46
|
+
/** The number of records of the whole job. */
|
|
47
|
+
totalRecords: number;
|
|
48
|
+
/** The number of records of the representative pilot. */
|
|
49
|
+
pilotRecords: number;
|
|
50
|
+
/** The maximum number of records of a scale-up batch. */
|
|
51
|
+
maxBatchRecords: number;
|
|
52
|
+
/** The maximum number of batches that may run at the same time. */
|
|
53
|
+
maxConcurrentBatches: number;
|
|
54
|
+
/**
|
|
55
|
+
* The measured cost of one record, in milliseconds.
|
|
56
|
+
*
|
|
57
|
+
* Without a measured cost the estimated duration of the job is
|
|
58
|
+
* unknown, and the plan says so.
|
|
59
|
+
*/
|
|
60
|
+
msPerRecord?: number;
|
|
61
|
+
/** The budget of the whole job, in minutes. */
|
|
62
|
+
budgetMinutes?: number;
|
|
63
|
+
/** How often a failed batch is tried again. */
|
|
64
|
+
maxAttempts?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The progress of the batches.
|
|
68
|
+
*/
|
|
69
|
+
export interface BatchProgress {
|
|
70
|
+
/** The batches that are done. */
|
|
71
|
+
done: number;
|
|
72
|
+
/** The batches that failed. */
|
|
73
|
+
failed: number;
|
|
74
|
+
/** The batches that still have to run. */
|
|
75
|
+
pending: number;
|
|
76
|
+
/** The records that are done. */
|
|
77
|
+
recordsDone: number;
|
|
78
|
+
/** The records of the whole job. */
|
|
79
|
+
recordsTotal: number;
|
|
80
|
+
/** The measured duration of the finished batches. */
|
|
81
|
+
durationMs: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The batches of a job.
|
|
85
|
+
*
|
|
86
|
+
* The first batch is the pilot. The rest are the scale-up, in the order
|
|
87
|
+
* of the records.
|
|
88
|
+
*/
|
|
89
|
+
export declare function buildBatches(plan: BatchPlan): Batch[];
|
|
90
|
+
/**
|
|
91
|
+
* The estimated duration of the whole job.
|
|
92
|
+
*
|
|
93
|
+
* The estimate needs a measured cost per record. Without one the answer
|
|
94
|
+
* is unknown: the plan never guesses a duration.
|
|
95
|
+
*/
|
|
96
|
+
export declare function estimateJobMs(plan: BatchPlan): number | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* May the scale-up start?
|
|
99
|
+
*
|
|
100
|
+
* The pilot has to be done and it has to have passed. A failed pilot
|
|
101
|
+
* stops the job: the plan never scales up on a failure.
|
|
102
|
+
*/
|
|
103
|
+
export declare function mayStartScaleUp(batches: Batch[]): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The batches that may run now.
|
|
106
|
+
*
|
|
107
|
+
* The scale-up waits for the pilot, the limit of parallel batches is
|
|
108
|
+
* respected, and a batch that already used up its attempts is never
|
|
109
|
+
* offered again.
|
|
110
|
+
*/
|
|
111
|
+
export declare function nextBatches(batches: Batch[], plan: BatchPlan): Batch[];
|
|
112
|
+
/**
|
|
113
|
+
* The result of one batch attempt.
|
|
114
|
+
*/
|
|
115
|
+
export interface BatchResult {
|
|
116
|
+
/** The id of the batch. */
|
|
117
|
+
id: string;
|
|
118
|
+
/** Did the batch succeed? */
|
|
119
|
+
ok: boolean;
|
|
120
|
+
/** The measured duration of the attempt. */
|
|
121
|
+
durationMs?: number;
|
|
122
|
+
/** The reason of a failure. */
|
|
123
|
+
failure?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Record the result of a batch attempt.
|
|
127
|
+
*
|
|
128
|
+
* A failed batch keeps its place: the batches that are done are never
|
|
129
|
+
* repeated, and a failed batch is tried again until it used up its
|
|
130
|
+
* attempts.
|
|
131
|
+
*/
|
|
132
|
+
export declare function recordBatchResult(batches: Batch[], result: BatchResult): Batch[];
|
|
133
|
+
/**
|
|
134
|
+
* The progress of the batches.
|
|
135
|
+
*/
|
|
136
|
+
export declare function batchProgress(batches: Batch[]): BatchProgress;
|
|
137
|
+
/**
|
|
138
|
+
* Is the job over the budget?
|
|
139
|
+
*
|
|
140
|
+
* The budget is a limit, not a wish: a job that spent it stops and
|
|
141
|
+
* reports. A budget that was never measured cannot be spent.
|
|
142
|
+
*/
|
|
143
|
+
export declare function overBudget(plan: BatchPlan, elapsedMs: number | undefined): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* The description of the batches, for the status line.
|
|
146
|
+
*
|
|
147
|
+
* The line is plain ASCII and names the measured facts.
|
|
148
|
+
*/
|
|
149
|
+
export declare function describeBatches(batches: Batch[]): string;
|
|
150
|
+
//# sourceMappingURL=batch-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-plan.d.ts","sourceRoot":"","sources":["../src/batch-plan.ts"],"names":[],"mappings":"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"}
|