Skip to content

Add OpenAI-compatible model provider - #167

Open
ndisidore wants to merge 2 commits into
mainfrom
feat/openai-compatible-provider
Open

Add OpenAI-compatible model provider#167
ndisidore wants to merge 2 commits into
mainfrom
feat/openai-compatible-provider

Conversation

@ndisidore

@ndisidore ndisidore commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Adds beta support for user-configured OpenAI-compatible Chat Completions providers (openai-compatible in config, OpenAI-compatible in the UI).

This first version is intentionally minimal:

  • Direct mode only; it bypasses user unified billing and is unavailable in platform AI Gateway mode.
  • Requires a model ID, bearer token, HTTPS base URL, context window, and output limit.
  • Rejects URL credentials, query strings, fragments, and invalid token limits. Pasted /chat/completions endpoints are normalized automatically.
  • Supports text only. Historical images become omitted-attachment markers.
  • Persists a conservative compatibility profile, using system and max_tokens while disabling optional features generic endpoints may not support. We can look at expanding this in the future

Should unlock the following services:

  • OpenRouter
  • Groq
  • DeepInfra
  • DeepSeek
  • Mistral AI
  • Moonshot AI / Kimi
  • Hugging Face Inference Providers
  • HTTPS-hosted vLLM, LiteLLM, llama.cpp, and similar self-hosted gateways
  • And a bunch more

Screenshots

Screenshot from 2026-08-12 08-56-28 Screenshot from 2026-08-12 09-05-30 Screenshot from 2026-08-12 09-05-44 Screenshot from 2026-08-12 09-06-17 Screenshot from 2026-08-12 09-07-37 Screenshot from 2026-08-12 09-08-27

@github-actions github-actions Bot added workshop/frontend Changes to the Workshop frontend kernel Changes to the Workshop kernel workshop/shared Changes to shared Workshop APIs labels Aug 12, 2026
@ask-bonk

ask-bonk Bot commented Aug 12, 2026

Copy link
Copy Markdown

gatewayNativeModel (line 183) is only reached via getModelViaUserGateway/gateway paths, which openai-compatible never reaches (short-circuited earlier). Its switch has a default returning undefined, so no exhaustiveness problem. Good — the design correctly keeps openai-compatible out of all gateway routing.

I've completed a thorough review. The change is well-structured, well-tested, and consistent with the codebase's capability/routing conventions. I found no actionable defects.

Summary of what I verified:

  • normalizeAiModelConfig validation/normalization is correct and thoroughly unit-tested (URL scheme, credentials, query/fragment, /chat/completions stripping, token-limit bounds, profile whitelist).
  • getModel short-circuits openai-compatible before both platform-gateway and user-gateway (BYOK) routing, matching the stated "direct mode only, bypasses unified billing, unavailable in gateway mode." The getModelDirect/getChatContext/addModel/listModels guards are consistent and defensive.
  • The non-null assertions on contextWindow/outputLimit are safe because every reachable path normalizes/validates first.
  • Attachment handling correctly degrades images/PDFs to text markers for the text-only profile, with the new modelSupportsChatAttachment checking resolved-model capabilities on replay.
  • Model config (with apiToken) is never returned to gadgets; only profile is listed.
  • gatewayNativeModel's switch is unaffected (openai-compatible never reaches it), so no exhaustiveness gap.
  • Frontend validation mirrors the backend, and the raw URL is intentionally normalized server-side.

LGTM!

github run

@ask-bonk

ask-bonk Bot commented Aug 12, 2026

Copy link
Copy Markdown

Confirmed: for the OpenAI provider (openai-completions api, line 644), baseUrl is https://api.openai.com/v1 — i.e., the /v1 root without /chat/completions. pi-ai appends the endpoint path. The openai-compatible normalization strips /chat/completions to produce the same shape. Consistent and correct.

The review is complete. Let me summarize my findings.

The PR is well-structured and thoroughly tested. My analysis of all 14 changed files:

  • ai-model-config.tsnormalizeAiModelConfig validation/normalization is correct; the non-null assertions are guarded by Number.isSafeInteger(...) checks that catch undefined. URL normalization (strip credentials/query/fragment//chat/completions, require HTTPS) is sound and matches the /v1-root baseUrl shape pi-ai expects (consistent with the existing openai direct path).
  • ai-models.tsgetModel correctly short-circuits openai-compatible before both platform-gateway and BYOK routing, and throws in AI Gateway mode. getModelDirect builds a text-only handle with the conservative compat profile. Assertions are safe because getModel/addModel normalize first.
  • user.tslistModels/addModel/getChatContext guards are consistent. The getChatContext refactor preserves gateway-first precedence (gwConfig?.resolveModel(modelId) ?? storedModel) and the new user-model-resolution.test.ts locks in the important property that a persisted openai-compatible model isn't silently replaced by a colliding gateway model after a mode switch.
  • chat-attachment-validation.ts / agent.tsmodelSupportsChatAttachment checks resolved-model capabilities on replay; images degrade cleanly to omitted-attachment text markers for the text-only profile.
  • agent-compaction.tsgetModelTokenLimits clamps to MAX_CUSTOM_MODEL_CONTEXT_WINDOW and reserves output correctly.
  • api.ts — new fields and MAX_CUSTOM_MODEL_CONTEXT_WINDOW are doc-commented per the shared-API bar; model config (with apiToken) is never exposed to gadgets, only profile.
  • Frontend AddModelModal.tsx — validation mirrors the backend; raw URL is intentionally normalized server-side.

I found no actionable defects. The change is consistent with the codebase's capability/routing conventions and the stated "direct mode only, unavailable in gateway mode" design.

LGTM!

github run

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

Labels

kernel Changes to the Workshop kernel workshop/frontend Changes to the Workshop frontend workshop/shared Changes to shared Workshop APIs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant