Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

- **kiro (system prompt leaked as raw user text):** when Claude Code routed through the Kiro/CodeWhisperer backend, the `system` message was normalized to a `user` turn with no wrapper, so the entire system prompt (environment info, tool definitions, memory instructions, etc.) appeared as if the user had typed it — polluting the model context. System-origin content is now wrapped in `<system-reminder>` tags before being merged into the Kiro user message, so the model can distinguish it from real user input. Real user turns are untouched. Regression guard: `tests/unit/kiro-system-reminder-2306.test.ts`. (thanks @VitzS7)

- **antigravity/gemini tool calls (`400 Unknown name "multipleOf"`):** requests routed to antigravity/gemini models with tools that declare a `multipleOf` numeric constraint failed with a hard upstream `400` (`Invalid JSON payload received. Unknown name "multipleOf"`). `multipleOf` is not part of the Gemini/antigravity OpenAPI 3.0 schema subset and was not being stripped from `function_declarations`. It is now removed at every schema level (top-level, nested, and array `items`), alongside the other unsupported constraints; `minimum`/`maximum` remain untouched. Regression guard: `tests/unit/gemini-multipleof-2309.test.ts`. (thanks @abil0321)

### 📝 Maintenance

- **test (deflake `setup-claude`):** `tests/unit/cli/setup-claude.test.ts` failed ~50% of runs with `Unable to deserialize cloned data due to invalid or unsupported version` at file teardown (all subtests passed), randomly reddening `Unit Tests fast-path (2/2)` / `Fast Quality Gates` across the PR→release queue. Root cause: `node --test` streams each file's report to the parent as V8-serialized frames on fd 1 (stdout), and the CLI helper under test (`syncClaudeProfilesFromModels`) prints progress via `console.log` — that stdout output interleaved with the serialized frames and corrupted the stream. The test now silences the stdout-writing `console` methods for the file's duration (no assertion inspects stdout), making it deterministic (15/15 green locally). ([#5959](https://github.com/diegosouzapw/OmniRoute/issues/5959))
Expand Down
4 changes: 4 additions & 0 deletions open-sse/translator/helpers/geminiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export const GEMINI_UNSUPPORTED_SCHEMA_KEYS = new Set([
"maxLength",
"exclusiveMinimum",
"exclusiveMaximum",
// `multipleOf` is not part of the Gemini/antigravity OpenAPI 3.0 schema subset;
// leaving it in function_declarations triggers a hard upstream 400
// ("Unknown name \"multipleOf\""). `minimum`/`maximum` ARE accepted and kept.
"multipleOf",
// NOTE: `pattern` is intentionally NOT in this set. Antigravity (Gemini-derived
// surface) accepts `pattern` on string constraints, and glob/grep/file-search
// tools depend on it to express their argument regex. Removing it produced
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/gemini-multipleof-2309.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* #2309 — antigravity/gemini returned [400] "Invalid JSON payload received.
* Unknown name \"multipleOf\" at 'request.tools[0].function_declarations[...]"
*
* Root cause: `multipleOf` (a JSON Schema numeric constraint) was NOT listed in
* `GEMINI_UNSUPPORTED_SCHEMA_KEYS`, so `cleanJSONSchemaForAntigravity` left it in
* the function-declaration parameters. The Gemini/antigravity upstream (OpenAPI
* 3.0 schema subset) rejects `multipleOf` with a hard 400.
*
* Fix: add `multipleOf` to the unsupported-keys set so it is stripped at every
* level (top-level property, nested object, and inside array `items`). Sibling
* numeric constraints `minimum`/`maximum` ARE accepted by Gemini and must stay.
*/
import test from "node:test";
import assert from "node:assert/strict";

import {
cleanJSONSchemaForAntigravity,
GEMINI_UNSUPPORTED_SCHEMA_KEYS,
} from "../../open-sse/translator/helpers/geminiHelper.ts";

test("#2309 multipleOf is stripped at all levels for antigravity/gemini schemas", () => {
const schema = {
type: "object",
properties: {
count: { type: "integer", multipleOf: 2, minimum: 0 },
ratio: { type: "number", multipleOf: 0.5 },
tags: { type: "array", items: { type: "number", multipleOf: 10 } },
},
};

const cleaned = JSON.stringify(cleanJSONSchemaForAntigravity(schema));

assert.ok(!cleaned.includes("multipleOf"), "multipleOf must be removed");
// Gemini DOES support minimum/maximum — those must survive.
assert.ok(cleaned.includes("minimum"), "minimum must be preserved");
});

test("#2309 multipleOf is in GEMINI_UNSUPPORTED_SCHEMA_KEYS", () => {
assert.ok(GEMINI_UNSUPPORTED_SCHEMA_KEYS.has("multipleOf"));
});
Loading