Providers: New page to manage provider connections #33

Closed
opened 2026-03-30 10:36:30 +00:00 by mahmoud · 4 comments
Owner

Problem

There is no Providers page. Users cannot add, view, or update their connected AI providers (OpenRouter, Groq, etc.) or their API keys.

Expected Behavior

A Providers tab/page that:

  • Lists all connected providers (e.g. OpenRouter, Groq, Llama)
  • Shows connection status (connected / error / not configured)
  • Allows adding a new provider by entering its API key as an env var
  • Allows updating or removing an existing provider's API key

Acceptance Criteria

  • Providers page exists and is reachable from sidebar
  • All configured providers are listed with status
  • Add provider flow works (name + API key input)
  • Edit / remove existing provider works
## Problem There is no Providers page. Users cannot add, view, or update their connected AI providers (OpenRouter, Groq, etc.) or their API keys. ## Expected Behavior A **Providers** tab/page that: - Lists all connected providers (e.g. OpenRouter, Groq, Llama) - Shows connection status (connected / error / not configured) - Allows adding a new provider by entering its API key as an env var - Allows updating or removing an existing provider's API key ## Acceptance Criteria - [x] Providers page exists and is reachable from sidebar - [x] All configured providers are listed with status - [x] Add provider flow works (name + API key input) - [x] Edit / remove existing provider works
Author
Owner

Implementation Spec for Issue #33 — Providers CRUD

Objective

Make the existing read-only Providers page fully functional with runtime add/edit/remove of provider API keys, .env persistence, and hot-reload of provider instances.

Approach

  1. Make Config and services mutable at runtime (wrap in RwLock)
  2. Add 3 RPC methods: providers.list, providers.add_key, providers.remove_key
  3. Add Config helpers for .env persistence and provider key mutation
  4. Add provider rebuild function to hot-reload services when keys change
  5. Rewrite providers_pane.html with interactive add/remove UI

Files to Modify

  • crates/hero_aibroker/src/config/mod.rs — Add KNOWN_PROVIDERS, set_provider_keys(), save_env_file(), env_file_path()
  • crates/hero_aibroker_ui/src/api/mod.rs — Wrap config/services in RwLock, add 3 RPC handlers + rebuild_providers()
  • crates/hero_aibroker_ui/src/api/chat.rs — Read lock on chat_service
  • crates/hero_aibroker_ui/src/api/tts.rs — Read lock on tts_service
  • crates/hero_aibroker_ui/src/api/stt.rs — Read lock on stt_service
  • crates/hero_aibroker_ui/src/api/embedding.rs — Read lock on embedding_service
  • crates/hero_aibroker_ui/src/main.rs — Wrap config/services in RwLock
  • crates/hero_aibroker_ui/templates/fragments/providers_pane.html — Interactive provider management UI

Implementation Steps

  1. Make Config mutable in AppState (wrap in RwLock)
  2. Make services replaceable at runtime (wrap in RwLock)
  3. Add Config mutation + .env persistence helpers
  4. Add provider rebuild function
  5. Add 3 RPC handlers (providers.list, add_key, remove_key)
  6. Rewrite providers_pane.html UI

Acceptance Criteria

  • Providers page lists all 4 known providers with status
  • Add provider key works (input + submit)
  • Remove provider key works (with confirmation)
  • Changes persist to .env file
  • Services hot-reload when keys change
  • Models become available immediately after adding a provider key

🤖 Generated with Claude Code

## Implementation Spec for Issue #33 — Providers CRUD ### Objective Make the existing read-only Providers page fully functional with runtime add/edit/remove of provider API keys, .env persistence, and hot-reload of provider instances. ### Approach 1. Make `Config` and services mutable at runtime (wrap in `RwLock`) 2. Add 3 RPC methods: `providers.list`, `providers.add_key`, `providers.remove_key` 3. Add Config helpers for .env persistence and provider key mutation 4. Add provider rebuild function to hot-reload services when keys change 5. Rewrite providers_pane.html with interactive add/remove UI ### Files to Modify - `crates/hero_aibroker/src/config/mod.rs` — Add `KNOWN_PROVIDERS`, `set_provider_keys()`, `save_env_file()`, `env_file_path()` - `crates/hero_aibroker_ui/src/api/mod.rs` — Wrap config/services in RwLock, add 3 RPC handlers + rebuild_providers() - `crates/hero_aibroker_ui/src/api/chat.rs` — Read lock on chat_service - `crates/hero_aibroker_ui/src/api/tts.rs` — Read lock on tts_service - `crates/hero_aibroker_ui/src/api/stt.rs` — Read lock on stt_service - `crates/hero_aibroker_ui/src/api/embedding.rs` — Read lock on embedding_service - `crates/hero_aibroker_ui/src/main.rs` — Wrap config/services in RwLock - `crates/hero_aibroker_ui/templates/fragments/providers_pane.html` — Interactive provider management UI ### Implementation Steps 1. Make Config mutable in AppState (wrap in RwLock) 2. Make services replaceable at runtime (wrap in RwLock) 3. Add Config mutation + .env persistence helpers 4. Add provider rebuild function 5. Add 3 RPC handlers (providers.list, add_key, remove_key) 6. Rewrite providers_pane.html UI ### Acceptance Criteria - [x] Providers page lists all 4 known providers with status - [x] Add provider key works (input + submit) - [x] Remove provider key works (with confirmation) - [x] Changes persist to .env file - [x] Services hot-reload when keys change - [x] Models become available immediately after adding a provider key --- 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Test Results

  • Total: 21
  • Passed: 21
  • Failed: 0

All tests pass after implementing Providers CRUD (RwLock wrapping, RPC handlers, UI rewrite).

🤖 Generated with Claude Code

## Test Results - **Total:** 21 - **Passed:** 21 - **Failed:** 0 All tests pass after implementing Providers CRUD (RwLock wrapping, RPC handlers, UI rewrite). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Implementation Summary

Changes Made

Backend — Config helpers (config/mod.rs)

  • Added KNOWN_PROVIDERS constant (openai, openrouter, groq, sambanova)
  • Added set_provider_keys(), save_env_file(), env_file_path() methods
  • .env persistence: reads existing file, updates API key lines, preserves everything else

Backend — Runtime mutability (api/mod.rs, main.rs)

  • Wrapped Config in Arc<RwLock<Config>> on AppState
  • Wrapped all 4 services (Chat, TTS, STT, Embedding) in Arc<RwLock<...>>
  • Wrapped Registry in Arc<RwLock<Arc<Registry>>>
  • Updated all handlers (chat.rs, tts.rs, stt.rs, embedding.rs) to acquire read locks

Backend — Provider CRUD (api/mod.rs)

  • rebuild_providers() — hot-reloads providers + registry + all services when keys change
  • providers.list RPC — returns all 4 known providers with status, key count, masked keys
  • providers.add_key RPC — adds a key, saves .env, rebuilds providers
  • providers.remove_key RPC — removes key by index, saves .env, rebuilds providers

Frontend — Providers pane (providers_pane.html)

  • Interactive cards for each provider: status badge, masked key list, remove buttons
  • Inline "Add Key" form per provider
  • Auto-reloads after add/remove operations

Test Results

  • 21 passed, 0 failed

Acceptance Criteria

  • Providers page lists all 4 known providers with status
  • Add provider key works (input + submit)
  • Remove provider key works (with confirmation)
  • Changes persist to .env file
  • Services hot-reload when keys change
  • Models become available immediately after adding a provider key

🤖 Generated with Claude Code

## Implementation Summary ### Changes Made **Backend — Config helpers** (`config/mod.rs`) - Added `KNOWN_PROVIDERS` constant (openai, openrouter, groq, sambanova) - Added `set_provider_keys()`, `save_env_file()`, `env_file_path()` methods - `.env` persistence: reads existing file, updates API key lines, preserves everything else **Backend — Runtime mutability** (`api/mod.rs`, `main.rs`) - Wrapped `Config` in `Arc<RwLock<Config>>` on AppState - Wrapped all 4 services (Chat, TTS, STT, Embedding) in `Arc<RwLock<...>>` - Wrapped Registry in `Arc<RwLock<Arc<Registry>>>` - Updated all handlers (chat.rs, tts.rs, stt.rs, embedding.rs) to acquire read locks **Backend — Provider CRUD** (`api/mod.rs`) - `rebuild_providers()` — hot-reloads providers + registry + all services when keys change - `providers.list` RPC — returns all 4 known providers with status, key count, masked keys - `providers.add_key` RPC — adds a key, saves .env, rebuilds providers - `providers.remove_key` RPC — removes key by index, saves .env, rebuilds providers **Frontend — Providers pane** (`providers_pane.html`) - Interactive cards for each provider: status badge, masked key list, remove buttons - Inline "Add Key" form per provider - Auto-reloads after add/remove operations ### Test Results - 21 passed, 0 failed ### Acceptance Criteria - [x] Providers page lists all 4 known providers with status - [x] Add provider key works (input + submit) - [x] Remove provider key works (with confirmation) - [x] Changes persist to .env file - [x] Services hot-reload when keys change - [x] Models become available immediately after adding a provider key 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Implementation committed: 0bfd710

Browse: 0bfd710

Implementation committed: `0bfd710` Browse: https://forge.ourworld.tf/lhumina_code/hero_aibroker/commit/0bfd710
mahmoud self-assigned this 2026-03-31 17:43:05 +00:00
mahmoud added this to the ACTIVE project 2026-03-31 17:43:12 +00:00
mahmoud removed their assignment 2026-03-31 17:43:12 +00:00
mahmoud added this to the now milestone 2026-03-31 17:43:15 +00:00
mahmoud self-assigned this 2026-03-31 17:43:51 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_aibroker#33
No description provided.