Repository navigation
Conversation
|
Hi, a gentle ping on this one when you have time. Status as of today:
This builds on #220/#223. It adds one shared invoke-contract resolver for test-active, test-provider and generate, and the If the size (~1.5k lines incl. tests) is a blocker, I can split it into:
It overlaps with #422 in |
Declare modelDiscoveryMode on provider capabilities so listing, Settings pickers, imports, and diagnostics stop treating GET /models as universal. Fixes OpenCoworkAI#210
Codex imports no longer stamp every provider infer-only. Official hosts that expose GET /models keep listing; custom and proxy hosts stay infer-only, matching the Claude Code host split. Settings connection failures now render ConnectionDiagnosticPanel with the row's modelDiscoveryMode so a /models 404 follows the declared mode.
Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com>
Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com>
Preserve modelDiscoveryMode semantics while taking OpenCoworkAI#508 ChatGPT Codex catalog suggestions (getCodexModelOptions) and the Codex model picker UI. ChatGPT Codex stays static-hint but still loads listForProvider for the maintained catalog. Custom openai-codex-responses providers keep the resolveListForProviderPlan static-hint path.
When Edit re-runs a best-effort /models probe after a non-endpoint toggle (TLS/keyless/private-network) and the probe fails, do not persist infer-only over an existing models discovery mode. Explicit manual choice and real baseUrl/wire changes still update the mode.
a0efc9d to
0e8c282
Compare
|
Rebased onto the updated #422 head (2cdaa41) rather than bare main, so this PR carries the formalized Conflict resolution
Head is |
There was a problem hiding this comment.
Findings
-
[Blocker]
apps/desktop/src/main/connection-ipc.tscontains several corrupted/unterminated string literals inclassifyHttpErrorandclassifyNetworkError— the added lines drop closing quotes/backticks and the${message}interpolation, which is a syntax break, not just mojibake. New lines in the diff includehint: 'API key ??????????? };(no closing'),hint: 'baseUrl ????????penAI ?????????????/v1 ????????https://your-host/v1??,(no closing'),hint: \????????${CONNECTION_FETCH_TIMEOUT_MS / 1000}s???????baseUrl ??????????,(no closing backtick), andhint: `????????{message}...(interpolation lost). BecauseclassifyHttpError/classifyNetworkErrorfeedinvokeFailureFields, this module won't parse, sopnpm typecheck,pnpm build, and every connection-ipc test fail. The surrounding i18n JSON in the same PR renders UTF‑8 correctly, so this is file-level encoding corruption inconnection-ipc.ts, not a display artifact. Suggested fix / next action: re-saveapps/desktop/src/main/connection-ipc.ts` as UTF‑8 and restore the original literals, e.g.if (status === 401 || status === 403) { return { code: '401', hint: 'API key 错误或权限不足' }; } if (status === 404) { return { code: '404', hint: 'baseUrl 路径错误。OpenAI 兼容代理通常需要 /v1 后缀(试试 https://your-host/v1)' }; } // network: hint: `请求超时(>${CONNECTION_FETCH_TIMEOUT_MS / 1000}s),检查 baseUrl 与网络可达性`, hint: `网络错误:${message}。查看日志:~/Library/Logs/open-codesign/main.log`,
Also restore the mangled
//comments (the??sequences) while you're in the file. -
[Major]
modelsProbeRelationForProviderinpackages/shared/src/base-url.tsnarrowsmodelDiscoveryModeto'models' | 'static-hint' | 'manual' | undefined, but the new value'infer-only'was added toProviderModelDiscoveryMode.buildEffectiveProviderContractinapps/desktop/src/main/effective-provider-contract.tspassesresolved.modelDiscoveryMode(the fullProviderModelDiscoveryModeunion), so this is aTS2345/TS2322assignability error andpnpm typecheckfails. Semanticallyinfer-onlyis already caught viasupportsModelsEndpoint === false, so only the type is wrong.
Suggested fix / next action: widen the param to accept all four modes (or reuseProviderModelDiscoveryMode) and, for clarity, add an explicitif (caps?.modelDiscoveryMode === 'infer-only') return 'unavailable';. -
[Minor] The connection test now always fires a real inference
POST(probeInferenceEndpoint) even whenGET /modelssucceeds, on every "Test connection" click. For per-token / rate-limited providers this is a billable, throttled request that previously only ran in the degrade path. Also, a404from the invoke probe (e.g. the configured model id does not exist) is reported asINVOKE_DIVERGED/ "reachable but generate would fail", which steers users toward switching wire when the actual fix is the model id;probeInferenceEndpointtreats only404and5xxas failures.apps/desktop/src/main/connection-ipc.tsprobeInferenceEndpoint/classifyInvokeAndModelsProbes.
Suggested fix / next action: confirm the extra billing/rate-limit cost is acceptable (or gate it), and distinguish a model-not-found 4xx from a genuine contract divergence so the toast/hint points at the model id instead of the wire. -
[Minor] Production
connection:v1:test-active/test-providerhandlers calltestInvokeContractdirectly (handleConnectionV1TestActive/handleConnectionV1TestProvider), while the new behavioral tests all driverunProviderTest. The two paths must stay in lockstep (e.g. LiteLLM hint application), and the actual IPC wiring isn't directly exercised.apps/desktop/src/main/connection-ipc.ts.
Suggested fix / next action: either route the handlers throughrunProviderTestor add a test that callshandleConnectionV1TestActive/handleConnectionV1TestProviderso the shipped path is covered; verifyrunProviderTestis still referenced from production code.
Questions
- Was the mojibake in
connection-ipc.tsintroduced by an editor/tool round-trip on non-UTF‑8? If so, please confirm the file is clean (abiome check/ throwawaytscon the file) before re-requesting review.
Summary
Review mode: initial
The design (single resolveEffectiveInvokeContract, /models treated as optional discovery, invoke-parity classification, discovery modes) is directionally sound and well covered by unit tests, and the changesets are present. However, the PR as pushed cannot build: connection-ipc.ts has syntax-breaking corrupted literals (Blocker), and the modelsProbeRelationForProvider signature rejection of infer-only will fail pnpm typecheck (Major). The remaining two items are verification/UX nits. The PR closes #216 (a slice of epic #214); the diff does touch the expected connection-test paths, so the Fixes #216 claim looks consistent — but it should not merge until the build-break issues are fixed and CI is green.
Testing
Not run (automation). The added Vitest coverage is broad (active snap vs named provider, Codex OAuth path, keyless, INVOKE_DIVERGED, degraded discovery), but it will not execute until the connection-ipc.ts syntax errors and the base-url.ts type error are fixed.
Open-CoDesign Bot
Typecheck failed after merging discovery modes onto main: the ChatGPT Codex RowModelSelector fixture omitted the required ProviderRow field.
Make connection:v1:test-active and test-provider share active-provider resolution, auth/headers, canonical baseUrl, wire, and keyless/OAuth rules with generate. Probe the real inference endpoint and treat GET /models as optional discovery, with structured diverges results when the host is reachable but invoke would fail. Fixes OpenCoworkAI#216 Signed-off-by: Xuanrui Li <xuanrui.li@se24.qmul.ac.uk>
0e8c282 to
ff72336
Compare
There was a problem hiding this comment.
Findings
-
[Blocker]
apps/desktop/src/main/connection-ipc.tsis still syntactically broken by the same UTF-8 corruption flagged in the prior review. The added lines includehint: 'API key ??????????? };(no closing quote,:314),hint: 'baseUrl ... ??,(no closing quote,:318), andhint: `????????${CONNECTION_FETCH_TIMEOUT_MS / 1000}s???????baseUrl ??????????,(no closing backtick,:339). The same hunk also truncatesTestEndpointResponseto| { ok: false;(:1409) and drops the${message}interpolation inclassifyNetworkError(:352). This makes the module fail to parse, sopnpm typecheck,pnpm build, and the connection-ipc tests cannot pass.
Suggested fix / next action: restoreapps/desktop/src/main/connection-ipc.tsfrom a clean UTF-8 source, fix theTestEndpointResponseunion to| { ok: false; error: string; message: string; hintKey?: string }, and runpnpm lint && pnpm typecheckbefore re-requesting review. -
[Major]
modelsProbeRelationForProviderstill excludes the newinfer-onlyvalue from its parameter type.packages/shared/src/base-url.ts:180acceptsmodelDiscoveryMode?: 'models' | 'static-hint' | 'manual' | undefined, butapps/desktop/src/main/effective-provider-contract.ts:83passesresolved.modelDiscoveryModetyped as the fullProviderModelDiscoveryModeunion. This is a TS2345 assignability error.
Suggested fix / next action: type the parameter withProviderModelDiscoveryMode(or add'infer-only') and add an explicitif (caps?.modelDiscoveryMode === 'infer-only') return 'unavailable';branch. -
[Major]
'INVOKE_DIVERGED'is added to the connection-test error union but not toErrorCodeinpackages/shared/src/diagnostics.ts:3.ProviderCardassignsres.codeinto a state typedErrorCodeatapps/desktop/src/renderer/src/components/settings/primitives.tsx:408, and the new test callsdiagnose('INVOKE_DIVERGED', baseCtx)atpackages/shared/src/diagnostics.test.ts:150. Both fail typecheck because the literal is not assignable toErrorCode.
Suggested fix / next action: add'INVOKE_DIVERGED'to theErrorCodeunion and keep thediagnosebranch/test aligned. -
[Minor]
connectionErrorFromUnknownpicks the ChatGPT-login hint by substring matching'chatgpt'or'codex'in any error message (apps/desktop/src/main/effective-provider-contract.ts:150-158). A regular provider such ascodex-deepseekwith a missing API key will therefore show the ChatGPT subscription hint instead of the API-key/import hint.
Suggested fix / next action: branch onERROR_CODES.CODEX_TOKEN_NOT_LOGGED_IN(orisCodexOAuthProvider(providerId, wire)) rather than message text.
Questions
- Was
connection-ipc.tsround-tripped through a non-UTF-8 editor/tool? If so, can you re-save the original file and confirmpnpm typechecklocally before the next CI run?
Summary
Review mode: follow-up after new commits. The previous Blocker (corrupted connection-ipc.ts literals) and Major (modelsProbeRelationForProvider type) remain unresolved, and the new ErrorCode mismatch is another typecheck blocker. The design is directionally sound and the added tests cover the intended parity cases, but the PR cannot build in its current state. I could not independently re-fetch linked issue #216 in this run; the diff still targets the connection-test/invoke-contract paths.
Testing
Not run (automation). The added Vitest coverage is broad, but it cannot execute until the parse and type errors above are fixed. Re-run pnpm lint && pnpm typecheck && pnpm test and include the result in the next update.
Open-CoDesign Bot
## Summary Make provider model discovery modes drive model listing, Settings pickers, imports, connection tests and diagnostic wording consistently. | Mode | Model selection | Connection test | | --- | --- | --- | | models | Remote listing | Probe listing, with inference fallback | | static-hint | Local catalog and configured default | Skip listing; preserve Codex OAuth token validation | | manual | Typed model ID | Skip listing and probe inference | | infer-only | Typed model ID | Treat missing listing as expected and probe inference | Existing configurations derive a mode when the optional field is absent; schemaVersion is unchanged. Built-in and imported providers get appropriate defaults. Explicitly rediscovering models or switching an edited provider back to the list now persists models mode; untouched edits and users who keep manual selection preserve their intent. Fixes #210 ## Validation - Added component regressions for manual/infer-only → model-list persistence, successful discovery, retained manual choice and untouched edits. - Shared/provider, listing, import, diagnostics and desktop regression suites passed. - Node 22 lint, full typecheck and build passed; local broad tests excluded real browser/Electron cases. - Full GitHub CI (lint, typecheck, all tests and build smoke) passed on ba7eb5f. - #519 supplies the follow-up actual-request-URL diagnostic plumbing. #421 is separate and is not included. --------- Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Lxr-max <344759596@qq.com>
…#519) ## Summary Carry the actual URL requested by a failed connection test into diagnostics, covering both model listing and inference probes. Settings prefers the returned attemptedUrl and retains the older listing-URL fallback for compatibility. For manual and infer-only providers, an inference 404 is reported as an endpoint error; the soft models-listing explanation is reserved for an actual listing request. These modes no longer receive an incorrect missing-/v1 suggestion. Follow-up to merged #422. Refs #210. The completed #422 implementation and #516 CLI timeout fix are already in main and are not additional changes in this PR. #421 is not included. ## Validation - Added ProviderCard interaction regressions for actual URL precedence, non-listing 404 wording, legacy-response fallback and listing diagnostics. - Added responses/Anthropic and network-error attempted-URL regressions alongside shared diagnostics tests. - Node 22 focused tests, workspace tests excluding local real-browser suites, script tests, lint, full typecheck and build passed. - Full GitHub CI is required before merge. --------- Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Lxr-max <344759596@qq.com> Co-authored-by: Li XuanRui <181566610+Lxr-max@users.noreply.github.com> Co-authored-by: Lxr-max <Lxr-max@users.noreply.github.com>
Summary
Connection tests (
connection:v1:test-active/connection:v1:test-provider) now validate the same effective provider contract thatgenerateuses, instead of treating aGET /models200 as Connection OK.Fixes #216 (slice of epic #214). Does not implement sibling #213.
Shared contract
resolveEffectiveInvokeContract()inapps/desktop/src/main/effective-provider-contract.tsis the single resolver for:resolveActiveModel()snap-to-config as generate (stale rendererprovideris ignored whencfg.activeProvideris set)resolveProviderModel) with no snap to the active slotresolveCredentialForProvider()— ChatGPT Codex usesgetValidAccessToken(), other providers share the same API-key / env / keyless rules as generateAuthorization: Bearervsx-api-keyfromauthHeaderNameForProvider()baseUrl:canonicalInvokeBaseUrl()(trailing slash +/v1for OpenAI-compatible wires)invokeUrlForWire()— Codex Responses vs Anthropic messages vs OpenAI chat completionsallowKeylessis trueGenerate and memory IPC now pass that canonical baseUrl into
complete(), andcomplete()canonicalizes once more so runtime cannot silently diverge./modelsvs real wiremodelsProbeRelationForWire()inpackages/shared:GET /modelsis not the generate contract. Generate never calls it. A 200 on/modelsis not Connection OK./modelsprobe; OAuth token resolution is the test.Probe both discovery and inference when discovery is optional:
/modelsok: true,compatibility: 'degraded',invokeParity: 'degraded-discovery'ok: false,compatibility: 'diverges',code: 'INVOKE_DIVERGED'ok: true,compatibility: 'compatible'ok: falsewith invoke errorRenderer toasts distinguish success / degraded discovery / reachable but diverges from real invoke / hard failure.
Tests
tokenStore.read()/chat/completions, not/responses/models200 + invoke 404 → diverges (test must not pass when runtime would fail)/models404 + invoke 200 → degraded pass (test must not fail when runtime would succeed)/chat/completionsPrinciples 5b
schemaVersionunchanged; new result fields are optional for older renderersConstraints
fetchagainst the same URLscomplete()uses