fix(adk): keep Ollama tool property order stable across requests - #2693
Open
garlicKim21 wants to merge 6 commits into
Open
fix(adk): keep Ollama tool property order stable across requests#2693garlicKim21 wants to merge 6 commits into
garlicKim21 wants to merge 6 commits into
Conversation
convertGenaiToolsToOllama ranges over the Go map of parameter properties and Sets each one into an api.ToolPropertiesMap. That type preserves insertion order, so a randomized range order is carried straight into the serialized request: the tool definitions come out in a different order on every call. Ollama servers cache on the prompt prefix. Tool definitions sit near the front of the rendered prompt, so a reordered tool block invalidates the prefix and the whole prompt is re-processed every request. Measured against a live agent with 9 tools bound (8 of them with more than one property): 5,400 distinct serializations of the tool block, so two consecutive requests agree 0.02% of the time. In a 19-request session the server logged a full re-process 19 times, and prefill accounted for 64% of the session's wall clock. The same agent on the Python runtime hit the cache on every turn, because dict iteration order is deterministic there. Sort the property names before inserting. Both branches of the conversion have the same problem, so both are sorted. Signed-off-by: Golden Garlic <148346166+garlicKim21@users.noreply.github.com>
EItanya
approved these changes
Sep 4, 2026
EItanya
enabled auto-merge (squash)
September 4, 2026 12:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
convertGenaiToolsToOllamaranges over the Go map of parameter properties andSets each one into anapi.ToolPropertiesMap:That type is order-preserving by design —
// ToolPropertiesMap holds tool properties in insertion order(ollama/api/types.go), with a dedicatedTestToolPropertiesMap_OrderPreservation. So the randomized range order iscarried straight into the serialized request and the tool definitions come out
in a different order on every call.
Ollama servers cache on the prompt prefix, and tool definitions sit near the
front of the rendered prompt. A reordered tool block invalidates the prefix, so
the entire prompt is re-processed on every request.
Both branches of the conversion (
ParametersJsonSchemaandParameters) havethe same problem. This sorts the property names before inserting.
Impact measured on a live agent
An agent with 9 tools bound, 8 of them with more than one property. Feeding the
real schemas through the current code path:
(Small Go maps live in one bucket, so the range order is a rotation rather than
a full shuffle — hence 5 variants for 5 properties, not 5!.)
Against the inference server, over one 19-request session:
wall clock spent re-reading a prompt that had barely changed
before the end of the (static, ~2,800 token) system instruction
The varying break point is itself a fingerprint of this bug: a static
difference would break at a constant offset, whereas here it breaks at
whichever tool first happens to differ.
Why the Python runtime was unaffected
The same agent, same config, on the Python ADK image hit the cache on every
turn. Python preserves dict insertion order deterministically, so the
equivalent conversion is stable there. Switching an agent's runtime from
pythontogois what surfaced this.Test
TestConvertGenaiToolsToOllamaPropertyOrderIsStableconverts the same tool 100times and asserts the property order is identical, then asserts the order is
sorted so it is stable across processes too.
Without the fix:
Environment
kagent 0.10.0-rc6, Go ADK runtime, declarative agent with an Ollama
ModelConfig, tools from two remote MCP servers.