-
-
Notifications
You must be signed in to change notification settings - Fork 60
fix: Claude model compatibility for Antigravity proxy #365
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
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ export interface ToolSettings { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nudgeFrequency: number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| protectedTools: string[] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contextLimit: number | `${number}%` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| textPartModels: string[] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface Tools { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -107,6 +108,7 @@ export const VALID_CONFIG_KEYS = new Set([ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.settings.nudgeFrequency", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.settings.protectedTools", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.settings.contextLimit", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.settings.textPartModels", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.distill", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.distill.permission", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tools.distill.showDistillation", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -303,6 +305,16 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tools.settings.textPartModels !== undefined && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| !Array.isArray(tools.settings.textPartModels) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errors.push({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: "tools.settings.textPartModels", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expected: "string[]", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actual: typeof tools.settings.textPartModels, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+308
to
+316
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | |
| tools.settings.textPartModels !== undefined && | |
| !Array.isArray(tools.settings.textPartModels) | |
| ) { | |
| errors.push({ | |
| key: "tools.settings.textPartModels", | |
| expected: "string[]", | |
| actual: typeof tools.settings.textPartModels, | |
| }) | |
| if (tools.settings.textPartModels !== undefined) { | |
| if (!Array.isArray(tools.settings.textPartModels)) { | |
| errors.push({ | |
| key: "tools.settings.textPartModels", | |
| expected: "string[]", | |
| actual: typeof tools.settings.textPartModels, | |
| }) | |
| } else if ( | |
| !tools.settings.textPartModels.every( | |
| (model) => typeof model === "string" | |
| ) | |
| ) { | |
| errors.push({ | |
| key: "tools.settings.textPartModels", | |
| expected: "string[]", | |
| actual: JSON.stringify(tools.settings.textPartModels), | |
| }) | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -253,13 +253,19 @@ export const insertPruneToolContext = ( | |||||||||
|
|
||||||||||
| // When following a user message, append a synthetic text part since models like Claude | ||||||||||
| // expect assistant turns to start with reasoning parts which cannot be easily faked. | ||||||||||
| // For models listed in textPartModels, always use text parts to avoid tool pairing issues. | ||||||||||
| // For all other cases, append a synthetic tool part to the last message which works | ||||||||||
| // across all models without disrupting their behavior. | ||||||||||
| if (lastNonIgnoredMessage.info.role === "user") { | ||||||||||
| const modelID = userInfo.model?.modelID || "" | ||||||||||
| const lowerModelID = modelID.toLowerCase() | ||||||||||
| const useTextPart = config.tools.settings.textPartModels.some( | ||||||||||
| (pattern) => lowerModelID.includes(pattern.toLowerCase()), | ||||||||||
|
||||||||||
| (pattern) => lowerModelID.includes(pattern.toLowerCase()), | |
| (pattern) => | |
| typeof pattern === "string" && | |
| lowerModelID.includes(pattern.toLowerCase()), |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,15 +24,14 @@ export const prune = ( | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const pruneFullTool = (state: SessionState, logger: Logger, messages: WithParts[]): void => { | ||||||||||||||||||||||
| const messagesToRemove: string[] = [] | ||||||||||||||||||||||
| let prunedCount = 0 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for (const msg of messages) { | ||||||||||||||||||||||
| if (isMessageCompacted(state, msg)) { | ||||||||||||||||||||||
| continue | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const parts = Array.isArray(msg.parts) ? msg.parts : [] | ||||||||||||||||||||||
| const partsToRemove: string[] = [] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for (const part of parts) { | ||||||||||||||||||||||
| if (part.type !== "tool") { | ||||||||||||||||||||||
|
|
@@ -45,26 +44,27 @@ const pruneFullTool = (state: SessionState, logger: Logger, messages: WithParts[ | |||||||||||||||||||||
| continue | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| partsToRemove.push(part.callID) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (partsToRemove.length === 0) { | ||||||||||||||||||||||
| continue | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| msg.parts = parts.filter( | ||||||||||||||||||||||
| (part) => part.type !== "tool" || !partsToRemove.includes(part.callID), | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| // Instead of removing the tool part entirely (which breaks Claude's | ||||||||||||||||||||||
| // tool_use/tool_result pairing in VALIDATED mode), replace the content | ||||||||||||||||||||||
| // with a placeholder. This preserves the tool part structure so the | ||||||||||||||||||||||
| // model-level conversion still generates matched functionCall/functionResponse pairs. | ||||||||||||||||||||||
| if (part.state?.input && typeof part.state.input === "object") { | ||||||||||||||||||||||
| for (const key of Object.keys(part.state.input)) { | ||||||||||||||||||||||
| if (typeof part.state.input[key] === "string") { | ||||||||||||||||||||||
| part.state.input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+51
to
+55
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (part.state?.status === "completed") { | ||||||||||||||||||||||
| part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT | ||||||||||||||||||||||
|
Comment on lines
+58
to
+59
|
||||||||||||||||||||||
| if (part.state?.status === "completed") { | |
| part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT | |
| if (part.state) { | |
| // When fully pruning a tool call, scrub outputs and errors regardless of status | |
| if ("output" in part.state) { | |
| part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT | |
| } | |
| if ("error" in part.state) { | |
| part.state.error = PRUNED_TOOL_OUTPUT_REPLACEMENT | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ import { ensureSessionInitialized } from "../state" | |
| import { saveSessionState } from "../state/persistence" | ||
| import { calculateTokensSaved, getCurrentParams } from "../strategies/utils" | ||
| import { getFilePathsFromParameters, isProtected } from "../protected-file-patterns" | ||
| import { buildToolIdList } from "../messages/utils" | ||
|
|
||
| // Shared logic for executing prune operations. | ||
| export async function executePruneOperation( | ||
|
|
@@ -47,10 +48,11 @@ export async function executePruneOperation( | |
| }) | ||
| const messages: WithParts[] = messagesResponse.data || messagesResponse | ||
|
|
||
| await ensureSessionInitialized(ctx.client, state, sessionId, logger, messages) | ||
| await syncToolCache(state, config, logger, messages) | ||
| await ensureSessionInitialized(ctx.client, state, sessionId, logger, messages) | ||
| await syncToolCache(state, config, logger, messages) | ||
| buildToolIdList(state, messages, logger) | ||
|
|
||
| const currentParams = getCurrentParams(state, messages, logger) | ||
| const currentParams = getCurrentParams(state, messages, logger) | ||
|
Comment on lines
+51
to
+55
|
||
|
|
||
| const toolIdList = state.toolIdList | ||
|
|
||
|
|
||
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.
The README documents the new
tools.settings.textPartModelsoption, but the referenced JSON schema (dcp.schema.json) does not currently include this property. Update the schema to keep editor validation/autocomplete in sync with the documented config.