fix: drop obsolete pi-mono workarounds

This commit is contained in:
Peter Steinberger
2026-01-21 19:48:16 +00:00
parent 9f999f6554
commit 41c9c214fc
7 changed files with 57 additions and 354 deletions

View File

@@ -4,8 +4,6 @@ import type { SessionManager } from "@mariozechner/pi-coding-agent";
import { registerUnhandledRejectionHandler } from "../../infra/unhandled-rejections.js";
import {
downgradeGeminiThinkingBlocks,
downgradeGeminiHistory,
isCompactionFailureError,
isGoogleModelApi,
sanitizeGoogleTurnOrdering,
@@ -52,42 +50,6 @@ function shouldSanitizeToolCallIds(modelApi?: string | null): boolean {
return isGoogleModelApi(modelApi) || OPENAI_TOOL_CALL_ID_APIS.has(modelApi);
}
function filterOpenAIReasoningOnlyMessages(
messages: AgentMessage[],
modelApi?: string | null,
): AgentMessage[] {
if (modelApi !== "openai-responses") return messages;
return messages.filter((msg) => {
if (!msg || typeof msg !== "object") return true;
if ((msg as { role?: unknown }).role !== "assistant") return true;
const assistant = msg as Extract<AgentMessage, { role: "assistant" }>;
const content = assistant.content;
if (!Array.isArray(content) || content.length === 0) return true;
let hasThinking = false;
let hasPairedContent = false;
for (const block of content) {
if (!block || typeof block !== "object") continue;
const type = (block as { type?: unknown }).type;
if (type === "thinking") {
hasThinking = true;
continue;
}
if (type === "toolCall" || type === "toolUse" || type === "functionCall") {
hasPairedContent = true;
break;
}
if (type === "text") {
const text = (block as { text?: unknown }).text;
if (typeof text === "string" && text.trim().length > 0) {
hasPairedContent = true;
break;
}
}
}
return !(hasThinking && !hasPairedContent);
});
}
function findUnsupportedSchemaKeywords(schema: unknown, path: string): string[] {
if (!schema || typeof schema !== "object") return [];
if (Array.isArray(schema)) {
@@ -233,7 +195,6 @@ export async function sanitizeSessionHistory(params: {
const modelId = (params.modelId ?? "").toLowerCase();
const isOpenRouterGemini =
(provider === "openrouter" || provider === "opencode") && modelId.includes("gemini");
const isGeminiLike = isGoogleModelApi(params.modelApi) || isOpenRouterGemini;
const sanitizedImages = await sanitizeSessionMessagesImages(params.messages, "session:history", {
sanitizeToolCallIds: shouldSanitizeToolCallIds(params.modelApi),
enforceToolCallLast: params.modelApi === "anthropic-messages",
@@ -242,26 +203,10 @@ export async function sanitizeSessionHistory(params: {
? { allowBase64Only: true, includeCamelCase: true }
: undefined,
});
// TODO REMOVE when https://github.com/badlogic/pi-mono/pull/838 is merged.
const openaiReasoningFiltered = filterOpenAIReasoningOnlyMessages(
sanitizedImages,
params.modelApi,
);
const repairedTools = sanitizeToolUseResultPairing(openaiReasoningFiltered);
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.
const downgradedThinking = shouldDowngradeThinking
? downgradeGeminiThinkingBlocks(repairedTools)
: repairedTools;
const shouldDowngradeHistory = shouldDowngradeThinking && !isAntigravityProvider;
const downgraded = shouldDowngradeHistory
? downgradeGeminiHistory(downgradedThinking)
: downgradedThinking;
const repairedTools = sanitizeToolUseResultPairing(sanitizedImages);
return applyGoogleTurnOrderingFix({
messages: downgraded,
messages: repairedTools,
modelApi: params.modelApi,
sessionManager: params.sessionManager,
sessionId: params.sessionId,

View File

@@ -36,11 +36,11 @@ describe("injectHistoryImagesIntoMessages", () => {
const didMutate = injectHistoryImagesIntoMessages(messages, new Map([[0, [image]]]));
expect(didMutate).toBe(false);
const content = messages[0]?.content;
if (!Array.isArray(content)) {
const first = messages[0];
if (!first || !Array.isArray(first.content)) {
throw new Error("expected array content");
}
expect(content).toHaveLength(2);
expect(first.content).toHaveLength(2);
});
it("ignores non-user messages and out-of-range indices", () => {