Commit Graph

184 Commits

Author SHA1 Message Date
bd5ca2dd98 fix(dashboard): allow unsafe-inline scripts in CSP
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
This commit adds 'unsafe-inline' to the script-src CSP directive. The frontend dashboard heavily relies on inline event handlers (e.g., onclick=...) dynamically generated via template literals in its vanilla JavaScript architecture. Without this directive, modern browsers block these handlers, rendering interactive elements like the Config button completely inert.
2026-03-07 00:45:30 +00:00
6a0aca1a6c fix(dashboard): relax CSP to allow external CDNs for UI libraries
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
This commit updates the Content Security Policy to allow scripts, styles, and fonts from cdn.jsdelivr.net, cdnjs.cloudflare.com, fonts.googleapis.com, and fonts.gstatic.com. This resolves the 'luxon is not defined' error and fixes the broken charts by allowing Chart.js, Luxon, FontAwesome, and Google Fonts to load properly in the dashboard.
2026-03-07 00:28:49 +00:00
4c629e17cb fix(dashboard): bypass global rate limiting for internal UI endpoints
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
This commit resolves the 'Failed to load statistics' issue where dashboard panels appeared empty. The dashboard makes 10+ concurrent API requests on load, which was instantly triggering the global rate limit's burst threshold (default 10). Internal dashboard endpoints are now exempt from this strict LLM-traffic rate limiting since they are already secured by admin authentication.
2026-03-07 00:22:27 +00:00
fc3bc6968d fixed ui
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-07 00:17:44 +00:00
d6280abad9 fix(dashboard): handle stale sessions and prevent form GET submission
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
This commit updates the frontend API client to intercept authentication errors (like a stale session after a server restart) and immediately clear the local storage and show the login screen. It also adds an onsubmit handler to the login form in index.html to prevent the browser from defaulting to a GET request that puts credentials in the URL if JavaScript fails to initialize or encounters an error.
2026-03-07 00:15:20 +00:00
96486b6318 security(dashboard): enforce admin authentication on all sensitive endpoints
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
This commit adds the missing auth::require_admin check to all analytics, system info, and configuration list endpoints. It also improves error logging in the usage summary handler to aid in troubleshooting 'Failed to load statistics' errors.
2026-03-07 00:07:14 +00:00
e8955fd36c merge
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-06 15:35:30 -05:00
a243a3987d fix(openai): use structured input and add probe for Responses API
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
Updated OpenAI Responses API to use a structured input format (array of objects) for better compatibility. Added a proactive error probe to chat_responses_stream to capture and log API error bodies on failure.
2026-03-06 20:26:14 +00:00
4be23629d8 fix build warnings
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-06 20:17:50 +00:00
dd54c14ff8 feat(openai): implement Responses API streaming and proactive routing
This commit adds support for the OpenAI Responses API in both streaming and non-streaming modes. It also implements proactive routing for gpt-5 and codex models and cleans up unused 'session' variable warnings across the dashboard source files.
2026-03-06 20:16:43 +00:00
633b69a07b docs: sync documentation with current implementation and archive stale plan
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-06 14:28:04 -05:00
975ae124d1 merge 2026-03-06 14:21:58 -05:00
9b8483e797 feat(security): implement AES-256-GCM encryption for API keys and HMAC-signed session tokens
This commit introduces:
- AES-256-GCM encryption for LLM provider API keys in the database.
- HMAC-SHA256 signed session tokens with activity-based refresh logic.
- Standardized frontend XSS protection using a global escapeHtml utility.
- Hardened security headers and request body size limits.
- Improved database integrity with foreign key enforcement and atomic transactions.
- Integration tests for the full encrypted key storage and proxy usage lifecycle.
2026-03-06 14:17:56 -05:00
d32386df3f fix(gemini): resolve 400 Bad Request by sanitizing thought_signature and improving tool name resolution
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
This commit fixes the Gemini API 'Invalid value at thought_signature' error by ensuring synthetic 'call_' IDs are not passed into the TYPE_BYTES field. It also adds a pre-pass to correctly resolve function names from tool call IDs for tool responses.
2026-03-06 14:59:04 +00:00
149a7c3a29 fix(deepseek): even stricter R1 history compliance and error 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
- Ensure ALL assistant messages in history have reasoning_content and string content.
- Use a single space as a professional minimal placeholder for missing reasoning.
- Log full offending request bodies at ERROR level for detailed debugging.
2026-03-05 20:51:43 +00:00
d9cfffea62 fix: comprehensive cross-provider tool calling and history 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
- Fix DeepSeek R1 (reasoner) 400 errors by ensuring assistant messages with
  tool_calls in history always have non-null 'content' and 'reasoning_content'.
- Implement deterministic tool call ID truncation (max 40 chars) for OpenAI
  compatibility (fixes errors when history contains long Gemini signatures).
- Automatic transition from 'max_tokens' to 'max_completion_tokens' for newer
  OpenAI models (o1, o3, gpt-5-nano).
- Added 'reasoning' and 'thought' aliases to reasoning_content for robust
  deserialization from various clients.
2026-03-05 20:41:17 +00:00
90ef026c96 Revert "feat(auth): refactor token resolution into shared TokenResolution and centralize in middleware; simplify AuthenticatedClient to carry resolved DB ID"
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
This reverts commit 5ddf284b8f.
2026-03-05 19:53:50 +00:00
5ddf284b8f feat(auth): refactor token resolution into shared TokenResolution and centralize in middleware; simplify AuthenticatedClient to carry resolved DB ID
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 14:45:17 -05:00
f5677afba0 fix(openai): transition to max_completion_tokens for newer 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
Newer OpenAI models (o1, o3, gpt-5) have deprecated 'max_tokens' in favor of
'max_completion_tokens'. The provider now automatically maps this parameter
to ensure compatibility and avoid 400 errors.
2026-03-05 19:32:56 +00:00
4ffc6452e0 fix: sanitize tool call IDs for OpenAI 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
OpenAI has a strict 40-character limit for tool call IDs. Long IDs (like
Gemini's 56-char thought signatures) are now deterministically truncated
to 40 characters when sending history back to OpenAI-compatible providers.
2026-03-05 19:26:53 +00:00
94162a3dcc fix: revert shared helper changes that broke standard OpenAI 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
- Move DeepSeek R1 reasoning_content and content:"" fixes to DeepSeekProvider only.
- Restore OpenAI-standard null content for tool calls in helpers.rs.
- Fixes 400 Bad Request for gpt-5-nano and other strict OpenAI models.
2026-03-05 19:21:26 +00:00
c26925c253 fix: improve error probing in OpenAI and DeepSeek providers 2026-03-05 19:20:35 +00:00
d0d64e2064 fix(openai): implement error probing and gpt-5-nano support
- Added error probing to capture detailed 400 Bad Request error bodies.
- Explicitly added gpt-5-nano to supports_model.
- Used parse_openai_stream_chunk helper for robust stream parsing.
2026-03-05 19:17:22 +00:00
6a324c08c7 fix(deepseek): more aggressive R1 fix and detailed error 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
- Ensure assistant tool calls always have content: "" instead of null.
- Add debug-level logging of the full request body when DeepSeek returns 400.
- Improved R1 placeholder injection to include content sanitation.
2026-03-05 19:11:46 +00:00
1ddb5277e9 fix(deepseek): ensure reasoning_content placeholder for R1 tool calls
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
- Added aliases 'reasoning' and 'thought' to reasoning_content field for better client compatibility.
- Implemented automatic 'Thinking...' placeholder injection for deepseek-reasoner history messages that contain tool_calls but lack reasoning_content.
- Restored strict parameter sanitation for deepseek-reasoner.
2026-03-05 18:56:16 +00:00
1067ceaecd style: remove unused sqlx import in server/mod.rs
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 18:45:25 +00:00
fc5d3ed636 refactor: unify authentication state and improve middleware efficiency
- Introduce AuthInfo struct for shared auth state.
- Populate AuthInfo in rate_limit_middleware and store in request extensions.
- Update AuthenticatedClient extractor to use pre-resolved AuthInfo.
- Simplify chat_completions by removing redundant DB lookups.
2026-03-05 18:44:41 +00:00
7411d3dbed fix(deepseek): preserve reasoning_content in history for R1
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
DeepSeek R1 (deepseek-reasoner) requires that assistant messages in the history
containing tool_calls must also include their reasoning_content field.
2026-03-05 18:24:06 +00:00
e3c1b9fa20 refactor: extract stream parsing helper and enable deepseek error probing
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 18:16:56 +00:00
c2bad90a8f fix(deepseek): add missing StreamExt import
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 18:08:20 +00:00
c7b67d5840 fix(deepseek): add more exhaustive sanitation for deepseek-reasoner
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
R1 model does not support presence_penalty, frequency_penalty, logit_bias,
logprobs, or top_logprobs. Added these to the list of stripped parameters.
2026-03-05 17:59:49 +00:00
7efb36029c fix(deepseek): sanitize requests for deepseek-reasoner
deepseek-reasoner (R1) does not support tools, temperature, or top_p.
These fields are now stripped to avoid 400 Bad Request errors.
2026-03-05 17:59:31 +00:00
6440e8cc13 fix(gemini): ensure final finish_reason is 'tool_calls' if any tools were seen
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 often sends tool calls in one chunk and then 'STOP' in a final chunk.
If we pass the raw 'stop' at the end, clients stop and ignore the previously
received tool calls. We now track if any tools were seen and override the
final 'stop' to 'tool_calls'.
2026-03-05 17:50:25 +00:00
5c5f836eca fix(gemini): override finish_reason to 'tool_calls' when tools are present
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 often reports 'STOP' even when tool calls are generated. To remain
OpenAI-compatible and ensure clients execute tools and continue, we must
report 'tool_calls' as the finish_reason when tools are present.
2026-03-05 17:45:55 +00:00
febfcafed4 fix(gemini): resolve 400 errors by strictly adhering to JSON schema
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
- Remove  from  as it is rejected by the API inside .
- Ensure  is always a JSON object (google.protobuf.Struct), wrapping non-object tool results in .
- Update extraction logic to only look for  in  sibling fields.
2026-03-05 17:39:50 +00:00
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