issue-flow 0.15.0 → 0.17.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/dist/agent-TB6W7PT7.js +30 -0
- package/dist/{analyze-O2PYDIFK.js → analyze-6M3KEOX7.js} +22 -22
- package/dist/{apply-SSU6QCD4.js → apply-ADB3ZK7W.js} +14 -14
- package/dist/{bench-ODFPAGW6.js → bench-FM7I7EIV.js} +23 -23
- package/dist/{chunk-BMHGRYL6.js → chunk-2SUFAE6X.js} +67 -24
- package/dist/chunk-2SUFAE6X.js.map +1 -0
- package/dist/{chunk-QRCGW2ZO.js → chunk-32JSYXEK.js} +8 -8
- package/dist/chunk-3R27MJ5R.js +25 -0
- package/dist/chunk-3R27MJ5R.js.map +1 -0
- package/dist/{chunk-MGCOQU6N.js → chunk-6YQT3SSM.js} +4 -4
- package/dist/chunk-6YQT3SSM.js.map +1 -0
- package/dist/{chunk-A35HE4V7.js → chunk-7F7LGMVO.js} +3 -3
- package/dist/{chunk-RPXDBX6R.js → chunk-A4H7P7T7.js} +102 -102
- package/dist/chunk-A4H7P7T7.js.map +1 -0
- package/dist/{chunk-2ZAM45PZ.js → chunk-ANI2NTR4.js} +9 -9
- package/dist/{chunk-ZPIVCM7Q.js → chunk-B3TSS7BT.js} +3 -3
- package/dist/chunk-C5TL7T4V.js +27 -0
- package/dist/chunk-C5TL7T4V.js.map +1 -0
- package/dist/chunk-D6ZBGJ3L.js +321 -0
- package/dist/chunk-D6ZBGJ3L.js.map +1 -0
- package/dist/{chunk-ZXPASFHG.js → chunk-DGRTJD5R.js} +3 -3
- package/dist/{chunk-6QYMSNVA.js → chunk-DUS5ZNKL.js} +476 -362
- package/dist/chunk-DUS5ZNKL.js.map +1 -0
- package/dist/{chunk-VR34TXHF.js → chunk-DV7HUC4Z.js} +7 -7
- package/dist/{chunk-6SRE4KD7.js → chunk-E6KXCV3T.js} +4 -4
- package/dist/{chunk-HGSYD57B.js → chunk-HJBF4WD2.js} +1656 -1070
- package/dist/chunk-HJBF4WD2.js.map +1 -0
- package/dist/{chunk-PCN7ZQND.js → chunk-HLAPOUEM.js} +8 -8
- package/dist/{chunk-WM3Y7Q4A.js → chunk-HY5HLFDU.js} +630 -571
- package/dist/chunk-HY5HLFDU.js.map +1 -0
- package/dist/{chunk-XDKGA6UX.js → chunk-ICM463EO.js} +64 -14
- package/dist/chunk-ICM463EO.js.map +1 -0
- package/dist/{chunk-MEFY4B7T.js → chunk-ISZ54SVE.js} +9 -9
- package/dist/{chunk-ARWNYXFL.js → chunk-KZ5EY5XX.js} +12 -12
- package/dist/{chunk-ZFIXEYUJ.js → chunk-KZXQWC7U.js} +32 -20
- package/dist/chunk-KZXQWC7U.js.map +1 -0
- package/dist/{chunk-KAHQ6F5C.js → chunk-LPWPFIIB.js} +11 -11
- package/dist/{chunk-FK4IDY6P.js → chunk-MI5TREN3.js} +9 -9
- package/dist/{chunk-UNQYMR3H.js → chunk-PPZ3K4YM.js} +2 -2
- package/dist/{chunk-F4OK7KEP.js → chunk-QMIQR7EE.js} +10 -10
- package/dist/{chunk-AYYMW33T.js → chunk-QPGEFLMY.js} +2 -2
- package/dist/chunk-RCZJQUTC.js +196 -0
- package/dist/chunk-RCZJQUTC.js.map +1 -0
- package/dist/{chunk-MROS3SKL.js → chunk-RNFUVKC3.js} +3 -3
- package/dist/{chunk-RWEXK55D.js → chunk-RYOUZ6EK.js} +2 -2
- package/dist/{chunk-6E2PEBFT.js → chunk-SGTTR4XW.js} +10 -10
- package/dist/{chunk-XQHFC62U.js → chunk-SOM4QA6C.js} +3 -3
- package/dist/{chunk-5ZKBIXET.js → chunk-UK4E2FUA.js} +132 -34
- package/dist/chunk-UK4E2FUA.js.map +1 -0
- package/dist/{chunk-6FXOU2KR.js → chunk-UWDCIFTP.js} +7 -7
- package/dist/{chunk-XG2NYDRA.js → chunk-VE3IYNDN.js} +3 -3
- package/dist/{chunk-3BWZO4YI.js → chunk-WCCZJL7W.js} +2 -2
- package/dist/{chunk-NVZMBXTE.js → chunk-XZUEFTUP.js} +6 -6
- package/dist/{chunk-TBDP6QPJ.js → chunk-YII4U7ZD.js} +10 -10
- package/dist/{chunk-TBDP6QPJ.js.map → chunk-YII4U7ZD.js.map} +1 -1
- package/dist/{chunk-4RXYFWP7.js → chunk-YUNBOUQH.js} +6 -6
- package/dist/{chunk-GSZCQUCY.js → chunk-YVPZUN6X.js} +2 -2
- package/dist/{chunk-XRLRKTQA.js → chunk-Z5O2XBWA.js} +14 -14
- package/dist/cli.js +61 -52
- package/dist/cli.js.map +1 -1
- package/dist/{config-UMP6DBJB.js → config-KGZUPAUP.js} +13 -13
- package/dist/{conventions-DKH7AE4T.js → conventions-RYN7OXJN.js} +15 -15
- package/dist/{diagnostics-GOGCLTRS.js → diagnostics-HTCWF7F4.js} +7 -7
- package/dist/execute-QL3ZQIAP.js +37 -0
- package/dist/{generate-AGBT7EHX.js → generate-CX6KNHZS.js} +22 -22
- package/dist/{git-AC542GU2.js → git-A2IP32PQ.js} +2 -2
- package/dist/init-PDVQDRS6.js +24 -0
- package/dist/{operations-JQYK2EMT.js → operations-CAKIT2BO.js} +15 -15
- package/dist/{permissions-6HL52K54.js → permissions-G4XCAESF.js} +4 -4
- package/dist/plan-PRORGS3L.js +34 -0
- package/dist/{policy-IMRXGG7X.js → policy-WX6O2JID.js} +14 -14
- package/dist/pr-27RMQI5F.js +39 -0
- package/dist/pr-review-VNESMAMT.js +32 -0
- package/dist/prd-ZNC4T5BS.js +33 -0
- package/dist/{ps-KUUZ6TUL.js → ps-76L6ZAZL.js} +12 -12
- package/dist/{recorder-BJ2KIAWT.js → recorder-N7U66HCO.js} +7 -7
- package/dist/{registry-SB7XTMGE.js → registry-XLHHYLTR.js} +5 -5
- package/dist/{resume-QNLQSCR5.js → resume-VLWIE264.js} +40 -38
- package/dist/{resume-QNLQSCR5.js.map → resume-VLWIE264.js.map} +1 -1
- package/dist/review-7CREJDKB.js +35 -0
- package/dist/routing-VCDYHSXA.js +33 -0
- package/dist/run-3MPORLF5.js +56 -0
- package/dist/{session-publisher-T7EI3CIP.js → session-publisher-KAJQRHNZ.js} +3 -2
- package/dist/{state-manager-ZEPWTCA6.js → state-manager-UPHO2EA2.js} +4 -4
- package/dist/state-manager-UPHO2EA2.js.map +1 -0
- package/dist/{usage-QL563I7F.js → usage-U7QNGCPK.js} +12 -12
- package/dist/{web-PPSMNTQ6.js → web-HUNDHCJ4.js} +21 -18
- package/dist/{web-PPSMNTQ6.js.map → web-HUNDHCJ4.js.map} +1 -1
- package/package.json +6 -5
- package/web/AGENTS.md +15 -11
- package/web/public/app.css +51 -0
- package/web/public/app.js +325 -56
- package/web/public/index.html +6 -2
- package/dist/agent-AT64RXTA.js +0 -30
- package/dist/chunk-5ZKBIXET.js.map +0 -1
- package/dist/chunk-6QYMSNVA.js.map +0 -1
- package/dist/chunk-7Z4Y3VKM.js +0 -26
- package/dist/chunk-7Z4Y3VKM.js.map +0 -1
- package/dist/chunk-BMHGRYL6.js.map +0 -1
- package/dist/chunk-HGSYD57B.js.map +0 -1
- package/dist/chunk-MGCOQU6N.js.map +0 -1
- package/dist/chunk-RPXDBX6R.js.map +0 -1
- package/dist/chunk-WM3Y7Q4A.js.map +0 -1
- package/dist/chunk-XDKGA6UX.js.map +0 -1
- package/dist/chunk-XLVGPXNL.js +0 -180
- package/dist/chunk-XLVGPXNL.js.map +0 -1
- package/dist/chunk-ZFIXEYUJ.js.map +0 -1
- package/dist/execute-E3BRMDAQ.js +0 -35
- package/dist/init-LLBVJNPE.js +0 -24
- package/dist/plan-HSLWDJEZ.js +0 -34
- package/dist/pr-6TCZXG6K.js +0 -39
- package/dist/pr-review-6MWJO2NP.js +0 -32
- package/dist/prd-D6YDYAFX.js +0 -33
- package/dist/review-3KJ4BH2V.js +0 -35
- package/dist/routing-TN7GLMGU.js +0 -94
- package/dist/routing-TN7GLMGU.js.map +0 -1
- package/dist/run-5EHIFF2V.js +0 -54
- /package/dist/{agent-AT64RXTA.js.map → agent-TB6W7PT7.js.map} +0 -0
- /package/dist/{analyze-O2PYDIFK.js.map → analyze-6M3KEOX7.js.map} +0 -0
- /package/dist/{apply-SSU6QCD4.js.map → apply-ADB3ZK7W.js.map} +0 -0
- /package/dist/{bench-ODFPAGW6.js.map → bench-FM7I7EIV.js.map} +0 -0
- /package/dist/{chunk-QRCGW2ZO.js.map → chunk-32JSYXEK.js.map} +0 -0
- /package/dist/{chunk-A35HE4V7.js.map → chunk-7F7LGMVO.js.map} +0 -0
- /package/dist/{chunk-2ZAM45PZ.js.map → chunk-ANI2NTR4.js.map} +0 -0
- /package/dist/{chunk-ZPIVCM7Q.js.map → chunk-B3TSS7BT.js.map} +0 -0
- /package/dist/{chunk-ZXPASFHG.js.map → chunk-DGRTJD5R.js.map} +0 -0
- /package/dist/{chunk-VR34TXHF.js.map → chunk-DV7HUC4Z.js.map} +0 -0
- /package/dist/{chunk-6SRE4KD7.js.map → chunk-E6KXCV3T.js.map} +0 -0
- /package/dist/{chunk-PCN7ZQND.js.map → chunk-HLAPOUEM.js.map} +0 -0
- /package/dist/{chunk-MEFY4B7T.js.map → chunk-ISZ54SVE.js.map} +0 -0
- /package/dist/{chunk-ARWNYXFL.js.map → chunk-KZ5EY5XX.js.map} +0 -0
- /package/dist/{chunk-KAHQ6F5C.js.map → chunk-LPWPFIIB.js.map} +0 -0
- /package/dist/{chunk-FK4IDY6P.js.map → chunk-MI5TREN3.js.map} +0 -0
- /package/dist/{chunk-UNQYMR3H.js.map → chunk-PPZ3K4YM.js.map} +0 -0
- /package/dist/{chunk-F4OK7KEP.js.map → chunk-QMIQR7EE.js.map} +0 -0
- /package/dist/{chunk-AYYMW33T.js.map → chunk-QPGEFLMY.js.map} +0 -0
- /package/dist/{chunk-MROS3SKL.js.map → chunk-RNFUVKC3.js.map} +0 -0
- /package/dist/{chunk-RWEXK55D.js.map → chunk-RYOUZ6EK.js.map} +0 -0
- /package/dist/{chunk-6E2PEBFT.js.map → chunk-SGTTR4XW.js.map} +0 -0
- /package/dist/{chunk-XQHFC62U.js.map → chunk-SOM4QA6C.js.map} +0 -0
- /package/dist/{chunk-6FXOU2KR.js.map → chunk-UWDCIFTP.js.map} +0 -0
- /package/dist/{chunk-XG2NYDRA.js.map → chunk-VE3IYNDN.js.map} +0 -0
- /package/dist/{chunk-3BWZO4YI.js.map → chunk-WCCZJL7W.js.map} +0 -0
- /package/dist/{chunk-NVZMBXTE.js.map → chunk-XZUEFTUP.js.map} +0 -0
- /package/dist/{chunk-4RXYFWP7.js.map → chunk-YUNBOUQH.js.map} +0 -0
- /package/dist/{chunk-GSZCQUCY.js.map → chunk-YVPZUN6X.js.map} +0 -0
- /package/dist/{chunk-XRLRKTQA.js.map → chunk-Z5O2XBWA.js.map} +0 -0
- /package/dist/{config-UMP6DBJB.js.map → config-KGZUPAUP.js.map} +0 -0
- /package/dist/{conventions-DKH7AE4T.js.map → conventions-RYN7OXJN.js.map} +0 -0
- /package/dist/{diagnostics-GOGCLTRS.js.map → diagnostics-HTCWF7F4.js.map} +0 -0
- /package/dist/{execute-E3BRMDAQ.js.map → execute-QL3ZQIAP.js.map} +0 -0
- /package/dist/{generate-AGBT7EHX.js.map → generate-CX6KNHZS.js.map} +0 -0
- /package/dist/{git-AC542GU2.js.map → git-A2IP32PQ.js.map} +0 -0
- /package/dist/{init-LLBVJNPE.js.map → init-PDVQDRS6.js.map} +0 -0
- /package/dist/{operations-JQYK2EMT.js.map → operations-CAKIT2BO.js.map} +0 -0
- /package/dist/{permissions-6HL52K54.js.map → permissions-G4XCAESF.js.map} +0 -0
- /package/dist/{plan-HSLWDJEZ.js.map → plan-PRORGS3L.js.map} +0 -0
- /package/dist/{policy-IMRXGG7X.js.map → policy-WX6O2JID.js.map} +0 -0
- /package/dist/{pr-6TCZXG6K.js.map → pr-27RMQI5F.js.map} +0 -0
- /package/dist/{pr-review-6MWJO2NP.js.map → pr-review-VNESMAMT.js.map} +0 -0
- /package/dist/{prd-D6YDYAFX.js.map → prd-ZNC4T5BS.js.map} +0 -0
- /package/dist/{ps-KUUZ6TUL.js.map → ps-76L6ZAZL.js.map} +0 -0
- /package/dist/{recorder-BJ2KIAWT.js.map → recorder-N7U66HCO.js.map} +0 -0
- /package/dist/{registry-SB7XTMGE.js.map → registry-XLHHYLTR.js.map} +0 -0
- /package/dist/{review-3KJ4BH2V.js.map → review-7CREJDKB.js.map} +0 -0
- /package/dist/{run-5EHIFF2V.js.map → routing-VCDYHSXA.js.map} +0 -0
- /package/dist/{session-publisher-T7EI3CIP.js.map → run-3MPORLF5.js.map} +0 -0
- /package/dist/{state-manager-ZEPWTCA6.js.map → session-publisher-KAJQRHNZ.js.map} +0 -0
- /package/dist/{usage-QL563I7F.js.map → usage-U7QNGCPK.js.map} +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MODEL_CATALOG_VERSION,
|
|
4
|
+
PRIORS_VERSION,
|
|
5
|
+
RECOMMENDED_POLICY_VERSION,
|
|
6
|
+
decideRouting
|
|
7
|
+
} from "./chunk-D6ZBGJ3L.js";
|
|
8
|
+
import {
|
|
9
|
+
GLOBAL_CONFIG_FILENAME,
|
|
10
|
+
loadRoutingConfig
|
|
11
|
+
} from "./chunk-HY5HLFDU.js";
|
|
12
|
+
import {
|
|
13
|
+
resolveIssuePaths
|
|
14
|
+
} from "./chunk-DV7HUC4Z.js";
|
|
15
|
+
import {
|
|
16
|
+
printError,
|
|
17
|
+
printInfo,
|
|
18
|
+
printSuccess
|
|
19
|
+
} from "./chunk-XZUEFTUP.js";
|
|
20
|
+
import {
|
|
21
|
+
getGlobalRoot
|
|
22
|
+
} from "./chunk-HAKDLR6N.js";
|
|
23
|
+
import {
|
|
24
|
+
getProjectRoot
|
|
25
|
+
} from "./chunk-YVPZUN6X.js";
|
|
26
|
+
import {
|
|
27
|
+
loadTaskPlan
|
|
28
|
+
} from "./chunk-SOM4QA6C.js";
|
|
29
|
+
import {
|
|
30
|
+
AGENT_PHASES,
|
|
31
|
+
routingConfigInputSchema
|
|
32
|
+
} from "./chunk-ICM463EO.js";
|
|
33
|
+
import {
|
|
34
|
+
writeFileAtomic
|
|
35
|
+
} from "./chunk-3R27MJ5R.js";
|
|
36
|
+
|
|
37
|
+
// src/commands/routing.ts
|
|
38
|
+
import { mkdir, readFile } from "fs/promises";
|
|
39
|
+
import { dirname, join } from "path";
|
|
40
|
+
var ROUTING_COMMAND_SCHEMA_VERSION = 1;
|
|
41
|
+
function targetLabel(target) {
|
|
42
|
+
if (target === void 0) return "\u2014";
|
|
43
|
+
if (typeof target === "string") return target;
|
|
44
|
+
const tier = target.tier ? `:${target.tier}` : "";
|
|
45
|
+
const model = target.model ? ` \xB7 ${target.model}` : "";
|
|
46
|
+
return `${target.provider}${tier}${model}`;
|
|
47
|
+
}
|
|
48
|
+
function targetKey(target) {
|
|
49
|
+
if (target === void 0) return "\u2014";
|
|
50
|
+
if (typeof target === "string") return target;
|
|
51
|
+
return `${target.harness}:${target.provider}:${target.model ?? ""}`;
|
|
52
|
+
}
|
|
53
|
+
async function runRoutingInspect(options) {
|
|
54
|
+
const config = await loadRoutingConfig();
|
|
55
|
+
const sample = decideRouting({
|
|
56
|
+
phase: "execute",
|
|
57
|
+
actualHarness: "claude-code",
|
|
58
|
+
mode: config.mode,
|
|
59
|
+
profile: config.profile
|
|
60
|
+
});
|
|
61
|
+
if (options.json === true) {
|
|
62
|
+
console.log(
|
|
63
|
+
JSON.stringify(
|
|
64
|
+
{
|
|
65
|
+
schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION,
|
|
66
|
+
priorsVersion: PRIORS_VERSION,
|
|
67
|
+
modelCatalogVersion: MODEL_CATALOG_VERSION,
|
|
68
|
+
recommendedPolicyVersion: RECOMMENDED_POLICY_VERSION,
|
|
69
|
+
config,
|
|
70
|
+
sample
|
|
71
|
+
},
|
|
72
|
+
null,
|
|
73
|
+
2
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
printInfo(`routing.mode: ${config.mode} (default shadow \u2014 records, does not act)`);
|
|
79
|
+
printInfo(`routing.profile: ${config.profile}`);
|
|
80
|
+
if (sample) {
|
|
81
|
+
printInfo(
|
|
82
|
+
`sample selected=${targetLabel(sample.selected)} actual=${targetLabel(sample.actual)} class=${sample.taskClass}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
async function runRoutingReport(options) {
|
|
88
|
+
if (options.issue === void 0) {
|
|
89
|
+
printInfo("Pass --issue N to compare selected vs actual on that plan.");
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
const paths = await resolveIssuePaths(options.issue);
|
|
93
|
+
const plan = await loadTaskPlan(paths.tasksFile);
|
|
94
|
+
const records = plan.executions ?? [];
|
|
95
|
+
let agree = 0;
|
|
96
|
+
let total = 0;
|
|
97
|
+
for (const record of records) {
|
|
98
|
+
const decision = record.routingDecision;
|
|
99
|
+
if (decision === void 0 || decision === null) continue;
|
|
100
|
+
total += 1;
|
|
101
|
+
if (targetKey(decision.selected) === targetKey(decision.actual)) agree += 1;
|
|
102
|
+
}
|
|
103
|
+
const rate = total === 0 ? 0 : agree / total;
|
|
104
|
+
if (options.json === true) {
|
|
105
|
+
console.log(
|
|
106
|
+
JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, total, agree, rate })
|
|
107
|
+
);
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
printInfo(`shadow agreement: ${agree}/${total} (${(rate * 100).toFixed(0)}%)`);
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
async function runRoutingExplain(options = {}) {
|
|
114
|
+
const config = await loadRoutingConfig();
|
|
115
|
+
const phases = AGENT_PHASES.map((phase) => {
|
|
116
|
+
const decision = decideRouting({
|
|
117
|
+
phase,
|
|
118
|
+
actualHarness: "claude-code",
|
|
119
|
+
actualProvider: "claude",
|
|
120
|
+
mode: config.mode === "off" ? "shadow" : config.mode,
|
|
121
|
+
profile: config.profile,
|
|
122
|
+
policy: config.policy
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
phase,
|
|
126
|
+
target: decision?.selected ?? null,
|
|
127
|
+
origin: config.policy === "recommended" ? "recommended policy" : "adaptive score"
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
if (options.json === true) {
|
|
131
|
+
console.log(
|
|
132
|
+
JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, config, phases }, null, 2)
|
|
133
|
+
);
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
printInfo(`routing policy: ${config.policy ?? "adaptive"} (${config.mode})`);
|
|
137
|
+
for (const phase of phases) {
|
|
138
|
+
printInfo(
|
|
139
|
+
`${phase.phase.padEnd(12)} ${targetLabel(phase.target ?? void 0)} (${phase.origin})`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
async function writeRoutingPreference(input) {
|
|
145
|
+
const parsed = routingConfigInputSchema.safeParse(input.values);
|
|
146
|
+
if (!parsed.success || Object.keys(parsed.data).length === 0) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
parsed.success ? "At least one routing setting is required." : `Invalid routing setting: ${parsed.error.issues[0]?.message ?? "invalid value"}.`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const path = input.target === "global" ? join(getGlobalRoot(), GLOBAL_CONFIG_FILENAME) : join(input.projectRoot ?? await getProjectRoot(), ".issue-flow.json");
|
|
152
|
+
let existing = {};
|
|
153
|
+
try {
|
|
154
|
+
const value = JSON.parse(await readFile(path, "utf-8"));
|
|
155
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
156
|
+
existing = value;
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (error.code !== "ENOENT") {
|
|
160
|
+
throw new Error(`Could not read ${path}: ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const current = existing.routing !== null && typeof existing.routing === "object" && !Array.isArray(existing.routing) ? existing.routing : {};
|
|
164
|
+
existing.routing = { ...current, ...parsed.data };
|
|
165
|
+
await mkdir(dirname(path), { recursive: true });
|
|
166
|
+
await writeFileAtomic(path, `${JSON.stringify(existing, null, 2)}
|
|
167
|
+
`);
|
|
168
|
+
return path;
|
|
169
|
+
}
|
|
170
|
+
async function runRoutingUse(policy, options = {}) {
|
|
171
|
+
if (policy !== "recommended") {
|
|
172
|
+
printError(`Unknown routing policy '${policy}'. Valid policy: recommended.`);
|
|
173
|
+
return 1;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const file = await writeRoutingPreference({
|
|
177
|
+
target: options.project === true ? "project" : "global",
|
|
178
|
+
values: { policy: "recommended" }
|
|
179
|
+
});
|
|
180
|
+
printSuccess(`Wrote recommended routing policy to ${file}`);
|
|
181
|
+
return 0;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
printError(error instanceof Error ? error.message : String(error));
|
|
184
|
+
return 1;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export {
|
|
189
|
+
ROUTING_COMMAND_SCHEMA_VERSION,
|
|
190
|
+
runRoutingInspect,
|
|
191
|
+
runRoutingReport,
|
|
192
|
+
runRoutingExplain,
|
|
193
|
+
writeRoutingPreference,
|
|
194
|
+
runRoutingUse
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=chunk-RCZJQUTC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/routing.ts"],"sourcesContent":["import { mkdir, readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { AGENT_PHASES } from '../agents/types.js';\nimport { GLOBAL_CONFIG_FILENAME, loadRoutingConfig } from '../config.js';\nimport { loadTaskPlan } from '../core/state-manager.js';\nimport { decideRouting } from '../routing/decide.js';\nimport { MODEL_CATALOG_VERSION } from '../routing/models.js';\nimport { RECOMMENDED_POLICY_VERSION } from '../routing/policy.js';\nimport { PRIORS_VERSION } from '../routing/priors.js';\nimport { type RoutingConfigInput, routingConfigInputSchema } from '../schemas.js';\nimport { getGlobalRoot } from '../storage/paths.js';\nimport { resolveIssuePaths } from '../storage/resolve.js';\nimport { printError, printInfo, printSuccess } from '../ui/logger.js';\nimport { writeFileAtomic } from '../utils/fs.js';\nimport { getProjectRoot } from '../utils/git.js';\n\nexport const ROUTING_COMMAND_SCHEMA_VERSION = 1;\n\nfunction targetLabel(\n target:\n | { harness: string; provider: string; model?: string | null; tier?: string }\n | string\n | undefined,\n): string {\n if (target === undefined) return '—';\n if (typeof target === 'string') return target;\n const tier = target.tier ? `:${target.tier}` : '';\n const model = target.model ? ` · ${target.model}` : '';\n return `${target.provider}${tier}${model}`;\n}\n\nfunction targetKey(\n target:\n | { harness: string; provider: string; model?: string | null; tier?: string }\n | string\n | undefined,\n): string {\n if (target === undefined) return '—';\n if (typeof target === 'string') return target;\n return `${target.harness}:${target.provider}:${target.model ?? ''}`;\n}\n\nexport async function runRoutingInspect(options: { json?: boolean }): Promise<number> {\n const config = await loadRoutingConfig();\n const sample = decideRouting({\n phase: 'execute',\n actualHarness: 'claude-code',\n mode: config.mode,\n profile: config.profile,\n });\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION,\n priorsVersion: PRIORS_VERSION,\n modelCatalogVersion: MODEL_CATALOG_VERSION,\n recommendedPolicyVersion: RECOMMENDED_POLICY_VERSION,\n config,\n sample,\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n printInfo(`routing.mode: ${config.mode} (default shadow — records, does not act)`);\n printInfo(`routing.profile: ${config.profile}`);\n if (sample) {\n printInfo(\n `sample selected=${targetLabel(sample.selected)} actual=${targetLabel(sample.actual)} class=${sample.taskClass}`,\n );\n }\n return 0;\n}\n\nexport async function runRoutingReport(options: {\n issue?: string;\n json?: boolean;\n}): Promise<number> {\n if (options.issue === undefined) {\n printInfo('Pass --issue N to compare selected vs actual on that plan.');\n return 0;\n }\n const paths = await resolveIssuePaths(options.issue);\n const plan = await loadTaskPlan(paths.tasksFile);\n const records = plan.executions ?? [];\n let agree = 0;\n let total = 0;\n for (const record of records) {\n const decision = record.routingDecision;\n if (decision === undefined || decision === null) continue;\n total += 1;\n if (targetKey(decision.selected) === targetKey(decision.actual)) agree += 1;\n }\n const rate = total === 0 ? 0 : agree / total;\n if (options.json === true) {\n console.log(\n JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, total, agree, rate }),\n );\n return 0;\n }\n printInfo(`shadow agreement: ${agree}/${total} (${(rate * 100).toFixed(0)}%)`);\n return 0;\n}\n\nexport async function runRoutingExplain(options: { json?: boolean } = {}): Promise<number> {\n const config = await loadRoutingConfig();\n const phases = AGENT_PHASES.map((phase) => {\n const decision = decideRouting({\n phase,\n actualHarness: 'claude-code',\n actualProvider: 'claude',\n mode: config.mode === 'off' ? 'shadow' : config.mode,\n profile: config.profile,\n policy: config.policy,\n });\n return {\n phase,\n target: decision?.selected ?? null,\n origin: config.policy === 'recommended' ? 'recommended policy' : 'adaptive score',\n };\n });\n if (options.json === true) {\n console.log(\n JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, config, phases }, null, 2),\n );\n return 0;\n }\n printInfo(`routing policy: ${config.policy ?? 'adaptive'} (${config.mode})`);\n for (const phase of phases) {\n printInfo(\n `${phase.phase.padEnd(12)} ${targetLabel(phase.target ?? undefined)} (${phase.origin})`,\n );\n }\n return 0;\n}\n\nexport async function writeRoutingPreference(input: {\n target: 'global' | 'project';\n values: RoutingConfigInput;\n projectRoot?: string;\n}): Promise<string> {\n const parsed = routingConfigInputSchema.safeParse(input.values);\n if (!parsed.success || Object.keys(parsed.data).length === 0) {\n throw new Error(\n parsed.success\n ? 'At least one routing setting is required.'\n : `Invalid routing setting: ${parsed.error.issues[0]?.message ?? 'invalid value'}.`,\n );\n }\n const path =\n input.target === 'global'\n ? join(getGlobalRoot(), GLOBAL_CONFIG_FILENAME)\n : join(input.projectRoot ?? (await getProjectRoot()), '.issue-flow.json');\n let existing: Record<string, unknown> = {};\n try {\n const value: unknown = JSON.parse(await readFile(path, 'utf-8'));\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n existing = value as Record<string, unknown>;\n }\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw new Error(`Could not read ${path}: ${(error as Error).message}`);\n }\n }\n const current =\n existing.routing !== null &&\n typeof existing.routing === 'object' &&\n !Array.isArray(existing.routing)\n ? (existing.routing as Record<string, unknown>)\n : {};\n existing.routing = { ...current, ...parsed.data };\n await mkdir(dirname(path), { recursive: true });\n await writeFileAtomic(path, `${JSON.stringify(existing, null, 2)}\\n`);\n return path;\n}\n\nexport async function runRoutingUse(\n policy: string,\n options: { global?: boolean; project?: boolean } = {},\n): Promise<number> {\n if (policy !== 'recommended') {\n printError(`Unknown routing policy '${policy}'. Valid policy: recommended.`);\n return 1;\n }\n try {\n const file = await writeRoutingPreference({\n target: options.project === true ? 'project' : 'global',\n values: { policy: 'recommended' },\n });\n printSuccess(`Wrote recommended routing policy to ${file}`);\n return 0;\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readSessionFile
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RYOUZ6EK.js";
|
|
5
5
|
import {
|
|
6
6
|
PROJECTS_DIR_NAME,
|
|
7
7
|
RUN_LOCK_FILENAME,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isProcessAlive,
|
|
13
13
|
isRunLockStale,
|
|
14
14
|
readRunLock
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ICM463EO.js";
|
|
16
16
|
|
|
17
17
|
// src/execution/registry.ts
|
|
18
18
|
import { readdir } from "fs/promises";
|
|
@@ -69,4 +69,4 @@ export {
|
|
|
69
69
|
classifyRunLock,
|
|
70
70
|
listLiveRuns
|
|
71
71
|
};
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
//# sourceMappingURL=chunk-RNFUVKC3.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
sessionSnapshotSchema
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ICM463EO.js";
|
|
5
5
|
|
|
6
6
|
// src/storage/session-file.ts
|
|
7
7
|
import { readFile, stat as statFile } from "fs/promises";
|
|
@@ -27,4 +27,4 @@ async function readSessionFile(filePath) {
|
|
|
27
27
|
export {
|
|
28
28
|
readSessionFile
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-RYOUZ6EK.js.map
|
|
@@ -5,32 +5,32 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_HEADLESS_TIMEOUT_MS,
|
|
7
7
|
runHeadless
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UK4E2FUA.js";
|
|
9
9
|
import {
|
|
10
10
|
getRegisteredProviders,
|
|
11
11
|
loadVerifyConfig,
|
|
12
12
|
probeAgent,
|
|
13
13
|
resolveAgentFor
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
getSessionPublisher
|
|
17
|
-
} from "./chunk-6QYMSNVA.js";
|
|
14
|
+
} from "./chunk-HY5HLFDU.js";
|
|
18
15
|
import {
|
|
19
16
|
VERIFY_FILENAME
|
|
20
17
|
} from "./chunk-HAKDLR6N.js";
|
|
21
18
|
import {
|
|
22
19
|
getProjectRoot,
|
|
23
20
|
run
|
|
24
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-YVPZUN6X.js";
|
|
22
|
+
import {
|
|
23
|
+
getSessionPublisher
|
|
24
|
+
} from "./chunk-DUS5ZNKL.js";
|
|
25
25
|
import {
|
|
26
26
|
attachVerdict
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-YII4U7ZD.js";
|
|
28
28
|
import {
|
|
29
29
|
redactSecrets
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-PPZ3K4YM.js";
|
|
31
31
|
import {
|
|
32
32
|
isoNow
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-SOM4QA6C.js";
|
|
34
34
|
|
|
35
35
|
// src/verify/run-issue.ts
|
|
36
36
|
import { join } from "path";
|
|
@@ -412,4 +412,4 @@ async function runAcceptance(options) {
|
|
|
412
412
|
export {
|
|
413
413
|
runAcceptance
|
|
414
414
|
};
|
|
415
|
-
//# sourceMappingURL=chunk-
|
|
415
|
+
//# sourceMappingURL=chunk-SGTTR4XW.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
isProcessAlive,
|
|
4
4
|
taskPlanSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ICM463EO.js";
|
|
6
6
|
import {
|
|
7
7
|
writeFileAtomic
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3R27MJ5R.js";
|
|
9
9
|
|
|
10
10
|
// src/core/state-manager.ts
|
|
11
11
|
import { readFile } from "fs/promises";
|
|
@@ -295,4 +295,4 @@ export {
|
|
|
295
295
|
clearLastError,
|
|
296
296
|
trimErrorMessage
|
|
297
297
|
};
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
298
|
+
//# sourceMappingURL=chunk-SOM4QA6C.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
decideRouting
|
|
4
|
-
} from "./chunk-XLVGPXNL.js";
|
|
5
2
|
import {
|
|
6
3
|
parseJournal
|
|
7
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WCCZJL7W.js";
|
|
8
5
|
import {
|
|
9
6
|
ensureCursorStorageGrant
|
|
10
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DGRTJD5R.js";
|
|
8
|
+
import {
|
|
9
|
+
decideRouting
|
|
10
|
+
} from "./chunk-D6ZBGJ3L.js";
|
|
11
11
|
import {
|
|
12
12
|
ensureRunnersRegistered,
|
|
13
13
|
getActiveResilienceConfig,
|
|
@@ -18,13 +18,14 @@ import {
|
|
|
18
18
|
loadAgentConfig,
|
|
19
19
|
loadRoutingConfig,
|
|
20
20
|
peekHarnessVersion,
|
|
21
|
+
probeAgent,
|
|
21
22
|
resolveAgentFor,
|
|
22
23
|
resolveAntigravityTimeoutMs,
|
|
23
24
|
runnerFor
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-HY5HLFDU.js";
|
|
25
26
|
import {
|
|
26
27
|
resolveProjectPaths
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-DV7HUC4Z.js";
|
|
28
29
|
import {
|
|
29
30
|
ElapsedTimer,
|
|
30
31
|
createSpinner,
|
|
@@ -34,40 +35,45 @@ import {
|
|
|
34
35
|
getInactivityTimeout,
|
|
35
36
|
getOutputCallback,
|
|
36
37
|
isVerbose,
|
|
38
|
+
printInfo,
|
|
37
39
|
useColor
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import {
|
|
40
|
-
getSessionPublisher
|
|
41
|
-
} from "./chunk-6QYMSNVA.js";
|
|
40
|
+
} from "./chunk-XZUEFTUP.js";
|
|
42
41
|
import {
|
|
43
42
|
bindDiagnosticContext,
|
|
44
43
|
writeDiagnostic
|
|
45
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-QPGEFLMY.js";
|
|
46
45
|
import {
|
|
47
46
|
abortableDelay,
|
|
48
47
|
resolvePolicy,
|
|
49
48
|
shouldFailover,
|
|
50
49
|
withRetry
|
|
51
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-YVPZUN6X.js";
|
|
51
|
+
import {
|
|
52
|
+
getSessionPublisher
|
|
53
|
+
} from "./chunk-DUS5ZNKL.js";
|
|
52
54
|
import {
|
|
53
55
|
beginExecution,
|
|
54
56
|
endExecution
|
|
55
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-YII4U7ZD.js";
|
|
56
58
|
import {
|
|
57
59
|
redactSecrets
|
|
58
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-PPZ3K4YM.js";
|
|
59
61
|
import {
|
|
60
62
|
isoNow,
|
|
61
63
|
sumUsage
|
|
62
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-SOM4QA6C.js";
|
|
63
65
|
import {
|
|
64
66
|
isAgentProviderId,
|
|
65
67
|
providersHealthSchema
|
|
66
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-ICM463EO.js";
|
|
67
69
|
import {
|
|
68
70
|
classify
|
|
69
71
|
} from "./chunk-XEYH6ZZI.js";
|
|
70
72
|
|
|
73
|
+
// src/core/headless.ts
|
|
74
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
75
|
+
import chalk from "chalk";
|
|
76
|
+
|
|
71
77
|
// src/routing/budget.ts
|
|
72
78
|
var DEFAULT_CEILINGS = {
|
|
73
79
|
maxCostUsdPerIssue: null,
|
|
@@ -304,6 +310,71 @@ async function acquireHalfOpenProbe(filePath, provider, options = {}) {
|
|
|
304
310
|
return { acquired, record };
|
|
305
311
|
}
|
|
306
312
|
|
|
313
|
+
// src/agents/routing-application.ts
|
|
314
|
+
function routingRecommendationLine(decision, phase) {
|
|
315
|
+
if (decision === null || decision.mode !== "recommend" || decision.reasonCodes.includes("EXPLICIT_CONFIG")) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
const tier = decision.selected.tier ? ` (${decision.selected.tier})` : "";
|
|
319
|
+
return `Routing suggests ${decision.selected.provider}:${decision.selected.model ?? "default"}${tier} for ${phase} (${decision.reasonCodes.join(", ")}) \xB7 apply with routing.mode active`;
|
|
320
|
+
}
|
|
321
|
+
async function applyRoutingDecision(original, decision, phase, options = {}) {
|
|
322
|
+
if (decision === null || decision.mode !== "active" || decision.reasonCodes.includes("EXPLICIT_CONFIG") || original.failover) {
|
|
323
|
+
return { selection: original, applied: false, warning: null };
|
|
324
|
+
}
|
|
325
|
+
const target = decision.selected;
|
|
326
|
+
if (!isAgentProviderId(target.provider)) {
|
|
327
|
+
return {
|
|
328
|
+
selection: original,
|
|
329
|
+
applied: false,
|
|
330
|
+
warning: `Routing target '${target.provider}' is not a registered provider for ${phase}; using ${original.provider}.`
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const selectedCandidate = decision.candidates.find(
|
|
334
|
+
(candidate) => candidate.eligible && candidate.harness === target.harness && candidate.provider === target.provider && candidate.model === (target.model ?? null)
|
|
335
|
+
);
|
|
336
|
+
if (selectedCandidate === void 0) {
|
|
337
|
+
return {
|
|
338
|
+
selection: original,
|
|
339
|
+
applied: false,
|
|
340
|
+
warning: `Routing target ${target.provider}:${target.model ?? "default"} is not an eligible catalog entry for ${phase}; using ${original.provider}.`
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
if (target.model !== null && target.model !== void 0 && !runnerFor(target.provider).capabilities.modelSelection) {
|
|
344
|
+
return {
|
|
345
|
+
selection: original,
|
|
346
|
+
applied: false,
|
|
347
|
+
warning: `Routing target ${target.provider} rejects model selection for ${phase}; using ${original.provider}.`
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const availability = await (options.probe ?? probeAgent)(target.provider);
|
|
351
|
+
if (!availability.installed || !availability.authenticated) {
|
|
352
|
+
return {
|
|
353
|
+
selection: original,
|
|
354
|
+
applied: false,
|
|
355
|
+
warning: `Routing target ${target.provider} is ${availability.installed ? "not authenticated" : "not installed"} for ${phase}; using ${original.provider}.`
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
applied: true,
|
|
360
|
+
warning: null,
|
|
361
|
+
selection: {
|
|
362
|
+
...original,
|
|
363
|
+
primary: target.provider,
|
|
364
|
+
provider: target.provider,
|
|
365
|
+
settings: {
|
|
366
|
+
...original.settings,
|
|
367
|
+
provider: target.provider,
|
|
368
|
+
model: target.model ?? null,
|
|
369
|
+
origin: { provider: "default", model: "default" }
|
|
370
|
+
},
|
|
371
|
+
failover: false,
|
|
372
|
+
reason: null,
|
|
373
|
+
cooldownUntil: null
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
307
378
|
// src/agents/select.ts
|
|
308
379
|
var AgentSelectionBlockedError = class extends Error {
|
|
309
380
|
provider;
|
|
@@ -538,7 +609,36 @@ function resetAgentInvocationState() {
|
|
|
538
609
|
}
|
|
539
610
|
async function invokeSelectedAgent(invocation) {
|
|
540
611
|
const config = getActiveResilienceConfig();
|
|
541
|
-
|
|
612
|
+
let selection = invocation.forceProvider === void 0 ? await selectAgentForInvocation(invocation.phase, { config }) : await selectionForForced(invocation);
|
|
613
|
+
const originalIdentity = declaredAgentIdentity(selection.provider);
|
|
614
|
+
const routingCfg = await loadRoutingConfig();
|
|
615
|
+
const agentCfg = await loadAgentConfig();
|
|
616
|
+
const routingDecision = decideRouting({
|
|
617
|
+
phase: invocation.phase,
|
|
618
|
+
actualHarness: originalIdentity.harness,
|
|
619
|
+
actualProvider: selection.provider,
|
|
620
|
+
actualModel: selection.settings.model,
|
|
621
|
+
mode: routingCfg.mode,
|
|
622
|
+
profile: routingCfg.profile,
|
|
623
|
+
policy: routingCfg.policy,
|
|
624
|
+
skipScore: hasExplicitAgentSelection(agentCfg, getAgentCliOverrides(), invocation.phase),
|
|
625
|
+
requiresExtraDirectories: (invocation.addDirs?.length ?? 0) > 0
|
|
626
|
+
});
|
|
627
|
+
const recommendation = routingRecommendationLine(routingDecision, invocation.phase);
|
|
628
|
+
if (recommendation !== null) printInfo(recommendation);
|
|
629
|
+
const routed = await applyRoutingDecision(selection, routingDecision, invocation.phase);
|
|
630
|
+
selection = routed.selection;
|
|
631
|
+
if (routed.warning !== null) {
|
|
632
|
+
writeDiagnostic({
|
|
633
|
+
level: "warning",
|
|
634
|
+
message: routed.warning,
|
|
635
|
+
fields: {
|
|
636
|
+
phase: invocation.phase,
|
|
637
|
+
harness: originalIdentity.harness,
|
|
638
|
+
model: selection.settings.model
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
}
|
|
542
642
|
const attempt = nextAttempt(invocation.phase);
|
|
543
643
|
const publisher = getSessionPublisher();
|
|
544
644
|
publisher.publish({
|
|
@@ -571,16 +671,14 @@ async function invokeSelectedAgent(invocation) {
|
|
|
571
671
|
}
|
|
572
672
|
const identity = declaredAgentIdentity(selection.provider);
|
|
573
673
|
const requested = selection.settings.model;
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
requiresExtraDirectories: (invocation.addDirs?.length ?? 0) > 0
|
|
583
|
-
});
|
|
674
|
+
const recordedRoutingDecision = routingDecision !== null && routed.applied ? {
|
|
675
|
+
...routingDecision,
|
|
676
|
+
actual: {
|
|
677
|
+
harness: identity.harness,
|
|
678
|
+
provider: selection.provider,
|
|
679
|
+
model: requested
|
|
680
|
+
}
|
|
681
|
+
} : routingDecision;
|
|
584
682
|
const executionId = await beginExecution({
|
|
585
683
|
purpose: invocation.purpose ?? invocation.phase,
|
|
586
684
|
attempt,
|
|
@@ -591,11 +689,13 @@ async function invokeSelectedAgent(invocation) {
|
|
|
591
689
|
harnessVersion: peekHarnessVersion(selection.provider) ?? null,
|
|
592
690
|
modelRequested: requested,
|
|
593
691
|
modelResolved: null,
|
|
594
|
-
modelSource: requested ? "config" : "unavailable",
|
|
692
|
+
modelSource: requested ? routed.applied ? "routing" : "config" : "unavailable",
|
|
595
693
|
...invocation.iteration === void 0 ? {} : { iteration: invocation.iteration },
|
|
596
694
|
...invocation.correctionCycle === void 0 ? {} : { correctionCycle: invocation.correctionCycle },
|
|
597
695
|
...invocation.storyIds === void 0 ? {} : { storyIds: invocation.storyIds },
|
|
598
|
-
...
|
|
696
|
+
...recordedRoutingDecision === null ? {} : {
|
|
697
|
+
routingDecision: recordedRoutingDecision
|
|
698
|
+
}
|
|
599
699
|
});
|
|
600
700
|
bindDiagnosticContext({
|
|
601
701
|
executionId,
|
|
@@ -775,7 +875,7 @@ async function invokeSelectedAgent(invocation) {
|
|
|
775
875
|
error: failure === null ? null : run.error ?? run.rawOutput,
|
|
776
876
|
exitCode: run.exitCode,
|
|
777
877
|
modelResolved: run.agent.model,
|
|
778
|
-
modelSource: run.agent.model ? requested ? "config" : "provider" : requested ? "config" : "unavailable",
|
|
878
|
+
modelSource: run.agent.model ? requested ? routed.applied ? "routing" : "config" : "provider" : requested ? routed.applied ? "routing" : "config" : "unavailable",
|
|
779
879
|
harnessVersion: run.harnessVersion ?? peekHarnessVersion(selection.provider) ?? null,
|
|
780
880
|
providerSessionId: run.sessionId ?? null,
|
|
781
881
|
storyIds: invocation.storyIds
|
|
@@ -970,8 +1070,6 @@ function buildDecompositionReport(input) {
|
|
|
970
1070
|
}
|
|
971
1071
|
|
|
972
1072
|
// src/core/headless.ts
|
|
973
|
-
import { readFile as readFile2 } from "fs/promises";
|
|
974
|
-
import chalk from "chalk";
|
|
975
1073
|
var DEFAULT_HEADLESS_TIMEOUT_MS = 9e5;
|
|
976
1074
|
async function escalatedTimeout(timeoutMs, history) {
|
|
977
1075
|
if (timeoutMs === 0 || history === void 0) return timeoutMs;
|
|
@@ -1200,4 +1298,4 @@ export {
|
|
|
1200
1298
|
DEFAULT_HEADLESS_TIMEOUT_MS,
|
|
1201
1299
|
runHeadless
|
|
1202
1300
|
};
|
|
1203
|
-
//# sourceMappingURL=chunk-
|
|
1301
|
+
//# sourceMappingURL=chunk-UK4E2FUA.js.map
|