Skip to content

feat(onboarding): verify Test connection without a model id (#792) - #1529

Open
lifelmy wants to merge 13 commits into
TokenRhythm:mainfrom
lifelmy:agent-tasks/792
Open

feat(onboarding): verify Test connection without a model id (#792)#1529
lifelmy wants to merge 13 commits into
TokenRhythm:mainfrom
lifelmy:agent-tasks/792

Conversation

@lifelmy

@lifelmy lifelmy commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Problem

Fixes #792.

In Settings → Model services, the Test connection button calls the onboarding.provider.probe RPC, whose underlying probe_llm_provider() hard-requires a model id (an empty model raises ValueError). That is a chicken-and-egg bind for a new user: you cannot know which models a provider serves until you can list them, but the model list is only fetched after the connection verifies — and the connection cannot be verified without already supplying a valid model id.

Change

When the model field is empty, connectivity is now verified through the model-list endpoint (GET /v1/models via the existing discover_provider_models()) instead of a one-token chat completion — exactly the behavior the issue proposes.

  • Backend (gateway/rpc_onboarding.py): onboarding.provider.probe branches on the model field. With a model it runs the usual usage-accounted chat probe; with an empty model it calls a new _connectivity_probe_via_discovery() helper that runs discover_provider_models() and maps the listing outcome (ok / failureKind / detail) back onto the frozen probe envelope. The chat-only timing fields (latencyMs, firstResponseMs, totalMs) stay at their never-reached-the-network sentinels since no chat round-trip happened. An ok listing that simply returns nothing still counts as reachable (the credentials verified). The wire contract is unchanged.
  • Frontend (useSetupCatalog.ts): for a draft primary-provider config, an empty model is no longer treated as a missing required field, so the Test connection button is enabled and probes with no model param. Stored/draft profile probes go through onboarding.llmProfile[.draft].probe, which still resolves a concrete deployment model, so those keep requiring a model.

Testing (all run locally, real execution)

  • uv run ruff check src testsall checks passed
  • uv run pytest -q tests/test_gateway/test_rpc_onboarding.py tests/test_contracts tests/test_onboarding1196 passed, 4 skipped
    • new: test_provider_probe_without_model_verifies_via_model_list, test_provider_probe_without_model_reports_auth_failure
  • uv run pytest -q tests/test_cli/test_models_probe.py12 passed; uv run pytest -q tests/test_onboarding/test_provider_probe.py → passed
  • uv run mypy src/opensquilla/gateway/rpc_onboarding.pyno issues
  • npx vitest run on useSetupCatalog.privacy.test.ts + useSetupProviderForm.test.ts (232 passed) and SetupProviderPanel.test.ts + SetupProviderCredentialCard.test.ts (123 passed); updated the privacy suite's model-less probe expectations
  • npm run build (Web UI artifact verified + staged), npm run typecheck (all guards passed), uv build --wheelbuilt opensquilla-0.5.4-py3-none-any.whl

Notes

I use a coding assistant to help implement, and I review and take responsibility for the final change. Opened as a draft for maintainer review; happy to adjust the surface (e.g. keep the button enabled but relabel it, or gate the fallback behind a capability flag) if you prefer a different shape.

Test connection required a model id: probe_llm_provider raises when the
model is empty and the Web UI disabled the button until a model was
entered. That is a chicken-and-egg bind — a user cannot list a
provider's models until the connection is verified, but cannot verify it
without already knowing a model.

onboarding.provider.probe now falls back to the model-list endpoint
(discover_provider_models) when the model field is empty, mapping the
listing outcome onto the frozen probe envelope (chat-only timings stay at
their never-reached sentinels). The Web UI no longer treats an empty
model as a missing required field for draft primary-provider probes;
stored/draft profile probes still resolve a concrete model.

Fixes TokenRhythm#792
@lifelmy
lifelmy marked this pull request as ready for review September 2, 2026 11:17
@lifelmy

lifelmy commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Current follow-up on head 64f14dcdfa after refreshing upstream/main (f9467234b5; branch is 0 behind / 6 ahead): the PR remains mergeable, and the implementation-specific suites pass locally.

Verification:

  • .venv/bin/pytest -q tests/test_gateway/test_rpc_onboarding.py → 72 passed
  • cd opensquilla-webui && bun run test:unit -- src/composables/setup/useSetupCatalog.privacy.test.ts → 175 passed

The remaining failed GitHub check is unrelated to this PR's onboarding diff: Windows high-risk (core) completed 6,947 tests successfully and then tests/test_process_tree.py::test_windows_gateway_crash_kills_job_and_reconcile_removes_stale_row timed out at its 15-second worker.wait() limit. CI result only mirrors that failure. I attempted gh run rerun 33724721382 --failed again, but GitHub rejected it because this contributor account lacks repository admin rights.

A maintainer/admin rerun of failed jobs for run 33724721382 is still needed to clear the transient Windows gate.

@lifelmy

lifelmy commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Refreshed this PR onto the latest upstream/main (3f92428e); current head is 31118a7d. The merge completed without manual conflict edits and preserved the model-id-free connection verification paths.

Verification on the refreshed head:

  • .venv/bin/pytest -q tests/test_onboarding tests/test_github_issue_link_sync.py -> 1001 passed, 4 skipped
  • npm --prefix opensquilla-webui run test:unit -- src/composables/setup/useSetupCatalog.privacy.test.ts -> 175 passed
  • focused ruff check -> passed
  • git diff --check upstream/main...HEAD -> passed

The push superseded the prior CI run containing the unrelated Windows core timeout. GitHub reports the refreshed branch as mergeable; its new CI jobs are running.

@lifelmy

lifelmy commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Refreshed this PR onto the latest upstream/main (4535029); new head is 33de521. The branch was 1 commit behind and merged cleanly without manual conflict edits. Verification: backend onboarding/RPC/issue-link suites passed (1073 passed, 4 skipped); WebUI privacy suite passed (175 passed); focused ruff and git diff --check passed.

@lifelmy

lifelmy commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Task A CI follow-up (2026-09-05): the completed Windows recovery-migration shard had one failure in test_aggregator_partial_output_idle_timeout_is_replaced_by_fixed_aggregator[tool], outside this PR's onboarding/WebUI diff; the other 4,251 tests in that phase passed. I re-ran the exact failing test 5 times locally and all 5 passed. The PR-focused backend run passed 75 tests (including onboarding and the failing ensemble test), WebUI privacy passed 175 tests, focused ruff and git diff --check passed. I attempted to rerun failed GitHub jobs, but GitHub requires repository admin rights for this run, so the failed check remains maintainer-controlled.

@lifelmy

lifelmy commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Task A refresh (2026-09-05): fetched latest upstream/main at 770ff387c6, merged it without conflicts, and pushed head cfad87c0d7. The two new base commits touch provider ensemble/runtime and WebUI toast-host paths; this PR's model-less Test connection behavior remains intact.

Verification on the refreshed head:

  • uv run pytest -q tests/test_gateway/test_rpc_onboarding.py tests/test_onboarding/test_flow_provider_verify.py -> 96 passed
  • npm --prefix opensquilla-webui run test:unit -- src/composables/setup/useSetupCatalog.privacy.test.ts -> 175 passed
  • focused uv run ruff check -> passed
  • git diff --check upstream/main...HEAD -> passed

No new comments/reviews or unresolved review threads.

@lifelmy

lifelmy commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Refreshed this branch onto latest upstream/main (1663b1a); new head is e3c1716. The one-commit base update merged without conflicts, preserving the onboarding Test connection behavior. Verification: backend onboarding suite 72 passed; WebUI privacy Vitest suite 175 passed; focused Ruff and git diff --check passed.

@lifelmy

lifelmy commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Task A refresh: merged latest upstream/main (846bbc6b) without conflicts; new head is d7a086ae8. The model-id-free Test connection behavior remains covered. Verification: full onboarding tests passed (984 passed, 4 skipped; one existing deprecation warning), focused Ruff passed, WebUI privacy Vitest passed (175 tests), and git diff --check upstream/main...HEAD passed.

@lifelmy

lifelmy commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Task A refresh: merged latest upstream/main (085bfed00d) without conflicts; new head is 7416f76f13. The upstream change consolidates settings and durable turn admission, and the model-id-free Test connection behavior remains intact. Verification: backend onboarding/provider verification tests passed (96), focused Ruff passed, WebUI privacy Vitest passed (175), and git diff --check upstream/main...HEAD passed.

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.

[Feature]: 设置-模型服务"测试连接"支持不填 Model ID 即可验证连通性

1 participant