- 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>
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>
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>
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>
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>
- 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>
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>
- 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>
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>
- 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>
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>
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>
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>
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>
- 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>
- 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>
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>
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>
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.
- 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>
- 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>
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>
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>
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>