gemma4-tool-shim / standalone.py
tpls's picture
shim: standalone.py
54704f8 verified
Raw
History Blame Contribute Delete
1.69 kB
"""Recover gemma-4 coder tool_calls WITHOUT litellm (or any framework).
Call your llama.cpp / OpenAI-compatible endpoint however you like, then run
`recovered_tool_calls()` on the assistant message text. The heavy lifting is in
`gemma_tool_parse.py` (pure stdlib) — this file is just the thin OpenAI-shape glue.
Run me directly for a demo: python standalone.py
"""
from __future__ import annotations
import json
from gemma_tool_parse import clean_content, find_tool_calls
def recovered_tool_calls(completion_text: str) -> tuple[list[dict], str | None]:
"""Turn a raw gemma-4 completion into OpenAI-style tool_calls.
Returns (tool_calls, leftover_content). When no call is present, tool_calls is
empty and leftover_content is the cleaned text (or None if it was pure markup).
"""
calls, leftover = find_tool_calls(completion_text)
if not calls:
return [], (clean_content(completion_text) or None)
tool_calls = [
{
"id": f"call_{i}",
"type": "function",
"function": {
"name": c["name"],
"arguments": json.dumps(c["arguments"], ensure_ascii=False),
},
}
for i, c in enumerate(calls)
]
return tool_calls, (leftover or None)
if __name__ == "__main__":
# The model leaks its call into `content` as native markup instead of structured
# tool_calls; recover it into the shape an OpenAI client expects.
demo = 'Sure! <|tool_call>call:get_weather{"city": "Paris", "units": "celsius"}'
tcs, content = recovered_tool_calls(demo)
print(json.dumps({"tool_calls": tcs, "content": content}, indent=2, ensure_ascii=False))