Skip to content

fix: make custom providers usable end-to-end in the Web UI - #312

Open
xieqian0816 wants to merge 1 commit into
yc-software:mainfrom
xieqian0816:codex/fix-custom-provider-web-flow
Open

fix: make custom providers usable end-to-end in the Web UI#312
xieqian0816 wants to merge 1 commit into
yc-software:mainfrom
xieqian0816:codex/fix-custom-provider-web-flow

Conversation

@xieqian0816

@xieqian0816 xieqian0816 commented Aug 10, 2026

Copy link
Copy Markdown

Summary

This makes an admin-registered custom model provider usable across the complete production Web flow: save it, pass readiness checks, expose its model in the picker, and run Web turns without requiring a second, explicit allowlist configuration.

Closes #236
Closes #282

This also fixes the custom-provider instance of the readiness symptom described in #290. It does not close #290's broader Claude/Codex subscription-harness case, and it intentionally does not address the separate boot-time PI_MODEL hydration race in #269.

Root cause and fix

Broken boundary Root cause Fix
Production Admin routes src/index.ts did not pass customProviders or refreshCustomProviders into createServer Wire both dependencies and add an entrypoint regression assertion
Portal/Admin readiness Readiness only considered built-in credential availability Include enabled, keyed custom-provider status without exposing credentials
Web turn validation With no explicit picker allowlist and no OpenRouter key, validation fell back to built-in model IDs Derive the default allowed set from the built-in + custom catalog while preserving explicit allowlists
Web model picker Runtime config only supplied name and provider, so arbitrary custom models could not be materialized Add protocol and token-window metadata, then construct a model from the correct protocol template
Admin refresh Onboarding did not load the custom-provider table on entry and could retain stale readiness after a save/remove Load the table with onboarding and refresh readiness after both mutations

The implementation stays generic for both supported custom-provider protocols (openai-completions and anthropic-messages); it does not special-case DeepSeek.

Security and compatibility

  • API keys remain encrypted, write-only, and absent from every response, runtime payload, screenshot, and fixture.
  • Runtime metadata adds only api, contextWindow, and maxTokens; the provider base URL and key are not sent to the browser.
  • Catalog fields are additive and optional, preserving existing built-in and OpenRouter clients.
  • An explicit Web UI allowlist remains restrictive. The broader catalog is used only when no allowlist is configured.
  • Custom-provider readiness requires an enabled provider with an actual stored key.

Automated verification

  • Focused core/Web/Admin/custom-provider/security tests: 63 passed, 0 failed.
  • Full root suite passed once: 3,818 tests, 0 failed, 135 skipped.
  • A post-review repeat hit one unrelated OpenCode zero-second startup-output timing assertion; test/opencode-harness.test.ts passed immediately in isolation: 10/10. No OpenCode code was changed.
  • npm run format:check
  • npm run typecheck
  • npm run lint
  • npm run lint:ox
  • CLI package build + npm run typecheck:contract
  • Deployment contract test: 1 passed.
  • Independent fresh-context review: no blocking findings. Its one P2 finding (stale readiness after custom-provider mutations) was fixed and covered before this commit.

Live production-style verification

I reloaded this branch with the repository's dev supervisor and tested through Chrome against a saved DeepSeek OpenAI-compatible provider.

  • Portal / returned the Web app instead of redirecting to onboarding.
  • Admin reported Ready, showed deepseek-v4-flash · custom provider key, and listed the stored key only as set (write-only).
  • The picker displayed DeepSeek V4 Flash under Pi without an explicit Web model allowlist.
  • Text turn returned exactly DS_PR_TEXT_OK_20260810.
  • Tool turn called execute with pwd; Admin recorded exit 0, the next DeepSeek request contained tool result /root/workspace, and the model returned DS_PR_TOOL_OK.
  • Evidence session: 4de03b0b-6ec4-426d-aa72-8fd066cf9246.

Admin reports the custom provider as ready

DeepSeek completes text and tool turns in the Web UI

Contribution note

I understand CONTRIBUTING.md normally asks bug reporters to open issues rather than implementation PRs. Both bugs already have focused issues, and this patch is intentionally narrow, independently reviewed, and implementation-ready so maintainers can review, merge, or cherry-pick it directly. I am happy to adapt it to the maintainers' preferred shape.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

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

Labels

None yet

Projects

None yet

1 participant