zz_

1f7e9127 ยท zzmq.dev@gmail.com/zz

Commit

1f7e9127fc9d757f5a699649841fc288186aa34e

Pluggable ChatBackend: Ollama (local) or Gemini (remote) for zz work Extracted a ChatBackend interface (agent/chatBackend.ts) that agent/ loop.ts talks to generically -- it no longer knows anything about Ollama's wire format directly. createOllamaBackend carries the existing streaming logic unchanged; createGeminiBackend is new, targeting Google AI Studio's free tier. Built against Google's own verified API reference, not assumption: a first fetch of Gemini docs returned a shape resembling OpenAI's Responses API (an "interactions" endpoint, "steps", function_call/ function_result) that didn't match anything I recognized as Gemini's real API -- cross-checked against the actual generateContent reference page, which confirmed the real shape (contents[]/parts[], functionCall/ functionResponse, systemInstruction) and contradicted the first result. Treated the first fetch as unverified and built against the confirmed one instead. zz work --provider gemini (default: ollama) selects the backend; --model picks the model for whichever provider. The API key comes from GEMINI_API_KEY or GOOGLE_AI_API_KEY, loaded from app/.env if present (process.loadEnvFile(), Node's built-in -- no new dependency); never exported into this conversation or printed anywhere. Verified the request/response conversion logic with a mocked fetch: system message -> systemInstruction (not in contents[]), assistant -> role "model", tool_calls -> functionCall parts, tool results -> functionResponse parts matched by name, and the response's text/ functionCall parts correctly reassembled into a ChatMessage. Not yet verified against the real API -- needs a real GEMINI_API_KEY to test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Troy Howard <thoward37@gmail.com> -- 2026-10-10T21:02:33.000Z

Tree at this commit