Right now we deserialize tool call definitions' arguments into golang
maps. These purposefully don't have a predictable iteration order,
whereas we want to maintain the order the user originally provided.
Unstable rendering of arguments means that we break the kv cache, which
this change fixes.
There's no way to build this in a fully backwards compatible way when
executing existing templates exactly as they are. We get around this by
rewriting templates dynamically just before they're rendered. This is
fragile, but perhaps the least bad option?
afaik gpt-oss is the first model that meaningfully transforms tool
function definitions in its template. We found that relatively common
definitions that include `anyOf` were not working because the template
was assuming that types were always defined via a `type` field.
anyOf allows for fully recursive types, so I exposed a
`toTypeScriptType()` function to handle this recursive logic in go and
keep the templates cleaner. The gpt-oss templates will need to be
updated to use this.
We should keep building out our function definition support to more
fully support the parts of json schema that make sense for this use
case, but in the meantime this will unblock some users (e.g., zed's
ollama integration w/ gpt-oss). Probably the most urgent is proper array
support
Fixes issue where tool calls that don't expect any parameters were
not being parsed. This also fixes two additional issues: one where
2+ tool calls would not be correctly parsed, and cases where tool calls
with invalid parameters would still get parsed