Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions docs/pr/provider-model-check-pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Add provider model-check support

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.

Remove this file. (docs/pr/* change is useless)


## Summary

This PR adds a lightweight **model check** workflow to the Add/Edit Provider UI so users can verify whether a provider endpoint, API key, and model ID are actually usable **before saving**.

## Why

Today, adding or editing a provider often requires trial-and-error:

- users may save an invalid model ID
- users may save a bad API key
- users may save an unreachable / misconfigured endpoint
- the actual failure is only discovered later when the provider is used

This change adds an explicit pre-save validation step that performs a real request and reports a clear result.

## What changed

### UI

- Added a **"检测模型" / model-check** action in both:
- Add Provider dialog
- Edit Provider panel
- Added inline feedback text for:
- success
- degraded / slow response
- model not found
- auth failure
- timeout
- unsupported protocol

### Frontend

- Added `src/lib/provider-model-check.ts`
- Wired `ProvidersSettings.tsx` to call the new API and surface results in the UI

### Backend

- Added `/api/provider-model-check`
- Added `electron/services/providers/provider-model-check.ts`
- The backend performs a real streaming request and treats the first returned chunk as proof that the model is usable

### Supported protocol paths

- `openai-completions`
- `openai-responses`
- `anthropic-messages`

## Validation behavior

The check intentionally stays lightweight:

- uses a tiny prompt (`Hi`)
- uses small token limits
- uses streaming mode
- considers the request successful once the first response chunk arrives

This makes the check fast while still proving that:

- the endpoint is reachable
- auth works
- the requested model exists / is accepted

## Verification

Validated locally on a clean upstream-based working tree with only the minimal feature patch applied.

Commands used:

```bash
pnpm run ext:bridge
pnpm exec tsc --noEmit
pnpm exec vite build
```

All passed successfully.

## Screenshot

A local verification screenshot is included in this branch:

- `docs/pr/provider-model-check-test.png`

It shows the provider settings UI with the model-check entry point and successful validation state used during testing.

## Scope / non-goals

This PR intentionally avoids unrelated customization:

- no branding changes
- no provider list policy changes
- no advanced-settings refactor
- no packaging / release pipeline changes

The goal is to keep this patch reviewable and upstream-friendly.
Binary file added docs/pr/provider-model-check-test.png

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.

ditto

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions electron/api/routes/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { validateApiKeyWithProvider } from '../../services/providers/provider-validation';
import { getProviderService } from '../../services/providers/provider-service';
import { providerAccountToConfig } from '../../services/providers/provider-store';
import { checkProviderModel, type ModelCheckInput } from '../../services/providers/provider-model-check';
import type { ProviderAccount } from '../../shared/providers/types';
import { logger } from '../../utils/logger';

Expand Down Expand Up @@ -50,6 +51,21 @@ export async function handleProviderRoutes(
);
};

if (url.pathname === '/api/provider-model-check' && req.method === 'POST') {
try {
const body = await parseJsonBody<ModelCheckInput>(req);
sendJson(res, 200, await checkProviderModel(body));
} catch (error) {
sendJson(res, 500, {
success: false,
status: 'failed',
message: String(error),
modelUsed: '',
});
}
return true;
}

if (url.pathname === '/api/provider-vendors' && req.method === 'GET') {
sendJson(res, 200, await providerService.listVendors());
return true;
Expand Down
Loading
Loading