mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-14 13:19:01 +03:00
OpenRouter, the generic Custom adapter and (in track B) CustoAI all speak the same Chat Completions shape: POST /chat/completions, POST /embeddings, Authorization: Bearer <key>, response with choices[0].message.content and usage. The transport and response parsing were duplicated in OpenRouterProvider and would be duplicated again by CustoAI. Move post_json / get_json / chat_completions / embeddings into a new ai/provider/openai_http.py module that owns the HTTP transport and OpenAI-shape parsing. Adapters keep their product semantics only: - OpenRouterProvider delegates chat (with usage.include=true to read usage.cost) and embed to openai_http; it is now a thin adapter, not a transport owner. - CustomProvider inherits the delegation unchanged. Update OpenRouterProviderProxyTests to mock openai_http.build_opener (the new transport location) and add the model field to the fake response so the parsed ChatResult matches. Verified: 13/13 integrations tests, 47/47 ai tests.