feat(clients): add native Gemini API client#13
Conversation
- Avoid cloning MessageContent on each stream chunk (create fresh per yield) - Replace .unwrap() with .expect() on RwLock operations - Add TODO for Gemini function calling / tools support - Mark parse_models_response as #[cfg(test)] (only used in tests now)
|
This incremental update includes 3 main changes:
Validated: the example reliably triggers |
|
This incremental update includes 3 main changes:
Validated: the example reliably triggers |
…wn tool results - Promote fallback ids to protocol ids when they arrive later in the stream, preferring same-index matches to avoid misassignment when chunk indices shift between SSE events. - Return an error instead of silently degrading when a tool result references an unknown tool_call_id. - Fix ensure_ordered_id to check the order list instead of calls_by_id. - Collapse nested if-let per clippy, tighten comments, shorten test names.
Changes since last reviewCore: stream tool-call id collision fixThe previous implementation used Promotion policy (3-tier):
The key design choice is tier 3: when multiple fallback calls share the same signature (same function name + args) and none has a protocol id yet, the protocol layer cannot tell them apart. Rather than guessing and potentially renaming the wrong call (state corruption), we conservatively skip the promotion. This may produce a duplicate call, but a duplicate is always safer than a wrong-assignment — downstream tool execution can handle an extra call, but cannot recover from a call whose id was silently swapped. This limitation is inherent to the Gemini streaming protocol when Other changes
|
445d950 to
097443d
Compare
097443d to
3e0378b
Compare

Summary
Adds a native Gemini API client (
GeminiClient) that talks directly to Google's Generative Language API, without going through an OpenAI-compatible shim.Changes
src/clients/gemini.rs(new) — FullBotClientimplementation for Gemini:GET /modelswithgenerateContentcapability filtering:streamGenerateContentwith SSEUser/Tool→user,Bot→model,System→system_instructionx-goog-api-keyheader +keyquery paramsrc/clients.rs— Registers thegeminimodule under theapi-clientsfeature gatesrc/prelude.rs— Re-exportsGeminiClientfor ergonomic usageDesign Notes
Arc<RwLock<Inner>>pattern used byOpenAiClientfor thread-safe cloningasync_stream+parse_sse(existing crate utility) for streamingtokio-specific APIs in the client itself)