Skip to content

Commit 721899b

Browse files
CopilotSivaKesava1
andauthored
Use corroborated routed endpoint in metadata
Co-authored-by: SivaKesava1 <11771739+SivaKesava1@users.noreply.github.com>
1 parent c7a186c commit 721899b

4 files changed

Lines changed: 56 additions & 3 deletions

File tree

‎actions/setup/js/awf_model_routing.cjs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,23 @@ function resolveAWFModelRoutingSelection(reflectData, routingRequired = false, a
7979
const provider = typeof selection.provider === "string" ? selection.provider.trim().toLowerCase() : "";
8080
const wireModel = typeof selection.wire_model === "string" ? selection.wire_model.trim() : "";
8181
const endpoint = typeof selection.endpoint === "string" ? selection.endpoint.trim() : "";
82+
const selectedEndpoint = typeof selection.selected_endpoint === "string" ? selection.selected_endpoint.trim() : endpoint;
8283
if (!["copilot", "github-copilot", "github"].includes(provider) || !wireModel || !endpoint) {
8384
return { selection: null, error: "AWF /reflect returned an incomplete or unsupported Copilot routing selection" };
8485
}
86+
if (endpoint !== selectedEndpoint && allowedEndpoints) {
87+
if (!allowEndpointOverride) {
88+
return { selection: null, error: `AWF /reflect selected endpoint ${endpoint}, which is not supported by this engine` };
89+
}
90+
const routingModel = getAWFRoutingModel(reflectData, wireModel);
91+
const supportedEndpoints = routingModel?.supported_endpoints;
92+
if (routingModel?.candidate_metadata_complete !== true || !Array.isArray(supportedEndpoints) || !supportedEndpoints.every(value => typeof value === "string")) {
93+
return { selection: null, error: `AWF /reflect cannot verify endpoints for model ${wireModel}; candidate metadata is incomplete for engine API ${allowedEndpoints.join(", ")}` };
94+
}
95+
if (!supportedEndpoints.includes(endpoint)) {
96+
return { selection: null, error: `AWF model ${wireModel} does not advertise endpoint ${endpoint}` };
97+
}
98+
}
8599
if (!isModelAvailableInReflectData(wireModel, reflectData, REFLECT_PROVIDER_ALIASES.github)) {
86100
return { selection: null, error: `AWF /reflect selected unavailable Copilot wire model ${wireModel}` };
87101
}

‎actions/setup/js/parse_token_usage.cjs‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function hasCorroboratedModelRoutingRequests(requestRecords, wireModel, endpoint
9393
}
9494

9595
function getModelRoutingSelectionFailureCode(error) {
96-
return /none compatible|not supported by this engine/.test(error) ? "unsupported_endpoint" : "invalid_selection";
96+
return /none compatible|not supported by this engine|does not advertise endpoint/.test(error) ? "unsupported_endpoint" : "invalid_selection";
9797
}
9898

9999
/** @returns {any|null} */
@@ -122,14 +122,21 @@ function resolveModelRoutingOutcome(env = process.env, ghAwDir = env.GH_AW_TMP_D
122122
failure_code: wireModel ? "" : "invalid_selection",
123123
};
124124
const policy = getAWFModelRoutingPolicy(String(env.GH_AW_ENGINE_ID || ""));
125-
const endpointOverride = !policy.endpoints.includes(routing.endpoint);
126125
const selectedAdvisory = advisory?.status === "selected" && (advisory.endpoint !== undefined || advisory.selected_endpoint !== undefined);
126+
const advisoryEndpointOverride = selectedAdvisory && ((typeof advisory.endpoint === "string" && advisory.endpoint !== routing.endpoint) || advisory.selected_endpoint !== routing.endpoint);
127+
const endpointOverride = !policy.endpoints.includes(routing.endpoint) || advisoryEndpointOverride;
127128
if (advisory?.status === "selected" && advisory.wire_model && advisory.wire_model !== wireModel) {
128129
routing = { ...routing, status: "rejected", failure_code: "harness_selection_mismatch", detail: "Harness routing outcome did not match the proxy selection" };
129130
} else if (["failed", "rejected", "pending", "unavailable"].includes(advisory?.status)) {
130131
routing = { ...routing, status: advisory.status, failure_code: advisory.failure_code || routing.failure_code, detail: advisory.detail || routing.detail };
131132
} else if (endpointOverride) {
132-
const checked = resolveAWFModelRoutingSelection({ ...reflectData, routing: { status: "selected", selection: routing } }, true, policy.endpoints, policy.allowEndpointOverride);
133+
const requestedEndpoint = selectedAdvisory && typeof advisory.endpoint === "string" ? advisory.endpoint : routing.endpoint;
134+
const checked = resolveAWFModelRoutingSelection(
135+
{ ...reflectData, routing: { status: "selected", selection: { ...routing, endpoint: requestedEndpoint, selected_endpoint: routing.endpoint } } },
136+
true,
137+
policy.endpoints,
138+
policy.allowEndpointOverride
139+
);
133140
if (checked.error || !checked.selection) {
134141
const detail = checked.error || "AWF /reflect did not return a compatible model-routing selection";
135142
routing = { ...routing, status: "rejected", failure_code: getModelRoutingSelectionFailureCode(detail), detail };

‎actions/setup/js/parse_token_usage.test.cjs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ describe("parse_token_usage", () => {
244244
expect(getEffectiveModelLabel(path.join(tmpDir, "aw_info.json"), "agent", process.env)).toBe("routed: opus50 max");
245245
});
246246

247+
test("records a corroborated pi effective endpoint even when AWF's endpoint is supported", async () => {
248+
setupClaudeRoutingFixture({ engine: "pi" });
249+
250+
await main();
251+
252+
expect(JSON.parse(originalReadFileSync(path.join(tmpDir, "aw_info.json"), "utf8")).model_routing).toMatchObject({
253+
status: "selected",
254+
endpoint: "/v1/messages",
255+
selected_endpoint: "/chat/completions",
256+
});
257+
});
258+
247259
test("attributes a corroborated Claude endpoint override from reflect when no harness outcome exists", async () => {
248260
setupClaudeRoutingFixture({ withOutcome: false });
249261

‎pkg/cli/model_routing_test.go‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,26 @@ func TestApplyAwInfoModelRoutingAddsEndpointMetadata(t *testing.T) {
143143
}
144144
}
145145

146+
func TestApplyAwInfoModelRoutingPrefersAgentArtifactCopy(t *testing.T) {
147+
runDir := t.TempDir()
148+
if err := os.MkdirAll(filepath.Join(runDir, "agent"), 0o700); err != nil {
149+
t.Fatal(err)
150+
}
151+
if err := os.WriteFile(filepath.Join(runDir, "aw_info.json"), []byte(`{"model":"agent"}`), 0o600); err != nil {
152+
t.Fatal(err)
153+
}
154+
if err := os.WriteFile(filepath.Join(runDir, "agent", "aw_info.json"), []byte(
155+
`{"model":"claude-opus-5","model_routing":{"status":"selected","endpoint":"/v1/messages","selected_endpoint":"/chat/completions"}}`,
156+
), 0o600); err != nil {
157+
t.Fatal(err)
158+
}
159+
160+
result := applyAwInfoModelRouting(&ModelRoutingSummary{Status: "selected", Endpoint: "/chat/completions"}, runDir)
161+
if result.EffectiveEndpoint != "/v1/messages" || result.SelectedEndpoint != "/chat/completions" {
162+
t.Fatalf("agent artifact endpoint metadata was not preferred: %+v", result)
163+
}
164+
}
165+
146166
func TestBuildAuditComparisonCandidateFromLegacySummary(t *testing.T) {
147167
runDir := t.TempDir()
148168
routingDir := filepath.Join(runDir, "sandbox", "firewall", "logs", "api-proxy-logs")

0 commit comments

Comments
 (0)