Repository navigation
fix(copilot): renegotiate after a cancelled Auto negotiation instead of dispatching the bare model #8417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(copilot): renegotiate after a cancelled Auto negotiation instead of dispatching the bare model #8417
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -196,7 +196,9 @@ describe("Copilot Auto permissions and negotiation", () => { | |
| calls++; throw new Error("network unavailable"); | ||
| }) as typeof fetch } as OcxProviderConfig; | ||
| expect((await resolveCopilotAuto(provider, "named", parsed)).modelId).toBe("named"); | ||
| expect(calls).toBe(1); | ||
| // An outage fallback is a usable named route, not a lapsed negotiation: no forced rebuild. | ||
| expect((await resolveCopilotAuto(provider, "named", parsed)).expiresAt).toBeUndefined(); | ||
| expect(calls).toBe(2); | ||
| }); | ||
| for (const cancelAt of ["/models/session", "/models/session/intent"] as const) { | ||
| test(`an authority change during ${cancelAt} also falls back instead of failing negotiation`, async () => { | ||
|
|
@@ -214,8 +216,11 @@ describe("Copilot Auto permissions and negotiation", () => { | |
| if (seen.length === (cancelAt === "/models/session" ? 1 : 2)) allowed = false; | ||
| return allowed; | ||
| }; | ||
| await expect(resolveCopilotAuto(provider, "auto", parsed, undefined, beforeSend)) | ||
| .resolves.toMatchObject({ modelId: "auto", auto: false }); | ||
| const selected = await resolveCopilotAuto(provider, "auto", parsed, undefined, beforeSend); | ||
| expect(selected).toMatchObject({ modelId: "auto", auto: false }); | ||
| // The fallback was never negotiated. request-transport fences dispatch on expiresAt, so an | ||
| // already-lapsed value makes dispatch renegotiate even if the selection becomes current again. | ||
| expect(selected.expiresAt).toBeLessThanOrEqual(Date.now()); | ||
|
Comment on lines
+221
to
+223
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| expect(seen.some(path => path.endsWith(cancelAt))).toBe(false); | ||
| }); | ||
| } | ||
|
|
@@ -227,8 +232,9 @@ describe("Copilot Auto permissions and negotiation", () => { | |
| await expect(resolveCopilotAuto(provider, "auto", parsed, AbortSignal.abort())).rejects.toThrow(); | ||
| // A manual account switch cancels the queued control-plane send. That is not a client | ||
| // abort: the caller revalidates the selection and rebuilds before dispatch. | ||
| await expect(resolveCopilotAuto(provider, "auto", parsed, undefined, () => false)) | ||
| .resolves.toMatchObject({ modelId: "auto", auto: false }); | ||
| const selected = await resolveCopilotAuto(provider, "auto", parsed, undefined, () => false); | ||
| expect(selected).toMatchObject({ modelId: "auto", auto: false }); | ||
| expect(selected.expiresAt).toBeLessThanOrEqual(Date.now()); | ||
| expect(sends).toBe(0); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: lidge-jun/opencodex
Length of output: 5494
Script executed:
Repository: lidge-jun/opencodex
Length of output: 38920
Script executed:
Repository: lidge-jun/opencodex
Length of output: 40147
Script executed:
Repository: lidge-jun/opencodex
Length of output: 43272
Script executed:
Repository: lidge-jun/opencodex
Length of output: 40345
Script executed:
Repository: lidge-jun/opencodex
Length of output: 21387
Renegotiate cancelled selections before wire validation.
If an account switch cancels session or intent negotiation, a request requiring
computer_usecan fail with HTTP 400 becauserequest-transport.ts:446validates the temporaryautoroute as Chat. The current account may support Responses. Rebuild the selection before validating its wire, with bounded retries.