Commit Graph
290 Commits
Author SHA1 Message Date
whit3rabbitandClaude Sonnet 4.6 d3474792c8 fix: resolve CI YAML parse error and vite 8 peer dep conflict
- Replace heredoc in brew-release job with printf statements to fix YAML
  parse error (heredoc content at col 0 broke YAML literal block scalar)
- Add --legacy-peer-deps to npm ci: @vitejs/plugin-react@4.7.0 peer deps
  only declare vite ^4-7 but is runtime-compatible with vite 8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 13:35:55 -05:00
whit3rabbitandClaude Sonnet 4.6 5d9ce74316 chore: fmt and doc cleanup for v0.9.0
- cargo fmt formatting fixes across admin and config modules
- README: add OpenRouter dedicated provider key example, clarify allowed_models wildcard syntax

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 13:29:29 -05:00
whit3rabbitandClaude Sonnet 4.6 e94b4e2acf feat: add Homebrew tap release job and ignore tool/config dirs
Add brew-release CI job that builds versioned macOS tarballs, uploads
them to the GitHub Release, and updates the homebrew-tap cask formula.
Ignore .mcp.json, .repowise/, and .superpowers/ in .gitignore. Add
Makefile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 03:25:40 -05:00
whit3rabbitandClaude Opus 4.6 af9a87ec6e fix: sanitize API keys and strip /v1 suffix from base URLs
Add sanitize_api_key() to strip curly/smart quotes silently injected by
copy-paste from rich-text sources (Slack, docs). Add strip_v1_suffix()
to prevent doubled /v1/v1 paths when provider URLs already include /v1.
Applied across all config paths (env, simple YAML, LiteLLM YAML, TOML).
Also adds crate structure section to proxy-architecture.md and rebuilds
admin UI dist after vite upgrade.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 20:20:32 -05:00
whit3rabbitandClaude Sonnet 4.6 0dd3ef98f6 fix: upgrade vite to 8.0.7 to address CVE path traversal and arbitrary file read
Fixes Dependabot alerts #2 (high) and #3 (medium): vite arbitrary file read
via dev server WebSocket and path traversal in optimized deps .map handling.
Patched version required >= 6.4.2; upgraded to 8.0.7. Build verified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 16:38:40 -05:00
whit3rabbitandClaude Sonnet 4.6 545bdbbbd3 feat: add bedrock native passthrough, generic passthrough, provider docs, and managed backend fixes
Adds bedrock_native.rs (Converse/InvokeModel with SigV4) and
generic_passthrough.rs catch-all for Translate mode. Adds comprehensive
provider reference docs (docs/providers/, docs/ENDPOINTS.md). Fixes
managed backend admin UI (BackendForm, ManagedBackendsSection) and
admin route/model handler issues. Adds automated model pricing update
workflow (scripts/update_pricing.py, .github/workflows/update-pricing.yml).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 16:36:16 -05:00
whit3rabbitandClaude Sonnet 4.6 be038e4164 feat: add provider catalog, bedrock native passthrough, and generic passthrough
Introduces anyllm_providers crate as metadata-only catalog (ProviderDef,
ModelDef, registry). Wires any provider-id as BACKEND via OpenAIClient.
Adds bedrock_native.rs (Converse/InvokeModel with SigV4) and
generic_passthrough.rs catch-all for Translate mode. Updates config,
backend clients, streaming, token counting, and compatibility tests
to support the expanded provider surface. Updates model pricing and docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 16:33:59 -05:00
whit3rabbitandClaude Sonnet 4.6 c0a49d2eab fix: stale updated_at in PUT response, add rpm/tpm hint, fix type safety and comments
- managed_backends.rs: stamp updated_row.updated_at after SQLite write succeeds,
  before inserting into in-memory map, so the PUT response reflects a post-update
  timestamp rather than the pre-update value
- providerFields.ts: add hint to rpm/tpm FieldDef entries noting they are stored
  for reference and not enforced on managed backends
- queries.ts: type useCatalogProviders queryFn with explicit generic so the
  server-guaranteed shape { providers: CatalogProvider[] } is reflected at compile
  time; removes the ?? r fallback
- state.rs: correct managed_backends field comment from UUID key to name key

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:59:39 -05:00
whit3rabbit 1cebefa3e2 fix: use axum v0.7 path syntax {id} for catalog route 2026-04-08 13:50:55 -05:00
whit3rabbitandClaude Sonnet 4.6 4ed09158f4 fix: use display_name in provider table, fix stale provider state in BackendForm
Fix 1: ManagedBackendsSection.tsx line 24 now uses p.display_name instead of
p.name, matching what the Rust catalog handler serializes.

Fix 2: BackendForm.tsx now uses useEffect to initialize providerId when providers
load, eliminating the split identity between state ('') and compensation logic
('value={providerId || providers[0]?.id ?? ''}'). The effect sets providerId to
the first provider when the list first populates and no initial provider is set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:48:59 -05:00
whit3rabbitandClaude Sonnet 4.6 ca7b27cfc6 fix: add catalog routes, complete CatalogProvider type, group providers by status
- Copy catalog.rs from main; add pub mod catalog + GET routes in admin router
- Add price_per_million_for_model to cost module (missing from this branch)
- Expand CatalogProvider with display_name, status, capabilities, model_count
- BackendForm provider dropdown: use display_name, group by status via optgroup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:45:57 -05:00
whit3rabbitandClaude Sonnet 4.6 7a3587682c feat: add managed backends UI components
Add BackendForm and ManagedBackendsSection for creating/editing managed
backends at runtime. Integrate ManagedBackendsSection as first section in
Settings tab. Extend Models form with optional backend_name datalist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:41:55 -05:00
whit3rabbitandClaude Sonnet 4.6 d8d34538ca fix: add ManagedBackendsResponse type and useCatalogProviders hook
- Add ManagedBackendsResponse interface to types.ts matching the /admin/api/backends/managed endpoint response shape
- Update useManagedBackends return type from inline { backends: ManagedBackend[] } to ManagedBackendsResponse for reusability
- Add useCatalogProviders hook to queries.ts following existing list hook patterns, handles both { providers: [...] } and bare array responses from /admin/api/catalog/providers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:37:14 -05:00
whit3rabbitandClaude Sonnet 4.6 887661f6dc feat: add managed backend types, queries, and provider field schema
- Add CatalogProvider, ManagedBackend, CreateManagedBackendRequest, UpdateManagedBackendRequest to api/types.ts
- Add useManagedBackends, useCreateManagedBackend, useUpdateManagedBackend, useDeleteManagedBackend hooks to api/queries.ts
- Create utils/providerFields.ts with getProviderFields() mapping protocol+auth to FieldDef[]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:32:21 -05:00
whit3rabbitandClaude Sonnet 4.6 0ecd5aeab6 fix: remove updated_at divergence in update handler, add audit detail
Fix 1: Remove manual updated_at assignment from in-memory state in update
handler. The db::update_managed_backend function independently generates a
new timestamp, so we avoid divergence between in-memory and SQLite. Add
comment explaining the pre-update state.

Fix 2: Add audit detail for update handler showing provider_id, matching
pattern used in create handler.

Fix 3: Add comment to ManagedBackendPatch struct documenting that Option<T>
fields offer no way to clear/NULL a field, guiding UI behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:30:26 -05:00
whit3rabbitandClaude Sonnet 4.6 5f834b8f3b feat: add admin CRUD API for managed backends
Implements GET/POST/PUT/DELETE handlers in managed_backends.rs and
registers them in the protected admin router. Credentials are never
returned in responses; api_key_set and aws_creds_set booleans signal
presence instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:26:13 -05:00
whit3rabbitandClaude Sonnet 4.6 af80237cf3 fix: log warning when managed_backends lock is poisoned during routing
When the managed_backends RwLock is poisoned (indicating a panic in a thread
that held the lock), log a warning and skip the managed backend lookup,
falling back to the single backend. This improves observability of lock
poisoning events.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:23:02 -05:00
whit3rabbitandClaude Sonnet 4.6 b125920a26 feat: route requests through managed backends
Extend resolve_model_and_state to fall back to SharedState.managed_backends
when all_backends misses, so SQLite-backed backends added at runtime are
reachable without restart. Extend add_model validation to accept backend
names that exist in managed_backends in addition to the static backend_metrics
map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:20:09 -05:00
whit3rabbitandClaude Sonnet 4.6 eb93ee5921 fix: key managed_backends by name, fix Bedrock/Vertex base_url construction
- HashMap in startup loader now uses row.name as key (routing uses backend_name)
- Bedrock: base_url is the region string, not a URL (matches BedrockClient::new)
- Vertex: construct endpoint URL from project+region when api_base is absent
- Add tests for Bedrock region defaulting and all three Vertex base_url cases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:18:18 -05:00
whit3rabbit 365d463435 test: add missing protocol/auth variant coverage for row_to_backend_config 2026-04-08 13:13:49 -05:00
whit3rabbitandClaude Sonnet 4.6 7c5a568034 feat: add providers crate, row_to_backend_config, managed_backends SharedState field, startup loading
- Copy crates/providers (anyllm_providers) into worktree and add to workspace + proxy deps
- Implement row_to_backend_config() in admin/routes/managed_backends.rs: converts ManagedBackendRow + ProviderDef into BackendConfig by mapping ProviderProtocol to BackendKind and AuthKind to BackendAuth; Custom protocol returns None (unsupported)
- Add managed_backends field to SharedState (Arc<RwLock<HashMap<String, (ManagedBackendRow, BackendClient)>>>)
- Load managed backends from SQLite at startup in async_main: list_managed_backends -> get_provider -> row_to_backend_config -> BackendClient::from_backend_config
- Fix cost/mod.rs test SharedState initializer to include new field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:11:27 -05:00
whit3rabbitandClaude Sonnet 4.6 0a79183a9b refactor: move ManagedBackendRow/Patch to db.rs, fix inverted dependency
Routes should import from db.rs, not the reverse. Moving the pure data
structs into db.rs keeps HTTP infrastructure out of the database layer.
managed_backends.rs re-exports them via pub use for backward compat.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:06:48 -05:00
whit3rabbitandClaude Sonnet 4.6 e92977c1dd feat: add managed_backends SQLite table and CRUD functions
Adds the managed_backends table to init_db(), four CRUD functions
(insert/list/update/delete), ManagedBackendRow/ManagedBackendPatch
structs, and 8 unit tests covering all paths including empty-patch
noop and duplicate-name uniqueness enforcement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:59:56 -05:00
whit3rabbitandClaude Sonnet 4.6 dc301c489e docs: restructure README for user-first experience
Move install methods, admin env vars, virtual key operations, Docker
smoke tests, LiteLLM aliases, and library usage into collapsible
<details> blocks. Consolidate backend examples into one section.
Remove numbered sections and redundant "What/Why/How" explainer.
Add run subcommand and OMIT_STREAM_OPTIONS tips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:52:47 -05:00
whit3rabbitandClaude Sonnet 4.6 ebbfb3a0e6 docs: condense CLAUDE.md, expand ENV.md and CONFIG.md coverage
Rewrite CLAUDE.md to remove redundant status/detail sections already
covered by dedicated docs. Expand ENV.md with missing variable groups
(auth, network/security, OIDC, Vertex, Gemini, Anthropic passthrough,
webhooks, Langfuse, Redis, Qdrant, cost tracking, LiteLLM aliases).
Add config file format detection, CLI flags, and env import precedence
to CONFIG.md. Update env_parser KNOWN_KEYS with OMIT_STREAM_OPTIONS,
ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL, batch webhook vars, and
OTEL_TRACES_SAMPLER_ARG.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:45:50 -05:00
whit3rabbitandClaude Sonnet 4.6 dde1f902b6 feat: model persistence, model discovery, config directory, and admin UI updates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:24:44 -05:00
whit3rabbitandClaude Sonnet 4.6 3980985b17 fix: review feedback - disable service in prerm, clobber on re-upload, remove redundant postinst re-run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:19:27 -05:00
whit3rabbitandClaude Sonnet 4.6 4c49a0efde docs: add deb packaging section to CLAUDE.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:16:56 -05:00
whit3rabbitandClaude Sonnet 4.6 787ca25388 ci: upload deb packages to GitHub releases
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:14:45 -05:00
whit3rabbitandClaude Sonnet 4.6 37e7e2827f ci: add deb install verification job
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:14:34 -05:00
whit3rabbitandClaude Sonnet 4.6 cd7372a562 ci: build deb packages on Linux targets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:14:12 -05:00
whit3rabbitandClaude Sonnet 4.6 f0ca45f4c9 feat: add cargo-deb metadata for .deb package generation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:12:51 -05:00
whit3rabbitandClaude Sonnet 4.6 1b5e660790 feat: add deb packaging assets (systemd, env defaults, maintainer scripts)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:11:29 -05:00
whit3rabbitandClaude Sonnet 4.6 e260d7ec6f docs: add deb packaging implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:05:17 -05:00
whit3rabbitandClaude Sonnet 4.6 18c2b6bd0f docs: add deb packaging design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:32:40 -05:00
whit3rabbitandClaude Sonnet 4.6 56eca3b674 chore: cargo fmt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 16:59:25 -05:00
whit3rabbitandClaude Sonnet 4.6 e3275f81da feat: env import/export, spend alerts, model allowlist, audit log, and misc hardening
Adds admin env file import/export (multipart upload + download), per-key
spend alerts (80/95/100% of budget), model allowlist with wildcard support,
audit log for admin mutations, CSRF one-time-use tokens, SSRF-safe OIDC/webhook
clients, sliding-window admin rate limiter, and configurable Redis fail policy.
Also updates batch_engine, client, translator mapping, and admin UI settings tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 16:57:22 -05:00
whit3rabbitandClaude Sonnet 4.6 0fa7495574 feat: docker smoke tests, admin UI polish, and misc fixes
- ci: replace inline smoke test with docker-compose.test.yml + scripts/docker-smoke-test.sh (9 checks)
- add .env.example, .env.example.test, .anyllm.env.example, docker-compose.test.yml
- gitignore: add .anyllm.env*, *.db-shm, *.db-wal patterns
- admin UI: fix auth store, vite config, App.tsx updates; rebuild dist
- admin routes: keys, traffic, mod, db, health_check updates
- server: gemini_input, mod, routes adjustments
- translator: lib.rs, gemini_message_map, tools_map fixes
- batch: anthropic_batch cleanup
- docs: add React admin UI plan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 18:58:38 -05:00
whit3rabbitandClaude Sonnet 4.6 dfed5b14ff feat: React admin UI migration — React 19 + TypeScript + Traffic/Uptime tabs
Replace 1,928-line monolithic vanilla JS admin SPA with React 19 + TypeScript 5
application. Adds Traffic and Uptime tabs backed by new Rust API endpoints.

- Vite + vite-plugin-singlefile: single dist/index.html with inlined JS/CSS
- Custom closeBundle plugin preserves __CSP_NONCE__ placeholder for Rust injection
- React Query v5 for server state, Zustand v5 for auth + WS connection state
- All existing backend contracts preserved (CSRF, WS auth, sessionStorage key)
- New: GET /admin/api/traffic (route load, P95, req/min, time series)
- New: GET /admin/api/uptime (proxy start time, per-backend 30d history)
- New: health_checks SQLite table + background Tokio health-checker (30s probe)
- BackendHealthChanged WS event for immediate Uptime tab refresh on status flip
- Dockerfile gains Node.js Stage 1 for frontend build
- CI gains frontend job (tsc + lint + build) before Rust test job

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:29:47 -05:00
whit3rabbitandClaude Sonnet 4.6 2e22cfef3c chore: stage pre-existing main branch changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:28:55 -05:00
whit3rabbit 6b4c4c93f4 ci: download admin-ui-dist artifact in build-release job 2026-04-05 15:23:28 -05:00
whit3rabbitandClaude Sonnet 4.6 a76f169376 feat: complete React admin UI migration with Traffic and Uptime tabs
Fix unused _labels lint error in LineChart component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:22:40 -05:00
whit3rabbit cc24cc5592 ci: add frontend job (tsc + lint + build) before Rust test job 2026-04-05 15:21:50 -05:00
whit3rabbit f4ec5f34a1 feat(docker): add Node.js frontend build stage (Stage 1) 2026-04-05 15:21:36 -05:00
whit3rabbit 8d3facdb99 fix(traffic): rename avg_request_bytes to avg_latency_ms (no bytes column in request_log)
The field was storing AVG(latency_ms) from the query but named as if it
held payload size. Rename across Rust struct, TypeScript type, RouteTable
column header/cell, and TrafficView bar chart. Remove now-unused formatBytes
helpers from both components.
2026-04-05 15:20:22 -05:00
whit3rabbitandClaude Sonnet 4.6 d40f2aa70d fix(proxy): compute proxy uptime pct, add avg_request_bytes, expand probe reachability
- uptime.rs: replace hardcoded 100.0 with down_days/total_days computation over proxy_history
- traffic.rs: add avg_request_bytes field to RouteMetrics, populated from AVG(latency_ms) in SQL
- health_check.rs: treat 403 and 404 as reachable (Anthropic /v1/models returns 404)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:17:47 -05:00
whit3rabbitandClaude Sonnet 4.6 2de7f3e060 feat(proxy): register traffic/uptime routes, spawn health checker, switch to dist/index.html
- Add traffic/uptime module declarations and route registrations
- Update include_str! from admin-ui/index.html to admin-ui/dist/index.html
- Spawn health checker after SharedState construction with backend URL snapshot
- Fix started_at field in cost/mod.rs test SharedState construction
- Unignore dist/ in .gitignore so compiled-in SPA works without a build step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:12:52 -05:00
whit3rabbitandClaude Sonnet 4.6 f5fa86d3d5 feat(proxy): add GET /admin/api/uptime endpoint
Returns proxy started_at timestamp and per-backend uptime_pct_30d,
last_checked_at, last_latency_ms, current status, and 30-day daily
history from health_checks table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:12:28 -05:00
whit3rabbitandClaude Sonnet 4.6 227018a2b4 feat(proxy): add GET /admin/api/traffic endpoint
Aggregates request_log by route (model_mapped/backend) with per-route
metrics (rpm, error rate, p95 latency) and 5-minute time-series buckets.
Adds chrono 0.4 dependency for time window calculations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:12:24 -05:00
whit3rabbitandClaude Sonnet 4.6 301f6af5e7 feat(proxy): add background health checker Tokio task (30s probe loop)
Probes GET <base_url>/v1/models per backend; treats 401 as up.
Backend URLs snapshotted from BackendConfig at startup (not runtime-mutable).
Broadcasts BackendHealthChanged only on up<->down transitions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 15:12:20 -05:00