fix: exclude google-antigravity from history downgrade hack (#894)
* Agent: exclude google-antigravity from history downgrade hack * Lint: fix formatting in test * Lint: formatting and unused vars in test * fix: preserve google-antigravity tool calls (#894) (thanks @mukhtharcm) --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
committed by
GitHub
parent
d0cb4e092f
commit
cd409e5667
@@ -18,6 +18,7 @@
|
|||||||
- Docs: clarify multi-gateway rescue bot guidance. (#969) — thanks @bjesuiter.
|
- Docs: clarify multi-gateway rescue bot guidance. (#969) — thanks @bjesuiter.
|
||||||
- Agents: add Current Date & Time system prompt section with configurable time format (auto/12/24).
|
- Agents: add Current Date & Time system prompt section with configurable time format (auto/12/24).
|
||||||
- Agents: avoid false positives when logging unsupported Google tool schema keywords.
|
- Agents: avoid false positives when logging unsupported Google tool schema keywords.
|
||||||
|
- Agents: skip Gemini history downgrades for google-antigravity to preserve tool calls. (#894) — thanks @mukhtharcm.
|
||||||
- Status: restore usage summary line for current provider when no OAuth profiles exist.
|
- Status: restore usage summary line for current provider when no OAuth profiles exist.
|
||||||
- Tools: normalize Slack/Discord message timestamps with `timestampMs`/`timestampUtc` while keeping raw provider fields.
|
- Tools: normalize Slack/Discord message timestamps with `timestampMs`/`timestampUtc` while keeping raw provider fields.
|
||||||
- macOS: add `system.which` for prompt-free remote skill discovery (with gateway fallback to `system.run`).
|
- macOS: add `system.which` for prompt-free remote skill discovery (with gateway fallback to `system.run`).
|
||||||
|
|||||||
109
src/agents/pi-embedded-runner.sanitize-session-history.test.ts
Normal file
109
src/agents/pi-embedded-runner.sanitize-session-history.test.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||||
|
import type { SessionManager } from "@mariozechner/pi-coding-agent";
|
||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import * as helpers from "./pi-embedded-helpers.js";
|
||||||
|
import { sanitizeSessionHistory } from "./pi-embedded-runner/google.js";
|
||||||
|
|
||||||
|
// Mock dependencies
|
||||||
|
vi.mock("./pi-embedded-helpers.js", async () => {
|
||||||
|
const actual = await vi.importActual("./pi-embedded-helpers.js");
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
isGoogleModelApi: vi.fn(),
|
||||||
|
downgradeGeminiHistory: vi.fn(),
|
||||||
|
sanitizeSessionMessagesImages: vi
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(async (msgs) => msgs),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// We don't mock session-transcript-repair.js as it is a pure function and complicates mocking.
|
||||||
|
// We rely on the real implementation which should pass through our simple messages.
|
||||||
|
|
||||||
|
describe("sanitizeSessionHistory", () => {
|
||||||
|
const mockSessionManager = {
|
||||||
|
getEntries: vi.fn().mockReturnValue([]),
|
||||||
|
appendCustomEntry: vi.fn(),
|
||||||
|
} as unknown as SessionManager;
|
||||||
|
|
||||||
|
const mockMessages: AgentMessage[] = [{ role: "user", content: "hello" }];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetAllMocks();
|
||||||
|
vi.mocked(helpers.sanitizeSessionMessagesImages).mockImplementation(
|
||||||
|
async (msgs) => msgs,
|
||||||
|
);
|
||||||
|
// Default mock implementation
|
||||||
|
vi.mocked(helpers.downgradeGeminiHistory).mockImplementation((msgs) => {
|
||||||
|
if (!msgs) return [];
|
||||||
|
return [...msgs, { role: "system", content: "downgraded" }];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should downgrade history for Google models if provider is not google-antigravity", async () => {
|
||||||
|
vi.mocked(helpers.isGoogleModelApi).mockReturnValue(true);
|
||||||
|
|
||||||
|
const result = await sanitizeSessionHistory({
|
||||||
|
messages: mockMessages,
|
||||||
|
modelApi: "google-gemini",
|
||||||
|
provider: "google-vertex",
|
||||||
|
sessionManager: mockSessionManager,
|
||||||
|
sessionId: "test-session",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(helpers.isGoogleModelApi).toHaveBeenCalledWith("google-gemini");
|
||||||
|
expect(helpers.downgradeGeminiHistory).toHaveBeenCalled();
|
||||||
|
// Check if the result contains the downgraded message
|
||||||
|
expect(result).toContainEqual({ role: "system", content: "downgraded" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should NOT downgrade history for google-antigravity provider", async () => {
|
||||||
|
vi.mocked(helpers.isGoogleModelApi).mockReturnValue(true);
|
||||||
|
|
||||||
|
const result = await sanitizeSessionHistory({
|
||||||
|
messages: mockMessages,
|
||||||
|
modelApi: "google-gemini",
|
||||||
|
provider: "google-antigravity",
|
||||||
|
sessionManager: mockSessionManager,
|
||||||
|
sessionId: "test-session",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(helpers.isGoogleModelApi).toHaveBeenCalledWith("google-gemini");
|
||||||
|
expect(helpers.downgradeGeminiHistory).not.toHaveBeenCalled();
|
||||||
|
// Result should not contain the downgraded message
|
||||||
|
expect(result).not.toContainEqual({
|
||||||
|
role: "system",
|
||||||
|
content: "downgraded",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should NOT downgrade history for non-Google models", async () => {
|
||||||
|
vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false);
|
||||||
|
|
||||||
|
const _result = await sanitizeSessionHistory({
|
||||||
|
messages: mockMessages,
|
||||||
|
modelApi: "anthropic-messages",
|
||||||
|
provider: "anthropic",
|
||||||
|
sessionManager: mockSessionManager,
|
||||||
|
sessionId: "test-session",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(helpers.isGoogleModelApi).toHaveBeenCalledWith("anthropic-messages");
|
||||||
|
expect(helpers.downgradeGeminiHistory).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should downgrade history if provider is undefined but model is Google", async () => {
|
||||||
|
vi.mocked(helpers.isGoogleModelApi).mockReturnValue(true);
|
||||||
|
|
||||||
|
const _result = await sanitizeSessionHistory({
|
||||||
|
messages: mockMessages,
|
||||||
|
modelApi: "google-gemini",
|
||||||
|
provider: undefined,
|
||||||
|
sessionManager: mockSessionManager,
|
||||||
|
sessionId: "test-session",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(helpers.isGoogleModelApi).toHaveBeenCalledWith("google-gemini");
|
||||||
|
expect(helpers.downgradeGeminiHistory).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -204,12 +204,15 @@ export async function sanitizeSessionHistory(params: {
|
|||||||
: undefined,
|
: undefined,
|
||||||
});
|
});
|
||||||
const repairedTools = sanitizeToolUseResultPairing(sanitizedImages);
|
const repairedTools = sanitizeToolUseResultPairing(sanitizedImages);
|
||||||
const shouldDowngradeGemini = isGeminiLike && !isAntigravityClaudeModel;
|
const isAntigravityProvider =
|
||||||
|
provider === "google-antigravity" || params.modelApi === "google-antigravity";
|
||||||
|
const shouldDowngradeThinking = isGeminiLike && !isAntigravityClaudeModel;
|
||||||
// Gemini rejects unsigned thinking blocks; downgrade them before send to avoid INVALID_ARGUMENT.
|
// Gemini rejects unsigned thinking blocks; downgrade them before send to avoid INVALID_ARGUMENT.
|
||||||
const downgradedThinking = shouldDowngradeGemini
|
const downgradedThinking = shouldDowngradeThinking
|
||||||
? downgradeGeminiThinkingBlocks(repairedTools)
|
? downgradeGeminiThinkingBlocks(repairedTools)
|
||||||
: repairedTools;
|
: repairedTools;
|
||||||
const downgraded = shouldDowngradeGemini
|
const shouldDowngradeHistory = shouldDowngradeThinking && !isAntigravityProvider;
|
||||||
|
const downgraded = shouldDowngradeHistory
|
||||||
? downgradeGeminiHistory(downgradedThinking)
|
? downgradeGeminiHistory(downgradedThinking)
|
||||||
: downgradedThinking;
|
: downgradedThinking;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user