Skip to content

Configure the Hub's AI provider for web clients (v0.16.0) - #15

Merged
gmpassos merged 1 commit into
masterfrom
feat/hub-ai-config
Jul 15, 2026
Merged

Configure the Hub's AI provider for web clients (v0.16.0)#15
gmpassos merged 1 commit into
masterfrom
feat/hub-ai-config

Conversation

@gmpassos

Copy link
Copy Markdown
Contributor

Completes the dashboard :ai / :ide work (shipped in dashboard 0.3.0): those agents proxy their provider calls through the Hub so no browser holds an API key — but omnyserver's Hub served no AI, so :ai had no default and only worked with a key typed into the dashboard. This gives the Hub an AI provider.

The gap

omnyserver's ShellHub.fromGrants built the omnyshell HubBroker without an aiProxy, so a web client's fetchHubAiConfig always answered available: false and every proxy request was rejected.

Changes

  • ShellHub.fromGrants(aiConfig:) → passes aiProxy: HttpProxyService(defaultConfig: aiConfig) to the broker. That single wiring lights up fetchHubAiConfig (key-less discovery) and the credential-injecting proxy — the key stays on the Hub.
  • hub start --ai-config (default <OMNYSERVER_HOME>/ai.yaml) → AiConfigIo.load → threaded in under --shell. Startup reports Hub AI: <provider> — proxying … or not configured.
  • omnyserver ai config | show | test — mirrors omnyshell ai …:
    • config writes provider/model/key/mode/language to ~/.omnyserver/ai.yaml (mode 600; --key - reads from a hidden prompt)
    • show prints the resolved config, key masked
    • test validates the key + models with a live provider request
    • keys may also come from ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY

Almost entirely reuse

AiConfig, AiConfigIo, HttpProxyService, providerFor, validateModels are all public in the omnyshell package omnyserver already depends on — this is CLI glue + the one broker wiring. Adds http (for ai test).

Verification

  • 291 tests + new: shell_hub_ai_test.dart (aiConfig → broker gets a proxy; without → none) and ai_command_test.dart (subprocess config/show/errors, isolated home).
  • Driven for real: ai config writes ~/.omnyserver/ai.yaml, ai show reflects it (key masked), and hub start --shell reports Hub AI: anthropic — proxying :ai for web clients (or not configured when absent).
  • analyze/format/dependency_validator/dart doc clean.

Note

The reused AiConfigIo writes a header comment reading ~/.omnyshell/ai.yaml even in omnyserver's file — cosmetic only (it's a comment), left as-is to avoid a needless omnyshell patch.

🤖 Generated with Claude Code

The dashboard's :ai and :ide run their provider calls through the Hub so no
browser holds an API key — but omnyserver's shell broker served no AI at all: it
built the omnyshell HubBroker without an aiProxy, so a web client's
fetchHubAiConfig always returned "unavailable".

- ShellHub.fromGrants gains an `aiConfig` and passes
  `aiProxy: HttpProxyService(defaultConfig: aiConfig)` to the broker. That one
  wiring makes fetchHubAiConfig and the credential-injecting proxy work — the key
  stays on the Hub.
- `hub start --ai-config` (default <OMNYSERVER_HOME>/ai.yaml) loads the config
  via AiConfigIo.load and threads it in under --shell; startup reports whether AI
  is configured.
- New `omnyserver ai config | show | test` command, mirroring omnyshell's:
  config writes provider/model/key/mode/language (600, `--key -` for a hidden
  prompt), show prints it with the key masked, test makes a live provider call.
  Keys may also come from ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY.

Almost entirely reuse — AiConfig, AiConfigIo, HttpProxyService, providerFor and
validateModels are public in the omnyshell package omnyserver already depends on.
Adds `http` (used by `ai test`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gmpassos
gmpassos merged commit adb9f61 into master Jul 15, 2026
5 checks passed
@gmpassos
gmpassos deleted the feat/hub-ai-config branch July 15, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant