Commit Graph

32 Commits

Author SHA1 Message Date
811885274b fix(gemini): handle 'Stream ended' gracefully and improve debug logging
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 17:34:40 +00:00
e307ecf11d fix(gemini): resolve 400 errors and unstable tool IDs in Gemini 3 models
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Ensure  is preserved in conversation history for Gemini 3 models.
- Support multiple  naming conventions (snake_case and camelCase).
- Implement stable tool call ID tracking during streaming using a stateful map.
- Improve  extraction from both Gemini parts and function calls.
- Fix incorrect tool call indices during streaming.
2026-03-05 17:29:25 +00:00
eac3781079 fix(gemini): force snake_case naming for thought_signature
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Despite struct-wide camelCase policy, Gemini 3 reasoning models strictly require 'thought_signature' in snake_case.
- Explicitly rename the field to resolve the 'missing thought_signature' 400 error.
2026-03-05 17:15:16 +00:00
76bf5b81d4 fix(gemini): rename field to thoughtSignature for native REST API compliance
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- The native Gemini REST API requires camelCase 'thoughtSignature' as a sibling to functionCall.
- Explicitly rename the field to match this requirement, resolving the 'missing thought_signature' 400 error.
2026-03-05 17:10:54 +00:00
90a3f5d7f8 fix(gemini): correct sibling positioning and snake_case naming of thought_signature
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 17:04:36 +00:00
f7f6768333 fix(gemini): final alignment of thought_signature nesting and naming
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 16:56:15 +00:00
5bbd5f77b9 fix(gemini): prevent 400 by filtering proxy-generated IDs from thought_signature
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Only restore thought_signature if the tool call ID doesn't start with 'call_'.
- This ensures proxy-generated UUIDs are never sent back to Gemini as signatures, which was causing base64 decoding failures.
2026-03-05 16:49:56 +00:00
8a33b147f1 fix(gemini): align thought_signature logic with Gemini API requirements
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Extract thought_signature from the Part level during response parsing.
- Provide thought_signature as a sibling to functionCall during request assembly.
- This fully resolves the 'Unknown name thoughtSignature at function_call' error.
2026-03-05 16:45:18 +00:00
154b7b3b77 fix(gemini): resolve 404 by fixing double-beta in API URL
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Update get_base_url to only perform replacement if the base_url specifically ends with /v1.
- This prevents malformed URLs like /v1betabeta when the base_url was already configured as v1beta.
2026-03-05 16:33:10 +00:00
3d43948dbe fix(gemini): improve Gemini 3 stability and diagnostics
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Switch Gemini 3 models to v1beta for both streaming and non-streaming (better reasoning support).
- Increase max_output_tokens cap to 65536 for reasoning-heavy models.
- Elevate API URL and chunk tracing to INFO level for easier production debugging.
2026-03-05 16:27:22 +00:00
a75c10bcd8 fix(gemini): resolve compilation errors and enable Gemini 3 reasoning
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 16:17:48 +00:00
0dd6212f0a fix(gemini): resolve 400 errors by refining safety settings and sanitizing stop sequences
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Exclude 'HARM_CATEGORY_CIVIC_INTEGRITY' when using v1 endpoint (v1beta only).
- Filter out empty strings from 'stop_sequences' which are rejected by Gemini.
- Update error probe to use non-streaming endpoint for better JSON error diagnostics.
2026-03-05 16:03:07 +00:00
f8598060f9 fix(gemini): resolve compilation errors and final parameter alignment
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 15:57:33 +00:00
3086a3b6d9 fix(gemini): sanitize tool parameters to remove unsupported JSON Schema fields
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Recursively remove '$schema', 'additionalProperties', 'exclusiveMaximum', and 'exclusiveMinimum' from tool definitions.
- These fields are frequently included by clients like opencode but are rejected by the Gemini API with 400 errors.
2026-03-05 15:48:29 +00:00
fb98f0ebb8 fix(gemini): strictly enforce alternating roles and improve message merging
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Merge all consecutive messages with the same role into a single GeminiContent object.
- Ensure the first message is always 'user' by prepending a placeholder if necessary.
- Add final check for empty contents to prevent sending malformed requests.
- This addresses strict role-sequence requirements in Gemini 2.0/3.0 models.
2026-03-05 15:41:36 +00:00
6b7e245827 feat(gemini): implement stream error probing for better diagnostics 2026-03-05 15:40:32 +00:00
6010ec97a8 fix(gemini): resolve 404 by defaulting Gemini 3+ to v1 endpoint
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Update get_base_url to prefer v1 for Gemini 3.0+ models even if they contain 'preview'.
- Add tracing::debug logs for the final API URLs used in both streaming and non-streaming requests.
2026-03-05 15:32:53 +00:00
bdf7b63238 fix(gemini): resolve compilation error by moving get_base_url into impl block
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-05 15:26:19 +00:00
be9fdd9a52 fix(gemini): implement dynamic API versioning and support Gemini 3
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Switch to v1beta endpoint for 'preview' and 'thinking' models.
- Update model version checks to include gemini-3 as a known version.
- Use get_base_url helper to construct dynamic URLs for both streaming and non-streaming requests.
2026-03-05 15:24:47 +00:00
e89658fd87 fix(gemini): add model mapping fallback and token clamping
- Map unknown Gemini model names to the configured default model to prevent 400 errors.
- Clamp max_tokens to a safe limit of 8192 for Gemini models.
- Clean up message filtering and role injection for better client compatibility.
2026-03-05 15:23:26 +00:00
a022bd1272 fix(gemini): resolve 400 stream errors and improve client compatibility
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Filter out empty text parts in Gemini requests to avoid 400 errors.
- Inject 'assistant' role into the first streaming chunk for better compatibility with clients like opencode.
- Fallback to tool_call_id for Gemini function responses when name is missing.
2026-03-05 15:16:19 +00:00
b0bd1fd143 fix(gemini): ensure conversation starts with user role and add empty message check
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
Gemini API requires the first message to be from the 'user' role.
This commit ensures that:
- If a conversation starts with a 'model' (assistant) role, a placeholder 'user' message is prepended.
- 'tool' results are correctly mapped to 'user' role parts.
- Sequential messages with the same role are merged.
- Empty content requests are prevented in both sync and stream paths.

This fixes 400 Bad Request errors when clients (like opencode) send
message histories that don't match Gemini's strict role requirements.
2026-03-05 08:48:25 -05:00
5b6583301d fix(providers): add registry routing, OpenAI Responses support and Gemini streaming fallbacks; compile fixes
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-04 14:17:30 -05:00
5a8510bf1e feat(providers): model-registry routing + Responses API support and streaming fallbacks for OpenAI/Gemini
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-04 13:36:03 -05:00
c3dda74113 style: fix cargo warnings (unused imports, dead_code)
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-03 15:21:07 -05:00
9b1e0ff669 fix(gemini): tolerate non-candidate SSE chunks
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
2026-03-03 11:06:58 -05:00
db5824f0fb feat: add cache token tracking and cache-aware cost calculation
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
Track cache_read_tokens and cache_write_tokens end-to-end: parse from
provider responses (OpenAI, DeepSeek, Grok, Gemini), persist to SQLite,
apply cache-aware pricing from the model registry, and surface in API
responses and the dashboard.

- Add cache fields to ProviderResponse, StreamUsage, RequestLog structs
- Parse cached_tokens (OpenAI/Grok), prompt_cache_hit/miss (DeepSeek),
  cachedContentTokenCount (Gemini) from provider responses
- Send stream_options.include_usage for streaming; capture real usage
  from final SSE chunk in AggregatingStream
- ALTER TABLE migration for cache_read_tokens/cache_write_tokens columns
- Cache-aware cost formula using registry cache_read/cache_write rates
- Update Provider trait calculate_cost signature across all providers
- Add cache_read_tokens/cache_write_tokens to Usage API response
- Dashboard: cache hit rate card, cache columns in pricing and usage
  tables, cache token aggregation in SQL queries
- Remove API debug panel and verbose console logging from api.js
- Bump static asset cache-bust to v5
2026-03-02 14:45:21 -05:00
8d50ce7c22 perf: eliminate per-request SQLite queries and optimize proxy latency
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
- Add in-memory ModelConfigCache (30s refresh, explicit invalidation)
  replacing 2 SQLite queries per request (model lookup + cost override)
- Configure all 5 provider HTTP clients with proper timeouts (300s),
  connection pooling (4 idle/host, 90s idle timeout), and TCP keepalive
- Move client_usage update to tokio::spawn in non-streaming path
- Use fast chars/4 heuristic for token estimation on large inputs (>1KB)
- Generate single UUID/timestamp per SSE stream instead of per chunk
- Add shared LazyLock<Client> for image fetching in multimodal module
- Add proxy overhead timing instrumentation for both request paths
- Fix test helper to include new model_config_cache field
2026-03-02 12:53:22 -05:00
9318336f62 feat: add tool-calling passthrough for all providers
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
Implement full OpenAI-compatible tool-calling support across the proxy,
enabling OpenCode to use llm-proxy as its sole LLM backend.

- Add 9 tool-calling types (Tool, FunctionDef, ToolChoice, ToolCall, etc.)
- Update ChatCompletionRequest/ChatMessage/ChatStreamDelta with tool fields
- Update UnifiedRequest/UnifiedMessage to carry tool data through the pipeline
- Shared helpers: messages_to_openai_json handles tool messages, build_openai_body
  includes tools/tool_choice, parse/stream extract tool_calls from responses
- Gemini: full OpenAI<->Gemini format translation (functionDeclarations,
  functionCall/functionResponse, synthetic call IDs, tool_config mapping)
- Gemini: extract duplicated message-conversion into shared convert_messages()
- Server: SSE streams include tool_calls deltas, finish_reason='tool_calls'
- AggregatingStream: accumulate tool call deltas across stream chunks
- OpenAI provider: add o4- prefix to supports_model()
2026-03-02 09:40:57 -05:00
2cdc49d7f2 refactor: comprehensive audit — fix bugs, harden security, deduplicate providers, add CI/Docker
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
Phase 1: Fix compilation (config_path Option<PathBuf>, streaming test, stale test cleanup)
Phase 2: Fix critical bugs (remove block_on deadlocks in 4 providers, fix broken SQL query builder)
Phase 3: Security hardening (session manager, real auth, token masking, Gemini key to header, password policy)
Phase 4: Implement stubs (real provider test, /proc health metrics, client/provider/backup endpoints, has_images)
Phase 5: Code quality (shared provider helpers, explicit re-exports, all Clippy warnings fixed, unwrap removal, 6 unused deps removed, dashboard split into 7 sub-modules)
Phase 6: Infrastructure (GitHub Actions CI, multi-stage Dockerfile, rustfmt.toml, clippy.toml, script fixes)
2026-03-02 00:35:45 -05:00
3165aa1859 feat: implement web UI for provider and model configuration
- Added 'provider_configs' and 'model_configs' tables to database.
- Refactored ProviderManager to support thread-safe dynamic updates and database overrides.
- Implemented 'Models' tab in dashboard to manage model visibility, mapping, and pricing.
- Added provider configuration modal to 'Providers' tab.
- Integrated database overrides into chat completion logic (enabled state, mapping, and cost).
2026-02-26 18:13:04 -05:00
1755075657 chore: initial clean commit 2026-02-26 13:56:21 -05:00