@tangle-network/agent-eval 0.200.0 → 0.201.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/CHANGELOG.md +8 -0
- package/dist/adapters/http.d.ts +7 -8
- package/dist/adapters/http.d.ts.map +1 -1
- package/dist/adapters/http.js +2 -2
- package/dist/adapters/http.js.map +1 -1
- package/dist/agent-profile-DDfIjdyS.d.ts.map +1 -1
- package/dist/analyst/index.d.ts +76 -76
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +6 -6
- package/dist/{analyze-runs-DFbp2gB8.js → analyze-runs-BrIibNd0.js} +47 -42
- package/dist/{analyze-runs-DFbp2gB8.js.map → analyze-runs-BrIibNd0.js.map} +1 -1
- package/dist/{ast-CP9ae9B0.js → ast-DJ6Bc7ab.js} +5 -4
- package/dist/{ast-CP9ae9B0.js.map → ast-DJ6Bc7ab.js.map} +1 -1
- package/dist/authenticity/index.d.ts +14 -15
- package/dist/authenticity/index.d.ts.map +1 -1
- package/dist/{baseline-BC-eBZ7U.js → baseline-CVKsfWTg.js} +2 -2
- package/dist/{baseline-BC-eBZ7U.js.map → baseline-CVKsfWTg.js.map} +1 -1
- package/dist/{benchmark-BeQJyrRC.js → benchmark-BywPeAUo.js} +4 -3
- package/dist/{benchmark-BeQJyrRC.js.map → benchmark-BywPeAUo.js.map} +1 -1
- package/dist/{benchmark-command-EBmuMUBo.js → benchmark-command-DFs_i62N.js} +24 -23
- package/dist/{benchmark-command-EBmuMUBo.js.map → benchmark-command-DFs_i62N.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +12 -12
- package/dist/benchmarks/index.d.ts.map +1 -1
- package/dist/benchmarks/index.js +3 -3
- package/dist/{bounded-process-BBZob7vl.js → bounded-process-Cj9YjXbE.js} +3 -3
- package/dist/{bounded-process-BBZob7vl.js.map → bounded-process-Cj9YjXbE.js.map} +1 -1
- package/dist/builder-eval/index.d.ts +16 -17
- package/dist/builder-eval/index.d.ts.map +1 -1
- package/dist/builder-eval/index.js +12 -10
- package/dist/builder-eval/index.js.map +1 -1
- package/dist/campaign/index.js +11 -11
- package/dist/{campaign-L391bmir.js → campaign-PmTWZi72.js} +30 -25
- package/dist/{campaign-L391bmir.js.map → campaign-PmTWZi72.js.map} +1 -1
- package/dist/{campaign-evidence-jL_U7Ikv.js → campaign-evidence-Dt_rWPk2.js} +4 -4
- package/dist/{campaign-evidence-jL_U7Ikv.js.map → campaign-evidence-Dt_rWPk2.js.map} +1 -1
- package/dist/{chat-client-CJORSG_J.js → chat-client-DUhWNQQS.js} +5 -4
- package/dist/{chat-client-CJORSG_J.js.map → chat-client-DUhWNQQS.js.map} +1 -1
- package/dist/{chat-json-call-DnlDjpco.js → chat-json-call-Dx_sHzqm.js} +2 -2
- package/dist/{chat-json-call-DnlDjpco.js.map → chat-json-call-Dx_sHzqm.js.map} +1 -1
- package/dist/{claim-V9Zqbq0J.js → claim-BXcZw-jo.js} +2 -2
- package/dist/{claim-V9Zqbq0J.js.map → claim-BXcZw-jo.js.map} +1 -1
- package/dist/cli.js +12 -11
- package/dist/cli.js.map +1 -1
- package/dist/contract/index.js +22 -19
- package/dist/contract/index.js.map +1 -1
- package/dist/{default-registry-xMLX160E.js → default-registry-D4qXx2aG.js} +2 -2
- package/dist/{default-registry-xMLX160E.js.map → default-registry-D4qXx2aG.js.map} +1 -1
- package/dist/define-agent-eval-1YuvJpOs.d.ts.map +1 -1
- package/dist/{define-agent-eval-7q_UwsTt.js → define-agent-eval-CJN9dTQw.js} +10 -9
- package/dist/{define-agent-eval-7q_UwsTt.js.map → define-agent-eval-CJN9dTQw.js.map} +1 -1
- package/dist/{descriptive-1V17A-qa.js → descriptive-D9LUFk1-.js} +2 -2
- package/dist/{descriptive-1V17A-qa.js.map → descriptive-D9LUFk1-.js.map} +1 -1
- package/dist/diagnosis/index.d.ts +7 -7
- package/dist/diagnosis/index.d.ts.map +1 -1
- package/dist/diagnosis/index.js +2 -2
- package/dist/diagnosis/index.js.map +1 -1
- package/dist/{dspy-rlm-engine-B5T43BkZ.js → dspy-rlm-engine-US8YsYGq.js} +5 -5
- package/dist/{dspy-rlm-engine-B5T43BkZ.js.map → dspy-rlm-engine-US8YsYGq.js.map} +1 -1
- package/dist/{eval-campaign-GapmPHIA.js → eval-campaign-ha_aWtk7.js} +14 -12
- package/dist/{eval-campaign-GapmPHIA.js.map → eval-campaign-ha_aWtk7.js.map} +1 -1
- package/dist/evaluation.d.ts +9 -10
- package/dist/evaluation.d.ts.map +1 -1
- package/dist/experiment/index.d.ts +29 -29
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +13 -12
- package/dist/experiment/index.js.map +1 -1
- package/dist/{exporters-DEcXbvgO.js → exporters-Coiv-qO2.js} +2 -2
- package/dist/{exporters-DEcXbvgO.js.map → exporters-Coiv-qO2.js.map} +1 -1
- package/dist/{external-optimizer-process-CEXcCKqd.js → external-optimizer-process-KLcw0Vnc.js} +2 -2
- package/dist/{external-optimizer-process-CEXcCKqd.js.map → external-optimizer-process-KLcw0Vnc.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-laM1-UDV.js → external-optimizer-subprocess-CkyUUV7h.js} +4 -4
- package/dist/{external-optimizer-subprocess-laM1-UDV.js.map → external-optimizer-subprocess-CkyUUV7h.js.map} +1 -1
- package/dist/fuzz.d.ts +15 -15
- package/dist/fuzz.d.ts.map +1 -1
- package/dist/{hf-dataset-CRqtSjnR.js → hf-dataset-kjIfIK_e.js} +3 -3
- package/dist/{hf-dataset-CRqtSjnR.js.map → hf-dataset-kjIfIK_e.js.map} +1 -1
- package/dist/hosted/index.d.ts +8 -8
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/{index-D4pC7Tvd2.d.ts → index-D4pC7Tvd.d.ts} +1 -1
- package/dist/index-D4pC7Tvd.d.ts.map +1 -0
- package/dist/index-DKmrHA02.d.ts.map +1 -1
- package/dist/{index-DNgf5gyG2.d.ts → index-DNgf5gyG.d.ts} +1 -1
- package/dist/index-DNgf5gyG.d.ts.map +1 -0
- package/dist/index.d.ts +124 -124
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -42
- package/dist/index.js.map +1 -1
- package/dist/{integrity-BFP4kjGj.js → integrity-BvnVARVl.js} +30 -29
- package/dist/{integrity-BFP4kjGj.js.map → integrity-BvnVARVl.js.map} +1 -1
- package/dist/{integrity-BvHANvnp.js → integrity-uwK7XC-8.js} +2 -2
- package/dist/{integrity-BvHANvnp.js.map → integrity-uwK7XC-8.js.map} +1 -1
- package/dist/{internal-BMFSR8Ns.js → internal-BOe3zmjQ.js} +2 -2
- package/dist/{internal-BMFSR8Ns.js.map → internal-BOe3zmjQ.js.map} +1 -1
- package/dist/{jev-review-Cu9xtIu4.js → jev-review-DZEjDzlF.js} +7 -5
- package/dist/{jev-review-Cu9xtIu4.js.map → jev-review-DZEjDzlF.js.map} +1 -1
- package/dist/jev.d.ts +10 -10
- package/dist/jev.d.ts.map +1 -1
- package/dist/jev.js +2 -2
- package/dist/{judge-calibration-DYmaBtJr.js → judge-calibration-C5zgtiJT.js} +2 -2
- package/dist/{judge-calibration-DYmaBtJr.js.map → judge-calibration-C5zgtiJT.js.map} +1 -1
- package/dist/kind-factory-CdPPHtGZ.js.map +1 -1
- package/dist/{llm-client-c_bKHTXz.js → llm-client-Bhqoglar.js} +6 -4
- package/dist/{llm-client-c_bKHTXz.js.map → llm-client-Bhqoglar.js.map} +1 -1
- package/dist/{llm-judge-CL6f3utD.js → llm-judge-C-0P1WiT.js} +26 -21
- package/dist/{llm-judge-CL6f3utD.js.map → llm-judge-C-0P1WiT.js.map} +1 -1
- package/dist/matrix/index.d.ts +1 -1
- package/dist/matrix/index.js +1 -1
- package/dist/{matrix-_NLSWsKM.d.ts → matrix--IZKROxD.d.ts} +2 -2
- package/dist/{matrix-_NLSWsKM.d.ts.map → matrix--IZKROxD.d.ts.map} +1 -1
- package/dist/{matrix-pWinRMPl.js → matrix-DnlHn5x1.js} +8 -6
- package/dist/{matrix-pWinRMPl.js.map → matrix-DnlHn5x1.js.map} +1 -1
- package/dist/meta-eval/index.d.ts +55 -55
- package/dist/meta-eval/index.d.ts.map +1 -1
- package/dist/meta-eval/index.js +4 -4
- package/dist/{mint-iCD-W43s.js → mint-vlRckJEX.js} +2 -2
- package/dist/{mint-iCD-W43s.js.map → mint-vlRckJEX.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +23 -23
- package/dist/multishot/golden/index.d.ts.map +1 -1
- package/dist/multishot/golden/index.js +1 -1
- package/dist/multishot/index.d.ts +9 -9
- package/dist/multishot/index.d.ts.map +1 -1
- package/dist/multishot/index.js +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{otel-spans-CQmSxtcS.js → otel-spans-C8YIJWy1.js} +9 -4
- package/dist/{otel-spans-CQmSxtcS.js.map → otel-spans-C8YIJWy1.js.map} +1 -1
- package/dist/{outcome-store-BXlkwMPR.js → outcome-store-DUcMj-3D.js} +2 -2
- package/dist/{outcome-store-BXlkwMPR.js.map → outcome-store-DUcMj-3D.js.map} +1 -1
- package/dist/package-version-D7lQHt_-.js.map +1 -1
- package/dist/{paired-arms-DKZFVPt8.js → paired-arms-DpS_h8ON.js} +8 -5
- package/dist/{paired-arms-DKZFVPt8.js.map → paired-arms-DpS_h8ON.js.map} +1 -1
- package/dist/{paired-binary-fzkwENI4.js → paired-binary-OMBVRtc-.js} +2 -2
- package/dist/{paired-binary-fzkwENI4.js.map → paired-binary-OMBVRtc-.js.map} +1 -1
- package/dist/{paired-promotion-decision-D5B1Cxc2.js → paired-promotion-decision-DhrmjdV8.js} +5 -4
- package/dist/{paired-promotion-decision-D5B1Cxc2.js.map → paired-promotion-decision-DhrmjdV8.js.map} +1 -1
- package/dist/{paired-tests-C8iCsioC.js → paired-tests-Ccr16gcW.js} +3 -3
- package/dist/{paired-tests-C8iCsioC.js.map → paired-tests-Ccr16gcW.js.map} +1 -1
- package/dist/pipelines/index.d.ts +19 -19
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +5 -4
- package/dist/pipelines/index.js.map +1 -1
- package/dist/{power-and-mde-K_CmO3dc.js → power-and-mde-bie6i965.js} +9 -6
- package/dist/{power-and-mde-K_CmO3dc.js.map → power-and-mde-bie6i965.js.map} +1 -1
- package/dist/{produced-state-DZMW8cuF.js → produced-state-CR2tAPLf.js} +8 -5
- package/dist/{produced-state-DZMW8cuF.js.map → produced-state-CR2tAPLf.js.map} +1 -1
- package/dist/{promotion-policy-C6FAJvmZ.js → promotion-policy-BI1RxzwD.js} +4 -4
- package/dist/{promotion-policy-C6FAJvmZ.js.map → promotion-policy-BI1RxzwD.js.map} +1 -1
- package/dist/{raw-provider-sink-CXuOhLvT.js → raw-provider-sink-rB2DYxr6.js} +2 -2
- package/dist/{raw-provider-sink-CXuOhLvT.js.map → raw-provider-sink-rB2DYxr6.js.map} +1 -1
- package/dist/{release-confidence-XQm_xjhR.js → release-confidence-CiFg1EPq.js} +3 -2
- package/dist/{release-confidence-XQm_xjhR.js.map → release-confidence-CiFg1EPq.js.map} +1 -1
- package/dist/{report-command-DKJ_yAIj.js → report-command-DzPpFgjB.js} +20 -18
- package/dist/{report-command-DKJ_yAIj.js.map → report-command-DzPpFgjB.js.map} +1 -1
- package/dist/reporting.js +5 -5
- package/dist/{reward-hacking-D0XwhVWE.js → reward-hacking-C-a__ShZ.js} +5 -3
- package/dist/{reward-hacking-D0XwhVWE.js.map → reward-hacking-C-a__ShZ.js.map} +1 -1
- package/dist/rl.d.ts +199 -202
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +48 -49
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +1 -1
- package/dist/rollout/index.js +5 -5
- package/dist/{rollout-B-XBReTC.js → rollout-BUQixCoc.js} +5 -5
- package/dist/{rollout-B-XBReTC.js.map → rollout-BUQixCoc.js.map} +1 -1
- package/dist/{rubric-predictive-validity-CCK-1B7w.js → rubric-predictive-validity-B0Pg-3I5.js} +3 -3
- package/dist/{rubric-predictive-validity-CCK-1B7w.js.map → rubric-predictive-validity-B0Pg-3I5.js.map} +1 -1
- package/dist/{run-record-tNnlQIrD.js → run-record-BB290Y9A.js} +5 -3
- package/dist/{run-record-tNnlQIrD.js.map → run-record-BB290Y9A.js.map} +1 -1
- package/dist/{schema-C1aaAxTf.js → schema-DAMp77zB.js} +24 -20
- package/dist/{schema-C1aaAxTf.js.map → schema-DAMp77zB.js.map} +1 -1
- package/dist/search/index.d.ts +34 -34
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +2 -2
- package/dist/{search-kernel-AVgIjXaI.js → search-kernel-Dpniloks.js} +33 -26
- package/dist/{search-kernel-AVgIjXaI.js.map → search-kernel-Dpniloks.js.map} +1 -1
- package/dist/{search-ledger-CL0-mXQ8.js → search-ledger-CXQPwdWz.js} +4 -3
- package/dist/{search-ledger-CL0-mXQ8.js.map → search-ledger-CXQPwdWz.js.map} +1 -1
- package/dist/{search-shipper-Cs6K4km9.js → search-shipper-DhhofkDX.js} +3 -6
- package/dist/{search-shipper-Cs6K4km9.js.map → search-shipper-DhhofkDX.js.map} +1 -1
- package/dist/{search-summary-DvWk0hb3.js → search-summary-C1nAHgkB.js} +4 -4
- package/dist/{search-summary-DvWk0hb3.js.map → search-summary-C1nAHgkB.js.map} +1 -1
- package/dist/{semantic-concept-judge-2SE_kXGF.js → semantic-concept-judge-BcjYg37z.js} +4 -4
- package/dist/{semantic-concept-judge-2SE_kXGF.js.map → semantic-concept-judge-BcjYg37z.js.map} +1 -1
- package/dist/{sequential-Yz3OSskl.js → sequential-DWn_np6P.js} +2 -3
- package/dist/{sequential-Yz3OSskl.js.map → sequential-DWn_np6P.js.map} +1 -1
- package/dist/{server-D56r1lhp.js → server-B4jMhqQn.js} +2 -2
- package/dist/{server-D56r1lhp.js.map → server-B4jMhqQn.js.map} +1 -1
- package/dist/{skillopt-optimization-method-B2syNik0.js → skillopt-optimization-method-Bls9t-G_.js} +9 -9
- package/dist/{skillopt-optimization-method-B2syNik0.js.map → skillopt-optimization-method-Bls9t-G_.js.map} +1 -1
- package/dist/{statistical-heldout-BAFDCo07.js → statistical-heldout-CNLOvRq_.js} +3 -3
- package/dist/{statistical-heldout-BAFDCo07.js.map → statistical-heldout-CNLOvRq_.js.map} +1 -1
- package/dist/statistical-heldout-HswMvzbP.d.ts.map +1 -1
- package/dist/{store-DNe_Uv1Q.js → store-BhNuLdJw.js} +3 -5
- package/dist/{store-DNe_Uv1Q.js.map → store-BhNuLdJw.js.map} +1 -1
- package/dist/store-C4avFjIi.d.ts.map +1 -1
- package/dist/{store-otlp-BPowgPm6.js → store-otlp-yd9lDziN.js} +2 -2
- package/dist/{store-otlp-BPowgPm6.js.map → store-otlp-yd9lDziN.js.map} +1 -1
- package/dist/{store-tool-spans-BaGakFc2.js → store-tool-spans-Biio4_Nw.js} +4 -4
- package/dist/{store-tool-spans-BaGakFc2.js.map → store-tool-spans-Biio4_Nw.js.map} +1 -1
- package/dist/storyboard/index.d.ts +20 -21
- package/dist/storyboard/index.d.ts.map +1 -1
- package/dist/{student-t-BA-Uy51p.js → student-t-BBZYka0E.js} +4 -3
- package/dist/{student-t-BA-Uy51p.js.map → student-t-BBZYka0E.js.map} +1 -1
- package/dist/{summary-report-BeYnvddy.js → summary-report-DLzptLSA.js} +8 -7
- package/dist/{summary-report-BeYnvddy.js.map → summary-report-DLzptLSA.js.map} +1 -1
- package/dist/supervisor-run/index.d.ts +25 -25
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +2 -2
- package/dist/{tool-waste-CJDfxH45.js → tool-waste-B-u3rzCz.js} +11 -6
- package/dist/{tool-waste-CJDfxH45.js.map → tool-waste-B-u3rzCz.js.map} +1 -1
- package/dist/trace-repair/index.d.ts +96 -96
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +1 -1
- package/dist/trace-repair/index.js.map +1 -1
- package/dist/traces.d.ts +29 -29
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +9 -7
- package/dist/traces.js.map +1 -1
- package/dist/trajectory-replay/index.d.ts +35 -35
- package/dist/trajectory-replay/index.d.ts.map +1 -1
- package/dist/trajectory-replay/index.js +5 -5
- package/dist/trajectory-replay/index.js.map +1 -1
- package/dist/{tree-Ki_gW7z8.js → tree-D48IJUK0.js} +39 -31
- package/dist/{tree-Ki_gW7z8.js.map → tree-D48IJUK0.js.map} +1 -1
- package/dist/wire/index.d.ts +48 -48
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +1 -1
- package/docs/jev-behavior-review.md +4 -3
- package/package.json +18 -36
- package/dist/index-D4pC7Tvd2.d.ts.map +0 -1
- package/dist/index-DNgf5gyG2.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ All notable changes to `@tangle-network/agent-eval` and its sibling `agent-eval-
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.201.0] — 2026-09-28
|
|
8
|
+
|
|
9
|
+
- chore(deps): update all dependencies to latest (#889)
|
|
10
|
+
|
|
11
|
+
## [0.200.1] — 2026-09-27
|
|
12
|
+
|
|
13
|
+
- fix(rl): only an exact scope rule calls a claim a hack (#886)
|
|
14
|
+
|
|
7
15
|
## [0.200.0] — 2026-09-27
|
|
8
16
|
|
|
9
17
|
- feat(rl): decide whether a checker-verified claim is a result about its source or only about its checker (#882)
|
package/dist/adapters/http.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { m as CostReceipt } from "../cost-ledger-DbQdN3nO.js";
|
|
|
2
2
|
import { R as Scenario, d as DispatchContext, f as DispatchFn } from "../types-DfvQOe91.js";
|
|
3
3
|
import "../index-EkRNsLr4.js";
|
|
4
4
|
//#region src/adapters/http.d.ts
|
|
5
|
-
interface HttpDispatchOptions<TScenario extends Scenario, _TArtifact> {
|
|
5
|
+
export interface HttpDispatchOptions<TScenario extends Scenario, _TArtifact> {
|
|
6
6
|
/** Static endpoint URL. Mutually exclusive with `resolveUrl`. */
|
|
7
7
|
url?: string;
|
|
8
8
|
/**
|
|
@@ -26,7 +26,7 @@ interface HttpDispatchOptions<TScenario extends Scenario, _TArtifact> {
|
|
|
26
26
|
/** Optional fetch override (auth wrappers, custom agent, mocks). */
|
|
27
27
|
fetchImpl?: typeof fetch;
|
|
28
28
|
}
|
|
29
|
-
interface HttpDispatchRequestBody<TScenario extends Scenario> {
|
|
29
|
+
export interface HttpDispatchRequestBody<TScenario extends Scenario> {
|
|
30
30
|
scenario: TScenario;
|
|
31
31
|
cellId: string;
|
|
32
32
|
runAttemptId: string;
|
|
@@ -36,7 +36,7 @@ interface HttpDispatchRequestBody<TScenario extends Scenario> {
|
|
|
36
36
|
placement?: string;
|
|
37
37
|
cycleId?: string;
|
|
38
38
|
}
|
|
39
|
-
interface HttpDispatchResponseBody<TArtifact> {
|
|
39
|
+
export interface HttpDispatchResponseBody<TArtifact> {
|
|
40
40
|
artifact: TArtifact;
|
|
41
41
|
/**
|
|
42
42
|
* Every paid-call receipt the worker's `ctx.cost` settled while producing
|
|
@@ -55,8 +55,8 @@ interface HttpDispatchResponseBody<TArtifact> {
|
|
|
55
55
|
* server's `runDispatchServer` translates the resulting `AbortError` into
|
|
56
56
|
* a 499 (client-closed) so the client doesn't retry.
|
|
57
57
|
*/
|
|
58
|
-
declare function httpDispatch<TScenario extends Scenario, TArtifact>(opts: HttpDispatchOptions<TScenario, TArtifact>): DispatchFn<TScenario, TArtifact>;
|
|
59
|
-
interface RunDispatchServerOptions<TScenario extends Scenario, TArtifact> {
|
|
58
|
+
export declare function httpDispatch<TScenario extends Scenario, TArtifact>(opts: HttpDispatchOptions<TScenario, TArtifact>): DispatchFn<TScenario, TArtifact>;
|
|
59
|
+
export interface RunDispatchServerOptions<TScenario extends Scenario, TArtifact> {
|
|
60
60
|
/** The Dispatch this server exposes — what runs when a request lands. */
|
|
61
61
|
dispatch: DispatchFn<TScenario, TArtifact>;
|
|
62
62
|
/** TCP port to bind. */
|
|
@@ -87,7 +87,7 @@ interface RunDispatchServerOptions<TScenario extends Scenario, TArtifact> {
|
|
|
87
87
|
error?: unknown;
|
|
88
88
|
}) => void;
|
|
89
89
|
}
|
|
90
|
-
interface DispatchServerHandle {
|
|
90
|
+
export interface DispatchServerHandle {
|
|
91
91
|
/** The actual bound port (useful when `port: 0` requests an ephemeral port). */
|
|
92
92
|
port: number;
|
|
93
93
|
/** Stop accepting new connections and drain existing ones. */
|
|
@@ -111,7 +111,6 @@ interface DispatchServerHandle {
|
|
|
111
111
|
* The server is `node:http`-based to keep the runtime dependency surface
|
|
112
112
|
* minimal — works in plain Node, sandbox, or any container.
|
|
113
113
|
*/
|
|
114
|
-
declare function runDispatchServer<TScenario extends Scenario, TArtifact>(opts: RunDispatchServerOptions<TScenario, TArtifact>): Promise<DispatchServerHandle>;
|
|
114
|
+
export declare function runDispatchServer<TScenario extends Scenario, TArtifact>(opts: RunDispatchServerOptions<TScenario, TArtifact>): Promise<DispatchServerHandle>;
|
|
115
115
|
//#endregion
|
|
116
|
-
export { DispatchServerHandle, HttpDispatchOptions, HttpDispatchRequestBody, HttpDispatchResponseBody, RunDispatchServerOptions, httpDispatch, runDispatchServer };
|
|
117
116
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","names":[],"sources":["../../src/adapters/http.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"http.d.ts","names":["Dispatch"],"sources":["../../src/adapters/http.ts"],"mappings":";;;;iBAyDiB,oBAAoB,kBAAkB,UAAU;;EAE/D;;;;;;EAMA,cAAc;IAAS,UAAU;IAAW;IAAoB;;;EAEhE,gCAAgC;;EAEhC,UAAU;;EAEV;;EAEA;;EAEA,mBAAmB;;iBAGJ,wBAAwB,kBAAkB;EACzD,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe,yBAAyB;EACxC,UAAU;;;;;;;;EAQV,WAAW;;;;;;;;;;wBAiBG,aAAa,kBAAkB,UAAU,WACvD,MAAM,oBAAoB,WAAW,aACpCA,WAAS,WAAW;iBA+JN,yBAAyB,kBAAkB,UAAU;;EAEpE,UAAUA,WAAS,WAAW;;EAE9B;;EAEA;;;;EAIA;;EAEA;;;;;;;;EAQA,kBACE,KAAK,wBAAwB,YAC7B,QAAQ,gBACL,QAAQ;;EAEb;;EAEA,aAAa;IACX;IACA;IACA;IACA;;;iBAIa;;EAEf;;EAEA,aAAa;;;;;;;;;;;;;;;;;;;;wBAqBO,kBAAkB,kBAAkB,UAAU,WAClE,MAAM,yBAAyB,WAAW,aACzC,QAAQ"}
|
package/dist/adapters/http.js
CHANGED
|
@@ -15,7 +15,7 @@ function resolveAuth(auth) {
|
|
|
15
15
|
function httpDispatch(opts) {
|
|
16
16
|
if (!opts.url && !opts.resolveUrl) throw new Error("httpDispatch: pass exactly one of `url` or `resolveUrl`.");
|
|
17
17
|
if (opts.url && opts.resolveUrl) throw new Error("httpDispatch: pass exactly one of `url` or `resolveUrl`, not both.");
|
|
18
|
-
const timeoutMs = opts.timeoutMs ??
|
|
18
|
+
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
19
19
|
const maxRetries = opts.retries ?? 2;
|
|
20
20
|
const f = opts.fetchImpl ?? ((...args) => fetch(...args));
|
|
21
21
|
return async (scenario, ctx) => {
|
|
@@ -149,7 +149,7 @@ async function replayReceipt(cost, receipt) {
|
|
|
149
149
|
async function runDispatchServer(opts) {
|
|
150
150
|
if (opts.auth === void 0) throw new Error("runDispatchServer: 'auth' is required (pass a bearer-token string, or `auth: false` explicitly for a closed-network test deployment).");
|
|
151
151
|
const path = opts.path ?? "/dispatch";
|
|
152
|
-
const maxBytes = opts.maxBodyBytes ??
|
|
152
|
+
const maxBytes = opts.maxBodyBytes ?? 10485760;
|
|
153
153
|
const expectedAuth = typeof opts.auth === "string" ? `Bearer ${opts.auth.replace(/^Bearer\s+/, "")}` : null;
|
|
154
154
|
const { createServer } = await import("node:http");
|
|
155
155
|
const server = createServer(async (req, res) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","names":[],"sources":["../../src/adapters/http.ts"],"sourcesContent":["/**\n * # `@tangle-network/agent-eval/adapters/http` — distributed Dispatch over HTTP.\n *\n * Decouples coordinator and worker. The coordinator (running\n * `runImprovementLoop` or `runCampaign`) can live anywhere — your VPC, a dev\n * laptop, a cron VM. The workers (running the actual agent) can live anywhere else — different\n * regions, different clouds, different boxes — as long as they speak HTTP.\n *\n * Both sides:\n *\n * - **`httpDispatch({ url | resolveUrl, ... })`** — client. Returns a\n * `Dispatch` that POSTs `{ scenario, ctx }` to a worker URL and parses\n * the artifact back. AbortSignal-aware, retries on idempotent errors,\n * bounded timeout per call.\n * - **`runDispatchServer({ dispatch, port, ... })`** — server. Wraps your\n * local `Dispatch` as an HTTP endpoint. Handles auth, JSON parsing,\n * error mapping, and cancellation when the client aborts.\n *\n * # Cost receipts cross the wire too\n *\n * A worker dispatch pays for its own model calls through its own\n * `ctx.cost` (wired by `contextFactory`) — a different `CostLedger` than the\n * coordinator's. `runDispatchServer` records every receipt that dispatch\n * settles and returns them alongside the artifact; `httpDispatch` replays\n * each one into the coordinator's `ctx.cost`, the same paid-call path a\n * local dispatch uses. A remote cell's spend therefore reaches the\n * coordinator's `CostLedger` — its summary, its cost ceiling, its\n * `CampaignCellResult.costUsd` — exactly like an in-process cell's does.\n * A worker with no `contextFactory` (or one that never touches `ctx.cost`)\n * sends no receipts, and the coordinator sees the cell as free, same as\n * today.\n *\n * # Topology examples\n *\n * **Single-worker:** coordinator on box A, worker on box B. Set\n * `httpDispatch({ url: 'https://box-b/dispatch' })`.\n *\n * **Multi-region:** N workers across regions. Use `httpDispatch({ resolveUrl })`\n * with a function that picks the URL per cell from `ctx.placement`. Combined\n * with `cellPlacement` on `RunCampaignOptions`, the substrate fans cells\n * across geographies in parallel.\n *\n * **Coordinator-as-a-service:** coordinator runs as a long-lived process or service\n * (holds optimization state across generations); workers are stateless\n * HTTP services that can scale horizontally per cell.\n */\n\nimport type { CampaignCostMeter, Dispatch, DispatchContext, Scenario } from '../contract'\nimport type { CostReceipt, CostReceiptInput } from '../cost-ledger'\n\n// ── Client ───────────────────────────────────────────────────────────\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- TArtifact is unused\n// in this options interface but kept as a parameter so callers can write\n// `HttpDispatchOptions<MyScenario, MyArtifact>` symmetrically with\n// `Dispatch<MyScenario, MyArtifact>`. Marking it unused at the position\n// where it bites.\nexport interface HttpDispatchOptions<TScenario extends Scenario, _TArtifact> {\n /** Static endpoint URL. Mutually exclusive with `resolveUrl`. */\n url?: string\n /**\n * Dynamic per-cell URL resolver. Receives the scenario + the substrate\n * placement key (from `RunCampaignOptions.cellPlacement`) and returns the\n * worker URL to invoke. Mutually exclusive with `url`.\n */\n resolveUrl?: (input: { scenario: TScenario; placement?: string; cellId: string }) => string\n /** Bearer token or static auth string set as `Authorization`. */\n auth?: string | (() => string | Promise<string>)\n /** Extra headers merged into every request. */\n headers?: Record<string, string>\n /** Per-call timeout in ms. Default 5 minutes. */\n timeoutMs?: number\n /** How many idempotent retries on 5xx / network errors. Default 2. */\n retries?: number\n /** Optional fetch override (auth wrappers, custom agent, mocks). */\n fetchImpl?: typeof fetch\n}\n\nexport interface HttpDispatchRequestBody<TScenario extends Scenario> {\n scenario: TScenario\n cellId: string\n runAttemptId: string\n rep: number\n generation?: number\n seed: number\n placement?: string\n cycleId?: string\n}\n\nexport interface HttpDispatchResponseBody<TArtifact> {\n artifact: TArtifact\n /**\n * Every paid-call receipt the worker's `ctx.cost` settled while producing\n * this artifact, in settlement order. Absent or empty when the worker\n * recorded no paid calls (no `contextFactory`, or a dispatch that pays\n * through some other channel entirely). `httpDispatch` replays each one\n * into the coordinator's own `ctx.cost`.\n */\n receipts?: CostReceipt[]\n}\n\nfunction resolveAuth(auth: HttpDispatchOptions<Scenario, unknown>['auth']): Promise<string | null> {\n if (!auth) return Promise.resolve(null)\n if (typeof auth === 'string') return Promise.resolve(auth)\n return Promise.resolve(auth())\n}\n\n/**\n * Wrap a remote HTTP endpoint as a `Dispatch`. The remote side should run\n * `runDispatchServer` (or any service that speaks the same wire shape).\n *\n * Cancellation: the substrate's per-cell `AbortSignal` is forwarded; the\n * server's `runDispatchServer` translates the resulting `AbortError` into\n * a 499 (client-closed) so the client doesn't retry.\n */\nexport function httpDispatch<TScenario extends Scenario, TArtifact>(\n opts: HttpDispatchOptions<TScenario, TArtifact>,\n): Dispatch<TScenario, TArtifact> {\n if (!opts.url && !opts.resolveUrl) {\n throw new Error('httpDispatch: pass exactly one of `url` or `resolveUrl`.')\n }\n if (opts.url && opts.resolveUrl) {\n throw new Error('httpDispatch: pass exactly one of `url` or `resolveUrl`, not both.')\n }\n const timeoutMs = opts.timeoutMs ?? 5 * 60 * 1000\n const maxRetries = opts.retries ?? 2\n const f: typeof fetch = opts.fetchImpl ?? ((...args) => fetch(...args))\n\n return async (scenario, ctx) => {\n const url =\n opts.url ?? opts.resolveUrl!({ scenario, placement: ctx.placement, cellId: ctx.cellId })\n const authValue = await resolveAuth(opts.auth)\n const body: HttpDispatchRequestBody<TScenario> = {\n scenario,\n cellId: ctx.cellId,\n runAttemptId: ctx.runAttemptId,\n rep: ctx.rep,\n generation: ctx.generation,\n seed: ctx.seed,\n placement: ctx.placement,\n cycleId: ctx.cycleId,\n }\n\n let lastError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Compose the request signal: caller's signal OR our timeout.\n const ourTimeout = AbortSignal.timeout(timeoutMs)\n const combinedSignal = AbortSignal.any([ctx.signal, ourTimeout])\n try {\n const res = await f(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(authValue\n ? {\n Authorization: authValue.startsWith('Bearer ')\n ? authValue\n : `Bearer ${authValue}`,\n }\n : {}),\n ...opts.headers,\n },\n body: JSON.stringify(body),\n signal: combinedSignal,\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n // A dispatch that pays for part of its work before failing (a judge\n // call that settles, then the provider call itself errors) still\n // owes that spend to the coordinator's ledger — read it before\n // deciding whether this attempt retries or this cell fails. A\n // non-JSON error body (401/404/413's plain text) carries none.\n for (const receipt of parseErrorReceipts(text)) {\n await replayReceipt(ctx.cost, receipt)\n }\n // 4xx is non-retryable (caller error, auth, bad scenario shape).\n // 5xx / 408 / 429 / 502 / 503 / 504 are retryable.\n const retryable = res.status >= 500 || res.status === 408 || res.status === 429\n if (!retryable || attempt === maxRetries) {\n throw new Error(`httpDispatch ${url} failed (${res.status}): ${text.slice(0, 500)}`)\n }\n // exponential backoff with jitter\n await sleep(2 ** attempt * 200 + Math.random() * 200)\n continue\n }\n const parsed = (await res.json()) as HttpDispatchResponseBody<TArtifact>\n for (const receipt of parsed.receipts ?? []) {\n await replayReceipt(ctx.cost, receipt)\n }\n return parsed.artifact\n } catch (err) {\n // Caller-driven abort is terminal — never retry.\n if (ctx.signal.aborted) throw err\n lastError = err\n if (attempt === maxRetries) throw err\n await sleep(2 ** attempt * 200 + Math.random() * 200)\n }\n }\n throw lastError ?? new Error('httpDispatch exhausted retries')\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const t = setTimeout(resolve, ms)\n // Don't keep node process alive purely for backoff sleeps.\n if (typeof (t as { unref?: () => void }).unref === 'function')\n (t as { unref: () => void }).unref()\n })\n}\n\n/** Best-effort receipts from a non-2xx `runDispatchServer` body. Any shape\n * that isn't `{ error, receipts? }` JSON (plain-text 401/404/413 bodies,\n * a non-`runDispatchServer` peer) yields none — never itself a reason to\n * fail the request. */\nfunction parseErrorReceipts(text: string): CostReceipt[] {\n try {\n const parsed = JSON.parse(text) as { receipts?: CostReceipt[] }\n return Array.isArray(parsed.receipts) ? parsed.receipts : []\n } catch {\n return []\n }\n}\n\n/**\n * Re-enter one already-settled remote receipt through `runPaidCall` — the\n * only path `CampaignCostMeter` admits. `execute` does no new work (the\n * spend already happened on the worker); it only replays the worker's\n * outcome so the coordinator's ledger records the same receipt (a settled\n * failure included, so its `error` and cost — a failed call can still burn\n * tokens — are never dropped on the floor). Faithfully replaying a remote\n * failure still returns `succeeded: false` from `runPaidCall`: that's not\n * ours to raise. Only a `receipt`-less failure is — it means `runPaidCall`\n * refused to admit the call at all (a duplicate `callId`, an unknown-cost\n * receipt under a capped coordinator ledger, a breached cost ceiling), so\n * the remote spend could not be accounted for.\n */\nasync function replayReceipt(cost: CampaignCostMeter, receipt: CostReceipt): Promise<void> {\n const knownCostUsd = receipt.costUnknown ? undefined : receipt.costUsd\n const observed = (): CostReceiptInput => ({\n model: receipt.model,\n inputTokens: receipt.inputTokens,\n outputTokens: receipt.outputTokens,\n ...(receipt.reasoningTokens === undefined ? {} : { reasoningTokens: receipt.reasoningTokens }),\n ...(receipt.cachedTokens === undefined ? {} : { cachedTokens: receipt.cachedTokens }),\n ...(receipt.cacheWriteTokens === undefined\n ? {}\n : { cacheWriteTokens: receipt.cacheWriteTokens }),\n ...(receipt.usageUnknown ? { usageUnknown: true as const } : {}),\n ...(knownCostUsd === undefined\n ? { costUnknown: true as const }\n : { actualCostUsd: knownCostUsd }),\n })\n const result = await cost.runPaidCall({\n callId: receipt.callId,\n channel: receipt.channel,\n actor: receipt.actor,\n model: receipt.model,\n maximumCharge:\n knownCostUsd === undefined ? undefined : { externallyEnforcedMaximumUsd: knownCostUsd },\n // No `signal`: the call already happened remotely. Aborting the replay\n // would not undo the spend, only hide it from the ledger.\n execute: async () => {\n if (receipt.error) throw new Error(receipt.error)\n return null\n },\n receipt: observed,\n receiptFromError: observed,\n })\n if (!result.succeeded && !result.receipt) {\n throw result.error\n }\n}\n\n// ── Server ───────────────────────────────────────────────────────────\n\nexport interface RunDispatchServerOptions<TScenario extends Scenario, TArtifact> {\n /** The Dispatch this server exposes — what runs when a request lands. */\n dispatch: Dispatch<TScenario, TArtifact>\n /** TCP port to bind. */\n port: number\n /** Optional bind host; defaults to 0.0.0.0. */\n host?: string\n /** Required for any non-test deployment: the bearer token clients must\n * send. The substrate refuses to start without auth unless `auth: false`\n * is set explicitly (intended ONLY for closed-network/internal testing). */\n auth: string | false\n /** Path the server listens on. Default `/dispatch`. */\n path?: string\n /**\n * Per-request handler that wraps `dispatch` with whatever context the\n * worker side needs to construct a `DispatchContext` — typically the\n * trace writer, artifact writer, and cost meter. The substrate provides\n * synthetic-but-typed defaults if not supplied; production deployments\n * should wire real ones (e.g. ship traces to your OTel collector).\n */\n contextFactory?: (\n req: HttpDispatchRequestBody<TScenario>,\n signal: AbortSignal,\n ) => Promise<DispatchContext>\n /** Optional max payload size for the request body (bytes). Default 10 MB. */\n maxBodyBytes?: number\n /** Hook for observability — called on every successful or failed turn. */\n onRequest?: (event: {\n cellId: string\n durationMs: number\n success: boolean\n error?: unknown\n }) => void\n}\n\nexport interface DispatchServerHandle {\n /** The actual bound port (useful when `port: 0` requests an ephemeral port). */\n port: number\n /** Stop accepting new connections and drain existing ones. */\n close: () => Promise<void>\n}\n\n/**\n * Start an HTTP server exposing a local `Dispatch` over the wire. Pair with\n * `httpDispatch` on the driver side.\n *\n * Wire shape:\n *\n * POST /dispatch\n * Authorization: Bearer <token>\n * Body: HttpDispatchRequestBody\n * 200 OK: HttpDispatchResponseBody\n * 401: missing/invalid auth\n * 408: per-request timeout exceeded\n * 499: client aborted before completion\n * 500: dispatch threw\n *\n * The server is `node:http`-based to keep the runtime dependency surface\n * minimal — works in plain Node, sandbox, or any container.\n */\nexport async function runDispatchServer<TScenario extends Scenario, TArtifact>(\n opts: RunDispatchServerOptions<TScenario, TArtifact>,\n): Promise<DispatchServerHandle> {\n if (opts.auth === undefined) {\n throw new Error(\n \"runDispatchServer: 'auth' is required (pass a bearer-token string, or `auth: false` explicitly for a closed-network test deployment).\",\n )\n }\n const path = opts.path ?? '/dispatch'\n const maxBytes = opts.maxBodyBytes ?? 10 * 1024 * 1024\n const expectedAuth =\n typeof opts.auth === 'string' ? `Bearer ${opts.auth.replace(/^Bearer\\s+/, '')}` : null\n\n // Lazy-import node:http so the file is usable from non-Node bundlers\n // that import the client side only (e.g. an edge driver shipping\n // httpDispatch alone). Server side is opt-in by calling this function.\n const { createServer } = await import('node:http')\n\n const server = createServer(async (req, res) => {\n const start = Date.now()\n let cellId = 'unknown'\n let success = false\n let errCaught: unknown\n // Hoisted so a dispatch that throws AFTER paying for some of its work\n // still reports that spend in the error response — a partial spend is\n // still spend, and it must reach the coordinator's ledger exactly like\n // a locally-dispatched cell's failure accounting does.\n const receipts: CostReceipt[] = []\n\n try {\n if (req.method !== 'POST' || req.url?.split('?')[0] !== path) {\n res.statusCode = 404\n res.end('not found')\n return\n }\n if (expectedAuth) {\n const got = req.headers.authorization\n if (got !== expectedAuth) {\n res.statusCode = 401\n res.end('unauthorized')\n return\n }\n }\n\n // Read body up to maxBytes\n const chunks: Buffer[] = []\n let totalBytes = 0\n const aborter = new AbortController()\n // The request stream's 'close' fires when the BODY completes, so it\n // cannot signal disconnection. The response stream's 'close' fires\n // once per exchange: with `writableEnded` still false it means the\n // client went away before the dispatch answered.\n res.on('close', () => {\n if (!res.writableEnded) aborter.abort()\n })\n\n for await (const chunk of req) {\n const buf = chunk as Buffer\n totalBytes += buf.length\n if (totalBytes > maxBytes) {\n res.statusCode = 413\n res.end('payload too large')\n return\n }\n chunks.push(buf)\n }\n\n const body = JSON.parse(\n Buffer.concat(chunks).toString('utf8'),\n ) as HttpDispatchRequestBody<TScenario>\n if (typeof body.runAttemptId !== 'string' || body.runAttemptId.trim().length === 0) {\n throw new Error('runDispatchServer: request runAttemptId is required')\n }\n cellId = body.cellId\n\n const ctx: DispatchContext = opts.contextFactory\n ? await opts.contextFactory(body, aborter.signal)\n : {\n cellId: body.cellId,\n runAttemptId: body.runAttemptId,\n rep: body.rep,\n generation: body.generation,\n seed: body.seed,\n signal: aborter.signal,\n placement: body.placement,\n cycleId: body.cycleId,\n trace: NOOP_TRACE,\n artifacts: NOOP_ARTIFACTS,\n cost: NOOP_COST,\n }\n if (ctx.runAttemptId !== body.runAttemptId) {\n throw new Error('runDispatchServer: contextFactory must preserve request runAttemptId')\n }\n\n // Record every receipt this dispatch settles on ITS OWN `ctx.cost` (the\n // worker's ledger, not the coordinator's) so the response can carry\n // them back. `httpDispatch` replays each one into the coordinator's\n // ledger — see the module doc.\n const recordingCost: CampaignCostMeter = {\n async runPaidCall(input) {\n const result = await ctx.cost.runPaidCall(input)\n if (result.receipt) receipts.push(result.receipt)\n return result\n },\n }\n\n const artifact = await opts.dispatch(body.scenario, { ...ctx, cost: recordingCost })\n const responseBody: HttpDispatchResponseBody<TArtifact> = {\n artifact,\n ...(receipts.length ? { receipts } : {}),\n }\n\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify(responseBody))\n success = true\n } catch (err) {\n errCaught = err\n // Client-cancelled — they don't care about the result.\n if ((err as Error)?.name === 'AbortError') {\n res.statusCode = 499\n res.end('client aborted')\n return\n }\n res.statusCode = 500\n res.setHeader('content-type', 'application/json')\n res.end(\n JSON.stringify({\n error: err instanceof Error ? err.message : String(err),\n ...(receipts.length ? { receipts } : {}),\n }),\n )\n } finally {\n opts.onRequest?.({\n cellId,\n durationMs: Date.now() - start,\n success,\n error: errCaught,\n })\n }\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(opts.port, opts.host ?? '0.0.0.0', () => resolve())\n })\n\n const addr = server.address()\n const boundPort = typeof addr === 'object' && addr ? addr.port : opts.port\n\n return {\n port: boundPort,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()))\n }),\n }\n}\n\n// ── No-op default ctx machinery (worker can replace via contextFactory) ──\n\nconst NOOP_TRACE = {\n span: () => ({\n end: () => {},\n setAttribute: () => {},\n setStatus: () => {},\n recordException: () => {},\n addEvent: () => {},\n }),\n} as unknown as DispatchContext['trace']\n\nconst NOOP_ARTIFACTS = {\n write: async () => undefined,\n read: async () => undefined,\n list: async () => [],\n} as unknown as DispatchContext['artifacts']\n\nconst NOOP_COST = {\n record: () => {},\n total: () => 0,\n} as unknown as DispatchContext['cost']\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"http.js","names":[],"sources":["../../src/adapters/http.ts"],"sourcesContent":["/**\n * # `@tangle-network/agent-eval/adapters/http` — distributed Dispatch over HTTP.\n *\n * Decouples coordinator and worker. The coordinator (running\n * `runImprovementLoop` or `runCampaign`) can live anywhere — your VPC, a dev\n * laptop, a cron VM. The workers (running the actual agent) can live anywhere else — different\n * regions, different clouds, different boxes — as long as they speak HTTP.\n *\n * Both sides:\n *\n * - **`httpDispatch({ url | resolveUrl, ... })`** — client. Returns a\n * `Dispatch` that POSTs `{ scenario, ctx }` to a worker URL and parses\n * the artifact back. AbortSignal-aware, retries on idempotent errors,\n * bounded timeout per call.\n * - **`runDispatchServer({ dispatch, port, ... })`** — server. Wraps your\n * local `Dispatch` as an HTTP endpoint. Handles auth, JSON parsing,\n * error mapping, and cancellation when the client aborts.\n *\n * # Cost receipts cross the wire too\n *\n * A worker dispatch pays for its own model calls through its own\n * `ctx.cost` (wired by `contextFactory`) — a different `CostLedger` than the\n * coordinator's. `runDispatchServer` records every receipt that dispatch\n * settles and returns them alongside the artifact; `httpDispatch` replays\n * each one into the coordinator's `ctx.cost`, the same paid-call path a\n * local dispatch uses. A remote cell's spend therefore reaches the\n * coordinator's `CostLedger` — its summary, its cost ceiling, its\n * `CampaignCellResult.costUsd` — exactly like an in-process cell's does.\n * A worker with no `contextFactory` (or one that never touches `ctx.cost`)\n * sends no receipts, and the coordinator sees the cell as free, same as\n * today.\n *\n * # Topology examples\n *\n * **Single-worker:** coordinator on box A, worker on box B. Set\n * `httpDispatch({ url: 'https://box-b/dispatch' })`.\n *\n * **Multi-region:** N workers across regions. Use `httpDispatch({ resolveUrl })`\n * with a function that picks the URL per cell from `ctx.placement`. Combined\n * with `cellPlacement` on `RunCampaignOptions`, the substrate fans cells\n * across geographies in parallel.\n *\n * **Coordinator-as-a-service:** coordinator runs as a long-lived process or service\n * (holds optimization state across generations); workers are stateless\n * HTTP services that can scale horizontally per cell.\n */\n\nimport type { CampaignCostMeter, Dispatch, DispatchContext, Scenario } from '../contract'\nimport type { CostReceipt, CostReceiptInput } from '../cost-ledger'\n\n// ── Client ───────────────────────────────────────────────────────────\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- TArtifact is unused\n// in this options interface but kept as a parameter so callers can write\n// `HttpDispatchOptions<MyScenario, MyArtifact>` symmetrically with\n// `Dispatch<MyScenario, MyArtifact>`. Marking it unused at the position\n// where it bites.\nexport interface HttpDispatchOptions<TScenario extends Scenario, _TArtifact> {\n /** Static endpoint URL. Mutually exclusive with `resolveUrl`. */\n url?: string\n /**\n * Dynamic per-cell URL resolver. Receives the scenario + the substrate\n * placement key (from `RunCampaignOptions.cellPlacement`) and returns the\n * worker URL to invoke. Mutually exclusive with `url`.\n */\n resolveUrl?: (input: { scenario: TScenario; placement?: string; cellId: string }) => string\n /** Bearer token or static auth string set as `Authorization`. */\n auth?: string | (() => string | Promise<string>)\n /** Extra headers merged into every request. */\n headers?: Record<string, string>\n /** Per-call timeout in ms. Default 5 minutes. */\n timeoutMs?: number\n /** How many idempotent retries on 5xx / network errors. Default 2. */\n retries?: number\n /** Optional fetch override (auth wrappers, custom agent, mocks). */\n fetchImpl?: typeof fetch\n}\n\nexport interface HttpDispatchRequestBody<TScenario extends Scenario> {\n scenario: TScenario\n cellId: string\n runAttemptId: string\n rep: number\n generation?: number\n seed: number\n placement?: string\n cycleId?: string\n}\n\nexport interface HttpDispatchResponseBody<TArtifact> {\n artifact: TArtifact\n /**\n * Every paid-call receipt the worker's `ctx.cost` settled while producing\n * this artifact, in settlement order. Absent or empty when the worker\n * recorded no paid calls (no `contextFactory`, or a dispatch that pays\n * through some other channel entirely). `httpDispatch` replays each one\n * into the coordinator's own `ctx.cost`.\n */\n receipts?: CostReceipt[]\n}\n\nfunction resolveAuth(auth: HttpDispatchOptions<Scenario, unknown>['auth']): Promise<string | null> {\n if (!auth) return Promise.resolve(null)\n if (typeof auth === 'string') return Promise.resolve(auth)\n return Promise.resolve(auth())\n}\n\n/**\n * Wrap a remote HTTP endpoint as a `Dispatch`. The remote side should run\n * `runDispatchServer` (or any service that speaks the same wire shape).\n *\n * Cancellation: the substrate's per-cell `AbortSignal` is forwarded; the\n * server's `runDispatchServer` translates the resulting `AbortError` into\n * a 499 (client-closed) so the client doesn't retry.\n */\nexport function httpDispatch<TScenario extends Scenario, TArtifact>(\n opts: HttpDispatchOptions<TScenario, TArtifact>,\n): Dispatch<TScenario, TArtifact> {\n if (!opts.url && !opts.resolveUrl) {\n throw new Error('httpDispatch: pass exactly one of `url` or `resolveUrl`.')\n }\n if (opts.url && opts.resolveUrl) {\n throw new Error('httpDispatch: pass exactly one of `url` or `resolveUrl`, not both.')\n }\n const timeoutMs = opts.timeoutMs ?? 5 * 60 * 1000\n const maxRetries = opts.retries ?? 2\n const f: typeof fetch = opts.fetchImpl ?? ((...args) => fetch(...args))\n\n return async (scenario, ctx) => {\n const url =\n opts.url ?? opts.resolveUrl!({ scenario, placement: ctx.placement, cellId: ctx.cellId })\n const authValue = await resolveAuth(opts.auth)\n const body: HttpDispatchRequestBody<TScenario> = {\n scenario,\n cellId: ctx.cellId,\n runAttemptId: ctx.runAttemptId,\n rep: ctx.rep,\n generation: ctx.generation,\n seed: ctx.seed,\n placement: ctx.placement,\n cycleId: ctx.cycleId,\n }\n\n let lastError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Compose the request signal: caller's signal OR our timeout.\n const ourTimeout = AbortSignal.timeout(timeoutMs)\n const combinedSignal = AbortSignal.any([ctx.signal, ourTimeout])\n try {\n const res = await f(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(authValue\n ? {\n Authorization: authValue.startsWith('Bearer ')\n ? authValue\n : `Bearer ${authValue}`,\n }\n : {}),\n ...opts.headers,\n },\n body: JSON.stringify(body),\n signal: combinedSignal,\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n // A dispatch that pays for part of its work before failing (a judge\n // call that settles, then the provider call itself errors) still\n // owes that spend to the coordinator's ledger — read it before\n // deciding whether this attempt retries or this cell fails. A\n // non-JSON error body (401/404/413's plain text) carries none.\n for (const receipt of parseErrorReceipts(text)) {\n await replayReceipt(ctx.cost, receipt)\n }\n // 4xx is non-retryable (caller error, auth, bad scenario shape).\n // 5xx / 408 / 429 / 502 / 503 / 504 are retryable.\n const retryable = res.status >= 500 || res.status === 408 || res.status === 429\n if (!retryable || attempt === maxRetries) {\n throw new Error(`httpDispatch ${url} failed (${res.status}): ${text.slice(0, 500)}`)\n }\n // exponential backoff with jitter\n await sleep(2 ** attempt * 200 + Math.random() * 200)\n continue\n }\n const parsed = (await res.json()) as HttpDispatchResponseBody<TArtifact>\n for (const receipt of parsed.receipts ?? []) {\n await replayReceipt(ctx.cost, receipt)\n }\n return parsed.artifact\n } catch (err) {\n // Caller-driven abort is terminal — never retry.\n if (ctx.signal.aborted) throw err\n lastError = err\n if (attempt === maxRetries) throw err\n await sleep(2 ** attempt * 200 + Math.random() * 200)\n }\n }\n throw lastError ?? new Error('httpDispatch exhausted retries')\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const t = setTimeout(resolve, ms)\n // Don't keep node process alive purely for backoff sleeps.\n if (typeof (t as { unref?: () => void }).unref === 'function')\n (t as { unref: () => void }).unref()\n })\n}\n\n/** Best-effort receipts from a non-2xx `runDispatchServer` body. Any shape\n * that isn't `{ error, receipts? }` JSON (plain-text 401/404/413 bodies,\n * a non-`runDispatchServer` peer) yields none — never itself a reason to\n * fail the request. */\nfunction parseErrorReceipts(text: string): CostReceipt[] {\n try {\n const parsed = JSON.parse(text) as { receipts?: CostReceipt[] }\n return Array.isArray(parsed.receipts) ? parsed.receipts : []\n } catch {\n return []\n }\n}\n\n/**\n * Re-enter one already-settled remote receipt through `runPaidCall` — the\n * only path `CampaignCostMeter` admits. `execute` does no new work (the\n * spend already happened on the worker); it only replays the worker's\n * outcome so the coordinator's ledger records the same receipt (a settled\n * failure included, so its `error` and cost — a failed call can still burn\n * tokens — are never dropped on the floor). Faithfully replaying a remote\n * failure still returns `succeeded: false` from `runPaidCall`: that's not\n * ours to raise. Only a `receipt`-less failure is — it means `runPaidCall`\n * refused to admit the call at all (a duplicate `callId`, an unknown-cost\n * receipt under a capped coordinator ledger, a breached cost ceiling), so\n * the remote spend could not be accounted for.\n */\nasync function replayReceipt(cost: CampaignCostMeter, receipt: CostReceipt): Promise<void> {\n const knownCostUsd = receipt.costUnknown ? undefined : receipt.costUsd\n const observed = (): CostReceiptInput => ({\n model: receipt.model,\n inputTokens: receipt.inputTokens,\n outputTokens: receipt.outputTokens,\n ...(receipt.reasoningTokens === undefined ? {} : { reasoningTokens: receipt.reasoningTokens }),\n ...(receipt.cachedTokens === undefined ? {} : { cachedTokens: receipt.cachedTokens }),\n ...(receipt.cacheWriteTokens === undefined\n ? {}\n : { cacheWriteTokens: receipt.cacheWriteTokens }),\n ...(receipt.usageUnknown ? { usageUnknown: true as const } : {}),\n ...(knownCostUsd === undefined\n ? { costUnknown: true as const }\n : { actualCostUsd: knownCostUsd }),\n })\n const result = await cost.runPaidCall({\n callId: receipt.callId,\n channel: receipt.channel,\n actor: receipt.actor,\n model: receipt.model,\n maximumCharge:\n knownCostUsd === undefined ? undefined : { externallyEnforcedMaximumUsd: knownCostUsd },\n // No `signal`: the call already happened remotely. Aborting the replay\n // would not undo the spend, only hide it from the ledger.\n execute: async () => {\n if (receipt.error) throw new Error(receipt.error)\n return null\n },\n receipt: observed,\n receiptFromError: observed,\n })\n if (!result.succeeded && !result.receipt) {\n throw result.error\n }\n}\n\n// ── Server ───────────────────────────────────────────────────────────\n\nexport interface RunDispatchServerOptions<TScenario extends Scenario, TArtifact> {\n /** The Dispatch this server exposes — what runs when a request lands. */\n dispatch: Dispatch<TScenario, TArtifact>\n /** TCP port to bind. */\n port: number\n /** Optional bind host; defaults to 0.0.0.0. */\n host?: string\n /** Required for any non-test deployment: the bearer token clients must\n * send. The substrate refuses to start without auth unless `auth: false`\n * is set explicitly (intended ONLY for closed-network/internal testing). */\n auth: string | false\n /** Path the server listens on. Default `/dispatch`. */\n path?: string\n /**\n * Per-request handler that wraps `dispatch` with whatever context the\n * worker side needs to construct a `DispatchContext` — typically the\n * trace writer, artifact writer, and cost meter. The substrate provides\n * synthetic-but-typed defaults if not supplied; production deployments\n * should wire real ones (e.g. ship traces to your OTel collector).\n */\n contextFactory?: (\n req: HttpDispatchRequestBody<TScenario>,\n signal: AbortSignal,\n ) => Promise<DispatchContext>\n /** Optional max payload size for the request body (bytes). Default 10 MB. */\n maxBodyBytes?: number\n /** Hook for observability — called on every successful or failed turn. */\n onRequest?: (event: {\n cellId: string\n durationMs: number\n success: boolean\n error?: unknown\n }) => void\n}\n\nexport interface DispatchServerHandle {\n /** The actual bound port (useful when `port: 0` requests an ephemeral port). */\n port: number\n /** Stop accepting new connections and drain existing ones. */\n close: () => Promise<void>\n}\n\n/**\n * Start an HTTP server exposing a local `Dispatch` over the wire. Pair with\n * `httpDispatch` on the driver side.\n *\n * Wire shape:\n *\n * POST /dispatch\n * Authorization: Bearer <token>\n * Body: HttpDispatchRequestBody\n * 200 OK: HttpDispatchResponseBody\n * 401: missing/invalid auth\n * 408: per-request timeout exceeded\n * 499: client aborted before completion\n * 500: dispatch threw\n *\n * The server is `node:http`-based to keep the runtime dependency surface\n * minimal — works in plain Node, sandbox, or any container.\n */\nexport async function runDispatchServer<TScenario extends Scenario, TArtifact>(\n opts: RunDispatchServerOptions<TScenario, TArtifact>,\n): Promise<DispatchServerHandle> {\n if (opts.auth === undefined) {\n throw new Error(\n \"runDispatchServer: 'auth' is required (pass a bearer-token string, or `auth: false` explicitly for a closed-network test deployment).\",\n )\n }\n const path = opts.path ?? '/dispatch'\n const maxBytes = opts.maxBodyBytes ?? 10 * 1024 * 1024\n const expectedAuth =\n typeof opts.auth === 'string' ? `Bearer ${opts.auth.replace(/^Bearer\\s+/, '')}` : null\n\n // Lazy-import node:http so the file is usable from non-Node bundlers\n // that import the client side only (e.g. an edge driver shipping\n // httpDispatch alone). Server side is opt-in by calling this function.\n const { createServer } = await import('node:http')\n\n const server = createServer(async (req, res) => {\n const start = Date.now()\n let cellId = 'unknown'\n let success = false\n let errCaught: unknown\n // Hoisted so a dispatch that throws AFTER paying for some of its work\n // still reports that spend in the error response — a partial spend is\n // still spend, and it must reach the coordinator's ledger exactly like\n // a locally-dispatched cell's failure accounting does.\n const receipts: CostReceipt[] = []\n\n try {\n if (req.method !== 'POST' || req.url?.split('?')[0] !== path) {\n res.statusCode = 404\n res.end('not found')\n return\n }\n if (expectedAuth) {\n const got = req.headers.authorization\n if (got !== expectedAuth) {\n res.statusCode = 401\n res.end('unauthorized')\n return\n }\n }\n\n // Read body up to maxBytes\n const chunks: Buffer[] = []\n let totalBytes = 0\n const aborter = new AbortController()\n // The request stream's 'close' fires when the BODY completes, so it\n // cannot signal disconnection. The response stream's 'close' fires\n // once per exchange: with `writableEnded` still false it means the\n // client went away before the dispatch answered.\n res.on('close', () => {\n if (!res.writableEnded) aborter.abort()\n })\n\n for await (const chunk of req) {\n const buf = chunk as Buffer\n totalBytes += buf.length\n if (totalBytes > maxBytes) {\n res.statusCode = 413\n res.end('payload too large')\n return\n }\n chunks.push(buf)\n }\n\n const body = JSON.parse(\n Buffer.concat(chunks).toString('utf8'),\n ) as HttpDispatchRequestBody<TScenario>\n if (typeof body.runAttemptId !== 'string' || body.runAttemptId.trim().length === 0) {\n throw new Error('runDispatchServer: request runAttemptId is required')\n }\n cellId = body.cellId\n\n const ctx: DispatchContext = opts.contextFactory\n ? await opts.contextFactory(body, aborter.signal)\n : {\n cellId: body.cellId,\n runAttemptId: body.runAttemptId,\n rep: body.rep,\n generation: body.generation,\n seed: body.seed,\n signal: aborter.signal,\n placement: body.placement,\n cycleId: body.cycleId,\n trace: NOOP_TRACE,\n artifacts: NOOP_ARTIFACTS,\n cost: NOOP_COST,\n }\n if (ctx.runAttemptId !== body.runAttemptId) {\n throw new Error('runDispatchServer: contextFactory must preserve request runAttemptId')\n }\n\n // Record every receipt this dispatch settles on ITS OWN `ctx.cost` (the\n // worker's ledger, not the coordinator's) so the response can carry\n // them back. `httpDispatch` replays each one into the coordinator's\n // ledger — see the module doc.\n const recordingCost: CampaignCostMeter = {\n async runPaidCall(input) {\n const result = await ctx.cost.runPaidCall(input)\n if (result.receipt) receipts.push(result.receipt)\n return result\n },\n }\n\n const artifact = await opts.dispatch(body.scenario, { ...ctx, cost: recordingCost })\n const responseBody: HttpDispatchResponseBody<TArtifact> = {\n artifact,\n ...(receipts.length ? { receipts } : {}),\n }\n\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify(responseBody))\n success = true\n } catch (err) {\n errCaught = err\n // Client-cancelled — they don't care about the result.\n if ((err as Error)?.name === 'AbortError') {\n res.statusCode = 499\n res.end('client aborted')\n return\n }\n res.statusCode = 500\n res.setHeader('content-type', 'application/json')\n res.end(\n JSON.stringify({\n error: err instanceof Error ? err.message : String(err),\n ...(receipts.length ? { receipts } : {}),\n }),\n )\n } finally {\n opts.onRequest?.({\n cellId,\n durationMs: Date.now() - start,\n success,\n error: errCaught,\n })\n }\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(opts.port, opts.host ?? '0.0.0.0', () => resolve())\n })\n\n const addr = server.address()\n const boundPort = typeof addr === 'object' && addr ? addr.port : opts.port\n\n return {\n port: boundPort,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close((err) => (err ? reject(err) : resolve()))\n }),\n }\n}\n\n// ── No-op default ctx machinery (worker can replace via contextFactory) ──\n\nconst NOOP_TRACE = {\n span: () => ({\n end: () => {},\n setAttribute: () => {},\n setStatus: () => {},\n recordException: () => {},\n addEvent: () => {},\n }),\n} as unknown as DispatchContext['trace']\n\nconst NOOP_ARTIFACTS = {\n write: async () => undefined,\n read: async () => undefined,\n list: async () => [],\n} as unknown as DispatchContext['artifacts']\n\nconst NOOP_COST = {\n record: () => {},\n total: () => 0,\n} as unknown as DispatchContext['cost']\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-profile-DDfIjdyS.d.ts","names":[],"sources":["../src/campaign/external-optimizer-contracts.ts","../src/analyst/benchmark-scoring.ts","../src/analyst/benchmark.ts","../src/agent-profile.ts"],"mappings":";;;;;;UAWiB;;EAEf;;EAEA;;EAEA;;cAGW,2CAA2C,SAAS;UAOhD;;EAEf;;EAEA;;cAGW,4CAA4C,SAAS;UAMjD;EACf;EACA;EACA,MAAM,OAAO;;EAEb,SAAS,QAAQ;;KAGP;KAEA,iCAAiC;UAE5B;EACf,WAAW;EACX;;iBAUc,sCACd,OAAO,QAAQ,6CACf,iBACC;iBAmBa,uCACd,OAAO,QAAQ,8CACf,iBACC;KAkBE,aAAa,KAAK,eAAc,6BACjC,IACA,0BAA0B,gBACf,aAAa,OACtB,+BACc,WAAW,IAAI,aAAa,EAAE,SAC1C;;KAGI,+BAA+B,aACzC,KAAK;EAA0B;;KAGrB;;UAMK;;WAEN;;WAEA,SAAS;;WAET,iBAAiB;WACjB,QAAQ;;;KAIP;WAEG;;WAEA,UAAU;;;;;;;WAOV,
|
|
1
|
+
{"version":3,"file":"agent-profile-DDfIjdyS.d.ts","names":["_$___cost_ledger0.CostReceiptInput"],"sources":["../src/campaign/external-optimizer-contracts.ts","../src/analyst/benchmark-scoring.ts","../src/analyst/benchmark.ts","../src/agent-profile.ts"],"mappings":"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"}
|