8000 feat(settings): cloud model presets in Settings and the setup wizard by adeelahmad · Pull Request #334 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

feat(settings): cloud model presets in Settings and the setup wizard - #334

Merged
adeelahmad merged 5 commits into
mainfrom
claude/project-thread-wssdga
Oct 11, 2026
Merged

adeelahmad merged 5 commits into
mainfrom
claude/project-thread-wssdga

Conversation

@adeelahmad
@adeelahmad adeelahmad commented Oct 10, 2026 •
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Before: switching to a cloud model meant opening Settings › LLM provider and typing the provider's address and model before pasting the key (5 clicks and 40 keys on a computer in the survey). Only the setup wizard offered anything in one click, and only for model servers running nearby.

After: Settings › LLM provider reuses the wizard's provider step. Both show the servers found nearby and, new, cloud providers with an OpenAI-compatible API: OpenAI, Anthropic, Google Gemini, OpenRouter, Groq, Mistral and DeepSeek. One click fills in the address and a model, puts the cursor in the API key field and links to where that provider hands out keys, so the switch is a click and a paste. The model stays editable, with the provider's other models suggested as you type.

Measured with ci/clicks/run.sh on main plus #325 (the phone survey, which adds the cloud-model journey), with that journey picking the OpenAI preset:

Switch to a cloud model Before After
Computer 5 clicks, 40 keys 3 clicks, 2 keys (the paste and Ctrl+S)
Phone 7 taps, 39 keys, 2 swipes 5 taps, 1 key (the paste), 1 swipe

The journey change and both baselines land in a small ci(clicks) follow-up once #325 merges, since the journey and baseline-phone.json only exist there. On today's main every journey matches baseline.json (the Clicks check is green).

Motivation and Context

From Adeel's ask to cut clicks, keys and touches; the survey (clicks-survey/latest.md) lists "Switch to a cloud model" at 5 clicks + 40 keys with a target of 4 clicks + 1 paste.

How

  • Backend: setup.CLOUD_PROVIDERS (name, address, model, suggested models, key page); GET /api/v1/setup/llm/providers (admins); the assistant's find_model_servers returns them as cloud next to the servers it finds.
  • Frontend: components/settings/model-providers.tsx (the hook and picker the wizard had inline, plus cloud providers), used by the wizard's model step and Settings › LLM provider. SettingField takes suggestions (a datalist); SecretSetting takes a hint and a focus signal (opens a saved key for replacing when the provider changes). In Settings the key now sits right under the address and model.
  • ci/clicks/journeys.mjs: the note journey waits for the new note's title to take the focus before typing, as a person would (it raced on a slow runner and counted an extra click).
  • make openapi regenerated the schema and client.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change; ! in the title)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project (ruff, eslint, prettier, tsc clean).
  • I added or updated tests (backend: providers endpoint and the assistant tool; frontend: wizard and Settings presets, focus, replacing a saved key, locked by .env).
  • My change requires documentation updates, and I have updated docs/ accordingly (configuration.md, Cloud model providers).
  • Users need more than the title to understand it, so I wrote it under ## Unreleased in CHANGELOG.md.

Done questions (AGENTS.md)

  • Goal: a click and a paste to switch to a cloud model; merges on green CI. The baseline update follows ci(clicks): survey every module, and on a phone with taps and swipes #325.
  • Agents: GET /api/v1/setup/llm/providers and find_model_servers give agents the same list.
  • Zero setup: nothing to install or set.
  • Fewest clicks and keystrokes: computer 3 clicks + paste + Ctrl+S (was 5 + 40), phone 5 taps + paste + 1 swipe (was 7 + 39 + 2).
  • Configurable: no new setting; every field stays editable.
  • Light: no new dependency.
  • Private and secure: nothing is sent until the admin saves; the endpoint is a static list behind admin sign-in, so no new surface for the threat model.
  • Cost: no model calls added.
  • User decides: presets only fill the form; nothing changes until Save, and defaults are unchanged.
  • Upgrades: n/a, no stored data changes.
  • Honest: docs list exactly the providers and models filled in; the numbers above are from local runs, labelled as such.
  • Tests, docs and generated files updated (make openapi).
  • Open standards (OpenAI-compatible APIs); no new dependencies.
  • Result reported with evidence. Refine later: the cloud-model journey and both baselines after ci(clicks): survey every module, and on a phone with taps and swipes #325; per-provider prices for the Costs page; refreshing the suggested model names as providers release new ones; on a phone the floating Ask button covers Save.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu

Settings > LLM provider reuses the setup wizard's provider step: the model
servers found nearby and, new, cloud providers with an OpenAI-compatible API
(OpenAI, Anthropic, Google Gemini, OpenRouter, Groq, Mistral, DeepSeek). One
click fills in the address and a model and focuses the API key field, so
switching to a cloud model is a click and a paste.

Agents get the same list from GET /api/v1/setup/llm/providers and the
assistant's find_model_servers tool.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu
The note page focuses its title once the note has loaded, so on a slow
runner the survey typed before that and counted an extra click and key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu
adeelahmad added a commit that referenced this pull request Oct 10, 2026
…PRs (#335)

The README and Get started say the web installer can install with the defaults in one click (#331). "In progress"
adds flagging instruction-like third-party text (#329), asking before the browser acts on what the assistant wrote
(#333) and cloud model presets (#334).


Claude-Session: https://claude.ai/code/session_01HDx7PPUauyjMn1LZs8JAsS

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
@adeelahmad
adeelahmad marked this pull request as ready for review October 11, 2026 01:36
@adeelahmad
adeelahmad merged commit de23168 into main Oct 11, 2026
11 checks passed
@adeelahmad
adeelahmad deleted the claude/project-thread-wssdga branch October 11, 2026 01:43
adeelahmad pushed a commit that referenced this pull request Oct 11, 2026
The same change as #350: Settings › LLM provider has cloud presets (#334), so
the journey picks OpenAI and pastes the key instead of typing the address and
model, which the form no longer has as plain text boxes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0173hj1h6qEeBT7zMzCgedwo
adeelahmad pushed a commit that referenced this pull request Oct 11, 2026
The cloud-model journey picks OpenAI from Settings › LLM provider's cloud
providers (#334) instead of typing the address and model, and both
baselines come from fresh runs: computer 3 clicks + 2 keys (was 5 + 40),
phone 5 taps + 1 key + 1 swipe (was 7 + 39 + 2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu
(cherry picked from commit d1d6cfd)
adeelahmad added a commit that referenced this pull request Oct 11, 2026
The cloud-model journey picks OpenAI from Settings › LLM provider's cloud
providers (#334) instead of typing the address and model, and both
baselines come from fresh runs: computer 3 clicks + 2 keys (was 5 + 40),
phone 5 taps + 1 key + 1 swipe (was 7 + 39 + 2).


Claude-Session: https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
adeelahmad pushed a commit that referenced this pull request Oct 11, 2026
…agent-connect baselines on main

The cloud-model journey from #350 (the Settings presets from #334 broke the old
one on main), with #350's baselines and the agent-connect entry from a run of
this branch on main.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JYGqrDpgP3Gcw1Jwf5mwT8
adeelahmad added a commit that referenced this pull request Oct 11, 2026
* ci: count clicks and keystrokes per feature, with a baseline

A Playwright survey (ci/clicks) drives a fresh Lens from the web installer
through setup and 19 features, counting clicks, keys and passkey prompts per
feature, module and page. The Clicks workflow fails when a journey takes more
than baseline.json.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XZkebEbpvyi9y3qmDVD8V

* ci(clicks): read --compare from the caller's folder; scroll past a covering button

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XZkebEbpvyi9y3qmDVD8V

* ci(clicks): summary step without A && B || C

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XZkebEbpvyi9y3qmDVD8V

* ci(clicks): survey every module, and on a phone with taps and swipes

The survey now runs twice, on a computer and on a phone (Pixel 7, touch),
w
8000
here clicks are taps, swipes to reach an off-screen control count, and
journeys use buttons instead of keyboard shortcuts. Twelve journeys cover
the modules the first survey left out: connecting an AI assistant over
MCP, uploading a file, watching a folder, entities, the graph, podcasts,
reports, workflows, templates, namespaces, speakers and switching to a
cloud model. baseline-phone.json records the phone run; journeys that
can't be done on a phone yet are kept as failed and don't turn CI red.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): steady phone swipes and journey waits

Measure where a control settles before counting a swipe, scope the webhook
token check to its dialog, and wait for the entity list to filter. The phone
baseline is the run with these fixes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): tap New conversation where Chat opens on the list

On a phone Chat opens on the conversation list, so the journey taps New
conversation when the question box isn't there. The computer baseline is a
run on main with the setup, Chat, Search and Notes cuts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* feat(ui): copy the MCP address from the account menu after setup

After setup Lens showed its MCP address nowhere but the setup wizard, so
connecting an assistant meant typing it. The account menu now has Copy MCP
address (one click, with a toast saying what to do with it), and API tokens
shows the address with Copy above Apps with access, saying to use an API
token while apps can't sign in.

Connecting an assistant over MCP drops from 3 clicks + 25 keys to 5 clicks
+ 1 paste on a computer and on a phone; the agent-connect journey now
copies from the menu and checks the clipboard, and both baselines carry it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JYGqrDpgP3Gcw1Jwf5mwT8

* ci(clicks): phone baseline on main with the setup and Notes cuts

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): wait for the imports' analysis before finding an entity

In CI the entity search opened before the imported transcripts were
analysed, so the entity wasn't there yet. The journey now waits (not
counted) until the API has it. The API's log is saved with the results, so
a failure in CI can be read from the artifact.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): wait on the Entities page, not the API

The API wants the session's bearer token, which the browser's requests
don't carry, so the wait reloads the Entities page until the entity shows
(not counted) and then starts the journey from Home.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): baselines on main with one-click install and named pipelines

Computer 93 clicks, 313 keys; phone 115 taps, 315 keys, 10 swipes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): make the podcast journey pick the pasted transcript

Both imports match "Welcome back", and the Library's order between them
varies. The dialog shows the recording's title, so on a phone the Create
button was below the screen for one and not the other (a swipe counted in
some runs only).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): agent-connect baselines from a run on the merged survey branch

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JYGqrDpgP3Gcw1Jwf5mwT8

* ci(clicks): baselines on main with the graph opening on your data

Computer 90 clicks, 313 keys; phone 119 taps, 322 keys, 11 swipes, and
the graph can be found on a phone now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0145yfQfD4eNkWHgPkk3Q82r

* ci(clicks): port the cloud-model journey through the presets (#350), agent-connect baselines on main

The cloud-model journey from #350 (the Settings presets from #334 broke the old
one on main), with #350's baselines and the agent-connect entry from a run of
this branch on main.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JYGqrDpgP3Gcw1Jwf5mwT8

---------

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
adeelahmad added a commit that referenced this pull request Oct 11, 2026
…monitoring switch as built (#351)

"Ask" names the built-in Telegram bot (#293) and Slack app (#287); "Connect your agents" adds mounting the graph's
files read-only over S3, WebDAV, NFS or SMB (#324, #295, #305) and copying the MCP address from the account menu
(#340); "Watch it run" says one switch in the web app starts Prometheus and Grafana (#337); "Light by default" adds
the cloud model presets (#334). The docs index gains the NFS and SMB pages, and "In progress" keeps only open PRs.


Claude-Session: https://claude.ai/code/session_01HDx7PPUauyjMn1LZs8JAsS

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
adeelahmad added a commit that referenced this pull request Oct 11, 2026
* feat(chat): built-in Telegram bot, on a shared chat-channel layer

Paste a bot tok
8122
en from @Botfather in Settings > Telegram and the assistant
answers there through getUpdates long polling: no Matterbridge, no public
address. It answers only people let in (one click from the settings page),
transcribes voice notes, holds files for the assistant to import, and keeps
everything Matterbridge rooms do (namespace routing, approving by reply).

channels.py is the adapter layer: Matterbridge and Telegram are adapters with
their own thread, lease and status, and bridge.handle serves both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194jTK9wbki29B4LcS7aKHG

* wip: mailbox settings and channel hooks

* feat(chat): the assistant's own email address, over IMAP and SMTP

People let in email or forward things to the assistant's mailbox; it answers
in the same thread and imports what's attached. Mail is answered only from
allowed senders whose provider vouched for From (Authentication-Results);
strangers are held on the settings page until let in. Forwarded text is
marked as third-party data. Plus addresses and mail routing rules pick the
namespace. Settings > Assistant email, with a Check button.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdrxhwvmLjFsfzQZ5pRJGC

* ci(clicks): switch to a cloud model through the presets

The cloud-model journey picks OpenAI from Settings › LLM provider's cloud
providers (#334) instead of typing the address and model, and both
baselines come from fresh runs: computer 3 clicks + 2 keys (was 5 + 40),
phone 5 taps + 1 key + 1 swipe (was 7 + 39 + 2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bmpwkzx9nwb1vcDxNMagtu
(cherry picked from commit d1d6cfd)

---------

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
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.

2 participants

0