fix(ai): kept antigravity failover before advisor silence
Gated empty-STOP silence acceptance on the last Cloud Code Assist endpoint so an earlier endpoint returning only empty streams still fails over instead of being recorded as a valid silent review. Added an Antigravity auto-mode regression covering failover exhaustion before silence.
This commit is contained in:
@@ -1006,7 +1006,12 @@ export const streamGoogleGeminiCli: StreamFunction<"google-gemini-cli"> = (
|
||||
}
|
||||
|
||||
const streamed = await streamResponse(currentResponse);
|
||||
const acceptedSilence = options?.acceptEmptyResponse === true && !streamed.strippedPlanningLeak;
|
||||
// Only accept an empty STOP as valid silence once every fallback
|
||||
// endpoint is exhausted: an earlier endpoint returning empty
|
||||
// successful streams must still fail over (Antigravity auto mode)
|
||||
// rather than be recorded as a real silent review.
|
||||
const acceptedSilence =
|
||||
options?.acceptEmptyResponse === true && !streamed.strippedPlanningLeak && isLastEndpoint;
|
||||
if (output.stopReason !== "stop" || streamed.meaningful || acceptedSilence) {
|
||||
receivedContent = streamed.meaningful || acceptedSilence;
|
||||
break;
|
||||
|
||||
@@ -364,6 +364,34 @@ describe("Google empty-response retry (Cloud Code Assist path)", () => {
|
||||
expect(textOf(result)).toBe("Recovered.");
|
||||
});
|
||||
|
||||
it("exhausts Antigravity auto failover before accepting silence", async () => {
|
||||
const requestedEndpoints: string[] = [];
|
||||
const fetchMock: FetchImpl = async input => {
|
||||
const endpoint = endpointFromInput(input);
|
||||
requestedEndpoints.push(endpoint);
|
||||
return withResponseUrl(sse(ccaChunk("")), endpoint);
|
||||
};
|
||||
|
||||
const stream = streamGoogleGeminiCli(antigravityModel, context, {
|
||||
apiKey: JSON.stringify({ token: "token", projectId: "proj-123" }),
|
||||
antigravityEndpointMode: "auto",
|
||||
acceptEmptyResponse: true,
|
||||
fetch: fetchMock,
|
||||
});
|
||||
const result = await stream.result();
|
||||
|
||||
// Daily still burns its empty-response budget and fails over; only the
|
||||
// last (sandbox) endpoint records the empty STOP as valid silence.
|
||||
expect(requestedEndpoints).toEqual([
|
||||
ANTIGRAVITY_DAILY_ENDPOINT,
|
||||
ANTIGRAVITY_DAILY_ENDPOINT,
|
||||
ANTIGRAVITY_DAILY_ENDPOINT,
|
||||
ANTIGRAVITY_SANDBOX_ENDPOINT,
|
||||
]);
|
||||
expect(result.stopReason).toBe("stop");
|
||||
expect(result.errorMessage).toBeUndefined();
|
||||
});
|
||||
|
||||
for (const { mode, endpoint } of [
|
||||
{ mode: "production", endpoint: ANTIGRAVITY_DAILY_ENDPOINT },
|
||||
{ mode: "sandbox", endpoint: ANTIGRAVITY_SANDBOX_ENDPOINT },
|
||||
|
||||
Reference in New Issue
Block a user