feat(pi): fetch and refresh upstream model lists, searchable model picker
- POST /pi/upstreams/{id}/models/refresh calls the provider's model list
endpoint (OpenAI-shaped /models, Anthropic /v1/models, Google
/v1beta/models, OpenRouter /api/v1/models; Radius via pi-ai refresh),
normalizes {id, displayName, contextWindow, supportsVision,
supportsTools, pricing} and stores it in pi_upstream.models (0044)
- GET .../models returns {source, fetchedAt, models[]}: remote merged
with the static catalog (remote first); failures (401/network/
unsupported) fall back to static with a one-line error
- POST /pi/models/probe for trying credentials before creating
- wizard and edit drawer: fetch button, searchable dropdown with
vision/tool tags, manual id, source line; default upstream needs a model
- tests: mock /models, 401, network failure; smoke step; runbook
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
e5abfa6217
commit
0765264a47
16 files changed
+1178
-52
No files matched your search
@@ -164,8 +164,8 @@ describe.skipIf(!hasPg)("Pi 上游(真实 PG)", () => {
|
||||
expect(tb).toMatchObject({ ok: true, mode: "auth", upstream: { status: "error", lastVerifiedAt: null } });
|
||||
expect(tb.message).toMatch(/最小补全/);
|
||||
const models = (await req("GET", `/pi/upstreams/${a.id}/models`)).body.data;
|
||||
expect(models.items.length).toBeGreaterThan(10);
|
||||
expect(models.refreshed).toBe(false);
|
||||
expect(models.models.length).toBeGreaterThan(10);
|
||||
expect(models).toMatchObject({ source: "static", fetchedAt: null, remoteSupported: true });
|
||||
|
||||
// 删除默认上游 → 默认清空,secret 一并删除
|
||||
const secretRef = (
|
||||
|
||||
Reference in new issue
Block a user