token-harness 0.1.23 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/package.json +1 -1
- package/sbom.json +3 -3
- package/token-harness.mjs +1173 -54
package/token-harness.mjs
CHANGED
|
@@ -759,6 +759,27 @@ function parseBoundaryPolicy(value3) {
|
|
|
759
759
|
return void 0;
|
|
760
760
|
return { model, reasoningEffort, verbosity, verification: "config-only" };
|
|
761
761
|
}
|
|
762
|
+
function parseNativeRoutingObservation(value3) {
|
|
763
|
+
if (value3 === null)
|
|
764
|
+
return null;
|
|
765
|
+
const row2 = record(value3);
|
|
766
|
+
if (row2 === null)
|
|
767
|
+
return void 0;
|
|
768
|
+
const configured = row2["configured"];
|
|
769
|
+
const promptSubmissions = row2["promptSubmissions"];
|
|
770
|
+
const subagentsStarted = row2["subagentsStarted"];
|
|
771
|
+
const subagentsStopped = row2["subagentsStopped"];
|
|
772
|
+
const reportedModels = row2["reportedModels"];
|
|
773
|
+
if (!(configured === null || typeof configured === "boolean") || !Number.isSafeInteger(promptSubmissions) || typeof promptSubmissions !== "number" || promptSubmissions < 0 || !Number.isSafeInteger(subagentsStarted) || typeof subagentsStarted !== "number" || subagentsStarted < 0 || !Number.isSafeInteger(subagentsStopped) || typeof subagentsStopped !== "number" || subagentsStopped < 0 || !Array.isArray(reportedModels) || !reportedModels.every((model) => typeof model === "string" && model.length <= 80))
|
|
774
|
+
return void 0;
|
|
775
|
+
return {
|
|
776
|
+
configured,
|
|
777
|
+
promptSubmissions,
|
|
778
|
+
subagentsStarted,
|
|
779
|
+
subagentsStopped,
|
|
780
|
+
reportedModels: [...new Set(reportedModels)]
|
|
781
|
+
};
|
|
782
|
+
}
|
|
762
783
|
function parseTaskBenchmarkCapture(value3) {
|
|
763
784
|
const row2 = record(value3);
|
|
764
785
|
if (row2 === null) {
|
|
@@ -785,7 +806,9 @@ function parseTaskBenchmarkCapture(value3) {
|
|
|
785
806
|
const localSessionsBefore = parsedLocalSessions === void 0 ? null : parsedLocalSessions;
|
|
786
807
|
const hasContextAtStart = Object.hasOwn(row2, "contextAtStart");
|
|
787
808
|
const contextAtStart = hasContextAtStart ? parseTaskBenchmarkContextSnapshot(row2["contextAtStart"]) : void 0;
|
|
788
|
-
|
|
809
|
+
const hasNativeRoutingAtStart = Object.hasOwn(row2, "nativeRoutingAtStart");
|
|
810
|
+
const nativeRoutingAtStart = hasNativeRoutingAtStart ? parseNativeRoutingObservation(row2["nativeRoutingAtStart"]) : void 0;
|
|
811
|
+
if (typeof benchmarkId !== "string" || !isTaskBenchmarkId(benchmarkId) || typeof variant !== "string" || !isTaskBenchmarkVariant(variant) || typeof taskClass !== "string" || !isTaskClass(taskClass) || typeof harnessId2 !== "string" || !isHarnessId(harnessId2) || typeof projectId !== "string" || projectId === "" || model === void 0 || reasoningEffort === void 0 || verbosity === void 0 || !validInstant(startedAt) || usageBefore === null || parsedLocalSessions === void 0 || hasContextAtStart && contextAtStart === void 0 || hasNativeRoutingAtStart && nativeRoutingAtStart === void 0) {
|
|
789
812
|
return {
|
|
790
813
|
ok: false,
|
|
791
814
|
reason: "invalid-shape",
|
|
@@ -807,6 +830,7 @@ function parseTaskBenchmarkCapture(value3) {
|
|
|
807
830
|
startedAt,
|
|
808
831
|
usageBefore,
|
|
809
832
|
...hasContextAtStart ? { contextAtStart: contextAtStart ?? null } : {},
|
|
833
|
+
...hasNativeRoutingAtStart ? { nativeRoutingAtStart: nativeRoutingAtStart ?? null } : {},
|
|
810
834
|
localSessionsBefore
|
|
811
835
|
}
|
|
812
836
|
};
|
|
@@ -842,7 +866,11 @@ function parseTaskBenchmarkReceipt(value3) {
|
|
|
842
866
|
const contextAtStart = hasContextAtStart ? parseTaskBenchmarkContextSnapshot(row2["contextAtStart"]) : void 0;
|
|
843
867
|
const hasContextAtFinish = Object.hasOwn(row2, "contextAtFinish");
|
|
844
868
|
const contextAtFinish = hasContextAtFinish ? parseTaskBenchmarkContextSnapshot(row2["contextAtFinish"]) : void 0;
|
|
845
|
-
|
|
869
|
+
const hasNativeRoutingAtStart = Object.hasOwn(row2, "nativeRoutingAtStart");
|
|
870
|
+
const nativeRoutingAtStart = hasNativeRoutingAtStart ? parseNativeRoutingObservation(row2["nativeRoutingAtStart"]) : void 0;
|
|
871
|
+
const hasNativeRoutingAtFinish = Object.hasOwn(row2, "nativeRoutingAtFinish");
|
|
872
|
+
const nativeRoutingAtFinish = hasNativeRoutingAtFinish ? parseNativeRoutingObservation(row2["nativeRoutingAtFinish"]) : void 0;
|
|
873
|
+
if (typeof benchmarkId !== "string" || benchmarkId === "" || typeof variant !== "string" || !isTaskBenchmarkVariant(variant) || typeof taskClass !== "string" || !isTaskClass(taskClass) || typeof harnessId2 !== "string" || !isHarnessId(harnessId2) || model === void 0 || reasoningEffort === void 0 || verbosity === void 0 || !validInstant(startedAt) || !validInstant(completedAt) || Date.parse(completedAt) < Date.parse(startedAt) || usageBefore === null || usageAfter === null || localUsage === void 0 || outcome2 === null || hasBoundaryPolicy && policyAtFinish === void 0 || hasContextAtStart && contextAtStart === void 0 || hasContextAtFinish && contextAtFinish === void 0 || hasNativeRoutingAtStart && nativeRoutingAtStart === void 0 || hasNativeRoutingAtFinish && nativeRoutingAtFinish === void 0) {
|
|
846
874
|
return {
|
|
847
875
|
ok: false,
|
|
848
876
|
reason: "invalid-shape",
|
|
@@ -868,7 +896,9 @@ function parseTaskBenchmarkReceipt(value3) {
|
|
|
868
896
|
outcome: outcome2,
|
|
869
897
|
...hasContextAtStart ? { contextAtStart: contextAtStart ?? null } : {},
|
|
870
898
|
...hasContextAtFinish ? { contextAtFinish: contextAtFinish ?? null } : {},
|
|
871
|
-
...hasBoundaryPolicy ? { policyAtFinish: policyAtFinish ?? null } : {}
|
|
899
|
+
...hasBoundaryPolicy ? { policyAtFinish: policyAtFinish ?? null } : {},
|
|
900
|
+
...hasNativeRoutingAtStart ? { nativeRoutingAtStart: nativeRoutingAtStart ?? null } : {},
|
|
901
|
+
...hasNativeRoutingAtFinish ? { nativeRoutingAtFinish: nativeRoutingAtFinish ?? null } : {}
|
|
872
902
|
}
|
|
873
903
|
};
|
|
874
904
|
}
|
|
@@ -888,7 +918,9 @@ function completeTaskBenchmarkCapture(capture, input) {
|
|
|
888
918
|
usageAfter: input.usageAfter,
|
|
889
919
|
localUsage: input.localUsage ?? null,
|
|
890
920
|
...capture.contextAtStart !== void 0 ? { contextAtStart: capture.contextAtStart } : {},
|
|
921
|
+
...capture.nativeRoutingAtStart !== void 0 ? { nativeRoutingAtStart: capture.nativeRoutingAtStart } : {},
|
|
891
922
|
...input.contextAtFinish !== void 0 ? { contextAtFinish: input.contextAtFinish } : {},
|
|
923
|
+
...input.nativeRoutingAtFinish !== void 0 ? { nativeRoutingAtFinish: input.nativeRoutingAtFinish } : {},
|
|
892
924
|
...input.policyAtFinish !== void 0 ? { policyAtFinish: input.policyAtFinish } : {},
|
|
893
925
|
outcome: {
|
|
894
926
|
qualityGate: input.qualityGate,
|
|
@@ -1096,7 +1128,8 @@ function buildTaskBenchmarkMatrix(pairs, selection = {
|
|
|
1096
1128
|
baselineLocalTokens,
|
|
1097
1129
|
optimizedLocalTokens,
|
|
1098
1130
|
localTokenSavingPercent: !bothQualityPassed || baselineLocalTokens === null || optimizedLocalTokens === null ? null : roundedPercent(baselineLocalTokens - optimizedLocalTokens, baselineLocalTokens),
|
|
1099
|
-
quota: comparison.quota
|
|
1131
|
+
quota: comparison.quota,
|
|
1132
|
+
...nativeRoutingComparison(baseline, optimized)
|
|
1100
1133
|
};
|
|
1101
1134
|
}).sort((left, right) => TASK_CLASS_ORDER.indexOf(left.taskClass) - TASK_CLASS_ORDER.indexOf(right.taskClass) || left.benchmarkId.localeCompare(right.benchmarkId));
|
|
1102
1135
|
const byTaskClass = TASK_CLASS_ORDER.map((taskClass) => ({
|
|
@@ -1110,6 +1143,36 @@ function buildTaskBenchmarkMatrix(pairs, selection = {
|
|
|
1110
1143
|
selection
|
|
1111
1144
|
};
|
|
1112
1145
|
}
|
|
1146
|
+
function nativeRoutingComparison(baseline, optimized) {
|
|
1147
|
+
const bStart = baseline.nativeRoutingAtStart;
|
|
1148
|
+
const bFinish = baseline.nativeRoutingAtFinish;
|
|
1149
|
+
const oStart = optimized.nativeRoutingAtStart;
|
|
1150
|
+
const oFinish = optimized.nativeRoutingAtFinish;
|
|
1151
|
+
if (bStart === void 0 && bFinish === void 0 && oStart === void 0 && oFinish === void 0)
|
|
1152
|
+
return {};
|
|
1153
|
+
const qualityGatesPassed = baseline.outcome.qualityGate === "passed" && optimized.outcome.qualityGate === "passed";
|
|
1154
|
+
if (bStart == null || bFinish == null || oStart == null || oFinish == null || bStart.configured === null || oStart.configured === null) {
|
|
1155
|
+
return {
|
|
1156
|
+
nativeRouting: {
|
|
1157
|
+
verdict: "unknown",
|
|
1158
|
+
baselineSubagents: bFinish?.subagentsStarted ?? null,
|
|
1159
|
+
optimizedSubagents: oFinish?.subagentsStarted ?? null,
|
|
1160
|
+
optimizedReportedModels: oFinish?.reportedModels ?? [],
|
|
1161
|
+
qualityGatesPassed
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
const attributed = bStart.configured === false && bFinish.configured === false && bFinish.subagentsStarted === 0 && oStart.configured === true && oFinish.configured === true && oFinish.promptSubmissions > 0 && oFinish.subagentsStarted > 0;
|
|
1166
|
+
return {
|
|
1167
|
+
nativeRouting: {
|
|
1168
|
+
verdict: attributed ? "attributed" : "not-attributed",
|
|
1169
|
+
baselineSubagents: bFinish.subagentsStarted,
|
|
1170
|
+
optimizedSubagents: oFinish.subagentsStarted,
|
|
1171
|
+
optimizedReportedModels: [...oFinish.reportedModels],
|
|
1172
|
+
qualityGatesPassed
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1113
1176
|
var TASK_BENCHMARK_RECEIPT_SCHEMA_VERSION, TASK_BENCHMARK_CAPTURE_SCHEMA_VERSION, BENCHMARK_ID, WINDOW_SCOPES, WINDOW_SOURCES, WINDOW_CONFIDENCES, WINDOW_KINDS, QUOTA_SCOPE_PRIORITY, TASK_CLASS_ORDER;
|
|
1114
1177
|
var init_benchmark = __esm({
|
|
1115
1178
|
"packages/core/dist/src/domain/benchmark.js"() {
|
|
@@ -4144,11 +4207,19 @@ function findCompatibilityRule(rules, query) {
|
|
|
4144
4207
|
candidates.push(rule);
|
|
4145
4208
|
}
|
|
4146
4209
|
if (query.observedVersions !== void 0) {
|
|
4147
|
-
const matchesObservedTuple = (rule) =>
|
|
4210
|
+
const matchesObservedTuple = (rule) => {
|
|
4211
|
+
if (rule.providers.some((provider) => rule.testedVersions[provider] === void 0)) {
|
|
4212
|
+
return false;
|
|
4213
|
+
}
|
|
4214
|
+
const testedHarnessVersion = rule.testedHarnessVersions?.[query.harness];
|
|
4215
|
+
if (rule.outcome === "ordered" && testedHarnessVersion === void 0)
|
|
4216
|
+
return false;
|
|
4217
|
+
return Object.entries(rule.testedVersions).every(([provider, version3]) => query.observedVersions?.[provider] === version3) && (testedHarnessVersion === void 0 || query.observedHarnessVersions?.[query.harness] === testedHarnessVersion);
|
|
4218
|
+
};
|
|
4148
4219
|
const exact = candidates.find(matchesObservedTuple);
|
|
4149
4220
|
if (exact !== void 0)
|
|
4150
4221
|
return exact;
|
|
4151
|
-
const matchingDimensions = (rule) => Object.entries(rule.testedVersions).filter(([provider, version3]) => query.observedVersions?.[provider] === version3).length +
|
|
4222
|
+
const matchingDimensions = (rule) => Object.entries(rule.testedVersions).filter(([provider, version3]) => query.observedVersions?.[provider] === version3).length + (rule.testedHarnessVersions?.[query.harness] !== void 0 && query.observedHarnessVersions?.[query.harness] === rule.testedHarnessVersions[query.harness] ? 1 : 0);
|
|
4152
4223
|
candidates.sort((left, right) => matchingDimensions(right) - matchingDimensions(left));
|
|
4153
4224
|
}
|
|
4154
4225
|
return candidates[0] ?? null;
|
|
@@ -4160,26 +4231,24 @@ function coversVersion(recorded, observed) {
|
|
|
4160
4231
|
}
|
|
4161
4232
|
function staleRecordedVersions(rule, observed) {
|
|
4162
4233
|
const stale2 = [];
|
|
4163
|
-
for (const
|
|
4234
|
+
for (const provider of rule.providers) {
|
|
4235
|
+
const recorded = rule.testedVersions[provider];
|
|
4164
4236
|
const seen = observed[provider] ?? null;
|
|
4165
|
-
const recordedVersion = parseSemanticVersion(recorded);
|
|
4237
|
+
const recordedVersion = recorded === void 0 ? null : parseSemanticVersion(recorded);
|
|
4166
4238
|
const seenVersion = seen === null ? null : parseSemanticVersion(seen);
|
|
4167
4239
|
if (recordedVersion !== null && seenVersion !== null && coversVersion(recordedVersion, seenVersion)) {
|
|
4168
4240
|
continue;
|
|
4169
4241
|
}
|
|
4170
|
-
stale2.push({ provider, recorded, observed: seen });
|
|
4242
|
+
stale2.push({ provider, recorded: recorded ?? null, observed: seen });
|
|
4171
4243
|
}
|
|
4172
4244
|
return stale2;
|
|
4173
4245
|
}
|
|
4174
|
-
function staleRecordedHarnessVersions(rule, observed) {
|
|
4175
|
-
const
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
stale2.push({ harness, recorded, observed: seen });
|
|
4181
|
-
}
|
|
4182
|
-
return stale2;
|
|
4246
|
+
function staleRecordedHarnessVersions(rule, observed, harness) {
|
|
4247
|
+
const recorded = rule.testedHarnessVersions?.[harness];
|
|
4248
|
+
if (recorded === void 0 && rule.outcome !== "ordered")
|
|
4249
|
+
return [];
|
|
4250
|
+
const seen = observed[harness] ?? null;
|
|
4251
|
+
return recorded !== void 0 && seen === recorded ? [] : [{ harness, recorded: recorded ?? null, observed: seen }];
|
|
4183
4252
|
}
|
|
4184
4253
|
var init_compatibility = __esm({
|
|
4185
4254
|
"packages/core/dist/src/domain/compatibility.js"() {
|
|
@@ -4808,7 +4877,7 @@ function narrowChannelOverlaps(context) {
|
|
|
4808
4877
|
...input.observedHarnessVersions === void 0 ? {} : { observedHarnessVersions: input.observedHarnessVersions }
|
|
4809
4878
|
});
|
|
4810
4879
|
const staleProviders = found === null ? [] : staleRecordedVersions(found, input.observedVersions);
|
|
4811
|
-
const staleHarnesses = found === null ? [] : staleRecordedHarnessVersions(found, input.observedHarnessVersions ?? {});
|
|
4880
|
+
const staleHarnesses = found === null ? [] : staleRecordedHarnessVersions(found, input.observedHarnessVersions ?? {}, harness);
|
|
4812
4881
|
const stale2 = [...staleProviders, ...staleHarnesses];
|
|
4813
4882
|
const rule = stale2.length > 0 ? null : found;
|
|
4814
4883
|
if (found !== null && stale2.length > 0) {
|
|
@@ -4819,8 +4888,8 @@ function narrowChannelOverlaps(context) {
|
|
|
4819
4888
|
detail: [
|
|
4820
4889
|
`${owners.join(" and ")} both use ${capability} on ${harness}/${toolFamily} at different interception points`,
|
|
4821
4890
|
`Rule ${found.id} was tested at ${[
|
|
4822
|
-
...staleProviders.map((entry) => `${entry.provider} ${entry.recorded}`),
|
|
4823
|
-
...staleHarnesses.map((entry) => `${entry.harness} ${entry.recorded}`)
|
|
4891
|
+
...staleProviders.map((entry) => `${entry.provider} ${entry.recorded ?? "not recorded"}`),
|
|
4892
|
+
...staleHarnesses.map((entry) => `${entry.harness} ${entry.recorded ?? "not recorded"}`)
|
|
4824
4893
|
].join(", ")}`,
|
|
4825
4894
|
`Installed now: ${[
|
|
4826
4895
|
...staleProviders.map((entry) => `${entry.provider} ${entry.observed ?? "unknown"}`),
|
|
@@ -4921,7 +4990,9 @@ function resolveContested(context) {
|
|
|
4921
4990
|
...input.observedHarnessVersions === void 0 ? {} : { observedHarnessVersions: input.observedHarnessVersions }
|
|
4922
4991
|
});
|
|
4923
4992
|
const stale2 = found === null ? [] : staleRecordedVersions(found, input.observedVersions);
|
|
4924
|
-
const
|
|
4993
|
+
const staleHarnesses = found === null ? [] : staleRecordedHarnessVersions(found, input.observedHarnessVersions ?? {}, scope.harness);
|
|
4994
|
+
const staleAll = [...stale2, ...staleHarnesses];
|
|
4995
|
+
const rule = staleAll.length > 0 ? null : found;
|
|
4925
4996
|
if (rule === null) {
|
|
4926
4997
|
if (found !== null) {
|
|
4927
4998
|
conflicts.push({
|
|
@@ -4930,11 +5001,17 @@ function resolveContested(context) {
|
|
|
4930
5001
|
claimants,
|
|
4931
5002
|
detail: [
|
|
4932
5003
|
`${claimants.join(" and ")} both claim ${capability} on ${formatCapabilityScope(scope)}`,
|
|
4933
|
-
`Rule ${found.id} was tested at ${
|
|
4934
|
-
|
|
5004
|
+
`Rule ${found.id} was tested at ${[
|
|
5005
|
+
...stale2.map((entry) => `${entry.provider} ${entry.recorded ?? "not recorded"}`),
|
|
5006
|
+
...staleHarnesses.map((entry) => `${entry.harness} ${entry.recorded ?? "not recorded"}`)
|
|
5007
|
+
].join(", ")}`,
|
|
5008
|
+
`Installed now: ${[
|
|
5009
|
+
...stale2.map((entry) => `${entry.provider} ${entry.observed ?? "unknown"}`),
|
|
5010
|
+
...staleHarnesses.map((entry) => `${entry.harness} ${entry.observed ?? "unknown"}`)
|
|
5011
|
+
].join(", ")}`,
|
|
4935
5012
|
"A compatibility result covers the versions it records, so this one is withdrawn rather than applied outside them"
|
|
4936
5013
|
],
|
|
4937
|
-
remediation: `Re-test ${found.id} against the installed
|
|
5014
|
+
remediation: `Re-test ${found.id} against the installed provider and harness versions, record the evidence for ${scope.harness}, or assign the scope explicitly with \`profile: custom\``
|
|
4938
5015
|
});
|
|
4939
5016
|
return;
|
|
4940
5017
|
}
|
|
@@ -9784,7 +9861,7 @@ var TOOL_VERSION;
|
|
|
9784
9861
|
var init_version2 = __esm({
|
|
9785
9862
|
"apps/cli/dist/src/version.js"() {
|
|
9786
9863
|
"use strict";
|
|
9787
|
-
TOOL_VERSION = "0.1.
|
|
9864
|
+
TOOL_VERSION = "0.1.24";
|
|
9788
9865
|
}
|
|
9789
9866
|
});
|
|
9790
9867
|
|
|
@@ -14677,7 +14754,10 @@ var init_claude = __esm({
|
|
|
14677
14754
|
versionCommand: { executable: "claude", args: ["--version"] },
|
|
14678
14755
|
interceptionPoints: [
|
|
14679
14756
|
{ scopeId: "pre-tool-use", eventName: "PreToolUse" },
|
|
14680
|
-
{ scopeId: "post-tool-use", eventName: "PostToolUse" }
|
|
14757
|
+
{ scopeId: "post-tool-use", eventName: "PostToolUse" },
|
|
14758
|
+
{ scopeId: "user-prompt-submit", eventName: "UserPromptSubmit" },
|
|
14759
|
+
{ scopeId: "subagent-start", eventName: "SubagentStart" },
|
|
14760
|
+
{ scopeId: "subagent-stop", eventName: "SubagentStop" }
|
|
14681
14761
|
],
|
|
14682
14762
|
configFiles: [
|
|
14683
14763
|
{
|
|
@@ -14686,7 +14766,13 @@ var init_claude = __esm({
|
|
|
14686
14766
|
parser: "json",
|
|
14687
14767
|
primary: true,
|
|
14688
14768
|
interceptionFormat: "hooks-event-command-list",
|
|
14689
|
-
interceptionPoints: [
|
|
14769
|
+
interceptionPoints: [
|
|
14770
|
+
"pre-tool-use",
|
|
14771
|
+
"post-tool-use",
|
|
14772
|
+
"user-prompt-submit",
|
|
14773
|
+
"subagent-start",
|
|
14774
|
+
"subagent-stop"
|
|
14775
|
+
]
|
|
14690
14776
|
},
|
|
14691
14777
|
{ path: ".claude/settings.json", scope: "project", parser: "json", primary: false },
|
|
14692
14778
|
{ path: ".claude/settings.local.json", scope: "project", parser: "json", primary: false }
|
|
@@ -15854,7 +15940,10 @@ var init_codex = __esm({
|
|
|
15854
15940
|
*/
|
|
15855
15941
|
interceptionPoints: [
|
|
15856
15942
|
{ scopeId: "pre-tool-use", eventName: "PreToolUse" },
|
|
15857
|
-
{ scopeId: "post-tool-use", eventName: "PostToolUse" }
|
|
15943
|
+
{ scopeId: "post-tool-use", eventName: "PostToolUse" },
|
|
15944
|
+
{ scopeId: "user-prompt-submit", eventName: "UserPromptSubmit" },
|
|
15945
|
+
{ scopeId: "subagent-start", eventName: "SubagentStart" },
|
|
15946
|
+
{ scopeId: "subagent-stop", eventName: "SubagentStop" }
|
|
15858
15947
|
],
|
|
15859
15948
|
configFiles: [
|
|
15860
15949
|
{ path: ".codex/config.toml", scope: "user", parser: "toml", primary: true },
|
|
@@ -15864,7 +15953,13 @@ var init_codex = __esm({
|
|
|
15864
15953
|
parser: "json",
|
|
15865
15954
|
primary: false,
|
|
15866
15955
|
interceptionFormat: "hooks-event-command-list",
|
|
15867
|
-
interceptionPoints: [
|
|
15956
|
+
interceptionPoints: [
|
|
15957
|
+
"pre-tool-use",
|
|
15958
|
+
"post-tool-use",
|
|
15959
|
+
"user-prompt-submit",
|
|
15960
|
+
"subagent-start",
|
|
15961
|
+
"subagent-stop"
|
|
15962
|
+
]
|
|
15868
15963
|
}
|
|
15869
15964
|
],
|
|
15870
15965
|
toolFamilies: [
|
|
@@ -16632,10 +16727,49 @@ var init_pi = __esm({
|
|
|
16632
16727
|
}
|
|
16633
16728
|
});
|
|
16634
16729
|
|
|
16730
|
+
// packages/adapters/dist/src/harnesses/native-prompt-routing.js
|
|
16731
|
+
function nativePromptRoutingHookEntries(harness, executable = "token-harness") {
|
|
16732
|
+
return NATIVE_PROMPT_ROUTING_EVENTS.map(({ eventName, commandEvent }) => {
|
|
16733
|
+
if (harness === "codex") {
|
|
16734
|
+
const command = `${executable} __internal-prompt-router codex ${commandEvent}`;
|
|
16735
|
+
const handler2 = {
|
|
16736
|
+
type: "command",
|
|
16737
|
+
command,
|
|
16738
|
+
commandWindows: command,
|
|
16739
|
+
timeout: 10
|
|
16740
|
+
};
|
|
16741
|
+
if (commandEvent === "prompt-submit")
|
|
16742
|
+
handler2["additionalContextLimit"] = 500;
|
|
16743
|
+
return { eventName, value: { hooks: [handler2] } };
|
|
16744
|
+
}
|
|
16745
|
+
const handler = {
|
|
16746
|
+
type: "command",
|
|
16747
|
+
command: executable,
|
|
16748
|
+
args: ["__internal-prompt-router", "claude", commandEvent],
|
|
16749
|
+
timeout: 10
|
|
16750
|
+
};
|
|
16751
|
+
return { eventName, value: { hooks: [handler] } };
|
|
16752
|
+
});
|
|
16753
|
+
}
|
|
16754
|
+
var NATIVE_PROMPT_ROUTING_EVENTS;
|
|
16755
|
+
var init_native_prompt_routing = __esm({
|
|
16756
|
+
"packages/adapters/dist/src/harnesses/native-prompt-routing.js"() {
|
|
16757
|
+
"use strict";
|
|
16758
|
+
NATIVE_PROMPT_ROUTING_EVENTS = [
|
|
16759
|
+
{ eventName: "UserPromptSubmit", commandEvent: "prompt-submit" },
|
|
16760
|
+
{ eventName: "SubagentStart", commandEvent: "subagent-start" },
|
|
16761
|
+
{ eventName: "SubagentStop", commandEvent: "subagent-stop" }
|
|
16762
|
+
];
|
|
16763
|
+
}
|
|
16764
|
+
});
|
|
16765
|
+
|
|
16635
16766
|
// packages/adapters/dist/src/harnesses/index.js
|
|
16636
16767
|
function listHarnessAdapters() {
|
|
16637
16768
|
return HARNESS_ADAPTERS;
|
|
16638
16769
|
}
|
|
16770
|
+
function findHarnessAdapter(id) {
|
|
16771
|
+
return HARNESS_ADAPTERS.find((adapter) => adapter.manifest.id === id) ?? null;
|
|
16772
|
+
}
|
|
16639
16773
|
var HARNESS_ADAPTERS;
|
|
16640
16774
|
var init_harnesses = __esm({
|
|
16641
16775
|
"packages/adapters/dist/src/harnesses/index.js"() {
|
|
@@ -16653,6 +16787,7 @@ var init_harnesses = __esm({
|
|
|
16653
16787
|
init_opencode();
|
|
16654
16788
|
init_pi();
|
|
16655
16789
|
init_claude();
|
|
16790
|
+
init_native_prompt_routing();
|
|
16656
16791
|
HARNESS_ADAPTERS = [
|
|
16657
16792
|
claudeAdapter,
|
|
16658
16793
|
codexAdapter,
|
|
@@ -17702,11 +17837,11 @@ async function plan(context, request) {
|
|
|
17702
17837
|
}));
|
|
17703
17838
|
continue;
|
|
17704
17839
|
}
|
|
17705
|
-
const
|
|
17840
|
+
const actionId2 = `harnesstrim-${harness.id}-hook-${digestText(target.configPath).slice(7, 15)}`;
|
|
17706
17841
|
actions.push(appendCommandHookAction({
|
|
17707
17842
|
target,
|
|
17708
17843
|
providerId: HARNESSTRIM2,
|
|
17709
|
-
actionId,
|
|
17844
|
+
actionId: actionId2,
|
|
17710
17845
|
command,
|
|
17711
17846
|
explanation: `Register HarnessTrim after ${harness.displayName} Bash commands and record reductions in ${metricsPath}${codexActivationNote(harness.id)}`
|
|
17712
17847
|
}));
|
|
@@ -22453,6 +22588,8 @@ function parseArgv(argv2, plannedCommands = PLANNED_COMMANDS) {
|
|
|
22453
22588
|
contextSnapshot: null,
|
|
22454
22589
|
nativePolicy: false,
|
|
22455
22590
|
agentSkill: false,
|
|
22591
|
+
agentRouting: false,
|
|
22592
|
+
disableAgentRouting: false,
|
|
22456
22593
|
verbose: false,
|
|
22457
22594
|
yes: false
|
|
22458
22595
|
};
|
|
@@ -22491,6 +22628,10 @@ function parseArgv(argv2, plannedCommands = PLANNED_COMMANDS) {
|
|
|
22491
22628
|
options.nativePolicy = true;
|
|
22492
22629
|
if (name2 === "--agent-skill")
|
|
22493
22630
|
options.agentSkill = true;
|
|
22631
|
+
if (name2 === "--agent-routing")
|
|
22632
|
+
options.agentRouting = true;
|
|
22633
|
+
if (name2 === "--disable-agent-routing")
|
|
22634
|
+
options.disableAgentRouting = true;
|
|
22494
22635
|
if (name2 === "--verbose")
|
|
22495
22636
|
options.verbose = true;
|
|
22496
22637
|
continue;
|
|
@@ -22727,6 +22868,14 @@ function parseArgv(argv2, plannedCommands = PLANNED_COMMANDS) {
|
|
|
22727
22868
|
}));
|
|
22728
22869
|
return usageError(json, diagnostics);
|
|
22729
22870
|
}
|
|
22871
|
+
if (options.agentRouting && options.disableAgentRouting) {
|
|
22872
|
+
diagnostics.push(diagnostic({
|
|
22873
|
+
severity: "error",
|
|
22874
|
+
code: "conflicting-prompt-routing-flags",
|
|
22875
|
+
message: "--agent-routing and --disable-agent-routing cannot be used together",
|
|
22876
|
+
remediation: "Choose one prompt-routing state to plan"
|
|
22877
|
+
}));
|
|
22878
|
+
}
|
|
22730
22879
|
if (!isAvailableCommand(command)) {
|
|
22731
22880
|
const planned = plannedCommands.includes(command);
|
|
22732
22881
|
diagnostics.push(planned ? diagnostic({
|
|
@@ -22796,7 +22945,557 @@ var init_argv = __esm({
|
|
|
22796
22945
|
"--tasks-left",
|
|
22797
22946
|
"--context-snapshot"
|
|
22798
22947
|
]);
|
|
22799
|
-
BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
22948
|
+
BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
22949
|
+
"--json",
|
|
22950
|
+
"--native-policy",
|
|
22951
|
+
"--agent-skill",
|
|
22952
|
+
"--agent-routing",
|
|
22953
|
+
"--disable-agent-routing",
|
|
22954
|
+
"--verbose",
|
|
22955
|
+
"--yes"
|
|
22956
|
+
]);
|
|
22957
|
+
}
|
|
22958
|
+
});
|
|
22959
|
+
|
|
22960
|
+
// apps/cli/dist/src/prompt-router.js
|
|
22961
|
+
function isHarness(value3) {
|
|
22962
|
+
return value3 === "claude" || value3 === "codex";
|
|
22963
|
+
}
|
|
22964
|
+
function expectedVersions(harness) {
|
|
22965
|
+
return harness === "codex" ? ["0.159.0", "0.160.0"] : ["2.1.274", "2.1.288"];
|
|
22966
|
+
}
|
|
22967
|
+
function configTarget(input) {
|
|
22968
|
+
if (!isHarness(input.harness) || input.home === null)
|
|
22969
|
+
return null;
|
|
22970
|
+
const adapter = findHarnessAdapter(harnessId(input.harness));
|
|
22971
|
+
const declaration = adapter?.manifest.configFiles.find((file) => file.scope === "user" && file.parser === "json" && file.interceptionPoints?.includes("user-prompt-submit") === true);
|
|
22972
|
+
if (declaration === void 0 || adapter === null)
|
|
22973
|
+
return null;
|
|
22974
|
+
const fileContext = {
|
|
22975
|
+
fs: input.fs,
|
|
22976
|
+
runner: input.runner,
|
|
22977
|
+
facts: input.facts,
|
|
22978
|
+
paths: { ...input.paths, home: input.home },
|
|
22979
|
+
projectRoot: input.projectRoot
|
|
22980
|
+
};
|
|
22981
|
+
return {
|
|
22982
|
+
harness: input.harness,
|
|
22983
|
+
path: resolveConfigPath(declaration, fileContext),
|
|
22984
|
+
version: input.version,
|
|
22985
|
+
fileContext
|
|
22986
|
+
};
|
|
22987
|
+
}
|
|
22988
|
+
function hookEntries(harness) {
|
|
22989
|
+
return nativePromptRoutingHookEntries(harnessId(harness), "token-harness");
|
|
22990
|
+
}
|
|
22991
|
+
function asRecord(value3) {
|
|
22992
|
+
return typeof value3 === "object" && value3 !== null && !Array.isArray(value3) ? value3 : null;
|
|
22993
|
+
}
|
|
22994
|
+
function parseHookDocument(text3) {
|
|
22995
|
+
let decoded;
|
|
22996
|
+
try {
|
|
22997
|
+
decoded = JSON.parse(text3);
|
|
22998
|
+
} catch {
|
|
22999
|
+
return { ok: false, reason: "The hook settings file is malformed JSON or contains comments." };
|
|
23000
|
+
}
|
|
23001
|
+
const root = asRecord(decoded);
|
|
23002
|
+
if (root === null)
|
|
23003
|
+
return { ok: false, reason: "The hook settings root must be a JSON object." };
|
|
23004
|
+
const hooksValue = root["hooks"];
|
|
23005
|
+
if (hooksValue === void 0)
|
|
23006
|
+
return { ok: true, hooks: {} };
|
|
23007
|
+
const hooks = asRecord(hooksValue);
|
|
23008
|
+
if (hooks === null)
|
|
23009
|
+
return { ok: false, reason: "The settings hooks property must be an object." };
|
|
23010
|
+
for (const { eventName } of hookEntries("codex")) {
|
|
23011
|
+
const entries = hooks[eventName];
|
|
23012
|
+
if (entries !== void 0 && !Array.isArray(entries))
|
|
23013
|
+
return { ok: false, reason: `The ${eventName} hook property must be an array.` };
|
|
23014
|
+
}
|
|
23015
|
+
return { ok: true, hooks };
|
|
23016
|
+
}
|
|
23017
|
+
function containsRouterCommand(value3, harness) {
|
|
23018
|
+
const row2 = asRecord(value3);
|
|
23019
|
+
const hooks = row2?.["hooks"];
|
|
23020
|
+
if (!Array.isArray(hooks))
|
|
23021
|
+
return false;
|
|
23022
|
+
return hooks.some((hook) => {
|
|
23023
|
+
const handler = asRecord(hook);
|
|
23024
|
+
if (handler === null)
|
|
23025
|
+
return false;
|
|
23026
|
+
if (harness === "codex")
|
|
23027
|
+
return [handler["command"], handler["commandWindows"]].some((command) => typeof command === "string" && command.includes(ROUTE_MARKER));
|
|
23028
|
+
const args = handler["args"];
|
|
23029
|
+
return handler["command"] === "token-harness" && Array.isArray(args) && args[0] === ROUTE_MARKER;
|
|
23030
|
+
});
|
|
23031
|
+
}
|
|
23032
|
+
function configHasExactRouter(hooks, harness) {
|
|
23033
|
+
let exactCount = 0;
|
|
23034
|
+
let routeCount = 0;
|
|
23035
|
+
for (const expected of hookEntries(harness)) {
|
|
23036
|
+
const live = hooks[expected.eventName];
|
|
23037
|
+
const entries = Array.isArray(live) ? live : [];
|
|
23038
|
+
const routeEntries = entries.filter((entry) => containsRouterCommand(entry, harness));
|
|
23039
|
+
routeCount += routeEntries.length;
|
|
23040
|
+
if (routeEntries.some((entry) => jsonValueDigest(entry) === jsonValueDigest(expected.value)))
|
|
23041
|
+
exactCount += 1;
|
|
23042
|
+
}
|
|
23043
|
+
return {
|
|
23044
|
+
complete: exactCount === hookEntries(harness).length,
|
|
23045
|
+
partial: routeCount > 0 && exactCount !== hookEntries(harness).length,
|
|
23046
|
+
conflict: routeCount > exactCount
|
|
23047
|
+
};
|
|
23048
|
+
}
|
|
23049
|
+
function routerOwnedArtifacts(journals, path, harness) {
|
|
23050
|
+
const expected = hookEntries(harness);
|
|
23051
|
+
for (const journal of journals) {
|
|
23052
|
+
const disabledHere = journal.entries.some((entry) => entry.actionId.startsWith(`native-prompt-routing:${harness}:disable:`) && entry.snapshots.some((snapshot) => snapshot.path === path));
|
|
23053
|
+
if (disabledHere && journal.outcome === "committed")
|
|
23054
|
+
return [];
|
|
23055
|
+
const relevant = journal.ownership.filter((artifact) => artifact.kind === "owned-json-entry" && artifact.path === path && artifact.placement === "array-element" && expected.some((entry) => artifact.pointer === `hooks.${entry.eventName}` && artifact.valueDigest === jsonValueDigest(entry.value)));
|
|
23056
|
+
if (relevant.length > 0)
|
|
23057
|
+
return journal.outcome === "committed" ? relevant : [];
|
|
23058
|
+
}
|
|
23059
|
+
return [];
|
|
23060
|
+
}
|
|
23061
|
+
async function journalsFor(input) {
|
|
23062
|
+
if (input.stateRoot === null)
|
|
23063
|
+
return [];
|
|
23064
|
+
const journalRoot = input.fs.join(input.stateRoot, "journals");
|
|
23065
|
+
if ((await input.fs.stat(journalRoot))?.kind !== "directory")
|
|
23066
|
+
return [];
|
|
23067
|
+
return new FileJournalStore({
|
|
23068
|
+
fs: input.fs,
|
|
23069
|
+
journalRoot,
|
|
23070
|
+
backupRoot: input.fs.join(input.stateRoot, "backups")
|
|
23071
|
+
}).list();
|
|
23072
|
+
}
|
|
23073
|
+
function actionId(harness, intent, eventName) {
|
|
23074
|
+
return `native-prompt-routing:${harness}:${intent}:${eventName}`;
|
|
23075
|
+
}
|
|
23076
|
+
async function planNativePromptRoutingInstall(input) {
|
|
23077
|
+
const diagnostics = [];
|
|
23078
|
+
const target = configTarget(input);
|
|
23079
|
+
if (target === null) {
|
|
23080
|
+
diagnostics.push(diagnostic({
|
|
23081
|
+
severity: "warning",
|
|
23082
|
+
code: "prompt-routing-target-unavailable",
|
|
23083
|
+
subject: input.harness,
|
|
23084
|
+
message: "No supported user-scope native prompt hook target is available",
|
|
23085
|
+
remediation: "Resolve the user home and harness installation, then refresh Token Harness"
|
|
23086
|
+
}));
|
|
23087
|
+
return { target: null, actions: [], diagnostics };
|
|
23088
|
+
}
|
|
23089
|
+
if (!expectedVersions(target.harness).includes(target.version ?? "")) {
|
|
23090
|
+
diagnostics.push(diagnostic({
|
|
23091
|
+
severity: "warning",
|
|
23092
|
+
code: "prompt-routing-version-unverified",
|
|
23093
|
+
subject: target.harness,
|
|
23094
|
+
message: `Native prompt routing has no hook fixture for ${target.harness} ${target.version ?? "unknown"}`,
|
|
23095
|
+
path: target.path,
|
|
23096
|
+
remediation: "Refresh Token Harness after the installed harness hook schema is fixture-tested"
|
|
23097
|
+
}));
|
|
23098
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23099
|
+
}
|
|
23100
|
+
const runtimeCheck = await input.runner.run({
|
|
23101
|
+
executable: "token-harness",
|
|
23102
|
+
args: ["__internal-prompt-router", target.harness, "--check"],
|
|
23103
|
+
cwd: input.projectRoot,
|
|
23104
|
+
timeoutMs: 3e3,
|
|
23105
|
+
maxOutputBytes: 256
|
|
23106
|
+
});
|
|
23107
|
+
if (runtimeCheck.failure !== null || runtimeCheck.exitCode !== 0 || runtimeCheck.stdout.trim() !== PROMPT_ROUTER_CHECK_MARKER) {
|
|
23108
|
+
diagnostics.push(diagnostic({
|
|
23109
|
+
severity: "error",
|
|
23110
|
+
code: "prompt-routing-runtime-unavailable",
|
|
23111
|
+
subject: target.harness,
|
|
23112
|
+
message: "The Token Harness executable found on PATH cannot serve the native prompt hook",
|
|
23113
|
+
path: target.path,
|
|
23114
|
+
remediation: "Install or update Token Harness so the same executable is available to the coding agent, then refresh and plan again"
|
|
23115
|
+
}));
|
|
23116
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23117
|
+
}
|
|
23118
|
+
const stat3 = await input.fs.stat(target.path);
|
|
23119
|
+
if (stat3 !== null && stat3.kind !== "file") {
|
|
23120
|
+
diagnostics.push(diagnostic({
|
|
23121
|
+
severity: "error",
|
|
23122
|
+
code: "prompt-routing-target-not-file",
|
|
23123
|
+
subject: target.harness,
|
|
23124
|
+
message: "A non-file occupies the native hook settings path",
|
|
23125
|
+
path: target.path,
|
|
23126
|
+
remediation: "Move the conflicting path and refresh Token Harness"
|
|
23127
|
+
}));
|
|
23128
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23129
|
+
}
|
|
23130
|
+
let hooks = {};
|
|
23131
|
+
if (stat3 !== null) {
|
|
23132
|
+
const parsed = parseHookDocument(DECODER4.decode(await input.fs.readFile(target.path)));
|
|
23133
|
+
if (!parsed.ok) {
|
|
23134
|
+
diagnostics.push(diagnostic({
|
|
23135
|
+
severity: "error",
|
|
23136
|
+
code: "prompt-routing-settings-unmergeable",
|
|
23137
|
+
subject: target.harness,
|
|
23138
|
+
message: parsed.reason,
|
|
23139
|
+
path: target.path,
|
|
23140
|
+
remediation: "Repair the JSON settings file or configure native prompt routing manually"
|
|
23141
|
+
}));
|
|
23142
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23143
|
+
}
|
|
23144
|
+
hooks = parsed.hooks;
|
|
23145
|
+
}
|
|
23146
|
+
const existing = configHasExactRouter(hooks, target.harness);
|
|
23147
|
+
if (existing.complete) {
|
|
23148
|
+
diagnostics.push(diagnostic({
|
|
23149
|
+
severity: "info",
|
|
23150
|
+
code: "prompt-routing-already-configured",
|
|
23151
|
+
subject: target.harness,
|
|
23152
|
+
message: "Native prompt routing hooks are already present; no settings are changed",
|
|
23153
|
+
path: target.path,
|
|
23154
|
+
remediation: null
|
|
23155
|
+
}));
|
|
23156
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23157
|
+
}
|
|
23158
|
+
if (existing.partial || existing.conflict) {
|
|
23159
|
+
diagnostics.push(diagnostic({
|
|
23160
|
+
severity: "error",
|
|
23161
|
+
code: "prompt-routing-existing-hook-conflict",
|
|
23162
|
+
subject: target.harness,
|
|
23163
|
+
message: "A partial or modified Token Harness prompt hook already exists and was left untouched",
|
|
23164
|
+
path: target.path,
|
|
23165
|
+
remediation: "Review the existing native routing entries before planning another change"
|
|
23166
|
+
}));
|
|
23167
|
+
return { target: target.path, actions: [], diagnostics };
|
|
23168
|
+
}
|
|
23169
|
+
const entries = hookEntries(target.harness);
|
|
23170
|
+
const action = {
|
|
23171
|
+
kind: "merge-json",
|
|
23172
|
+
id: actionId(target.harness, "enable", "all"),
|
|
23173
|
+
riskClass: "reversible",
|
|
23174
|
+
requiresNetwork: false,
|
|
23175
|
+
requiresElevation: false,
|
|
23176
|
+
affectedPaths: [target.path],
|
|
23177
|
+
affectedProcesses: [target.harness],
|
|
23178
|
+
preconditions: [
|
|
23179
|
+
"the harness hook settings remain absent or valid JSON",
|
|
23180
|
+
"no Token Harness native prompt-routing hooks are already present"
|
|
23181
|
+
],
|
|
23182
|
+
postconditions: entries.map((entry) => `${entry.eventName} has one Token Harness-owned hook`),
|
|
23183
|
+
rollbackData: "file-snapshot",
|
|
23184
|
+
explanation: `Enable automatic native prompt routing for ${target.harness}` + (target.harness === "codex" ? "; manually enable and trust this hook in Codex after applying" : "; start a new Claude Code session after applying"),
|
|
23185
|
+
path: target.path,
|
|
23186
|
+
ownedPointers: entries.map((entry) => `hooks.${entry.eventName}`),
|
|
23187
|
+
operations: entries.map((entry) => ({
|
|
23188
|
+
kind: "append",
|
|
23189
|
+
pointer: `hooks.${entry.eventName}`,
|
|
23190
|
+
value: entry.value,
|
|
23191
|
+
expectedValueDigest: null
|
|
23192
|
+
})),
|
|
23193
|
+
createIfMissing: true
|
|
23194
|
+
};
|
|
23195
|
+
return { target: target.path, actions: [action], diagnostics };
|
|
23196
|
+
}
|
|
23197
|
+
async function planNativePromptRoutingRemoval(input) {
|
|
23198
|
+
const diagnostics = [];
|
|
23199
|
+
const target = configTarget(input);
|
|
23200
|
+
if (target === null || input.stateRoot === null) {
|
|
23201
|
+
diagnostics.push(diagnostic({
|
|
23202
|
+
severity: "warning",
|
|
23203
|
+
code: "prompt-routing-removal-unavailable",
|
|
23204
|
+
subject: input.harness,
|
|
23205
|
+
message: "The owned native prompt-routing configuration could not be located safely",
|
|
23206
|
+
remediation: "Refresh Token Harness from the signed-in user environment"
|
|
23207
|
+
}));
|
|
23208
|
+
return { target: target?.path ?? null, actions: [], diagnostics };
|
|
23209
|
+
}
|
|
23210
|
+
const expected = hookEntries(target.harness);
|
|
23211
|
+
const journals = await journalsFor({ fs: input.fs, stateRoot: input.stateRoot });
|
|
23212
|
+
const artifacts = routerOwnedArtifacts(journals, target.path, target.harness);
|
|
23213
|
+
const actions = expected.flatMap((entry) => {
|
|
23214
|
+
const pointer = `hooks.${entry.eventName}`;
|
|
23215
|
+
const targetArtifact = artifacts.find((artifact) => artifact.kind === "owned-json-entry" && artifact.pointer === pointer && artifact.valueDigest === jsonValueDigest(entry.value));
|
|
23216
|
+
if (targetArtifact === void 0)
|
|
23217
|
+
return [];
|
|
23218
|
+
const reverses = actionId(target.harness, "enable", "all");
|
|
23219
|
+
return [
|
|
23220
|
+
{
|
|
23221
|
+
kind: "remove-owned-change",
|
|
23222
|
+
id: actionId(target.harness, "disable", entry.eventName),
|
|
23223
|
+
riskClass: "reversible",
|
|
23224
|
+
requiresNetwork: false,
|
|
23225
|
+
requiresElevation: false,
|
|
23226
|
+
affectedPaths: [target.path],
|
|
23227
|
+
affectedProcesses: [target.harness],
|
|
23228
|
+
preconditions: [`${entry.eventName} still contains the exact Token Harness-owned hook`],
|
|
23229
|
+
postconditions: [`${entry.eventName} no longer contains the owned prompt-routing hook`],
|
|
23230
|
+
rollbackData: "file-snapshot",
|
|
23231
|
+
explanation: `Disable automatic native prompt routing for ${target.harness}`,
|
|
23232
|
+
path: target.path,
|
|
23233
|
+
reverses,
|
|
23234
|
+
target: targetArtifact
|
|
23235
|
+
}
|
|
23236
|
+
];
|
|
23237
|
+
});
|
|
23238
|
+
if (actions.length === 0)
|
|
23239
|
+
diagnostics.push(diagnostic({
|
|
23240
|
+
severity: "info",
|
|
23241
|
+
code: "prompt-routing-not-owned",
|
|
23242
|
+
subject: target.harness,
|
|
23243
|
+
message: "Token Harness owns no native prompt-routing hooks here, so nothing is removed",
|
|
23244
|
+
path: target.path,
|
|
23245
|
+
remediation: null
|
|
23246
|
+
}));
|
|
23247
|
+
return { target: target.path, actions, diagnostics };
|
|
23248
|
+
}
|
|
23249
|
+
async function readEvents(input) {
|
|
23250
|
+
if (input.stateRoot === null)
|
|
23251
|
+
return { state: "unavailable", events: [] };
|
|
23252
|
+
const directory = input.fs.join(input.stateRoot, "prompt-routing");
|
|
23253
|
+
if ((await input.fs.stat(directory))?.kind !== "directory")
|
|
23254
|
+
return { state: "available", events: [] };
|
|
23255
|
+
const files = (await input.fs.readDirectory(directory)).filter((name2) => /^events-\d{4}-\d{2}\.jsonl$/.test(name2)).sort().reverse();
|
|
23256
|
+
const events = [];
|
|
23257
|
+
let scannedBytes = 0;
|
|
23258
|
+
try {
|
|
23259
|
+
for (const file of files) {
|
|
23260
|
+
const path = input.fs.join(directory, file);
|
|
23261
|
+
const stat3 = await input.fs.stat(path);
|
|
23262
|
+
if (stat3 === null || stat3.kind !== "file")
|
|
23263
|
+
continue;
|
|
23264
|
+
if (stat3.byteLength > MAX_EVENT_FILE_BYTES || scannedBytes + stat3.byteLength > MAX_EVENT_SCAN_BYTES)
|
|
23265
|
+
return { state: "limited", events };
|
|
23266
|
+
const bytes = await input.fs.readFile(path);
|
|
23267
|
+
if (bytes.byteLength !== stat3.byteLength)
|
|
23268
|
+
return { state: "limited", events };
|
|
23269
|
+
scannedBytes += bytes.byteLength;
|
|
23270
|
+
const text3 = DECODER4.decode(bytes);
|
|
23271
|
+
for (const line of text3.split("\n")) {
|
|
23272
|
+
if (line === "")
|
|
23273
|
+
continue;
|
|
23274
|
+
try {
|
|
23275
|
+
const value3 = JSON.parse(line);
|
|
23276
|
+
if (!isPromptRouterEvent(value3))
|
|
23277
|
+
continue;
|
|
23278
|
+
if (input.harness !== void 0 && value3.harness !== input.harness)
|
|
23279
|
+
continue;
|
|
23280
|
+
if (input.projectId !== void 0 && value3.projectId !== input.projectId)
|
|
23281
|
+
continue;
|
|
23282
|
+
if (input.since !== void 0 && value3.timestamp < input.since)
|
|
23283
|
+
continue;
|
|
23284
|
+
events.push(value3);
|
|
23285
|
+
} catch {
|
|
23286
|
+
}
|
|
23287
|
+
}
|
|
23288
|
+
if (input.since !== void 0 && file.slice(7, 14) < input.since.slice(0, 7))
|
|
23289
|
+
break;
|
|
23290
|
+
}
|
|
23291
|
+
return { state: "available", events };
|
|
23292
|
+
} catch {
|
|
23293
|
+
return { state: "unavailable", events: [] };
|
|
23294
|
+
}
|
|
23295
|
+
}
|
|
23296
|
+
function isPromptRouterEvent(value3) {
|
|
23297
|
+
const row2 = asRecord(value3);
|
|
23298
|
+
return row2?.["schemaVersion"] === 1 && typeof row2["timestamp"] === "string" && Number.isFinite(Date.parse(row2["timestamp"])) && (row2["harness"] === "claude" || row2["harness"] === "codex") && typeof row2["projectId"] === "string" && ["prompt-submit", "subagent-start", "subagent-stop"].includes(String(row2["type"])) && (row2["model"] === null || typeof row2["model"] === "string" && row2["model"].length <= 80) && (row2["agentType"] === null || typeof row2["agentType"] === "string" && row2["agentType"].length <= 80);
|
|
23299
|
+
}
|
|
23300
|
+
async function recordNativePromptRoutingHook(input) {
|
|
23301
|
+
if (input.fs === null || input.stateRoot === null || input.projectId === null)
|
|
23302
|
+
return;
|
|
23303
|
+
let payload = null;
|
|
23304
|
+
if (input.event !== "prompt-submit" && input.hookInput !== null) {
|
|
23305
|
+
try {
|
|
23306
|
+
payload = asRecord(JSON.parse(input.hookInput));
|
|
23307
|
+
} catch {
|
|
23308
|
+
payload = null;
|
|
23309
|
+
}
|
|
23310
|
+
}
|
|
23311
|
+
const agentTypeRaw = payload?.["agent_type"];
|
|
23312
|
+
const agentType = input.event !== "prompt-submit" && typeof agentTypeRaw === "string" && agentTypeRaw.length <= 80 ? agentTypeRaw : null;
|
|
23313
|
+
const timestamp = new Date(input.now).toISOString();
|
|
23314
|
+
const event = {
|
|
23315
|
+
schemaVersion: 1,
|
|
23316
|
+
timestamp,
|
|
23317
|
+
harness: input.harness,
|
|
23318
|
+
projectId: input.projectId,
|
|
23319
|
+
type: input.event,
|
|
23320
|
+
// Hook payload model fields can identify the root session, not the spawned child. Until an
|
|
23321
|
+
// adapter has a versioned child-model field, keep actual worker identity unknown.
|
|
23322
|
+
model: null,
|
|
23323
|
+
agentType
|
|
23324
|
+
};
|
|
23325
|
+
const partition = `events-${timestamp.slice(0, 7)}.jsonl`;
|
|
23326
|
+
const directory = input.fs.join(input.stateRoot, "prompt-routing");
|
|
23327
|
+
await input.fs.createDirectory(directory);
|
|
23328
|
+
await input.fs.appendFile(input.fs.join(directory, partition), UTF84.encode(`${JSON.stringify(event)}
|
|
23329
|
+
`));
|
|
23330
|
+
}
|
|
23331
|
+
function summarizeEvents(events) {
|
|
23332
|
+
return {
|
|
23333
|
+
promptSubmissions: events.filter((event) => event.type === "prompt-submit").length,
|
|
23334
|
+
subagentsStarted: events.filter((event) => event.type === "subagent-start").length,
|
|
23335
|
+
subagentsStopped: events.filter((event) => event.type === "subagent-stop").length,
|
|
23336
|
+
reportedModels: [
|
|
23337
|
+
...new Set(events.filter((event) => event.type === "subagent-start" || event.type === "subagent-stop").flatMap((event) => event.model === null ? [] : [event.model]))
|
|
23338
|
+
],
|
|
23339
|
+
lastObservedAt: events.map((event) => event.timestamp).sort().at(-1) ?? null
|
|
23340
|
+
};
|
|
23341
|
+
}
|
|
23342
|
+
async function observeNativePromptRouting(input) {
|
|
23343
|
+
const harness = isHarness(input.harness) ? input.harness : "codex";
|
|
23344
|
+
const base = {
|
|
23345
|
+
harness,
|
|
23346
|
+
state: "unavailable",
|
|
23347
|
+
label: "Not verified",
|
|
23348
|
+
detail: "Native prompt routing could not be checked on this harness.",
|
|
23349
|
+
configPath: null,
|
|
23350
|
+
configured: null,
|
|
23351
|
+
promptSubmissions: 0,
|
|
23352
|
+
subagentsStarted: 0,
|
|
23353
|
+
subagentsStopped: 0,
|
|
23354
|
+
reportedModels: [],
|
|
23355
|
+
lastObservedAt: null,
|
|
23356
|
+
receiptState: "unavailable"
|
|
23357
|
+
};
|
|
23358
|
+
const target = configTarget({ ...input, harness: input.harness });
|
|
23359
|
+
if (target === null)
|
|
23360
|
+
return base;
|
|
23361
|
+
const eventResult = await readEvents({
|
|
23362
|
+
fs: input.fs,
|
|
23363
|
+
stateRoot: input.stateRoot,
|
|
23364
|
+
harness,
|
|
23365
|
+
...input.projectId === null ? {} : { projectId: input.projectId },
|
|
23366
|
+
since: new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString()
|
|
23367
|
+
});
|
|
23368
|
+
const summary = summarizeEvents(eventResult.events);
|
|
23369
|
+
const stat3 = await input.fs.stat(target.path);
|
|
23370
|
+
if (stat3 === null) {
|
|
23371
|
+
return {
|
|
23372
|
+
...base,
|
|
23373
|
+
state: "absent",
|
|
23374
|
+
label: "Disabled",
|
|
23375
|
+
detail: "Automatic routing is off. No Token Harness native prompt hook is installed.",
|
|
23376
|
+
configPath: target.path,
|
|
23377
|
+
configured: false,
|
|
23378
|
+
...summary,
|
|
23379
|
+
receiptState: eventResult.state
|
|
23380
|
+
};
|
|
23381
|
+
}
|
|
23382
|
+
if (stat3.kind !== "file")
|
|
23383
|
+
return {
|
|
23384
|
+
...base,
|
|
23385
|
+
state: "conflict",
|
|
23386
|
+
label: "Path conflict",
|
|
23387
|
+
detail: "A non-file occupies the native hook settings path.",
|
|
23388
|
+
configPath: target.path,
|
|
23389
|
+
...summary,
|
|
23390
|
+
receiptState: eventResult.state
|
|
23391
|
+
};
|
|
23392
|
+
let hooks;
|
|
23393
|
+
try {
|
|
23394
|
+
const parsed = parseHookDocument(DECODER4.decode(await input.fs.readFile(target.path)));
|
|
23395
|
+
if (!parsed.ok)
|
|
23396
|
+
return {
|
|
23397
|
+
...base,
|
|
23398
|
+
state: "conflict",
|
|
23399
|
+
label: "Settings need review",
|
|
23400
|
+
detail: parsed.reason,
|
|
23401
|
+
configPath: target.path,
|
|
23402
|
+
...summary,
|
|
23403
|
+
receiptState: eventResult.state
|
|
23404
|
+
};
|
|
23405
|
+
hooks = parsed.hooks;
|
|
23406
|
+
} catch {
|
|
23407
|
+
return {
|
|
23408
|
+
...base,
|
|
23409
|
+
state: "unavailable",
|
|
23410
|
+
label: "Not verified",
|
|
23411
|
+
detail: "The hook settings file could not be read safely.",
|
|
23412
|
+
configPath: target.path,
|
|
23413
|
+
...summary,
|
|
23414
|
+
receiptState: eventResult.state
|
|
23415
|
+
};
|
|
23416
|
+
}
|
|
23417
|
+
const match = configHasExactRouter(hooks, harness);
|
|
23418
|
+
if (match.conflict || match.partial) {
|
|
23419
|
+
return {
|
|
23420
|
+
...base,
|
|
23421
|
+
state: "conflict",
|
|
23422
|
+
label: "Custom hook needs review",
|
|
23423
|
+
detail: "A partial or edited Token Harness prompt-routing hook was found and was not changed.",
|
|
23424
|
+
configPath: target.path,
|
|
23425
|
+
...summary,
|
|
23426
|
+
receiptState: eventResult.state
|
|
23427
|
+
};
|
|
23428
|
+
}
|
|
23429
|
+
if (!match.complete) {
|
|
23430
|
+
return {
|
|
23431
|
+
...base,
|
|
23432
|
+
state: "absent",
|
|
23433
|
+
label: "Disabled",
|
|
23434
|
+
detail: "Automatic routing is off. No Token Harness native prompt hook is installed.",
|
|
23435
|
+
configPath: target.path,
|
|
23436
|
+
configured: false,
|
|
23437
|
+
...summary,
|
|
23438
|
+
receiptState: eventResult.state
|
|
23439
|
+
};
|
|
23440
|
+
}
|
|
23441
|
+
const artifacts = routerOwnedArtifacts(await journalsFor(input), target.path, harness);
|
|
23442
|
+
const state = artifacts.length === hookEntries(harness).length ? "managed" : "external";
|
|
23443
|
+
const hasRuntimeReceipt = summary.promptSubmissions > 0;
|
|
23444
|
+
const label = state === "external" ? hasRuntimeReceipt ? "Runtime observed \xB7 external" : "Enabled externally" : hasRuntimeReceipt ? "Runtime observed" : harness === "codex" ? "Configured \xB7 trust or runtime pending" : "Configured \xB7 runtime pending";
|
|
23445
|
+
const detail2 = summary.promptSubmissions > 0 ? `${String(summary.promptSubmissions)} prompt hook(s), ${String(summary.subagentsStarted)} native agent start(s), ${String(summary.subagentsStopped)} stop(s) observed in this project during the last 30 days.${eventResult.state === "limited" ? " Counts are partial because the local receipt scan reached its safety limit." : eventResult.state === "unavailable" ? " Local runtime receipts could not be read." : ""}` : harness === "codex" ? "The hook is configured. Review and trust it in Codex with /hooks, then submit a prompt to produce a runtime receipt." : "The hook is configured. Start a new Claude Code session, submit a prompt, and Token Harness will show the runtime receipt.";
|
|
23446
|
+
return {
|
|
23447
|
+
...base,
|
|
23448
|
+
state,
|
|
23449
|
+
label,
|
|
23450
|
+
detail: detail2,
|
|
23451
|
+
configPath: target.path,
|
|
23452
|
+
configured: true,
|
|
23453
|
+
...summary,
|
|
23454
|
+
receiptState: eventResult.state
|
|
23455
|
+
};
|
|
23456
|
+
}
|
|
23457
|
+
async function nativeRoutingObservationForBenchmark(input) {
|
|
23458
|
+
const observed = await observeNativePromptRouting({
|
|
23459
|
+
...input,
|
|
23460
|
+
projectId: input.projectId
|
|
23461
|
+
});
|
|
23462
|
+
const configured = observed.configured;
|
|
23463
|
+
if (input.startedAt === void 0)
|
|
23464
|
+
return {
|
|
23465
|
+
configured,
|
|
23466
|
+
promptSubmissions: 0,
|
|
23467
|
+
subagentsStarted: 0,
|
|
23468
|
+
subagentsStopped: 0,
|
|
23469
|
+
reportedModels: []
|
|
23470
|
+
};
|
|
23471
|
+
const found = await readEvents({
|
|
23472
|
+
fs: input.fs,
|
|
23473
|
+
stateRoot: input.stateRoot,
|
|
23474
|
+
harness: observed.harness,
|
|
23475
|
+
projectId: input.projectId,
|
|
23476
|
+
since: input.startedAt
|
|
23477
|
+
});
|
|
23478
|
+
const summary = summarizeEvents(found.events);
|
|
23479
|
+
return {
|
|
23480
|
+
configured,
|
|
23481
|
+
promptSubmissions: summary.promptSubmissions,
|
|
23482
|
+
subagentsStarted: summary.subagentsStarted,
|
|
23483
|
+
subagentsStopped: summary.subagentsStopped,
|
|
23484
|
+
reportedModels: summary.reportedModels
|
|
23485
|
+
};
|
|
23486
|
+
}
|
|
23487
|
+
var UTF84, DECODER4, ROUTE_MARKER, MAX_EVENT_FILE_BYTES, MAX_EVENT_SCAN_BYTES, PROMPT_ROUTER_CHECK_MARKER;
|
|
23488
|
+
var init_prompt_router = __esm({
|
|
23489
|
+
"apps/cli/dist/src/prompt-router.js"() {
|
|
23490
|
+
"use strict";
|
|
23491
|
+
init_src();
|
|
23492
|
+
init_src3();
|
|
23493
|
+
UTF84 = new TextEncoder();
|
|
23494
|
+
DECODER4 = new TextDecoder("utf-8", { fatal: true });
|
|
23495
|
+
ROUTE_MARKER = "__internal-prompt-router";
|
|
23496
|
+
MAX_EVENT_FILE_BYTES = 4 * 1024 * 1024;
|
|
23497
|
+
MAX_EVENT_SCAN_BYTES = 16 * 1024 * 1024;
|
|
23498
|
+
PROMPT_ROUTER_CHECK_MARKER = "token-harness-prompt-router-v1";
|
|
22800
23499
|
}
|
|
22801
23500
|
});
|
|
22802
23501
|
|
|
@@ -24065,7 +24764,7 @@ var init_agent_skill = __esm({
|
|
|
24065
24764
|
"apps/cli/dist/src/agent-skill.js"() {
|
|
24066
24765
|
"use strict";
|
|
24067
24766
|
init_src();
|
|
24068
|
-
TOKEN_HARNESS_AGENT_SKILL = "---\nname: token-harness\ndescription: Optimizes local Claude Code or Codex work against observed subscription allowance, context pressure, quality floors, and project-local benchmark evidence using the Token Harness CLI.
|
|
24767
|
+
TOKEN_HARNESS_AGENT_SKILL = "---\nname: token-harness\ndescription: Optimizes local Claude Code or Codex work against observed subscription allowance, context pressure, quality floors, and project-local benchmark evidence using the Token Harness CLI. Guides native subagent model routing for substantial bounded coding tasks. Use for substantial coding work where native delegation may apply, or when the user asks about allowance, model/effort/verbosity choices, quota fit, or Token Harness.\n---\n\n# Token Harness\n\nUse Token Harness as a local deterministic policy engine. Do not reproduce its quota math or invent provider conversions yourself.\n\n## Automatic routing\n\nWhen enabled in the Token Harness dashboard, a native prompt hook supplies the routing policy on every submitted prompt. This works without invoking this skill or prefixing the prompt with a command. The hook asks the coding agent to delegate only eligible bounded work; it does not change the root model or prove which child model ran. Use this skill when the user asks for explicit quota-aware advice or a benchmark.\n\n## Default workflow\n\n1. Confirm `token-harness --version` works. If it is missing, do not install it silently. If the user asked to install or set up Token Harness, follow that request; otherwise explain that the local CLI is required.\n2. Identify the harness you are currently running as: `claude` for Claude Code or `codex` for Codex. Do not guess from repository files.\n3. Classify the current task conservatively:\n - `mechanical`: formatting, rename, lookup, simple edits, deterministic scaffolding.\n - `standard`: ordinary implementation, tests, focused bug fixes.\n - `hard`: multi-file reasoning, ambiguous failures, migrations, difficult reviews.\n - `critical`: architecture, security-sensitive work, releases, or high-regression-risk changes.\n If uncertain between two classes, use the higher class.\n4. For a substantial task, or whenever the user asks about allowance/efficiency, run:\n\n `token-harness optimize --harness <claude|codex> --task <class> --profile balanced --json`\n\n5. Treat the JSON result as evidence, not as permission to mutate configuration. Prefer recommendations that reduce avoidable context or session overhead before lowering a quality floor.\n6. Continue with the user's task. Mention Token Harness only when it materially changes the plan, recommends a user-visible action, or lacks enough evidence.\n\nDo not run Token Harness before every trivial tool call. One observation at a meaningful task boundary is normally enough; re-observe when the task class changes materially, after a quota reset, after a substantial session/context change, or when the user asks.\n\n## Active context evidence\n\nWhen the current conversation or your own tool results directly establish useful task-state evidence, you may pass a short-lived `--context-snapshot` file to `optimize`. This metadata is for the CLI; never ask the user to write or understand the JSON. Skip the snapshot when no actionable evidence is directly observable or a temporary file cannot be safely created and removed.\n\n- Set task boundary, validation and quality only from explicit task state and checks you observed. Use `unknown` when those facts are missing or ambiguous.\n- Mark material superseded or condensable only when its current state is directly clear. Include `byteLength` only when tooling measured the exact local bytes; otherwise use `null`. Never estimate bytes from tokens.\n- Set reducer attribution only when directly known; otherwise use `unknown`. Do not include transcript text, prompts, tool payloads, source text, paths, MCP names or schemas.\n- Add a checkpoint byte ceiling only when you will use that same ceiling for the existing bounded `token-harness handoff` command. Omit it when no artifact budget is configured.\n- Create the metadata file temporarily, run `optimize`, then remove it. Treat the decision as advice; do not mask, summarize, compact or start a session on the user's behalf.\n\n## Explicit workload\n\nOnly pass `--tasks-left N` when the remaining accepted-task count is explicit from the user or an explicit task list already in the conversation. Never infer it from token history, source files, GitHub issues, or a guessed backlog. When it is explicit, add it to the same advisory call:\n\n`token-harness optimize --harness <claude|codex> --task <class> --profile balanced --tasks-left <N> --json`\n\nFor multiple independent new tasks whose explicit list can be classified by task class, Token Harness can compare Claude and Codex with:\n\n`token-harness schedule --current <current> --candidate <other> --workload mechanical=N,standard=N,hard=N,critical=N --json`\n\nOmit zero-count classes. This is for queued new work, not an in-progress handoff. Never switch harnesses automatically from this result.\n\n## Native subagent model routing\n\nUse native subagents as the only model-routing surface. This routes delegated work; it never changes the model already selected for the root conversation. Keep Codex as the first supported path.\n\nFor Codex, when the task is substantial and contains a complete, bounded implementation unit that can be handed off without duplicating work, delegate that unit to one native subagent with `model: gpt-6-luna` if Luna is present in the current Codex model picker/catalog. Set the model explicitly in the native spawn request: when it is omitted, Codex inherits the root model and reasoning effort, so a generic delegation is not a cost-routed delegation. If a higher-priority instruction forbids specifying the child model, skip cost routing and continue with the root model. Keep the root model responsible for task framing, integration, and acceptance review. Do not run the same implementation in both agents. Use at most one cost-routed worker at a time.\n\nSkip routing for trivial tasks, tightly coupled or shared-write work, architecture/security/release decisions, work that needs the root model's full context or judgment throughout, when the user asks not to delegate, when the root model is Luna or cannot be identified, or when the requested model is not currently available. Do not substitute an unverified model ID or silently fall back to another harness. If no supported route is available, continue with the current root model.\n\nFor Claude Code, apply the same bounded-task rules only when Claude Code is already configured and authenticated and native subagents are available. Request the current native `haiku` alias for an eligible worker; do not configure Claude Code or authenticate on the user's behalf.\n\nTreat the selected child model as a routing request until Codex or Claude Code visibly reports the worker's actual model. A skill instruction is not runtime telemetry. Subagents add context and coordination overhead and can consume more total tokens than single-agent work; do not claim token, quota, or cost savings without paired, quality-gated usage evidence for the same harness and task class.\n\n## Persistent native changes\n\n`optimize` is advisory. If it recommends a persistent model/reasoning/verbosity change and the user wants it applied:\n\n1. Build a reviewed plan with `token-harness plan --harness <claude|codex> --native-policy --task <class> --profile balanced --json`.\n2. Summarize the exact proposed change, scope, and any limitations to the user.\n3. Apply only after the user explicitly approves the proposed mutation. Use the returned plan id with `token-harness apply --plan <id> --yes`.\n4. Do not treat a persisted preference as a live change to an already-running session. Follow the plan/result instructions about when it takes effect.\n\nNever silently change authentication, billing, provider, model routing, hooks, trust, or purchase/redeem credits.\n\n## Evidence rules\n\n- Never equate local token counts with subscription quota.\n- Never compare raw Claude and Codex percentages as if they were the same currency.\n- Unknown allowance or benchmark evidence stays unknown.\n- Preserve task quality floors; do not lower effort merely because a cheaper setting exists.\n- Prefer project-local measured outcomes and backend quota deltas when Token Harness exposes them.\n- Do not add an MCP server or background model just to use this skill. The local CLI is the tool surface.\n";
|
|
24069
24768
|
ENCODER = new TextEncoder();
|
|
24070
24769
|
SKILL_DIGEST = digestBytes(ENCODER.encode(TOKEN_HARNESS_AGENT_SKILL));
|
|
24071
24770
|
TARGETS = {
|
|
@@ -26045,6 +26744,41 @@ async function computePlan(context) {
|
|
|
26045
26744
|
}
|
|
26046
26745
|
}
|
|
26047
26746
|
}
|
|
26747
|
+
if (context.agentRouting === true || context.disableAgentRouting === true) {
|
|
26748
|
+
const harness = context.harness;
|
|
26749
|
+
if (harness !== harnessId("claude") && harness !== CODEX12) {
|
|
26750
|
+
diagnostics.push(diagnostic({
|
|
26751
|
+
severity: "warning",
|
|
26752
|
+
code: "prompt-routing-harness-required",
|
|
26753
|
+
subject: harness,
|
|
26754
|
+
message: "Automatic prompt routing requires an explicit Claude Code or Codex harness",
|
|
26755
|
+
remediation: "Choose the detected agent in the guided app, or pass --harness claude|codex"
|
|
26756
|
+
}));
|
|
26757
|
+
} else if (context.adapters === null) {
|
|
26758
|
+
diagnostics.push(diagnostic({
|
|
26759
|
+
severity: "warning",
|
|
26760
|
+
code: "prompt-routing-adapters-unavailable",
|
|
26761
|
+
subject: harness,
|
|
26762
|
+
message: "The native prompt hook could not be planned without filesystem adapters",
|
|
26763
|
+
remediation: "Refresh Token Harness from a supported local environment"
|
|
26764
|
+
}));
|
|
26765
|
+
} else {
|
|
26766
|
+
const input = {
|
|
26767
|
+
fs: context.adapters.fs,
|
|
26768
|
+
home: context.home,
|
|
26769
|
+
harness,
|
|
26770
|
+
version: versions.harnesses[harness] ?? null,
|
|
26771
|
+
runner: context.adapters.runner,
|
|
26772
|
+
facts: context.platform,
|
|
26773
|
+
paths: context.adapters.paths,
|
|
26774
|
+
projectRoot: context.projectRoot,
|
|
26775
|
+
stateRoot: context.stateRoot
|
|
26776
|
+
};
|
|
26777
|
+
const routingPlan = context.agentRouting ? await planNativePromptRoutingInstall(input) : await planNativePromptRoutingRemoval(input);
|
|
26778
|
+
actions.push(...routingPlan.actions);
|
|
26779
|
+
diagnostics.push(...routingPlan.diagnostics);
|
|
26780
|
+
}
|
|
26781
|
+
}
|
|
26048
26782
|
if (context.nativePolicy === true && context.harness === harnessId("claude")) {
|
|
26049
26783
|
if (context.taskClass === void 0 || context.taskClass === null) {
|
|
26050
26784
|
diagnostics.push(diagnostic({
|
|
@@ -26227,6 +26961,7 @@ var init_plan2 = __esm({
|
|
|
26227
26961
|
init_src3();
|
|
26228
26962
|
init_src();
|
|
26229
26963
|
init_agent_skill();
|
|
26964
|
+
init_prompt_router();
|
|
26230
26965
|
init_apply();
|
|
26231
26966
|
init_context_cost2();
|
|
26232
26967
|
init_optimize();
|
|
@@ -26303,6 +27038,48 @@ async function verifyManagedIntegrationPostconditions(context, integrations) {
|
|
|
26303
27038
|
}
|
|
26304
27039
|
return diagnostics;
|
|
26305
27040
|
}
|
|
27041
|
+
async function verifyNativePromptRoutingPostconditions(context, actions) {
|
|
27042
|
+
const routing = actions.filter((action) => action.id.startsWith("native-prompt-routing:"));
|
|
27043
|
+
if (routing.length === 0)
|
|
27044
|
+
return [];
|
|
27045
|
+
if (context.adapters === null || context.stateRoot === null || context.harness !== harnessId("claude") && context.harness !== harnessId("codex")) {
|
|
27046
|
+
return [
|
|
27047
|
+
diagnostic({
|
|
27048
|
+
severity: "error",
|
|
27049
|
+
code: "prompt-routing-postcondition-unavailable",
|
|
27050
|
+
subject: context.harness,
|
|
27051
|
+
message: "Native prompt-routing configuration could not be read after the change",
|
|
27052
|
+
remediation: "Keep the transaction rollback and review a fresh plan from the local agent environment"
|
|
27053
|
+
})
|
|
27054
|
+
];
|
|
27055
|
+
}
|
|
27056
|
+
const observed = await observeNativePromptRouting({
|
|
27057
|
+
fs: context.adapters.fs,
|
|
27058
|
+
home: context.home,
|
|
27059
|
+
stateRoot: context.stateRoot,
|
|
27060
|
+
harness: context.harness,
|
|
27061
|
+
version: null,
|
|
27062
|
+
runner: context.adapters.runner,
|
|
27063
|
+
facts: context.platform,
|
|
27064
|
+
paths: context.adapters.paths,
|
|
27065
|
+
projectRoot: context.projectRoot,
|
|
27066
|
+
projectId: context.adapters.projectIdFor(context.projectRoot)
|
|
27067
|
+
});
|
|
27068
|
+
const shouldBeEnabled = routing.some((action) => action.id.includes(":enable:"));
|
|
27069
|
+
const satisfied = shouldBeEnabled ? observed.configured === true : observed.configured === false;
|
|
27070
|
+
if (satisfied)
|
|
27071
|
+
return [];
|
|
27072
|
+
return [
|
|
27073
|
+
diagnostic({
|
|
27074
|
+
severity: "error",
|
|
27075
|
+
code: "prompt-routing-postcondition-unmet",
|
|
27076
|
+
subject: context.harness,
|
|
27077
|
+
path: observed.configPath,
|
|
27078
|
+
message: `Native prompt-routing hooks were not observed in the requested state after the change: ${observed.label}`,
|
|
27079
|
+
remediation: "Review the hook settings and allow the transaction to restore its backup"
|
|
27080
|
+
})
|
|
27081
|
+
];
|
|
27082
|
+
}
|
|
26306
27083
|
function transactionIdFor(planId, at) {
|
|
26307
27084
|
const digest = digestText(`${planId} ${at}`);
|
|
26308
27085
|
return digest.slice(digest.indexOf(":") + 1, digest.indexOf(":") + 13);
|
|
@@ -26369,6 +27146,8 @@ async function runApply(context) {
|
|
|
26369
27146
|
const diagnostics = [];
|
|
26370
27147
|
let stored = null;
|
|
26371
27148
|
let storedAgentSkill = false;
|
|
27149
|
+
let storedAgentRouting = false;
|
|
27150
|
+
let storedAgentRoutingRemoval = false;
|
|
26372
27151
|
let planningContext = context;
|
|
26373
27152
|
const rejectedReport = () => ({
|
|
26374
27153
|
...emptyReport3("rejected"),
|
|
@@ -26422,11 +27201,15 @@ async function runApply(context) {
|
|
|
26422
27201
|
return finish3("rejected", EXIT_CODES["precondition-drift"], rejectedReport(), diagnostics);
|
|
26423
27202
|
}
|
|
26424
27203
|
storedAgentSkill = stored.actions.some((action) => action.id.startsWith("agent-skill:"));
|
|
27204
|
+
storedAgentRouting = stored.actions.some((action) => action.id.startsWith("native-prompt-routing:") && action.id.includes(":enable:"));
|
|
27205
|
+
storedAgentRoutingRemoval = stored.actions.some((action) => action.id.startsWith("native-prompt-routing:") && action.id.includes(":disable:"));
|
|
26425
27206
|
planningContext = {
|
|
26426
27207
|
...context,
|
|
26427
27208
|
harness: stored.harness,
|
|
26428
27209
|
provider,
|
|
26429
|
-
agentSkill: storedAgentSkill
|
|
27210
|
+
agentSkill: storedAgentSkill,
|
|
27211
|
+
agentRouting: storedAgentRouting,
|
|
27212
|
+
disableAgentRouting: storedAgentRoutingRemoval
|
|
26430
27213
|
};
|
|
26431
27214
|
} catch {
|
|
26432
27215
|
diagnostics.push(diagnostic({
|
|
@@ -26450,6 +27233,16 @@ async function runApply(context) {
|
|
|
26450
27233
|
}));
|
|
26451
27234
|
return finish3("rejected", EXIT_CODES["precondition-drift"], rejectedReport(), diagnostics);
|
|
26452
27235
|
}
|
|
27236
|
+
if (stored !== null && (storedAgentRouting || storedAgentRoutingRemoval) && computed.report.planId !== stored.planId) {
|
|
27237
|
+
diagnostics.push(diagnostic({
|
|
27238
|
+
severity: "error",
|
|
27239
|
+
code: "prompt-routing-plan-drift",
|
|
27240
|
+
subject: stored.harness,
|
|
27241
|
+
message: "The native prompt-routing target or ownership changed after the reviewed preview",
|
|
27242
|
+
remediation: "Review a fresh prompt-routing preview; nothing was written"
|
|
27243
|
+
}));
|
|
27244
|
+
return finish3("rejected", EXIT_CODES["precondition-drift"], rejectedReport(), diagnostics);
|
|
27245
|
+
}
|
|
26453
27246
|
if (computed.blocked.length > 0 && computed.report.actions.length === 0) {
|
|
26454
27247
|
return finish3("rejected", EXIT_CODES["unsupported-environment"], rejectedReport(), diagnostics);
|
|
26455
27248
|
}
|
|
@@ -26553,7 +27346,10 @@ async function runApply(context) {
|
|
|
26553
27346
|
// RFC 0004 §Process policy: an installer reaches the machine through the runner or not at all.
|
|
26554
27347
|
runner: context.adapters.runner,
|
|
26555
27348
|
now: context.now,
|
|
26556
|
-
verifyPostconditions: async () =>
|
|
27349
|
+
verifyPostconditions: async () => [
|
|
27350
|
+
...await verifyManagedIntegrationPostconditions(context, computed.managedIntegrations),
|
|
27351
|
+
...await verifyNativePromptRoutingPostconditions(context, actions)
|
|
27352
|
+
]
|
|
26557
27353
|
});
|
|
26558
27354
|
diagnostics.push(...transaction.diagnostics);
|
|
26559
27355
|
const report = {
|
|
@@ -26589,6 +27385,7 @@ var init_apply = __esm({
|
|
|
26589
27385
|
"use strict";
|
|
26590
27386
|
init_src();
|
|
26591
27387
|
init_src3();
|
|
27388
|
+
init_prompt_router();
|
|
26592
27389
|
init_candidate_lifecycle();
|
|
26593
27390
|
init_plan2();
|
|
26594
27391
|
init_snapshot_safety();
|
|
@@ -26888,6 +27685,18 @@ async function runBenchmarkStart(context) {
|
|
|
26888
27685
|
runContext(observedContext),
|
|
26889
27686
|
runHistory({ ...observedContext, since: "1d", until: null })
|
|
26890
27687
|
]);
|
|
27688
|
+
const nativeRoutingAtStart = context.adapters === null ? null : await nativeRoutingObservationForBenchmark({
|
|
27689
|
+
fs: context.adapters.fs,
|
|
27690
|
+
home: context.home,
|
|
27691
|
+
stateRoot: context.stateRoot,
|
|
27692
|
+
harness,
|
|
27693
|
+
version: null,
|
|
27694
|
+
runner: context.adapters.runner,
|
|
27695
|
+
facts: context.platform,
|
|
27696
|
+
paths: context.adapters.paths,
|
|
27697
|
+
projectRoot: context.projectRoot,
|
|
27698
|
+
projectId
|
|
27699
|
+
});
|
|
26891
27700
|
const budget = budgetResult.data?.harnesses.find((item) => item.harnessId === harness);
|
|
26892
27701
|
const contextObservation = contextResult.data?.harnesses.find((item) => item.harnessId === harness);
|
|
26893
27702
|
const policy = benchmarkPolicySnapshot(contextObservation);
|
|
@@ -26906,7 +27715,8 @@ async function runBenchmarkStart(context) {
|
|
|
26906
27715
|
startedAt,
|
|
26907
27716
|
usageBefore: budget?.windows ?? [],
|
|
26908
27717
|
contextAtStart,
|
|
26909
|
-
localSessionsBefore
|
|
27718
|
+
localSessionsBefore,
|
|
27719
|
+
nativeRoutingAtStart
|
|
26910
27720
|
};
|
|
26911
27721
|
if (!await writeJson(context, paths.capturePath, capture)) {
|
|
26912
27722
|
return commandResult({
|
|
@@ -27091,6 +27901,19 @@ async function runBenchmarkFinish(context) {
|
|
|
27091
27901
|
runContext(completedContext),
|
|
27092
27902
|
runHistory({ ...completedContext, since: "1d", until: null })
|
|
27093
27903
|
]);
|
|
27904
|
+
const nativeRoutingAtFinish = context.adapters === null ? null : await nativeRoutingObservationForBenchmark({
|
|
27905
|
+
fs: context.adapters.fs,
|
|
27906
|
+
home: context.home,
|
|
27907
|
+
stateRoot: context.stateRoot,
|
|
27908
|
+
harness: parsed.capture.harnessId,
|
|
27909
|
+
version: null,
|
|
27910
|
+
runner: context.adapters.runner,
|
|
27911
|
+
facts: context.platform,
|
|
27912
|
+
paths: context.adapters.paths,
|
|
27913
|
+
projectRoot: context.projectRoot,
|
|
27914
|
+
projectId,
|
|
27915
|
+
startedAt: parsed.capture.startedAt
|
|
27916
|
+
});
|
|
27094
27917
|
const budget = budgetResult.data?.harnesses.find((item) => item.harnessId === parsed.capture.harnessId);
|
|
27095
27918
|
const localUsage = parsed.capture.localSessionsBefore !== null && historyResult.data?.source.state === "available" ? deriveTaskLocalUsage(parsed.capture.localSessionsBefore, snapshotTaskLocalSessions(historyResult.data.sessions), parsed.capture.startedAt, completedAt) : null;
|
|
27096
27919
|
const finishContextObservation = contextResult.data?.harnesses.find((item) => item.harnessId === parsed.capture.harnessId);
|
|
@@ -27102,7 +27925,8 @@ async function runBenchmarkFinish(context) {
|
|
|
27102
27925
|
failedAttempts,
|
|
27103
27926
|
localUsage,
|
|
27104
27927
|
contextAtFinish: taskBenchmarkContextSnapshot(finishContextObservation),
|
|
27105
|
-
policyAtFinish: benchmarkPolicySnapshot(finishContextObservation)
|
|
27928
|
+
policyAtFinish: benchmarkPolicySnapshot(finishContextObservation),
|
|
27929
|
+
nativeRoutingAtFinish
|
|
27106
27930
|
});
|
|
27107
27931
|
if (!completed.ok) {
|
|
27108
27932
|
return commandResult({
|
|
@@ -27159,6 +27983,7 @@ var init_benchmark_capture = __esm({
|
|
|
27159
27983
|
init_budget2();
|
|
27160
27984
|
init_context_cost2();
|
|
27161
27985
|
init_history2();
|
|
27986
|
+
init_prompt_router();
|
|
27162
27987
|
CLAUDE13 = harnessId("claude");
|
|
27163
27988
|
CODEX13 = harnessId("codex");
|
|
27164
27989
|
CAPTURE_HARNESSES = /* @__PURE__ */ new Set([CLAUDE13, CODEX13]);
|
|
@@ -33774,12 +34599,19 @@ not-exercised, which is not a failure.`,
|
|
|
33774
34599
|
|
|
33775
34600
|
Usage
|
|
33776
34601
|
token-harness plan [--json] [--harness <id>] [--provider <id>] [--project <dir>]
|
|
34602
|
+
[--agent-routing | --disable-agent-routing]
|
|
33777
34603
|
[--native-policy] [--task <class>] [--profile <name>]
|
|
33778
34604
|
[--reserve <0-95>] [--tasks-left <n>]
|
|
33779
34605
|
|
|
33780
34606
|
Read-only. Exits 0 when a plan was produced, and 4 when a hard conflict prevents
|
|
33781
34607
|
apply. Nothing is changed either way.
|
|
33782
34608
|
|
|
34609
|
+
--agent-routing adds the native per-prompt hook for the selected Claude Code or Codex
|
|
34610
|
+
harness. --disable-agent-routing removes only exact hook entries owned by Token Harness.
|
|
34611
|
+
Both changes use the normal stored-plan, approval, verification and rollback path. Claude
|
|
34612
|
+
loads the change in a new session; Codex requires the user to review and trust the hook in
|
|
34613
|
+
/hooks. Configuration is shown separately from runtime callbacks in the guided app.
|
|
34614
|
+
|
|
33783
34615
|
--native-policy adds reviewed Codex native settings derived from the same optimizer
|
|
33784
34616
|
policy as token-harness optimize. This build manages reasoning effort and verbosity
|
|
33785
34617
|
only. A field coming from project config or a selected profile is left untouched.
|
|
@@ -33998,6 +34830,8 @@ async function run(options) {
|
|
|
33998
34830
|
nativePolicy: invocation.options.nativePolicy,
|
|
33999
34831
|
env: options.env ?? {},
|
|
34000
34832
|
agentSkill: invocation.options.agentSkill,
|
|
34833
|
+
agentRouting: invocation.options.agentRouting,
|
|
34834
|
+
disableAgentRouting: invocation.options.disableAgentRouting,
|
|
34001
34835
|
since: invocation.options.since,
|
|
34002
34836
|
until: invocation.options.until,
|
|
34003
34837
|
planId: invocation.options.plan,
|
|
@@ -34488,6 +35322,48 @@ function allowanceEvidence(entries, scope, quality) {
|
|
|
34488
35322
|
pairs: deltas.length
|
|
34489
35323
|
};
|
|
34490
35324
|
}
|
|
35325
|
+
function routedAllowanceEvidence(entries, scope) {
|
|
35326
|
+
const deltas = entries.flatMap((entry) => {
|
|
35327
|
+
const quota = entry.quota;
|
|
35328
|
+
if (quota === null || quota.scope !== scope || quota.confidence !== "authoritative")
|
|
35329
|
+
return [];
|
|
35330
|
+
return [quota.baselineDeltaUsedPercent - quota.optimizedDeltaUsedPercent];
|
|
35331
|
+
});
|
|
35332
|
+
const savedPercent = median2(deltas);
|
|
35333
|
+
return {
|
|
35334
|
+
state: savedPercent === null ? "not-measured" : "measured",
|
|
35335
|
+
scope,
|
|
35336
|
+
savedPercent: savedPercent === null ? null : roundOne(savedPercent),
|
|
35337
|
+
equivalentMinutes: scope === "five-hour" && savedPercent !== null ? roundOne(savedPercent * 3) : null,
|
|
35338
|
+
pairs: deltas.length
|
|
35339
|
+
};
|
|
35340
|
+
}
|
|
35341
|
+
function routingEvidence(entries) {
|
|
35342
|
+
const routed = entries.filter((entry) => entry.nativeRouting?.verdict === "attributed");
|
|
35343
|
+
const eligible = routed.filter((entry) => entry.nativeRouting?.qualityGatesPassed === true);
|
|
35344
|
+
const local = eligible.filter((entry) => entry.baselineLocalTokens !== null && entry.optimizedLocalTokens !== null);
|
|
35345
|
+
const baselineLocalTokens = local.length ? local.reduce((total, entry) => total + (entry.baselineLocalTokens ?? 0), 0) : null;
|
|
35346
|
+
const optimizedLocalTokens = local.length ? local.reduce((total, entry) => total + (entry.optimizedLocalTokens ?? 0), 0) : null;
|
|
35347
|
+
const savedLocalTokens = baselineLocalTokens === null || optimizedLocalTokens === null ? null : baselineLocalTokens - optimizedLocalTokens;
|
|
35348
|
+
const localTokenSavingPercent = baselineLocalTokens === null || optimizedLocalTokens === null || baselineLocalTokens <= 0 ? null : roundOne(savedLocalTokens / baselineLocalTokens * 100);
|
|
35349
|
+
const qualityBlockedPairs = routed.length - eligible.length;
|
|
35350
|
+
return {
|
|
35351
|
+
state: routed.length === 0 ? "not-measured" : eligible.length === 0 ? "blocked-by-quality" : "measured",
|
|
35352
|
+
pairs: eligible.length,
|
|
35353
|
+
qualityBlockedPairs,
|
|
35354
|
+
localPairs: local.length,
|
|
35355
|
+
baselineLocalTokens,
|
|
35356
|
+
optimizedLocalTokens,
|
|
35357
|
+
savedLocalTokens,
|
|
35358
|
+
localTokenSavingPercent,
|
|
35359
|
+
allowance5h: routedAllowanceEvidence(eligible, "five-hour"),
|
|
35360
|
+
allowance7d: routedAllowanceEvidence(eligible, "weekly"),
|
|
35361
|
+
reportedChildModels: [
|
|
35362
|
+
...new Set(eligible.flatMap((entry) => entry.nativeRouting?.optimizedReportedModels ?? []))
|
|
35363
|
+
],
|
|
35364
|
+
basis: routed.length === 0 ? "No paired benchmark currently proves that a native prompt hook ran and started a subagent." : eligible.length === 0 ? "Routing callbacks were observed, but all attributed pairs failed the quality gate; no savings are credited." : local.length > 0 || eligible.some((entry) => entry.quota?.confidence === "authoritative") ? "Exact local token counts and authoritative quota deltas are reported in separate units, only for attributed pairs that passed both quality gates." : "Routing was observed and both quality gates passed, but local token or authoritative quota usage was unavailable; no savings amount is inferred."
|
|
35365
|
+
};
|
|
35366
|
+
}
|
|
34491
35367
|
function guidedValueEvidence(report) {
|
|
34492
35368
|
const entries = report?.entries ?? [];
|
|
34493
35369
|
const quality = qualityEvidence(entries);
|
|
@@ -34496,6 +35372,7 @@ function guidedValueEvidence(report) {
|
|
|
34496
35372
|
allowance5h: allowanceEvidence(entries, "five-hour", quality),
|
|
34497
35373
|
allowance7d: allowanceEvidence(entries, "weekly", quality),
|
|
34498
35374
|
quality,
|
|
35375
|
+
routing: routingEvidence(entries),
|
|
34499
35376
|
candidates: (report?.candidateEvidence ?? []).map((item) => ({ ...item })),
|
|
34500
35377
|
apiCost: {
|
|
34501
35378
|
state: "not-measured",
|
|
@@ -34740,7 +35617,7 @@ function guidanceView(id, observation) {
|
|
|
34740
35617
|
...observation.state === "absent" ? { action: { kind: "skill", label: "Enable in-session guidance", harness: id } } : {}
|
|
34741
35618
|
};
|
|
34742
35619
|
}
|
|
34743
|
-
function agentRules(id, providers, context, guidance) {
|
|
35620
|
+
function agentRules(id, providers, context, guidance, promptRouting) {
|
|
34744
35621
|
const observation = context?.harnesses.find((item) => item.harnessId === id);
|
|
34745
35622
|
const reasoning = reasoningView(id, observation);
|
|
34746
35623
|
return [
|
|
@@ -34790,6 +35667,29 @@ function agentRules(id, providers, context, guidance) {
|
|
|
34790
35667
|
next: guidance?.state === "managed" ? "Keep coding normally. Ask the agent to use Token Harness when you want an explicit quota-aware check." : guidance?.state === "external" ? "The matching skill can be used as-is. Token Harness keeps it user-owned." : guidance?.state === "conflict" ? "Review the existing skill manually. Token Harness will not overwrite it." : "Enable this once, then keep coding normally. Ask the agent to use Token Harness for a task when you want an explicit check.",
|
|
34791
35668
|
...guidance?.action ? { action: guidance.action } : {}
|
|
34792
35669
|
},
|
|
35670
|
+
{
|
|
35671
|
+
id: `${id}-prompt-routing`,
|
|
35672
|
+
title: "Automatic prompt routing",
|
|
35673
|
+
state: promptRouting?.label ?? "Not verified",
|
|
35674
|
+
mode: promptRouting?.state === "absent" ? "not-enabled" : promptRouting?.state === "managed" || promptRouting?.state === "external" ? "automatic" : "integration",
|
|
35675
|
+
what: promptRouting?.detail ?? "Adds a native prompt hook that supplies the routing policy on every submitted prompt.",
|
|
35676
|
+
why: "Eligible bounded work may use a cheaper native subagent. The root conversation model stays unchanged, and the model decides whether a native subagent is appropriate.",
|
|
35677
|
+
evidence: promptRouting?.promptSubmissions ? `${String(promptRouting.promptSubmissions)} prompt callback(s) and ${String(promptRouting.subagentsStarted)} subagent start(s) observed in the last 30 days. Actual child model is shown only when the harness reports it.` : promptRouting?.configured ? "The hook is configured, but no prompt callback has been observed yet. Configuration alone is not runtime proof." : "No runtime routing evidence has been recorded yet.",
|
|
35678
|
+
next: promptRouting?.state === "absent" ? "Enable routing once, restart or trust the hook if the harness requires it, then keep using prompts normally." : promptRouting?.state === "managed" ? "Routing is enabled. Disable it here if you want to stop injecting the policy on each prompt." : promptRouting?.state === "external" ? "This hook is user-owned. Token Harness can report it but will not remove it." : promptRouting?.detail ?? "Refresh to inspect the native prompt-hook state.",
|
|
35679
|
+
...promptRouting?.state === "absent" ? {
|
|
35680
|
+
action: {
|
|
35681
|
+
kind: "routing-enable",
|
|
35682
|
+
label: "Enable automatic routing",
|
|
35683
|
+
harness: id
|
|
35684
|
+
}
|
|
35685
|
+
} : promptRouting?.state === "managed" ? {
|
|
35686
|
+
action: {
|
|
35687
|
+
kind: "routing-disable",
|
|
35688
|
+
label: "Disable automatic routing",
|
|
35689
|
+
harness: id
|
|
35690
|
+
}
|
|
35691
|
+
} : {}
|
|
35692
|
+
},
|
|
34793
35693
|
{
|
|
34794
35694
|
id: `${id}-mcp`,
|
|
34795
35695
|
title: "Connected tools",
|
|
@@ -35023,11 +35923,13 @@ var init_guided = __esm({
|
|
|
35023
35923
|
now;
|
|
35024
35924
|
random;
|
|
35025
35925
|
observeGuidance;
|
|
35026
|
-
|
|
35926
|
+
observeRouting;
|
|
35927
|
+
constructor(call, now, random, observeGuidance = null, observeRouting = null) {
|
|
35027
35928
|
this.call = call;
|
|
35028
35929
|
this.now = now;
|
|
35029
35930
|
this.random = random;
|
|
35030
35931
|
this.observeGuidance = observeGuidance;
|
|
35932
|
+
this.observeRouting = observeRouting;
|
|
35031
35933
|
}
|
|
35032
35934
|
status() {
|
|
35033
35935
|
return {
|
|
@@ -35099,6 +36001,7 @@ var init_guided = __esm({
|
|
|
35099
36001
|
const empty2 = () => ({ data: null, diagnostics: [], exitCode: 9 });
|
|
35100
36002
|
let doctor = empty2(), budget = empty2(), context = empty2();
|
|
35101
36003
|
let guidance;
|
|
36004
|
+
let promptRouting;
|
|
35102
36005
|
const observe = async (id, args) => {
|
|
35103
36006
|
let result6;
|
|
35104
36007
|
try {
|
|
@@ -35116,7 +36019,7 @@ var init_guided = __esm({
|
|
|
35116
36019
|
loading.agents = this.agentView(doctor, budget, context, {
|
|
35117
36020
|
rules: loading.stages.find((item) => item.id === "rules")?.state !== "working",
|
|
35118
36021
|
allowance: loading.stages.find((item) => item.id === "allowance")?.state !== "working"
|
|
35119
|
-
}, guidance);
|
|
36022
|
+
}, guidance, promptRouting);
|
|
35120
36023
|
};
|
|
35121
36024
|
const [, , , metrics, status, benchmark] = await Promise.all([
|
|
35122
36025
|
observe("agents", ["doctor"]).then((result6) => {
|
|
@@ -35143,6 +36046,29 @@ var init_guided = __esm({
|
|
|
35143
36046
|
}
|
|
35144
36047
|
}));
|
|
35145
36048
|
}
|
|
36049
|
+
if (this.observeRouting !== null) {
|
|
36050
|
+
promptRouting = {};
|
|
36051
|
+
await Promise.all(["claude", "codex"].map(async (harness) => {
|
|
36052
|
+
try {
|
|
36053
|
+
promptRouting[harness] = await this.observeRouting(harness);
|
|
36054
|
+
} catch {
|
|
36055
|
+
promptRouting[harness] = {
|
|
36056
|
+
harness,
|
|
36057
|
+
state: "unavailable",
|
|
36058
|
+
label: "Not verified",
|
|
36059
|
+
detail: "Native prompt-hook status could not be checked.",
|
|
36060
|
+
configPath: null,
|
|
36061
|
+
configured: null,
|
|
36062
|
+
promptSubmissions: 0,
|
|
36063
|
+
subagentsStarted: 0,
|
|
36064
|
+
subagentsStopped: 0,
|
|
36065
|
+
reportedModels: [],
|
|
36066
|
+
lastObservedAt: null,
|
|
36067
|
+
receiptState: "unavailable"
|
|
36068
|
+
};
|
|
36069
|
+
}
|
|
36070
|
+
}));
|
|
36071
|
+
}
|
|
35146
36072
|
updateAgents();
|
|
35147
36073
|
}),
|
|
35148
36074
|
observe("savings", [
|
|
@@ -35156,7 +36082,7 @@ var init_guided = __esm({
|
|
|
35156
36082
|
observe("checks", ["status"]),
|
|
35157
36083
|
observe("value", ["benchmark-matrix"])
|
|
35158
36084
|
]);
|
|
35159
|
-
const agents = this.agentView(doctor, budget, context, { rules: true, allowance: true }, guidance);
|
|
36085
|
+
const agents = this.agentView(doctor, budget, context, { rules: true, allowance: true }, guidance, promptRouting);
|
|
35160
36086
|
const notices = [];
|
|
35161
36087
|
if (doctor.data === null)
|
|
35162
36088
|
notices.push("The agent inventory could not be read. Check the local installation and refresh.");
|
|
@@ -35184,7 +36110,7 @@ var init_guided = __esm({
|
|
|
35184
36110
|
notices
|
|
35185
36111
|
};
|
|
35186
36112
|
}
|
|
35187
|
-
agentView(doctor, budget, context, complete2, guidance) {
|
|
36113
|
+
agentView(doctor, budget, context, complete2, guidance, promptRouting) {
|
|
35188
36114
|
const present = (doctor.data?.harnesses ?? []).filter((item) => item.state !== "absent" && (item.harnessId === "claude" || item.harnessId === "codex"));
|
|
35189
36115
|
return present.map((agent) => {
|
|
35190
36116
|
const providers = (doctor.data?.providers ?? []).filter((provider) => provider.state === "configured" && provider.configuredHarnesses.includes(agent.harnessId)).map((p) => p.providerId);
|
|
@@ -35207,8 +36133,9 @@ var init_guided = __esm({
|
|
|
35207
36133
|
effort: observed?.nativeEffort?.current ?? observed?.reasoningEffort ?? null,
|
|
35208
36134
|
reasoning: reasoningView(agent.harnessId, observed),
|
|
35209
36135
|
...guidance?.[agent.harnessId] ? { guidance: guidance[agent.harnessId] } : {},
|
|
36136
|
+
...promptRouting?.[agent.harnessId] ? { promptRouting: promptRouting[agent.harnessId] } : {},
|
|
35210
36137
|
allowanceAction: allowanceAction(usage?.diagnostics ?? []),
|
|
35211
|
-
rules: agentRules(agent.harnessId, providers, context.data, guidance?.[agent.harnessId]),
|
|
36138
|
+
rules: agentRules(agent.harnessId, providers, context.data, guidance?.[agent.harnessId], promptRouting?.[agent.harnessId]),
|
|
35212
36139
|
allowance: (usage?.windows ?? []).map((window) => ({
|
|
35213
36140
|
label: window.scope === "five-hour" ? "5-hour allowance" : `${window.scope} allowance`,
|
|
35214
36141
|
remaining: window.remainingPercent,
|
|
@@ -35243,11 +36170,13 @@ var init_guided = __esm({
|
|
|
35243
36170
|
"setup",
|
|
35244
36171
|
"effort",
|
|
35245
36172
|
"skill",
|
|
36173
|
+
"routing-enable",
|
|
36174
|
+
"routing-disable",
|
|
35246
36175
|
"undo",
|
|
35247
36176
|
"remove",
|
|
35248
36177
|
"candidate-setup",
|
|
35249
36178
|
"candidate-remove"
|
|
35250
|
-
].includes(action) || data["harness"] !== void 0 && !["claude", "codex"].includes(String(data["harness"])) || data["harnesses"] !== void 0 && !validHarnesses || data["harnesses"] !== void 0 && action !== "setup" || data["harnesses"] !== void 0 && data["harness"] !== void 0 || data["task"] !== void 0 && !TASKS.has(String(data["task"])) || data["provider"] !== void 0 && !["rtk", "harnesstrim", "mcptoon", "gitnexus", "headroom"].includes(String(data["provider"])) || data["candidate"] !== void 0 && !["mcptoon", "gitnexus"].includes(String(data["candidate"])) || action === "effort" && (data["harness"] === void 0 || data["task"] === void 0) || action === "skill" && data["harness"] === void 0 || action === "remove" && (data["provider"] === void 0 || data["harness"] !== void 0 || data["harnesses"] !== void 0 || data["task"] !== void 0 || data["candidate"] !== void 0) || data["provider"] !== void 0 && action !== "remove" && action !== "setup" || candidateAction && (data["candidate"] === void 0 || data["harness"] === void 0 || data["provider"] !== void 0 || data["task"] !== void 0) || !candidateAction && data["candidate"] !== void 0)
|
|
36179
|
+
].includes(action) || data["harness"] !== void 0 && !["claude", "codex"].includes(String(data["harness"])) || data["harnesses"] !== void 0 && !validHarnesses || data["harnesses"] !== void 0 && action !== "setup" || data["harnesses"] !== void 0 && data["harness"] !== void 0 || data["task"] !== void 0 && !TASKS.has(String(data["task"])) || data["provider"] !== void 0 && !["rtk", "harnesstrim", "mcptoon", "gitnexus", "headroom"].includes(String(data["provider"])) || data["candidate"] !== void 0 && !["mcptoon", "gitnexus"].includes(String(data["candidate"])) || action === "effort" && (data["harness"] === void 0 || data["task"] === void 0) || action === "skill" && data["harness"] === void 0 || (action === "routing-enable" || action === "routing-disable") && data["harness"] === void 0 || action === "remove" && (data["provider"] === void 0 || data["harness"] !== void 0 || data["harnesses"] !== void 0 || data["task"] !== void 0 || data["candidate"] !== void 0) || data["provider"] !== void 0 && action !== "remove" && action !== "setup" || candidateAction && (data["candidate"] === void 0 || data["harness"] === void 0 || data["provider"] !== void 0 || data["task"] !== void 0) || !candidateAction && data["candidate"] !== void 0)
|
|
35251
36180
|
throw new GuideError(400, "Choose a supported agent and action.");
|
|
35252
36181
|
return this.exclusive(async () => {
|
|
35253
36182
|
this.approval = null;
|
|
@@ -35435,13 +36364,17 @@ var init_guided = __esm({
|
|
|
35435
36364
|
args.push("--provider", setupProvider);
|
|
35436
36365
|
if (data["action"] === "skill") {
|
|
35437
36366
|
args.push("--provider", "none", "--agent-skill");
|
|
36367
|
+
} else if (data["action"] === "routing-enable") {
|
|
36368
|
+
args.push("--provider", "none", "--agent-routing");
|
|
36369
|
+
} else if (data["action"] === "routing-disable") {
|
|
36370
|
+
args.push("--provider", "none", "--disable-agent-routing");
|
|
35438
36371
|
} else if (data["action"] === "effort")
|
|
35439
36372
|
args.push("--provider", "none", "--native-policy", "--task", String(data["task"]), "--profile", data["task"] === "mechanical" ? "economy" : data["task"] === "standard" ? "balanced" : "quality");
|
|
35440
36373
|
const result6 = await this.call(args);
|
|
35441
36374
|
const report = result6.data;
|
|
35442
36375
|
if (report === null || result6.exitCode !== 0 || report.conflicts.length > 0 || report.actions.length === 0 || !report.persisted || report.planId === null) {
|
|
35443
36376
|
const subject = setupProvider !== null ? `${name(agent.harnessId)} \xB7 ${name(setupProvider)}` : name(agent.harnessId);
|
|
35444
|
-
notices.push(`${subject}: ${explainGuideIssue(result6.diagnostics, data["action"] === "effort" ? "No supported preference change is needed or available. Your current preference is kept." : data["action"] === "skill" ? "In-session guidance is already present, or an existing user-owned skill location was left untouched." : "No safe setup change is available for the current provider, agent version and platform.")}`);
|
|
36377
|
+
notices.push(`${subject}: ${explainGuideIssue(result6.diagnostics, data["action"] === "effort" ? "No supported preference change is needed or available. Your current preference is kept." : data["action"] === "skill" ? "In-session guidance is already present, or an existing user-owned skill location was left untouched." : data["action"] === "routing-enable" || data["action"] === "routing-disable" ? "No safe native prompt-routing change is available for the current harness, hook state and ownership evidence." : "No safe setup change is available for the current provider, agent version and platform.")}`);
|
|
35445
36378
|
continue;
|
|
35446
36379
|
}
|
|
35447
36380
|
plans.push(report.planId);
|
|
@@ -35451,6 +36384,8 @@ var init_guided = __esm({
|
|
|
35451
36384
|
description: "Installs one reviewed Token Harness Agent Skill in the standard user skill directory. It does not change model, login, billing, hooks, trust, or the current conversation.",
|
|
35452
36385
|
files: 1
|
|
35453
36386
|
});
|
|
36387
|
+
} else if (data["action"] === "routing-enable" || data["action"] === "routing-disable") {
|
|
36388
|
+
changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
|
|
35454
36389
|
} else {
|
|
35455
36390
|
changes.push(...report.actions.map((action2) => describeChange(action2, agent.harnessId)));
|
|
35456
36391
|
}
|
|
@@ -35468,7 +36403,7 @@ var init_guided = __esm({
|
|
|
35468
36403
|
plans,
|
|
35469
36404
|
transactionId: null,
|
|
35470
36405
|
provider: null,
|
|
35471
|
-
description: data["action"] === "effort" ? "Task preference" : data["action"] === "skill" ? "In-session guidance" : "Integration setup",
|
|
36406
|
+
description: data["action"] === "effort" ? "Task preference" : data["action"] === "skill" ? "In-session guidance" : data["action"] === "routing-enable" || data["action"] === "routing-disable" ? "Automatic prompt routing" : "Integration setup",
|
|
35472
36407
|
operation: "apply",
|
|
35473
36408
|
network
|
|
35474
36409
|
};
|
|
@@ -35480,7 +36415,7 @@ var init_guided = __esm({
|
|
|
35480
36415
|
notices,
|
|
35481
36416
|
expiresAt: id === null ? null : new Date(expires).toISOString(),
|
|
35482
36417
|
network,
|
|
35483
|
-
restart: data["action"] === "effort" || data["action"] === "skill"
|
|
36418
|
+
restart: data["action"] === "effort" || data["action"] === "skill" || data["action"] === "routing-enable" || data["action"] === "routing-disable"
|
|
35484
36419
|
};
|
|
35485
36420
|
});
|
|
35486
36421
|
}
|
|
@@ -38470,6 +39405,31 @@ var init_guided_product_client = __esm({
|
|
|
38470
39405
|
'caption',
|
|
38471
39406
|
),
|
|
38472
39407
|
);
|
|
39408
|
+
const routing = agent.promptRouting;
|
|
39409
|
+
const routingCard = node('div', undefined, 'routing-feature');
|
|
39410
|
+
const routingHead = node('div', undefined, 'tool-head');
|
|
39411
|
+
routingHead.append(
|
|
39412
|
+
node('strong', 'Automatic prompt routing'),
|
|
39413
|
+
pill(routing?.label || 'Not verified', routing?.state === 'managed' ? 'good' : routing?.state === 'absent' ? '' : 'warn'),
|
|
39414
|
+
);
|
|
39415
|
+
routingCard.append(
|
|
39416
|
+
routingHead,
|
|
39417
|
+
node(
|
|
39418
|
+
'p',
|
|
39419
|
+
routing?.detail || 'A native hook can inject the routing policy on every submitted prompt. Setup and runtime activity are tracked separately.',
|
|
39420
|
+
'caption',
|
|
39421
|
+
),
|
|
39422
|
+
);
|
|
39423
|
+
const routingActions = node('div', undefined, 'inline-actions');
|
|
39424
|
+
if (routing?.state === 'absent') {
|
|
39425
|
+
routingActions.append(actionButton('Enable routing', () => reviewPromptRouting(agent.id, true), 'secondary'));
|
|
39426
|
+
} else if (routing?.state === 'managed') {
|
|
39427
|
+
routingActions.append(actionButton('Disable routing', () => reviewPromptRouting(agent.id, false), 'secondary'));
|
|
39428
|
+
} else if (routing?.state === 'external') {
|
|
39429
|
+
routingActions.append(node('span', 'Managed elsewhere · left untouched', 'caption'));
|
|
39430
|
+
}
|
|
39431
|
+
if (routingActions.children.length) routingCard.append(routingActions);
|
|
39432
|
+
card.append(routingCard);
|
|
38473
39433
|
if (baseline.unavailable.length) {
|
|
38474
39434
|
const details = node('details', undefined, 'agent-details');
|
|
38475
39435
|
details.append(node('summary', 'Connection limitations'));
|
|
@@ -38561,6 +39521,57 @@ var init_guided_product_client = __esm({
|
|
|
38561
39521
|
});
|
|
38562
39522
|
}
|
|
38563
39523
|
|
|
39524
|
+
function reviewPromptRouting(agentId, enabled) {
|
|
39525
|
+
if (busy) return;
|
|
39526
|
+
const run = modal((enabled ? 'Enable' : 'Disable') + ' automatic routing · ' + agentName(agentId));
|
|
39527
|
+
$('modal-content').append(
|
|
39528
|
+
messageBox(
|
|
39529
|
+
'How this works',
|
|
39530
|
+
enabled
|
|
39531
|
+
? 'Token Harness adds a native UserPromptSubmit hook that supplies a short routing policy on each prompt. The agent may delegate eligible bounded work to a lower-cost native subagent; the root model stays the same.'
|
|
39532
|
+
: 'Token Harness removes only the exact native routing entries it owns. User-edited or manually installed hooks remain untouched.',
|
|
39533
|
+
),
|
|
39534
|
+
progress('Preparing a read-only plan', 'No harness settings change until you approve the exact preview.'),
|
|
39535
|
+
);
|
|
39536
|
+
$('modal-actions').append(modalClose('Cancel'));
|
|
39537
|
+
setBusy(true, false);
|
|
39538
|
+
ensureSession()
|
|
39539
|
+
.then(() => request('/api/preview', {
|
|
39540
|
+
action: enabled ? 'routing-enable' : 'routing-disable',
|
|
39541
|
+
harness: agentId,
|
|
39542
|
+
}))
|
|
39543
|
+
.then(data => {
|
|
39544
|
+
if (run !== modalRun || !$('modal').open) return;
|
|
39545
|
+
pendingTicket = data.ticket;
|
|
39546
|
+
$('modal-content').replaceChildren();
|
|
39547
|
+
for (const change of data.changes || []) {
|
|
39548
|
+
const item = node('article', undefined, 'preview-change');
|
|
39549
|
+
item.append(node('h3', change.title), node('p', change.description));
|
|
39550
|
+
$('modal-content').append(item);
|
|
39551
|
+
}
|
|
39552
|
+
if (!(data.changes || []).length)
|
|
39553
|
+
$('modal-content').append(messageBox('No change proposed', (data.notices || []).join(' ') || 'The current routing state or ownership evidence does not support a safe change.'));
|
|
39554
|
+
for (const notice of data.notices || []) $('modal-content').append(node('p', notice, 'notice-row'));
|
|
39555
|
+
$('modal-content').append(messageBox(
|
|
39556
|
+
agentId === 'codex' ? 'Codex trust step' : 'When it takes effect',
|
|
39557
|
+
agentId === 'codex'
|
|
39558
|
+
? 'After Apply, review and trust the UserPromptSubmit hook in Codex using /hooks. Until a callback is observed, the dashboard will show it as configured but not runtime verified.'
|
|
39559
|
+
: 'After Apply, start a new Claude Code session. The dashboard will show configured state first and runtime activity after the next prompt callback.',
|
|
39560
|
+
'safe',
|
|
39561
|
+
));
|
|
39562
|
+
$('modal-actions').replaceChildren(modalClose(data.ticket ? 'Cancel' : 'Done'));
|
|
39563
|
+
if (data.ticket) $('modal-actions').append(actionButton(enabled ? 'Apply routing hook' : 'Remove owned routing hook', () => applyTicket(data.ticket)));
|
|
39564
|
+
})
|
|
39565
|
+
.catch(error => {
|
|
39566
|
+
if (run !== modalRun) return;
|
|
39567
|
+
$('modal-error').textContent = error.message;
|
|
39568
|
+
$('modal-error').hidden = false;
|
|
39569
|
+
})
|
|
39570
|
+
.finally(() => {
|
|
39571
|
+
if (run === modalRun) setBusy(false, false);
|
|
39572
|
+
});
|
|
39573
|
+
}
|
|
39574
|
+
|
|
38564
39575
|
function reviewSetup(providerId = null) {
|
|
38565
39576
|
if (busy) return;
|
|
38566
39577
|
const choices = setupChoiceData(providerId);
|
|
@@ -39251,10 +40262,6 @@ var init_guided_product_client = __esm({
|
|
|
39251
40262
|
node('strong', component?.configuredHarnesses?.length ? component.configuredHarnesses.map(agentName).join(', ') : 'No detected agent'),
|
|
39252
40263
|
);
|
|
39253
40264
|
const measured = rows.filter(row => row.providerId === id);
|
|
39254
|
-
facts.append(
|
|
39255
|
-
node('span', 'Recorded results'),
|
|
39256
|
-
node('strong', measured.length ? measured.length + ' recorded result' + (measured.length === 1 ? '' : 's') : 'None in this period'),
|
|
39257
|
-
);
|
|
39258
40265
|
card.append(facts);
|
|
39259
40266
|
if (!measured.length) {
|
|
39260
40267
|
card.append(
|
|
@@ -39358,6 +40365,29 @@ var init_guided_product_client = __esm({
|
|
|
39358
40365
|
metricCard('5h / 7d allowance', allowance.value, allowance.detail, allowance.cls),
|
|
39359
40366
|
metricCard('Quality', quality.value, quality.detail, quality.cls),
|
|
39360
40367
|
);
|
|
40368
|
+
const routed = current?.value?.routing;
|
|
40369
|
+
const quotaParts = [];
|
|
40370
|
+
if (routed?.allowance5h?.state === 'measured' && routed.allowance5h.savedPercent !== null)
|
|
40371
|
+
quotaParts.push(routed.allowance5h.savedPercent >= 0
|
|
40372
|
+
? '5h saved ' + count(routed.allowance5h.savedPercent) + '%'
|
|
40373
|
+
: '5h use +' + count(Math.abs(routed.allowance5h.savedPercent)) + '%');
|
|
40374
|
+
if (routed?.allowance7d?.state === 'measured' && routed.allowance7d.savedPercent !== null)
|
|
40375
|
+
quotaParts.push(routed.allowance7d.savedPercent >= 0
|
|
40376
|
+
? '7d saved ' + count(routed.allowance7d.savedPercent) + '%'
|
|
40377
|
+
: '7d use +' + count(Math.abs(routed.allowance7d.savedPercent)) + '%');
|
|
40378
|
+
const routingValue = routed?.state === 'blocked-by-quality'
|
|
40379
|
+
? 'Not credited'
|
|
40380
|
+
: routed?.savedLocalTokens !== null && routed?.savedLocalTokens !== undefined
|
|
40381
|
+
? (routed.savedLocalTokens >= 0
|
|
40382
|
+
? count(routed.savedLocalTokens) + ' tokens saved' + (routed.localTokenSavingPercent === null ? '' : ' · ' + count(routed.localTokenSavingPercent) + '%')
|
|
40383
|
+
: count(Math.abs(routed.savedLocalTokens)) + ' tokens added' + (routed.localTokenSavingPercent === null ? '' : ' · ' + count(Math.abs(routed.localTokenSavingPercent)) + '%'))
|
|
40384
|
+
: quotaParts.length ? 'Allowance measured' : routed?.state === 'measured' ? 'Usage unavailable' : 'Not measured yet';
|
|
40385
|
+
const routingDetail = routed?.state === 'blocked-by-quality'
|
|
40386
|
+
? routed.basis
|
|
40387
|
+
: (quotaParts.length ? quotaParts.join(' · ') + '. ' : '') +
|
|
40388
|
+
(routed?.pairs ? count(routed.pairs) + ' quality-passed routed pair(s). ' : '') +
|
|
40389
|
+
'Local tokens and allowance percentages are separate measurements. Actual child model is not exposed by every harness hook.';
|
|
40390
|
+
$('result-summary').append(metricCard('Automatic routing', routingValue, routingDetail, routed?.state === 'measured' ? 'positive' : ''));
|
|
39361
40391
|
renderResultOptimizers();
|
|
39362
40392
|
renderResultAgents();
|
|
39363
40393
|
renderSavings();
|
|
@@ -39505,6 +40535,7 @@ var init_guided_product_styles = __esm({
|
|
|
39505
40535
|
.setup-step{margin:1.6rem 0}.step-heading{display:grid;grid-template-columns:34px 1fr;gap:.65rem;align-items:start;margin-bottom:.7rem}.step-number{display:grid;place-items:center;width:32px;height:32px;border-radius:9px;background:var(--accent);color:#fff;font-weight:900}.step-heading h2{margin:0}.step-heading p{margin:.2rem 0;color:var(--muted)}
|
|
39506
40536
|
.connection-overview{display:grid;gap:.75rem}.connection-summary{display:flex;align-items:center;justify-content:space-between;gap:1rem;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1rem}.connection-summary p{margin:.15rem 0 0}.connection-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius);background:var(--panel)}.connection-table{min-width:max(720px,100%)}.connection-row{display:grid;grid-template-columns:minmax(170px,1.25fr) repeat(var(--connection-columns),minmax(130px,1fr)) minmax(155px,.8fr);align-items:center;gap:.6rem;padding:.72rem .8rem;border-bottom:1px solid var(--line)}.connection-row:last-child{border-bottom:0}.connection-head{background:var(--panel-soft);color:var(--muted);font-size:.8rem}.connection-name{display:grid;gap:.12rem}.connection-cell,.connection-action{min-width:0}.connection-action{display:flex;justify-content:flex-end}.tool-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.8rem}.candidate-comparison-toolbar{grid-column:1/-1;justify-content:flex-end;align-self:start}.tool-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1rem;box-shadow:var(--shadow)}.tool-card.experimental{border-style:dashed}.tool-card.compact{box-shadow:none}.tool-card>p{color:var(--muted);margin:.65rem 0}.tool-head{display:flex;align-items:flex-start;justify-content:space-between;gap:.75rem}.tool-head h3{margin:0}.tool-facts{display:grid;grid-template-columns:auto 1fr;gap:.3rem .75rem;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:.65rem 0;margin:.65rem 0}.tool-facts span{color:var(--muted);font-size:.8rem}.tool-facts strong{font-size:.85rem}
|
|
39507
40537
|
.connection-role{max-width:28ch}.setup-choice-list{display:grid;gap:.55rem;margin:.9rem 0}.setup-choice-list h3{margin:.25rem 0 0}.setup-choice{display:grid;grid-template-columns:auto 1fr;align-items:start;gap:.7rem;padding:.8rem;border:1px solid var(--line);border-radius:12px;background:var(--panel);cursor:pointer}.setup-choice:hover{border-color:var(--accent);background:var(--accent-soft)}.setup-choice input{inline-size:1.1rem;block-size:1.1rem;margin:.15rem 0 0;accent-color:var(--accent)}.setup-choice-copy{display:grid;gap:.2rem}.setup-choice-limitation{color:var(--muted)}
|
|
40538
|
+
.routing-feature{margin:.8rem 0;padding:.8rem;border:1px solid var(--line);border-radius:12px;background:var(--panel-soft)}.routing-feature .tool-head{align-items:center}.routing-feature p{margin:.55rem 0;color:var(--muted)}
|
|
39508
40539
|
.managed-action-box{margin-top:.8rem;background:var(--panel-soft);border:1px solid var(--line);border-radius:12px;padding:.85rem}.managed-action-box p{margin:.1rem 0 .65rem}
|
|
39509
40540
|
.maintenance-list{display:grid;gap:.55rem}.maintenance-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:.8rem}.maintenance-row p{margin:.15rem 0}
|
|
39510
40541
|
.explain-box{background:var(--panel-soft);border:1px solid var(--line);border-radius:12px;padding:.8rem;margin:.6rem 0}.explain-box p{margin:.25rem 0;color:var(--muted)}.explain-box.warn{background:var(--warn-soft);border-color:color-mix(in srgb,var(--warn) 35%,var(--line))}.explain-box.safe{background:var(--good-soft);border-color:color-mix(in srgb,var(--good) 30%,var(--line))}.operation-progress{margin:.75rem 0;padding:.8rem;border:1px solid var(--line);border-radius:12px}.operation-progress p{margin:.35rem 0 0}
|
|
@@ -40185,7 +41216,7 @@ ${GUIDE_CANDIDATE_READINESS_JS}`;
|
|
|
40185
41216
|
</div>
|
|
40186
41217
|
|
|
40187
41218
|
<section class="setup-step" id="coding-agents">
|
|
40188
|
-
<div class="section-title"><div><h2>Coding agents</h2><p>
|
|
41219
|
+
<div class="section-title"><div><h2>Coding agents</h2><p>Enable automatic per-prompt routing here for each detected coding app. The card distinguishes hook configuration from callbacks actually observed at runtime.</p></div></div>
|
|
40189
41220
|
<div id="setup-agents" class="tool-grid"><article class="tool-card"><h3>Checking agents\u2026</h3></article></div>
|
|
40190
41221
|
<details class="disclosure advanced-disclosure">
|
|
40191
41222
|
<summary>Agent details and optional reasoning settings</summary>
|
|
@@ -40653,6 +41684,19 @@ async function runAsDatabaseReader(argv2) {
|
|
|
40653
41684
|
process5.exitCode = 0;
|
|
40654
41685
|
return true;
|
|
40655
41686
|
}
|
|
41687
|
+
function parsePromptRouterEvent(value3) {
|
|
41688
|
+
if (value3 === "prompt-submit" || value3 === "subagent-start" || value3 === "subagent-stop")
|
|
41689
|
+
return value3;
|
|
41690
|
+
return null;
|
|
41691
|
+
}
|
|
41692
|
+
function emitPromptRouterContext(harness) {
|
|
41693
|
+
process5.stdout.write(JSON.stringify({
|
|
41694
|
+
hookSpecificOutput: {
|
|
41695
|
+
hookEventName: "UserPromptSubmit",
|
|
41696
|
+
additionalContext: ROUTING_CONTEXT[harness]
|
|
41697
|
+
}
|
|
41698
|
+
}) + "\n");
|
|
41699
|
+
}
|
|
40656
41700
|
async function readStandardInput() {
|
|
40657
41701
|
const chunks = [];
|
|
40658
41702
|
let bytes = 0;
|
|
@@ -40677,6 +41721,16 @@ async function main(argv2) {
|
|
|
40677
41721
|
}
|
|
40678
41722
|
return;
|
|
40679
41723
|
}
|
|
41724
|
+
if (argv2[0] === PROMPT_ROUTER_FLAG && argv2[2] === "--check") {
|
|
41725
|
+
if (argv2[1] === "claude" || argv2[1] === "codex") {
|
|
41726
|
+
process5.stdout.write(`${PROMPT_ROUTER_CHECK_MARKER2}
|
|
41727
|
+
`);
|
|
41728
|
+
process5.exitCode = EXIT_CODES.ok;
|
|
41729
|
+
} else {
|
|
41730
|
+
process5.exitCode = EXIT_CODES["usage-error"];
|
|
41731
|
+
}
|
|
41732
|
+
return;
|
|
41733
|
+
}
|
|
40680
41734
|
const opensGuide = argv2.length === 0 || argv2[0] === "start" || argv2[0] === "ui";
|
|
40681
41735
|
const readOnly = argv2.includes("--read-only");
|
|
40682
41736
|
const uiInvocation = opensGuide ? parseUiArgs(argv2.slice(1).filter((arg) => arg !== "--read-only")) : null;
|
|
@@ -40746,6 +41800,34 @@ Run token-harness ui --help for usage.
|
|
|
40746
41800
|
env: process5.env,
|
|
40747
41801
|
stdoutIsTty: process5.stdout.isTTY === true
|
|
40748
41802
|
};
|
|
41803
|
+
if (argv2[0] === PROMPT_ROUTER_FLAG) {
|
|
41804
|
+
const selected = argv2[1];
|
|
41805
|
+
const event = parsePromptRouterEvent(argv2[2]);
|
|
41806
|
+
if (selected !== "claude" && selected !== "codex" || event === null) {
|
|
41807
|
+
process5.exitCode = EXIT_CODES.ok;
|
|
41808
|
+
return;
|
|
41809
|
+
}
|
|
41810
|
+
const input = await readStandardInput();
|
|
41811
|
+
if (resolution.ok && fs !== null && input !== null) {
|
|
41812
|
+
try {
|
|
41813
|
+
const projectId = attribution.salt === null ? null : deriveProjectId(process5.cwd(), attribution.salt, resolution.environment.facts.os === "windows");
|
|
41814
|
+
await recordNativePromptRoutingHook({
|
|
41815
|
+
fs,
|
|
41816
|
+
stateRoot: resolution.environment.paths.state,
|
|
41817
|
+
harness: selected,
|
|
41818
|
+
event,
|
|
41819
|
+
projectId,
|
|
41820
|
+
now: (/* @__PURE__ */ new Date()).toISOString(),
|
|
41821
|
+
hookInput: input
|
|
41822
|
+
});
|
|
41823
|
+
} catch {
|
|
41824
|
+
}
|
|
41825
|
+
}
|
|
41826
|
+
if (event === "prompt-submit")
|
|
41827
|
+
emitPromptRouterContext(selected);
|
|
41828
|
+
process5.exitCode = EXIT_CODES.ok;
|
|
41829
|
+
return;
|
|
41830
|
+
}
|
|
40749
41831
|
if (argv2[0] === RTK_HOOK_PROXY_FLAG) {
|
|
40750
41832
|
const selected = argv2[1];
|
|
40751
41833
|
if (selected !== "claude" && selected !== "codex") {
|
|
@@ -40968,6 +42050,35 @@ async function runGuidedUi(options, base) {
|
|
|
40968
42050
|
stateRoot: base.stateRoot ?? null,
|
|
40969
42051
|
harness
|
|
40970
42052
|
});
|
|
42053
|
+
}, async (harness) => {
|
|
42054
|
+
if (base.adapters === null || base.adapters === void 0 || base.platform === null) {
|
|
42055
|
+
return {
|
|
42056
|
+
harness,
|
|
42057
|
+
state: "unavailable",
|
|
42058
|
+
label: "Not verified",
|
|
42059
|
+
detail: "The local filesystem is unavailable, so native prompt routing cannot be checked.",
|
|
42060
|
+
configPath: null,
|
|
42061
|
+
configured: null,
|
|
42062
|
+
promptSubmissions: 0,
|
|
42063
|
+
subagentsStarted: 0,
|
|
42064
|
+
subagentsStopped: 0,
|
|
42065
|
+
reportedModels: [],
|
|
42066
|
+
lastObservedAt: null,
|
|
42067
|
+
receiptState: "unavailable"
|
|
42068
|
+
};
|
|
42069
|
+
}
|
|
42070
|
+
return observeNativePromptRouting({
|
|
42071
|
+
fs: base.adapters.fs,
|
|
42072
|
+
home: base.home,
|
|
42073
|
+
stateRoot: base.stateRoot ?? null,
|
|
42074
|
+
harness: harnessId(harness),
|
|
42075
|
+
version: null,
|
|
42076
|
+
runner: base.adapters.runner,
|
|
42077
|
+
facts: base.platform,
|
|
42078
|
+
paths: base.adapters.paths,
|
|
42079
|
+
projectRoot: base.cwd,
|
|
42080
|
+
projectId: base.adapters.projectIdFor(base.cwd)
|
|
42081
|
+
});
|
|
40971
42082
|
});
|
|
40972
42083
|
const token = randomBytes2(32).toString("hex");
|
|
40973
42084
|
let authority = "";
|
|
@@ -41068,7 +42179,7 @@ async function runSavingsView(args, base) {
|
|
|
41068
42179
|
}
|
|
41069
42180
|
return result6.exitCode;
|
|
41070
42181
|
}
|
|
41071
|
-
var RTK_HOOK_PROXY_FLAG, MAX_HOOK_INPUT_BYTES, UI_SECURITY_HEADERS;
|
|
42182
|
+
var RTK_HOOK_PROXY_FLAG, PROMPT_ROUTER_FLAG, PROMPT_ROUTER_CHECK_MARKER2, MAX_HOOK_INPUT_BYTES, ROUTING_CONTEXT, UI_SECURITY_HEADERS;
|
|
41072
42183
|
var init_main = __esm({
|
|
41073
42184
|
"apps/cli/dist/src/main.js"() {
|
|
41074
42185
|
"use strict";
|
|
@@ -41079,11 +42190,19 @@ var init_main = __esm({
|
|
|
41079
42190
|
init_version2();
|
|
41080
42191
|
init_guided();
|
|
41081
42192
|
init_agent_skill();
|
|
42193
|
+
init_prompt_router();
|
|
41082
42194
|
init_guided_candidate_campaign_status();
|
|
41083
42195
|
init_guided_http();
|
|
41084
42196
|
init_rtk_hook_proxy();
|
|
42197
|
+
init_prompt_router();
|
|
41085
42198
|
RTK_HOOK_PROXY_FLAG = "__internal-rtk-hook";
|
|
42199
|
+
PROMPT_ROUTER_FLAG = "__internal-prompt-router";
|
|
42200
|
+
PROMPT_ROUTER_CHECK_MARKER2 = "token-harness-prompt-router-v1";
|
|
41086
42201
|
MAX_HOOK_INPUT_BYTES = 1024 * 1024;
|
|
42202
|
+
ROUTING_CONTEXT = {
|
|
42203
|
+
codex: "For substantial coding work, delegate at most one independent bounded subtask to a native subagent with gpt-6-luna if available and the root is not Luna. Keep trivial, coupled, security, architecture, release, and integration decisions on the root. Specify the model; if unavailable, stay on the root. The root reviews. Claim savings only from paired, quality-gated measurements.",
|
|
42204
|
+
claude: "For substantial coding work, delegate at most one independent bounded subtask to a native subagent with the current Haiku alias if available and cheaper than the root. Keep trivial, coupled, security, architecture, release, and integration decisions on the root. Specify the model; if unavailable, stay on the root. The root reviews. Claim savings only from paired, quality-gated measurements."
|
|
42205
|
+
};
|
|
41087
42206
|
UI_SECURITY_HEADERS = {
|
|
41088
42207
|
"Cache-Control": "no-store",
|
|
41089
42208
|
"Content-Security-Policy": "default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'",
|