Skip to content

feat(desktop): preview and normalize custom OpenAI request URLs - #5693

Open
liuxiaocs7 wants to merge 8 commits into
apache:mainfrom
liuxiaocs7:feat/live-model-request-url-preview
Open

liuxiaocs7 wants to merge 8 commits into
apache:mainfrom
liuxiaocs7:feat/live-model-request-url-preview

Conversation

@liuxiaocs7

@liuxiaocs7 liuxiaocs7 commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

Summary

A custom OpenAI relay configured with a full endpoint can send requests to /chat/completions/chat/completions or discover models under /responses/models. The service URL field now previews the final request address as the user types, in both connection creation and editing.

Chat and Responses previews, connection probes, SDK requests, and model discovery share endpoint normalization. Full endpoint inputs avoid duplicate suffixes; custom prefixes are preserved without assuming /v1. Empty or invalid drafts hide the preview, and long addresses wrap with an accessible description on the input.

Fixes #5692

Verification

  • npm run build, npm run typecheck, and npm run lint: passed.
  • Biome formatting: all tracked files passed. The checkout-wide command also finds unrelated untracked local research files, which are not part of this PR.
  • Desktop suite: 2,834 passed (NODE_OPTIONS=--disable-warning=ExperimentalWarning npm --workspace @maka/desktop run test:dist).
  • Runtime thinking options, endpoint, Responses wire, and model discovery suites: 81 passed. Vercel wire assertions cover each advertised effort without freezing the snapshot catalog list. The added regressions exercise actual probe, SDK generation, and discovery paths and fail on the original duplicated URLs.
  • Regenerated Astryx surface inventory: coverage check and 19 generator tests passed.
  • Renderer architecture check and npx knip --workspace apps/desktop / npx knip --workspace packages/ui: passed.
  • Browser verification: live updates in add/edit forms, both protocols, clearing and incomplete input, full endpoint deduplication, narrow-window wrapping, and accessible input descriptions.

The full-workspace suite was also run. Local failures remain outside this change: the Runtime Host implementation-child test also times out with the baseline Runtime sources, and the Eval Python tests are incompatible with the system Python 3.9. The other process/timing failures passed on isolated serial reruns.

The screenshots use the actual upstream and PR forms with an example relay address:

Before After
Service URL editor before this change Service URL editor with a live request URL preview

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Codex assisted with implementation, regression tests, browser verification, and issue/PR drafting. The implementation and follow-up commits include Generated-by: Codex.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 24, 2026
Show the final Chat or Responses request URL as custom relay addresses are
edited in both connection forms. Hide incomplete drafts and preserve custom
prefixes, with wrapping and accessible descriptions for the live preview.

Share endpoint normalization between the preview, connection probes, SDK
requests and model discovery. Full endpoint inputs previously duplicated
/chat/completions or incorrectly appended /models beneath the endpoint.

Generated-by: Codex
Register the new provider endpoint field in both generated inventories so the CI coverage gate matches the renderer tree.

Generated-by: Codex
The refreshed models.dev snapshot adds minimal and xhigh for the exact Vercel model. Verify the namespace and wire value of every advertised effort instead of freezing its full catalog list, retaining explicit high, off and exact-model-ID assertions.

Generated-by: Codex
@liuxiaocs7
liuxiaocs7 force-pushed the feat/live-model-request-url-preview branch from 88fee82 to 8d65721 Compare September 24, 2026 09:58
Merge the latest main and adapt request URL previews and model discovery to custom connections with per-model protocols. Preserve endpoint normalization across Chat and Responses and the Vercel reasoning assertions.

Generated-by: Codex
Regenerate the Astryx surface inventory after merging main, preserving the request URL preview field alongside the new upstream surfaces.

Generated-by: Codex

@Astro-Han Astro-Han left a comment

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.

Adversarial pass at 0ea5494d5; verified SDK URL composition against the installed @ai-sdk/openai/openai-compatible versions and exercised openAiBaseUrl across the input-shape matrix.

The core fix is correct: openAiBaseUrl is the single suffix-stripping authority (the while loop even peels already-duplicated …/chat/completions/chat/completions), custom prefixes are preserved without assuming /v1, the codec rejects query/fragment/userinfo/non-http(s) before normalization so the preview is byte-identical to the wire request, invalid drafts hide it, and probes/SDK send/discovery all funnel through it. No P0/P1.

One P2 inline — model discovery still strips endpoint suffixes only for providerType === 'custom', while send and probe now strip for every OpenAI wire. A non-custom provider that allows endpoint override (OpenRouter, DeepSeek, etc.) with a saved full-endpoint baseUrl now probes and chats correctly but discovers models at …/chat/completions/models — a new inconsistent state (pre-PR it failed uniformly). Strip whenever the resolved adapter kind is openai/openai-compatible instead of keying on providerType.

P3s, all deferrable: openai-compatible adapters with normalizeBaseUrl bypass the strip and can produce …/chat/completions/v1/chat/completions (kimi-coding-plan only — compose the two normalizers); redactSecrets can make the preview differ from the request for token-shaped path segments (safe direction, worth a comment); duplicate preview render in the legacy-credential edit edge; a decorative ternary in discovery where both branches call openAiBaseUrl; the anthropic-messages wire has the same bug class with no preview (issue-scoped, worth noting); and the inherent ambiguity — a gateway legitimately mounted at /chat/completions gets stripped — deserves one line in the openai-urls.ts comment.

Comment thread packages/runtime/src/model-fetcher.ts Outdated
Merge main while retaining coverage for every known Vercel reasoning level and allowing additional advertised levels. Regenerate the Astryx inventory for the merged renderer tree.

Generated-by: Codex
Normalize model discovery in the resolved OpenAI adapter branch and compose Kimi Chat endpoint stripping with version-prefix normalization. Preserve one visible endpoint preview for legacy credential edits and document display redaction and endpoint-path ambiguity.

Cover non-custom providers, Kimi probe and SDK URLs, and accessible legacy endpoint previews with regressions that fail before the fix.

Generated-by: Codex
Regenerate the Astryx inventory for the merged renderer tree, re-pin compatible protocol declarations to epoch 189, and retain the request URL preview and reviewer fixes.

Generated-by: Codex
@github-actions github-actions Bot added effort/L Under 1000 readable lines and removed effort/M Under 500 readable lines labels Sep 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(desktop): custom OpenAI relay URLs can duplicate endpoint paths

2 participants