Skip to content

Add Agent Settings UI for AI search#2320

Merged
Mbeaulne merged 1 commit into
masterfrom
05-27-agent-settings-ui
Jun 5, 2026
Merged

Add Agent Settings UI for AI search#2320
Mbeaulne merged 1 commit into
masterfrom
05-27-agent-settings-ui

Conversation

@Mbeaulne

@Mbeaulne Mbeaulne commented May 27, 2026

Copy link
Copy Markdown
Collaborator

Tophatting

Manual tophatting recommended because this PR adds a settings screen.

  1. Turn on the Components V2 beta flag.
  2. Open Settings → Agent Configuration.
  3. Try saving without a model and confirm the inline error is shown.
  4. Enter a provider URL, API key, and model id, then click “Test connection”.

What changed

Adds the Agent Settings screen for configuring AI search.

Users can enter:

  • API base URL
  • API key
  • model id

The screen can test whether the provider is reachable and whether the model exists.

Why

Components V2 AI search should work with a user-provided OpenAI-compatible API. This keeps credentials out of the app bundle and lets users choose their own provider/model.

Test plan

  • Turn on the Components V2 beta flag
  • Open Settings → Agent Configuration
  • Try saving without a model and confirm inline validation appears
  • Enter a provider URL/key/model and click “Test connection”
  • Run pnpm exec vitest run src/routes/Settings/sections/AgentSettings.test.tsx
  • Run pnpm run typecheck --pretty false

@github-actions

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown

🎩 Preview

A preview build has been created at: 05-27-agent-settings-ui/fb6f2d0

@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 8d45929 to 38e0b45 Compare May 27, 2026 20:29
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch 2 times, most recently from 38b163d to bb24190 Compare May 27, 2026 23:18
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from bb24190 to 839c5d2 Compare May 28, 2026 17:25
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 3cbeeb6 to 26745bd Compare May 28, 2026 18:37
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch 2 times, most recently from 0e1f178 to 496907a Compare May 28, 2026 18:40
Comment thread src/routes/Settings/sections/AgentSettings.tsx
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 496907a to 718a81a Compare May 29, 2026 14:38
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 26745bd to 0f078bc Compare May 29, 2026 14:38
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch 4 times, most recently from 254c824 to 0417a6f Compare May 29, 2026 18:04
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 0f078bc to c4dd973 Compare June 3, 2026 13:42
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 0417a6f to 8e168da Compare June 3, 2026 13:42
@Mbeaulne Mbeaulne mentioned this pull request Jun 3, 2026
8 tasks
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from c4dd973 to fff5c0d Compare June 3, 2026 15:13
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 8e168da to f5acd71 Compare June 3, 2026 15:13
@Mbeaulne Mbeaulne mentioned this pull request Jun 3, 2026
8 tasks
@Mbeaulne Mbeaulne marked this pull request as ready for review June 3, 2026 15:28
@Mbeaulne Mbeaulne requested a review from a team as a code owner June 3, 2026 15:28

@morgan-wowk morgan-wowk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 AI-assisted review — one non-blocking a11y follow-up.

setModel(e.target.value);
setValidationError(null);
}}
aria-label="Model id"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 AI-assisted review (non-blocking — fine to punt to a later PR)

The Model field has a visible <Label htmlFor="agent-settings-model">Model</Label> (:201) but the input also sets aria-label="Model id". aria-label wins, so screen readers announce "Model id" while sighted users see "Model", and it overrides the label association (the other two fields share this redundancy).

Options: (a) drop the aria-labels — the <Label htmlFor> already names the field; (b) make visible label and aria-label match; (c) use aria-labelledby pointing at the label.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 User scenario

A screen-reader user tabs to the Model field and hears "Model id" announced, while the visible label everyone else sees reads "Model" — the mismatch makes the form harder to follow and to reference in docs/support.

@morgan-wowk morgan-wowk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved with comments

@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from f5acd71 to 6ade827 Compare June 4, 2026 20:43
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from fff5c0d to 39aee24 Compare June 4, 2026 20:43
Comment thread react-compiler.config.js
// Convert to glob patterns for ESLint
export const REACT_COMPILER_ENABLED_GLOBS = REACT_COMPILER_ENABLED_DIRS.map(
(dir) => `${dir}/**/*.{ts,tsx}`,
(path) => (/\.[cm]?[jt]sx?$/.test(path) ? path : `${path}/**/*.{ts,tsx}`),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 This is an AI-generated code review comment.

This glob change silently activates the ESLint react-compiler rule on ~30 pre-existing file entries.

REACT_COMPILER_ENABLED_DIRS has long contained individual file paths (e.g. src/hooks/useFavorites.ts, and many *.tsx entries below). Under the old mapper, a file entry became the glob src/hooks/useFavorites.ts/**/*.{ts,tsx}, which matches nothing — so the rule was never actually enforced on any of those individually-listed files. This change passes file entries through verbatim, so the rule now applies to all of them at once, not just the newly-added typography.tsx.

Correct fix, but the blast radius is much larger than this PR's stated scope: any pre-existing compiler-rule violation in those files will now surface as a lint error. No code change needed — just confirm pnpm lint passes repo-wide (not only on typography.tsx), and consider calling this out in the PR description.

setModel(e.target.value);
setValidationError(null);
}}
aria-label="Model id"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 This is an AI-generated code review comment.

Redundant aria-labels duplicate the <Label>, and the Model field's disagrees with its visible label.

Each Input already has an associated <Label htmlFor> that supplies the accessible name, so the added aria-label is redundant — and here it overrides the visible label with different text:

<Label htmlFor="agent-settings-model">Model</Label>   // visible: "Model"
aria-label="Model id"                                  // accessible name: "Model id"

The visible/accessible-name divergence ("Model" vs "Model id") is what voice-control and screen-reader users trip over. The other two fields are merely redundant (identical text). These aria-labels appear to exist only so the tests can call getByLabelText("Model id"), but getByLabelText already resolves associated <label> text.

Fix: drop the three aria-labels and let the <Label> name each input (update the test to query "Model"). If you want the name to read "Model id", change the visible <Label> text instead so the two stay in sync.

const { config, update, clear, isConfigured } = useComponentSearchSettings();
const notify = useToastNotification();

const [apiBase, setApiBase] = useState(config.apiBase);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 This is an AI-generated code review comment.

Form state seeds from config once and never re-syncs.

const [apiBase, setApiBase] = useState(config.apiBase);
const [apiKey, setApiKey] = useState(config.apiKey);
const [model, setModel] = useState(config.model);

useComponentSearchSettings is backed by useSyncExternalStore with cross-tab sync, so config can change after mount (e.g. saved/cleared in another tab). These local states only capture the initial value, so the form won't reflect such external changes.

Minor for a single-tab settings page, but worth a conscious decision since the underlying hook went to the trouble of supporting cross-tab updates. If you want it to track external changes, sync via an effect keyed on config, or treat config as the source of truth for non-dirty fields.


setTesting(true);
try {
const response = await fetch(`${trimmed.apiBase}/models`, {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 This is an AI-generated code review comment.

The connection-test fetch has no timeout/abort.

const response = await fetch(`${trimmed.apiBase}/models`, {
  headers: { authorization: `Bearer ${trimmed.apiKey}` },
});

The testRunIdRef guard nicely handles Clear-during-test and stale responses, but a provider that hangs (no response) leaves the button stuck on "Testing…" indefinitely, with no recovery short of clicking Clear.

Optional fix: pass AbortSignal.timeout(…) to fetch and surface the abort as a "Test failed: timed out" toast.

@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 6ade827 to 25768e9 Compare June 4, 2026 20:52
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 39aee24 to 18bcfe1 Compare June 4, 2026 20:52
autoComplete="off"
spellCheck={false}
/>
<Text id="agent-settings-model-hint" size="xs" tone="subdued">

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

curious if we need a id field on a text component?

*/
className?: string;

/** HTML id used to associate text with form controls and ARIA descriptions. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

isn't that what Label is for?

@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 25768e9 to 8cc6ede Compare June 4, 2026 21:03
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ai-rerank-service branch from 18bcfe1 to 6a60fc3 Compare June 4, 2026 21:03
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from 8cc6ede to a2ec331 Compare June 4, 2026 21:46

Mbeaulne commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator Author

Merge activity

  • Jun 5, 2:37 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 5, 2:48 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 5, 2:51 PM UTC: @Mbeaulne merged this pull request with Graphite.

@Mbeaulne Mbeaulne changed the base branch from 05-27-agent-settings-ai-rerank-service to graphite-base/2320 June 5, 2026 14:42
@Mbeaulne Mbeaulne changed the base branch from graphite-base/2320 to master June 5, 2026 14:46
@Mbeaulne Mbeaulne force-pushed the 05-27-agent-settings-ui branch from a2ec331 to fb6f2d0 Compare June 5, 2026 14:47
@Mbeaulne Mbeaulne merged commit cb0548a into master Jun 5, 2026
17 checks passed
@Mbeaulne Mbeaulne deleted the 05-27-agent-settings-ui branch June 5, 2026 14:51
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.

3 participants