Part of #1592
Scope
Implement native function calling for Gemini via tools + functionDeclarations.
Files to Modify
crates/zeph-llm/src/gemini.rs -- implement chat_with_tools(), tool definition conversion, tool result handling
Key Implementation Details
Tool Definition Conversion (Zeph -> Gemini)
Zeph ToolDefinition maps to Gemini functionDeclarations:
- JSON Schema type names must be UPPERCASED:
string -> STRING, object -> OBJECT, etc.
$ref / $defs references must be inlined (Gemini does not support JSON Schema references)
- Nested in
tools[0].functionDeclarations[] (not flat like OpenAI)
Tool Call Parsing (Gemini -> Zeph)
Gemini returns functionCall as a part in candidates[0].content.parts[]:
{ "functionCall": { "name": "tool_name", "args": {...} } }
Map to ToolUseRequest { id: generated_uuid, name, input: args }.
Note: Gemini does not return a tool call ID -- generate a UUID locally.
Tool Result Format (Zeph -> Gemini)
Tool results are sent as functionResponse parts in a user message:
{ "role": "user", "parts": [{ "functionResponse": { "name": "...", "response": {...} } }] }
Tool Config
Send toolConfig.functionCallingConfig.mode as "AUTO" (default).
Acceptance Criteria
Part of #1592
Scope
Implement native function calling for Gemini via
tools+functionDeclarations.Files to Modify
crates/zeph-llm/src/gemini.rs-- implementchat_with_tools(), tool definition conversion, tool result handlingKey Implementation Details
Tool Definition Conversion (Zeph -> Gemini)
Zeph
ToolDefinitionmaps to GeminifunctionDeclarations:string->STRING,object->OBJECT, etc.$ref/$defsreferences must be inlined (Gemini does not support JSON Schema references)tools[0].functionDeclarations[](not flat like OpenAI)Tool Call Parsing (Gemini -> Zeph)
Gemini returns
functionCallas a part incandidates[0].content.parts[]:{ "functionCall": { "name": "tool_name", "args": {...} } }Map to
ToolUseRequest { id: generated_uuid, name, input: args }.Note: Gemini does not return a tool call ID -- generate a UUID locally.
Tool Result Format (Zeph -> Gemini)
Tool results are sent as
functionResponseparts in a user message:{ "role": "user", "parts": [{ "functionResponse": { "name": "...", "response": {...} } }] }Tool Config
Send
toolConfig.functionCallingConfig.modeas"AUTO"(default).Acceptance Criteria
supports_tool_use()returnstruechat_with_tools()sends correctly formatted function declarationsChatResponse::ToolUsefunctionResponseparts$ref/$defsinlined in schema conversion