feat: full tool call support (OpenAI + Gemini endpoints)

- store.rs: Add tool context storage (active tools, tool config, pending
  tool results, call_id mapping, last function calls for history rewrite)
- types.rs: Add tools/tool_choice fields to ResponsesRequest, add
  build_function_call_output helper for OpenAI function_call output items
- modify.rs: Replace hardcoded get_weather with dynamic ToolContext
  injection. Add openai_tools_to_gemini and openai_tool_choice_to_gemini
  converters. Add conversation history rewriting for tool result turns
  (replaces fake 'Tool call completed' model turn with real functionCall,
  injects functionResponse before last user turn)
- proxy.rs: Build ToolContext from MitmStore before calling modify_request.
  Save last_function_calls for history rewriting on subsequent turns
- responses.rs: Store client tools in MitmStore before LS call. Detect
  function_call_output in input array for tool result submission. Return
  captured functionCalls as OpenAI function_call output items with
  generated call_ids and stringified arguments
- gemini.rs: New Gemini-native endpoint (POST /v1/gemini) with zero
  format translation. Accepts functionDeclarations directly, returns
  functionCall in Gemini format directly
- mod.rs: Wire /v1/gemini route, bump version to 3.3.0
This commit is contained in:
Nikketryhard
2026-02-14 22:56:44 -06:00
parent 8455aa674f
commit 786987116b
8 changed files with 989 additions and 51 deletions

View File

@@ -1,6 +1,7 @@
//! Axum API server — OpenAI-compatible Responses + Chat Completions endpoints.
mod completions;
mod gemini;
mod models;
mod polling;
mod responses;
@@ -41,6 +42,7 @@ pub fn router(state: Arc<AppState>) -> Router {
"/v1/chat/completions",
post(completions::handle_completions),
)
.route("/v1/gemini", post(gemini::handle_gemini))
.route("/v1/models", get(handle_models))
.route("/v1/sessions", get(handle_list_sessions))
.route("/v1/sessions/{id}", delete(handle_delete_session))
@@ -59,11 +61,12 @@ pub fn router(state: Arc<AppState>) -> Router {
async fn handle_root() -> Json<serde_json::Value> {
Json(serde_json::json!({
"service": "antigravity-openai-proxy",
"version": "3.2.0",
"version": "3.3.0",
"runtime": "rust",
"endpoints": [
"/v1/chat/completions",
"/v1/responses",
"/v1/gemini",
"/v1/models",
"/v1/sessions",
"/v1/token",