Commit Graph
30 Commits
Author SHA1 Message Date
whit3rabbitandClaude Opus 4.8 7fc44582c6 fix: enforce model allowlist on Bedrock native routes; fix model discovery
Bedrock native routes (converse/converse-stream/invoke/invoke-with-response-
stream) now enforce the virtual key's model allowlist, closing a model-scope
bypass where a model-scoped key could invoke any Bedrock modelId.

Admin UI "Query models" discovery: stop doubling /v1 into /v1/v1/models for
local providers whose catalog base URL already ends in /v1, trim trailing
slashes off api_base, support Anthropic-native providers (x-api-key +
anthropic-version auth, display_name model field), and show/warn about the
discovery target URL in the Add-Backend form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 09:14:20 -05:00
whit3rabbitandClaude Opus 4.8 a108c35ff1 feat(admin-ui): default-open provider options, route curl snippet, live proxy status
Admin UI UX fixes plus the route-dispatch feature set:

- Providers: selecting a provider shows the full key/options form immediately
  instead of hiding it behind a "+ Add key" button; "Cancel" becomes "Reset".
- Routes: enabled routes show a ready-to-run curl snippet (endpoint URL from the
  new proxy_port on /admin/api/status, route name as the model) with a copy button.
- Settings: live proxy status badge (running/unreachable) backed by a proxy_running
  TCP liveness check on /admin/api/status, plus a per-save "applied live" toast.
- Backend: plumb proxy listen_port into SharedState; expose proxy_port + proxy_running.
- Also includes the RouteRouter dispatch layer, per-route option overrides, local-LLM
  backend support, favorites, and model discovery (see CHANGELOG [Unreleased]).

Ignore .gate/ security-scanner scratch artifacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 07:48:13 -05:00
whit3rabbit 8d523abd63 feat: pxpipe context compression + forge guardrails + LiteLLM catalog refresh + otel security bump 2026-07-05 16:22:51 -05:00
whit3rabbitandClaude Sonnet 5 a87cae6ca4 feat: ANTHROPIC_FORWARD_CLIENT_AUTH with live admin-UI toggle
Adds opt-in client-credential forwarding for Anthropic passthrough
(single-key/BYOK deployments), plus fixes found in review:

- Startup safeguard now shares one check (server/middleware/auth.rs)
  with the live admin PUT /admin/api/config path, closing a bypass
  where PROXY_OPEN_RELAY=true alongside 2+ PROXY_API_KEYS entries
  slipped past the old startup-only check.
- x-goog-api-key is now recognized as a forwardable credential
  (renamed to x-api-key upstream, since Anthropic doesn't understand
  that header name), matching validate_auth's precedence.
- Managed (admin-API) backends no longer carry a dead
  forward_client_auth field that could never take effect.
- ClientAuthPath forwarding decisions are now double-checked against
  live VirtualKeyContext/JwtClaims presence, not just the enum, to
  fail closed if the two ever desync.
- Moved from a per-backend BackendConfig field to a global
  RuntimeConfig field (like anthropic_thinking_repair), making it
  live-toggleable from the admin UI with no restart, and uniform
  across every Anthropic-kind backend in a multi-backend deployment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 15:40:53 -05:00
whit3rabbitandClaude Sonnet 5 9456d1ad1b feat: opt-in forge-guardrails tool-call policy + Anthropic thinking-block repair
- Tool-call guardrails (lsp_first/quiet_command/write_payload_cap nudges,
  fingerprint dedup) for local-LLM tool loops. Configurable via YAML
  tool_execution.guardrails, FORGE_TOOL_CALL_POLICY env fallback, or the
  admin UI (live, no restart).
- Anthropic thinking-block record/repair (ANTHROPIC_THINKING_REPAIR):
  records ground truth off the real API and repairs client-corrupted
  thinking/redacted_thinking blocks in replayed conversations.
- Bidirectional thinking_blocks (signature/redacted state) round-trip
  through the OpenAI-compat wire format for LiteLLM-style clients.
- Review fixes: guardrail-mode divergence between streaming/non-streaming
  paths, cross-backend/tenant cache-namespace collision, client-controlled
  integer overflow in thinking budget_tokens, dropped reasoning_content and
  citations on repair/translation paths, a fail-closed race under cache
  eviction, plus dedup/simplification cleanup and doc corrections.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 13:03:02 -05:00
whit3rabbit ce89a2d19c Release 0.10.1 2026-06-20 15:24:43 -05:00
whit3rabbit af7fe570c7 fix: complete admin UI and backend wiring 2026-06-20 11:01:29 -05:00
whit3rabbitandClaude Opus 4.8 65cf673b97 feat: performative admin UI redesign + admin API contract fixes
Large admin-ui refactor (Performative component system, sidebar nav,
provider/route tabs) plus backend module restructuring.

Admin UI contract fixes (this session):
- Fix Models page crash: useBackends unwraps {backends:[...]}; align
  ModelEntry to {model_name, deployments} and ModelsResponse.strategy;
  fix add-model body to {model_name, actual_model, backend_name}.
- Fix Backends/Providers health rendering: source per-backend status and
  latency from the uptime endpoint (health_checks); narrow Backend type to
  the real get_backends shape.
- Route + sidebar-link the previously-unrouted Backends tab.

Verified: cargo test (exit 0), clippy -D warnings (exit 0), fmt --check,
admin-ui tsc + vite build all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:13:59 -05:00
whit3rabbit 85477cee8b fix: enforce virtual-key model allowlist on model-selecting passthrough routes (#15)
* fix(proxy): enforce virtual key model allowlist on passthrough endpoints

* fix: enforce virtual key policy on model passthroughs
2026-05-23 15:20:58 -05:00
whit3rabbit 1f300d8566 Fix virtual-key accounting across generation routes 2026-05-23 12:22:39 -05:00
whit3rabbit 158815acbd Block virtual-key passthrough bypass 2026-05-23 12:22:39 -05:00
whit3rabbitandClaude Sonnet 4.6 816b64ae6a feat: add 16 new provider stubs and providers catalog UI tab
New providers: assemblyai, baidu, blackboxai, brave, cartesia, deepgram,
elevenlabs, exa, iflytek, lmsys, playht, pollinations, serper, siliconflow,
stability, tavily. Registered in mod.rs and registry.rs.

Adds a Providers tab to the admin UI with a ProviderIcon component and
catalog route. Updates backend, streaming, config, and test infrastructure
to align with the expanded provider set. Bumps all crate versions to 0.9.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:42:46 -05:00
whit3rabbit b6158cf3fe feat: refactor admin routes into modular sub-modules and implement model management API endpoints 2026-04-04 20:30:13 -05:00
whit3rabbitandClaude Sonnet 4.6 0593d1ae1b feat: add has_more to pagination responses, disable Next when no more results
Fetch limit+1 rows in get_requests and get_audit_log; if the extra row
exists set has_more=true and truncate back to limit. Admin UI disables
the Next button when has_more is false. Two new integration tests verify
the field is present and false on an empty DB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 20:30:13 -05:00
whit3rabbitandClaude Sonnet 4.6 28580ff311 fix: validate backend_name exists before adding model deployment
Rejects POST /admin/api/models with 400 if the backend_name is not in
backend_metrics, preventing silent routing failures at dispatch time.
Includes a regression test that confirms the guard fires correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 20:30:13 -05:00
whit3rabbitandClaude Sonnet 4.6 84315840f8 fix: harden security, fix expires_at TTL, improve translation accuracy
- Wrap admin token in Zeroizing<String> so memory is wiped on drop
- Use SSRF-safe HTTP client for Langfuse and webhook dispatcher
- Wire up webhook dispatcher at startup (was previously un-started)
- Fix batch expires_at: was using now instead of now+24h
- Extract epoch_secs() helper; replace 4 inline SystemTime::now() blocks
- Gemini tool_choice {type:tool}: use ANY+allowedFunctionNames instead of AUTO
- Map Anthropic thinking budget_tokens to OpenAI reasoning_effort
- Preserve temperature/top_p for GA o-series models (o1/o3/o3-mini/o4-mini);
  only strip for o1-preview and o1-mini which reject those params
- Azure simple config: always route through default_base_url; guard against
  double-appending deployment path when user provides a full URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 13:33:23 -05:00
whit3rabbitandClaude Sonnet 4.6 8ac9ef2677 Merge feat/batch-engine-phase1 into main
Resolves conflicts: take HEAD (security audit) for mcp.rs imports,
register_server_blocking error handling, and maybe_execute_tools loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 16:00:37 -05:00
whit3rabbitandClaude Sonnet 4.6 bdf73c9057 test(admin): update virtual_keys tests for one-time CSRF tokens
CSRF tokens are now one-time use. Tests updated to:
- Pre-insert TEST_CSRF_TOKEN in test_admin_router() for unit tests
- Call reinsert_csrf() before each additional mutation in multi-step tests
- Add fetch_csrf() helper for real-server tests
- update create_key_via_admin() to fetch a fresh token per call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 06:48:44 -05:00
whit3rabbit 9803668b7d feat(proxy): wire batch_engine into proxy crate
- Replace batch/mod.rs types with re-exports from anyllm_batch_engine
- Strip batch/db.rs to Anthropic->OpenAI ID mapping only (batch_file/batch_job owned by engine)
- Rewrite batch/routes.rs to use BatchEngine for upload, create, get, list, cancel
- Remove batch_file/batch_job table creation from admin/db.rs init_db
- Add batch_engine parameter to app_multi_with_shared (5th arg, Option<Arc<BatchEngine>>)
- Initialize BatchEngine in main.rs with its own SQLite connection (admin-enabled path)
- Update batch_api.rs tests to use make_test_batch_engine() helper
- Fix anthropic_batch.rs to call init_anthropic_batch_map_table instead of removed init_batch_tables
- Add cancel_queued_batch integration test
2026-03-31 06:48:16 -05:00
whit3rabbitandClaude Sonnet 4.6 3a62796a75 feat(tools): wire ToolEngineState into AppState with config-driven setup
Add ToolEngineState struct (registry, policy, loop_config, mcp_manager)
and tool_engine field to AppState. Update app_multi_with_shared signature
to accept the new parameter; all callers pass None until config-driven
wiring is implemented in a future task.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:07:23 -05:00
whit3rabbitandClaude Opus 4.6 b6277a8b86 feat: operator observability dashboard with error classification
- Admin UI: operator view with request volume, token usage, latency,
  cost charts, failure table, and request timeline
- Backend: add error_kind() method and infer_error_kind() for stable
  error classification (rate_limit, timeout, backend_error, client_error)
- Admin DB: error_kind column in request_log, observability aggregate
  queries (bucketed timeseries, failure breakdown, timeline)
- Gemini: improved streaming translation, thinking block support,
  grounding metadata passthrough
- Request timeout: configurable REQUEST_TIMEOUT_SECS with streaming
  watchdog
- Model pricing: MODEL_PRICING_FILE for external pricing overrides
- Degradation header: ANYLLM_DEGRADATION_WARNINGS env var control

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:12:03 -05:00
whit3rabbitandClaude Sonnet 4.6 f15af5969b fix(config): add expose_degradation_warnings to all Config struct literals in tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:06:35 -05:00
whit3rabbitandClaude Sonnet 4.6 4fbaf43011 fix(security): populate source_ip in all admin audit log entries
Add ConnectInfo<SocketAddr> extractor to all seven admin mutation
handlers (put_config, delete_config_override, create_key, update_key,
revoke_key, add_model, remove_model). Pass addr.ip().to_string() as
source_ip in each emit_audit call.

Update integration tests to use into_make_service_with_connect_info
and MockConnectInfo so the ConnectInfo extractor is satisfied in test
servers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 06:38:05 -05:00
whit3rabbitandClaude Opus 4.6 5c73adfaea feat(admin): team-focused UI overhaul with key editing and audit log
Backend:
- PUT /admin/api/keys/{id}: update virtual key fields (role immutable),
  refreshes DashMap, emits key_updated audit entry
- update_virtual_key(): resets spend period when budget_duration changes
- query_audit_log(): action, target_type, since, until filter params
- query_request_log(): add until filter param; wire through RequestsQuery
- GET /admin/api/metrics: include streaming counters (started/completed/failed/disconnected)
- GET /admin/api/env: include RATE_LIMIT_FAIL_POLICY

UI:
- Dashboard: streaming metrics stat row
- Request Log: key filter dropdown, since/until date pickers, Key column
- Access Control tab: allowed_models tag input, edit modal, budget progress
  bars, key prefix link navigates to filtered request log
- Settings: override badges from overridden_keys, Security section
  (IP allowlist, rate limit fail policy)
- Audit tab: action/target/date filters, paginated table

Tests:
- 7 unit tests for update_virtual_key and query_audit_log filters
- 4 integration tests for PUT /admin/api/keys/{id} lifecycle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 18:08:34 -05:00
whit3rabbit 6cd37068e3 feat(admin): add CSRF token middleware and /admin/csrf-token endpoint
- validate_csrf middleware: rejects POST/PUT/DELETE without matching X-CSRF-Token header + csrf_token cookie
- GET /admin/csrf-token: public endpoint returning JSON + Set-Cookie (not httpOnly, SameSite=Strict)
- CSRF middleware layered inside validate_admin_token (auth checked first)
- 7 new unit tests in routes.rs for CSRF behavior
- Updated virtual_keys.rs integration tests to include CSRF headers on all POST/DELETE admin calls
2026-03-27 23:45:03 -05:00
whit3rabbitandClaude Sonnet 4.6 f3f5179a64 security: add rate limiting to admin API endpoints (10 RPM per IP)
Defense-in-depth against token brute-force on the admin API. Uses a
DashMap-based sliding window (60s) per client IP, applied as the
outermost middleware layer on protected admin routes. Admin server now
uses into_make_service_with_connect_info to expose client IP. Limit
is configurable at runtime via set_admin_rpm for test flexibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:45:37 -05:00
whit3rabbitandClaude Sonnet 4.6 915a703a5a security: HMAC-SHA256 keyed hashing for virtual keys with dual-mode migration
New virtual keys are hashed with HMAC-SHA256 using a per-installation
secret (auto-generated and stored in SQLite settings table). Auth
middleware tries HMAC hash first, falls back to legacy SHA-256 for
pre-existing keys. This binds key hashes to the installation, so a
stolen database cannot be used to brute-force keys elsewhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:14:34 -05:00
whit3rabbitandClaude Sonnet 4.6 25279835a7 feat: add LiteLLM config.yaml compatibility and model-level routing
Accept LiteLLM config.yaml directly via PROXY_CONFIG=config.yaml. Parses
model_list with provider/model format, supports multiple deployments per
model name with round-robin + RPM-aware load balancing, cross-backend
dispatch, and os.environ/VAR env var syntax. Adds env var aliases for
LITELLM_MASTER_KEY, AZURE_API_KEY, AZURE_API_BASE, LITELLM_CONFIG.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 05:39:51 -05:00
whit3rabbitandClaude Opus 4.6 d6b9d61071 feat: add caching, batch API, cost tracking, budget/RBAC, audio/image passthrough
LiteLLM parity features:
- Response caching (in-memory moka, optional Redis tier) with per-request TTL
- Batch API (file upload, job creation/listing via OpenAI delegation)
- Per-key budget enforcement (daily/monthly/lifetime) with lazy period reset
- RBAC (admin/developer key roles, developer keys blocked from /admin/)
- Audio transcription/speech and image generation passthrough
- Fallback chain config (YAML-based, 5xx/429 failover)
- Cost tracking foundation (model pricing DB, per-key spend queries)

Code quality cleanup (simplify pass):
- Extract try_cache_response helper (was copy-pasted 4x)
- Extract common_routes for batch/models (was duplicated across 3 HandlerMode arms)
- Deduplicate embeddings_passthrough to delegate to raw_passthrough
- Remove dead code: inject_cost_header, BudgetDuration::from_str_lossy, duplicate CacheConfig
- Collapse epoch_to_ymd wrapper into pub(crate) days_to_ymd

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:23:38 -05:00
whit3rabbitandClaude Sonnet 4.6 0942072b29 chore: docs, CI, and polish for litellm gap fill
Update CLAUDE.md and README.md to document new backends (Azure, Bedrock),
virtual key management, rate limiting, OTEL, and client v0.2.0. Add CI
workflow for the new integration test suite. Final task-list completions
and virtual key integration tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 06:36:09 -05:00