Assistant app home, provider settings, Test connection, per-call usage and prices #12

Merged
KofTwentyTwo merged 1 commits from feature/app-home-settings into develop 2026-10-13 15:09:26 +00:00
KofTwentyTwo commented 2026-10-13 15:01:53 +00:00 (Migrated from github.com)

What

Owner request: a real app home (health, usage, costs) and a settings screen (provider, API key, test connectivity).

  • Provider settings (assistant_provider): type (registered AssistantProviderType, with AnthropicProviderType in the Anthropic module), model, enabled/default, base URL override, monthly cost cap (USD), max output tokens per request, max concurrent requests, and the last connection test. The default enabled row is the active provider. With no rows, the provider registered in code answers, so current hosts keep working.
  • API keys are never stored. A row names the environment variable that holds the key (apiKeyEnvName). Only allow-listed names are accepted: each type's default plus allowedApiKeyEnvNames. A base URL override must be in allowedBaseUrls. apiKeyStatus is computed on read (Set • …abcd (from ANTHROPIC_API_KEY)) and dropped on save, so no read path returns the key. A pasted key is refused before it is stored. See docs/DESIGN.md for why we use a reference: core has no secret field type, and the RC.6 cipher (qqq#1123/#1107) is for backup artifacts and is unreleased.
  • Test connection: a record action on providers, as a standard streamed ETL with Review and Result lines and no custom form. It makes one short live call (32 output tokens max, effort low). The result is saved on the row and recorded as a TEST usage row.
  • assistant_usage: one row per model call (turn steps and tests) with provider, model, status, error kind, HTTP status, latency, tokens and cost. It is a child list on conversations and providers.
  • assistant_model_price: editable USD per million tokens, used for every call's cost. The reference DDL seeds the Anthropic list prices of 2026-10, and the config defaults now cover all current Claude models.
  • App home (assistantHome): health, providers, usage by day, costs against the caps, by user, top tools and recent failures. It uses real rows only, with empty states, in flow/grid layout (no tables, no inner scroll), light and dark.
  • Nav: the home plus Providers, Conversations, Model prices and Policy. Retention is now a table action on conversations.
  • Every assistant_* table has AI exposure NONE.

Tests

CI=true ./mvnw verify: green. Core 78 tests, Anthropic 10, checkstyle clean, coverage gates met.

  • New AssistantSettingsTest covers:
    • metadata
    • the key is never returned (query, get, entity JSON), and the forged status is not stored
    • unsafe settings refused (pasted key, DATABASE_PASSWORD, unknown URL, bad limits)
    • default/active selection
    • the Test connection action: Review and Result lines, saved result, TEST usage rows, no-key short-circuit
    • per-call usage and price math, the per-request cap and the monthly cap
    • the home, empty and with data
  • New AnthropicProviderTypeTest runs Test connection against the recorded HTTP server: the key reaches the API as x-api-key; a 401 gives a readable error without the key.

Screenshots

docs/screenshots/ (local AssistantDemoServer, never production): home, provider, provider without a key, edit, prices. Light and dark at 390 and 1440.

Upgrade

Three new tables (DDL in docs/schema-postgres.sql) and withProviderType(new AnthropicProviderType()). See UPGRADE.md.

🤖 Generated with Claude Code

## What Owner request: a real app home (health, usage, costs) and a settings screen (provider, API key, test connectivity). - **Provider settings** (`assistant_provider`): type (registered `AssistantProviderType`, with `AnthropicProviderType` in the Anthropic module), model, enabled/default, base URL override, monthly cost cap (USD), max output tokens per request, max concurrent requests, and the last connection test. The default enabled row is the active provider. With no rows, the provider registered in code answers, so current hosts keep working. - **API keys are never stored.** A row names the environment variable that holds the key (`apiKeyEnvName`). Only allow-listed names are accepted: each type's default plus `allowedApiKeyEnvNames`. A base URL override must be in `allowedBaseUrls`. `apiKeyStatus` is computed on read (`Set • …abcd (from ANTHROPIC_API_KEY)`) and dropped on save, so no read path returns the key. A pasted key is refused before it is stored. See docs/DESIGN.md for why we use a reference: core has no secret field type, and the RC.6 cipher (qqq#1123/#1107) is for backup artifacts and is unreleased. - **Test connection**: a record action on providers, as a standard streamed ETL with Review and Result lines and no custom form. It makes one short live call (32 output tokens max, effort low). The result is saved on the row and recorded as a `TEST` usage row. - **`assistant_usage`**: one row per model call (turn steps and tests) with provider, model, status, error kind, HTTP status, latency, tokens and cost. It is a child list on conversations and providers. - **`assistant_model_price`**: editable USD per million tokens, used for every call's cost. The reference DDL seeds the Anthropic list prices of 2026-10, and the config defaults now cover all current Claude models. - **App home** (`assistantHome`): health, providers, usage by day, costs against the caps, by user, top tools and recent failures. It uses real rows only, with empty states, in flow/grid layout (no tables, no inner scroll), light and dark. - **Nav**: the home plus Providers, Conversations, Model prices and Policy. Retention is now a table action on conversations. - Every `assistant_*` table has AI exposure `NONE`. ## Tests `CI=true ./mvnw verify`: green. Core 78 tests, Anthropic 10, checkstyle clean, coverage gates met. - New `AssistantSettingsTest` covers: - metadata - the key is never returned (query, get, entity JSON), and the forged status is not stored - unsafe settings refused (pasted key, `DATABASE_PASSWORD`, unknown URL, bad limits) - default/active selection - the Test connection action: Review and Result lines, saved result, TEST usage rows, no-key short-circuit - per-call usage and price math, the per-request cap and the monthly cap - the home, empty and with data - New `AnthropicProviderTypeTest` runs Test connection against the recorded HTTP server: the key reaches the API as `x-api-key`; a 401 gives a readable error without the key. ## Screenshots `docs/screenshots/` (local `AssistantDemoServer`, never production): home, provider, provider without a key, edit, prices. Light and dark at 390 and 1440. ## Upgrade Three new tables (DDL in `docs/schema-postgres.sql`) and `withProviderType(new AnthropicProviderType())`. See UPGRADE.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.