Skip to content

refactor(gateway): derive the settings view from the settings - #1190

Merged
peteski22 merged 2 commits into
mainfrom
refactor/settings-view-from-settings
Sep 16, 2026
Merged

peteski22 merged 2 commits into
mainfrom
refactor/settings-view-from-settings

Conversation

@peteski22

@peteski22 peteski22 commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Description

The dashboard's Settings page shows a read-only view of the gateway's configuration, grouped by topic, with credentials and structured blocks left out. Until now, which setting went where was kept in two hand-maintained lists in the settings endpoint. Every new setting had to be added to one of them, or a test failed.

Now each setting says where it belongs, on its own field: shown in a named group, omitted, or secret. The endpoint lays the view out from those declarations. A setting with no declaration fails at import, so a new one still cannot be forgotten, and it fails earlier than a test would.

Nothing changes for anyone using Otari. The settings response is byte-for-byte identical before and after, including the order of fields. Eleven field declarations moved within the config so that declaration order matches the order the view already had.

Churn, measured over 90 days as the epic asks: config.py goes from 70 commits to 71 and routes/settings.py from 29 to 30. Authors unchanged.

How to test it locally

make lint && make typecheck
uv run pytest tests/unit/test_settings_view.py tests/unit/test_settings_endpoint.py

What to look for: GET /api/v1/settings answers exactly what it did before. test_settings_endpoint.py is unchanged and still passes, including the check that every config field is either shown or deliberately omitted. test_settings_view.py covers the mechanism on small models: group order, declaration order within a group, and that a field with no declaration, or two, is refused.

Run locally: lint, typecheck, the full unit suite (3462 passed; the 14 failures are the generated-master-key and Claude Code import tests, which fail the same way on main in my checkout because a local .env sets OTARI_MASTER_KEY and my shell sets OTARI_API_KEY). The smoke gate and the integration suite are left to CI: the same .env sets OTARI_PORT, which the smoke gate's server picks up in place of its own port.

PR Type

  • New Feature
  • Bug Fix
  • Refactor
  • Documentation
  • Infrastructure / CI

Relevant issues

Fixes #1176. Part of #1171.

Checklist

  • I understand the code I am submitting.
  • I have added or updated tests that cover my change (tests/unit, tests/integration).
  • I ran the Definition of Done checks locally (make lint, make typecheck, make test). Lint, typecheck, and make test-unit ran locally; make test-integration is left to CI.
  • Documentation was updated where necessary.
  • If the API contract changed, I regenerated the OpenAPI spec (uv run python scripts/generate_openapi.py). Not applicable: the response shape is unchanged.

AI Usage

  • No AI was used.
  • AI was used for drafting/refactoring.
  • This is fully AI-generated.

AI Model/Tool used: Claude Fable 5.1, through Claude Code.

Any additional AI details you'd like to share: The issue and the decision to keep the field order by moving declarations were Peter's. The agent implemented the change, wrote the tests, and ran the checks. Peter reviewed the result before it was pushed.

  • I am an AI Agent filling out this form (check box if true)

Summary

  • Added visibility metadata to configuration fields.
  • Derived the settings endpoint view from this metadata.
  • Reordered selected fields to preserve the existing response order.
  • Added validation for missing or duplicate visibility declarations.
  • Added tests for grouping, ordering, credentials, and invalid declarations.

This removes hand-maintained visibility lists and keeps future settings changes aligned with the endpoint view.

Technical notes

The settings response remains unchanged. Test execution results are unavailable because the repository clone failed.

@peteski22
peteski22 deployed to integration-tests September 15, 2026 19:29 — with GitHub Actions Active
@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 9bf8ea1b-c68f-4bc7-b2ba-8c9c6177a080

📥 Commits

Reviewing files that changed from the base of the PR and between c208ab1 and 9073577.

📒 Files selected for processing (3)
  • src/gateway/AGENTS.md
  • src/gateway/core/config.py
  • tests/unit/test_settings_view.py

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.


Walkthrough

The change moves settings visibility into GatewayConfig field metadata. settings_view.py validates and derives the layout. The settings route uses the derived shown and hidden fields. Unit tests cover ordering, omissions, secrets, and invalid annotations.

Changes

Settings view derivation

Layer / File(s) Summary
View metadata and derivation
src/gateway/core/settings_view.py, tests/unit/test_settings_view.py
Defines visibility markers, display groups, layout derivation, annotation validation, and tests for ordering, omissions, secrets, and errors.
Configuration visibility metadata
src/gateway/core/config.py
Annotates server, rate-limiting, general, authentication, and mail fields.
Remaining configuration visibility metadata
src/gateway/core/config.py
Annotates routing, metering, model, file, vision, and tools fields.
Settings route integration
src/gateway/api/routes/settings.py, src/gateway/AGENTS.md
Replaces route-local visibility lists with the layout derived from GatewayConfig and documents the annotation requirement.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Refactor

Suggested reviewers: daavoo

Merge Risk: ⚪ Minimal · up to 90735

No verified merge-blocking behavior change remains.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title clearly describes the refactor, uses imperative mood, and is under 70 characters. However, it starts with refactor(gateway): rather than the required refactor: prefix. Change the title to start with an allowed prefix exactly, for example refactor: derive the settings view from the settings. Remove the scope unless scoped prefixes are explicitly permitted by the repository rules.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 4 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is complete and directly explains the change, testing steps, PR type, linked issues, checklist status, and AI usage. It also clearly documents the tests not run locally and why.
Linked Issues check ✅ Passed Issue #1176 requires metadata on configuration fields, derived settings layouts, and unchanged endpoint output. The PR adds Shown, Omitted, and Secret metadata, derives the route layout with `de…
Out of Scope Changes check ✅ Passed The changes remain within Issue #1176. The metadata model, field annotations, derived route layout, declaration reordering, guidance, and focused tests all support replacing the hand-maintained settin…
Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 4 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/settings-view-from-settings
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch refactor/settings-view-from-settings

Warning

Git: CodeRabbit could not clone the repository, so clone-backed analysis was skipped and this review may be incomplete. Verify repository clone access, such as SSH credentials, before requesting another full review. If clone access is intentionally unavailable, use path_filters to narrow the review scope.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@peteski22
peteski22 requested a review from daavoo September 15, 2026 19:32

@daavoo daavoo left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebuilt both versions and compared them: the derived view is exactly what main hard-coded, down to group order, field order within each group, and the hidden set. The eleven moved declarations are right.

pd @peteski22 there are merge conflicts

Comment thread src/gateway/core/settings_view.py
Comment thread src/gateway/core/config.py Outdated
The settings endpoint kept two hand-maintained tuples of field names:
the grouped view and the deliberate omissions. Every new setting had to
edit one of them, or the coverage test failed.

Carry the view on each field instead. Every GatewayConfig field is
annotated with exactly one of Shown(group), OMITTED or SECRET, and the
endpoint lays its view out from those. A field with no annotation fails
at import, so a new setting still cannot be forgotten. The endpoint's
output is identical: eleven field declarations moved so declaration
order within a group matches the order the view already had.

Part of #1176.
Both markers hide a field, so marking a credential OMITTED would hide it
just as well and the module's "never carries a credential" rule would be
description rather than contract. Assert the marker for all seven,
including the two the endpoint's own credential test never named.

Also revert four line reflows a whole-file format left behind. They are
unrelated to this change.
@peteski22
peteski22 force-pushed the refactor/settings-view-from-settings branch from c208ab1 to 9073577 Compare September 16, 2026 09:53
@peteski22
peteski22 deployed to integration-tests September 16, 2026 09:53 — with GitHub Actions Active
@peteski22
peteski22 merged commit 7066dd4 into main Sep 16, 2026
12 checks passed
@peteski22
peteski22 deleted the refactor/settings-view-from-settings branch September 16, 2026 09:56

This branch was successfully deployed

1 active deployment
integration-tests — 9073577b Deployed Sep 16, 2026 by peteski22 via test-integration #1996
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.

Settings view derived from the settings

2 participants