Skip to content

refactor(ai): extract connection-diagnostics and local-model-discovery - #761

Merged
qnbs merged 1 commit into
mainfrom
refactor/ai-discovery-extraction-20260915
Sep 15, 2026
Merged

qnbs merged 1 commit into
mainfrom
refactor/ai-discovery-extraction-20260915

Conversation

@qnbs

@qnbs qnbs commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

User description

Summary

Continues the Strangler-pattern decomposition of services/aiProviderService.ts that PR #759 started for providers/lifecycle/contracts, this time for the discovery layer: testAIConnection and local-model discovery/scanning.

Scope

Behavior-preserving extraction, reconstructed fresh against current main (not the stale #747 reference branch, which predates #759 and would have silently dropped several QNBS-v3/ADR comments added since):

  • services/ai/discovery/connectionTests.ts: testAIConnection (all seven provider branches unchanged) plus its TestConnectionResult/TestConnectionErrorKind types.
  • services/ai/discovery/localModelDiscovery.ts: listOllamaModels, listLocalBackendModels, testOpenAiCompatibleLocalConnection, scanLocalOpenAiCompatibleEndpoints, and the LocalServerDiagnostic/LocalEndpointScanResult/LocalEndpointScanState types, plus the localServerFailure/localServerTransport helpers.
  • aiProviderService.ts re-exports both modules' public surface unchanged, so every existing import site (Settings AI provider cards, WebLLM panel, ProForge orchestration, etc.) keeps working without a source-level change.

Explicitly out of scope for this slice (per current owner map): #713, #714, #729, #731, #732, provider/model routing policy, any new discovery semantics, and #743 qualification work. The orchestration/ layer (generateText, streamText, generateImage, generateJson, providerDispatch, fallbackState) is a separate, larger residual slice, not touched here.

Relation to PR #747

#747 (refactor(ai): decompose ai provider service) remains frozen/reference-only per this repo's convention and is not merged or cherry-picked. This PR reconstructs the still-missing discovery-layer piece of that decomposition fresh from current main.

Test plan

  • Full suite (206 tests) across tests/unit/aiProviderService.test.ts, tests/unit/aiProviderService.fallbackChain.test.ts, tests/unit/settings/WebLlmPanel.test.tsx, tests/unit/settings/AiProviderCard.test.tsx, tests/unit/ollamaService.test.ts — all pass unchanged.
  • Single-checker tsgo typecheck clean.
  • pnpm run ci:prepush PASS.
  • Biome clean.

Summary by Sourcery

Enhancements:

  • Extract AI connection testing and local-model discovery into dedicated discovery modules while preserving their existing behavior and public API.

Summary by cubic

Splits connection diagnostics and local-model discovery out of services/aiProviderService.ts into two new modules. This is a behavior-preserving refactor, so existing functionality and call sites remain unchanged.

  • Moves testAIConnection and its result/error types to services/ai/discovery/connectionTests.ts.
  • Moves local Ollama / OpenAI-compatible model listing, local connection testing, and endpoint scanning to services/ai/discovery/localModelDiscovery.ts.
  • aiProviderService.ts now re-exports the moved functions and types, so no consumer changes are needed.
  • Provider routing, orchestration, and fallback logic stay in services/aiProviderService.ts.

Written for commit d22ad5f. Summary will update on new commits.

Review in cubic


CodeAnt-AI Description

Reorganize AI connection checks and local model discovery without changing how users access them

What Changed

  • AI connection checks and local model discovery now live in dedicated modules while remaining available through the existing service interface
  • Local model checks classify timeouts, unreachable servers, blocked requests, invalid responses, and missing models for clearer settings feedback
  • Local endpoint scanning checks Ollama, LM Studio, and vLLM, including Ollama installations that do not support the OpenAI-compatible endpoint
  • Connection checks continue to support desktop local servers, optional browser Ollama access, cloud providers, WebLLM, ONNX, and Transformers

Impact

✅ Clearer local-server connection errors
✅ Reliable Ollama detection across versions
✅ Existing AI provider settings continue to work

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features
    • Added AI provider connection checks with clearer diagnostics for missing credentials, network failures, unsupported environments, and unavailable capabilities.
    • Added automatic discovery of locally hosted models from Ollama, LM Studio, vLLM, and OpenAI-compatible servers.
    • Added endpoint scanning to identify reachable local servers and report connection status.
    • Expanded support for validating connections across hosted and local AI providers, including browser-based model runtimes.

Continues the Strangler-pattern decomposition of services/aiProviderService.ts
that PR #759 started for providers/lifecycle/contracts, this time for the
discovery layer: testAIConnection and local-model discovery/scanning.

Behavior-preserving extraction, verified against current main (not the stale
#747 reference branch, which predates #759 and would have dropped several
QNBS-v3/ADR comments added since):

- services/ai/discovery/connectionTests.ts: testAIConnection (all seven
  provider branches unchanged) plus its TestConnectionResult/
  TestConnectionErrorKind types. Multi-line historical QNBS-v3/ADR comments
  condensed to one physical line each per this repo's own comment policy —
  git sees every line of a newly-created file as added, so the diff-aware
  historical-debt exemption does not apply to a moved comment the way it
  would to an untouched one.
- services/ai/discovery/localModelDiscovery.ts: listOllamaModels,
  listLocalBackendModels, testOpenAiCompatibleLocalConnection,
  scanLocalOpenAiCompatibleEndpoints, and the LocalServerDiagnostic/
  LocalEndpointScanResult/LocalEndpointScanState types, plus the
  localServerFailure/localServerTransport helpers.
- aiProviderService.ts re-exports both modules' public surface unchanged, so
  every existing import site (Settings AI provider cards, WebLLM panel,
  ProForge orchestration, etc.) keeps working without a source-level change.

Explicitly out of scope for this slice (per current owner map): #713, #714,
#729, #731, #732, provider/model routing policy, any new discovery semantics,
and #743 qualification work. The orchestration/ layer (generateText,
streamText, generateImage, generateJson, providerDispatch, fallbackState) is
a separate, larger residual slice, not touched here.

Test plan: full suite (206 tests) across tests/unit/aiProviderService.test.ts,
tests/unit/aiProviderService.fallbackChain.test.ts,
tests/unit/settings/WebLlmPanel.test.tsx,
tests/unit/settings/AiProviderCard.test.tsx, tests/unit/ollamaService.test.ts
— all pass unchanged. Single-checker typecheck clean. ci:prepush PASS.
@codeant-ai

codeant-ai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR d22ad5f Sep 15, 2026 · 21:34 21:36

@sourcery-ai sourcery-ai Bot 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.

Sorry @qnbs, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 4 hours and 49 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@vercel

vercel Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
worldscript-studio Ready Ready Preview Sep 15, 2026 9:34pm UTC

@codeant-ai

codeant-ai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR continues the Strangler-pattern decomposition by moving connection diagnostics and local-model discovery from aiProviderService.ts into focused discovery modules, while preserving behavior and re-exporting the same public surface for existing callers.

Sequence diagram for local OpenAI-compatible connection diagnostics

sequenceDiagram
    participant Caller as Settings caller
    participant Test as testOpenAiCompatibleLocalConnection
    participant HTTP as localServerFetch
    participant Server as Local model server

    Caller->>Test: testOpenAiCompatibleLocalConnection(baseUrl)
    Test->>Test: normalizeOpenAiCompatibleBaseUrl(baseUrl)
    Test->>HTTP: localServerFetch(/models)
    HTTP->>Server: GET /models
    Server-->>HTTP: Response
    HTTP-->>Test: Response
    alt HTTP error
        Test-->>Caller: TestConnectionResult httpError
    else Invalid or empty model list
        Test-->>Caller: TestConnectionResult invalidResponse or noModels
    else Models available
        Test-->>Caller: TestConnectionResult with LocalServerDiagnostic
    end
Loading

Sequence diagram for local endpoint scanning

sequenceDiagram
    participant Caller as Settings caller
    participant Scan as scanLocalOpenAiCompatibleEndpoints
    participant HTTP as localServerFetch
    participant Ollama as Ollama endpoint
    participant Local as LMStudio or vLLM endpoint

    Caller->>Scan: scanLocalOpenAiCompatibleEndpoints()
    par Scan Ollama
        Scan->>HTTP: localServerFetch(/api/tags)
        HTTP->>Ollama: GET /api/tags
        Ollama-->>HTTP: Response or failure
        opt Native Ollama request fails without timeout
            Scan->>HTTP: localServerFetch(/v1/models)
            HTTP->>Ollama: GET /v1/models
            Ollama-->>HTTP: Response
        end
    and Scan LMStudio and vLLM
        Scan->>HTTP: localServerFetch(/v1/models)
        HTTP->>Local: GET /v1/models
        Local-->>HTTP: Response or failure
    end
    Scan-->>Caller: LocalEndpointScanResult[]
Loading

Sequence diagram for provider connection testing

sequenceDiagram
    participant Caller as Settings caller
    participant Test as testAIConnection
    participant KeyStore as storageService
    participant Provider as Provider endpoint

    Caller->>Test: testAIConnection(provider, opts)
    Test->>KeyStore: getApiKey(provider)
    KeyStore-->>Test: API key or missing key
    alt API key missing
        Test-->>Caller: TestConnectionResult noApiKey
    else Provider request
        Test->>Provider: Connection request
        Provider-->>Test: HTTP response
        alt Request succeeds
            Test-->>Caller: TestConnectionResult ok
        else Request fails
            Test-->>Caller: TestConnectionResult httpError or unexpected
        end
    end
Loading

File-Level Changes

Change Details Files
Extract connection testing into a dedicated discovery module while preserving provider behavior and the existing public API.
  • Moved all seven provider connection-test branches and their result/error classification types.
  • Retained provider-specific API-key checks, endpoint policies, timeouts, desktop/browser routing, proxy handling, and diagnostic logging.
  • Imported shared local OpenAI-compatible testing from the local discovery module.
services/ai/discovery/connectionTests.ts
Extract local model enumeration and local endpoint diagnostics into a dedicated discovery module.
  • Moved Ollama and OpenAI-compatible model listing, connection testing, failure classification, and endpoint scanning.
  • Preserved endpoint normalization, Tauri transport selection, timeout handling, response validation, model extraction, and scan-state classification.
  • Kept Ollama native endpoint probing with OpenAI-compatible fallback.
services/ai/discovery/localModelDiscovery.ts
Turn the provider service into a compatibility facade for the extracted discovery APIs.
  • Removed discovery implementations and their now-unused imports from the service.
  • Re-exported all discovery functions and public result/diagnostic types so existing consumers remain source-compatible.
  • Left orchestration, routing, lifecycle, provider implementations, and fallback behavior untouched.
services/aiProviderService.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Sep 15, 2026
@codeant-ai

codeant-ai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: d22ad5f0
Scan Time: 2026-09-15 22:06:06 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 3.3% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@codescene-access codescene-access Bot 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.

Code Health Improved (1 files improve in Code Health)

Gates Failed
New code is healthy (2 new files with code health below 10.00)

Our agent can fix these. Install it.

Gates Passed
2 Quality Gates Passed

Reason for failure
New code is healthy Violations Code Health Impact
connectionTests.ts 2 rules 8.76 Suppress
localModelDiscovery.ts 1 rule 9.31 Suppress

See analysis details in CodeScene

View Improvements
File Code Health Impact Categories Improved
aiProviderService.ts 6.07 → 7.37 Complex Method, Complex Conditional, Overall Code Complexity

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

Comment thread services/ai/discovery/connectionTests.ts
Comment thread services/ai/discovery/connectionTests.ts
Comment thread services/ai/discovery/localModelDiscovery.ts
Comment thread services/ai/discovery/localModelDiscovery.ts
@github-actions

Copy link
Copy Markdown

[check-pr-size] PR size is over the target tier (normal profile): 3 files, 849 meaningful lines, 1 commits — limit ≤8 files / ≤400 lines / ≤6 commits. Consider splitting into smaller, independently reviewable PRs.

@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: defaults

Review profile: CHILL

Plan: Essentials

Run ID: 5c42f3c2-bba1-442e-9f87-60b981935152

📥 Commits

Reviewing files that changed from the base of the PR and between 76442df and d22ad5f.

📒 Files selected for processing (3)
  • services/ai/discovery/connectionTests.ts
  • services/ai/discovery/localModelDiscovery.ts
  • services/aiProviderService.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

Added dedicated modules for AI provider connection testing and local-model discovery. The AI provider service now re-exports these APIs and removes their previous in-file implementations.

Changes

AI discovery APIs

Layer / File(s) Summary
Provider connection testing
services/ai/discovery/connectionTests.ts
Defines typed connection results and tests OpenAI-compatible APIs, Ollama, Anthropic, Grok, Gemini, WebLLM, ONNX, and Transformers.js with classified failures and bounded requests.
Local endpoint discovery
services/ai/discovery/localModelDiscovery.ts
Adds local-server diagnostics, OpenAI-compatible model loading, and parallel scans for Ollama, LM Studio, and vLLM.
AI provider service integration
services/aiProviderService.ts
Removes the previous in-file implementations and re-exports the dedicated discovery APIs. It also adds streamOllama to the service exports.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant testAIConnection
  participant RuntimeChecks
  participant ProviderEndpoint
  testAIConnection->>RuntimeChecks: validate provider key and runtime
  testAIConnection->>ProviderEndpoint: send bounded connectivity request
  ProviderEndpoint-->>testAIConnection: return response or classified failure
  testAIConnection-->>RuntimeChecks: return TestConnectionResult
Loading

Merge Risk: ⚪ Minimal · up to d22ad

No verified merge-blocking behavior remains in the extracted discovery modules or their re-exports.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: extracting AI connection diagnostics and local model discovery into dedicated modules.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • 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/ai-discovery-extraction-20260915

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

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread services/ai/discovery/connectionTests.ts
Comment thread services/ai/discovery/connectionTests.ts
Comment thread services/ai/discovery/localModelDiscovery.ts
Comment thread services/ai/discovery/localModelDiscovery.ts
@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.78788% with 21 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
services/ai/discovery/localModelDiscovery.ts 65.30% 12 Missing and 5 partials ⚠️
services/ai/discovery/connectionTests.ts 92.00% 1 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@qnbs
qnbs merged commit 4137286 into main Sep 15, 2026
46 of 47 checks passed
@qnbs
qnbs deleted the refactor/ai-discovery-extraction-20260915 branch September 15, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant