Skip to content

feat: support provider_base_urls for native-openai path#809

Open
leoge007 wants to merge 1 commit intogarrytan:masterfrom
leoge007:feat/provider-base-urls-for-native-openai
Open

feat: support provider_base_urls for native-openai path#809
leoge007 wants to merge 1 commit intogarrytan:masterfrom
leoge007:feat/provider-base-urls-for-native-openai

Conversation

@leoge007
Copy link
Copy Markdown

@leoge007 leoge007 commented May 10, 2026

Problem

When provider_base_urls.openai is configured in ~/.gbrain/config.json (e.g. pointing to SiliconFlow, Azure OpenAI, vLLM, or any OpenAI-compatible endpoint), gbrain still sends requests directly to OpenAI's API for the native-openai recipe. The base_urls config is only respected by the openai-compat recipe tier.

This means users who want to use OpenAI-compatible embedding/chat/expansion providers through the native-openai path cannot do so, even though provider_base_urls is a documented config field in GBrainConfig.

Changes

1. gateway.ts — Pass baseURL to createOpenAI() in embedding path

The expansion and chat native-openai paths already read cfg.base_urls?.[recipe.id] and pass it as baseURL. The embedding path was missing this. Now all three paths consistently route through the configured base URL.

Also passes hasCustomBaseUrl to assertTouchpoint() and dimsProviderOptions() so downstream logic can adapt.

2. model-resolver.ts — Relax model whitelist when custom base URL is set

assertTouchpoint() now accepts a hasCustomBaseUrl parameter. When true, it skips the model-name whitelist check for native-tier recipes. This is safe because:

  • A custom base URL means the user is explicitly routing to a non-OpenAI endpoint
  • Such endpoints may offer models not in the OpenAI recipe list (e.g. Qwen/Qwen3-Embedding-8B)
  • The user has already opted into this by configuring provider_base_urls

3. dims.ts — Pass dimensions when using custom base URL

dimsProviderOptions() now accepts a hasCustomBaseUrl parameter. When true for the native-openai path, it passes the dimensions parameter unconditionally (not just for text-embedding-3-*). This is needed because:

  • OpenAI-compatible endpoints (SiliconFlow, Azure OpenAI, etc.) typically support the dimensions parameter
  • Embedding models like Qwen3-Embedding support Matryoshka dimension reduction
  • Without this, dimension mismatches occur (e.g. model returns 4096 dims but schema expects 1536)

Usage Example

// ~/.gbrain/config.json
{
  "engine": "pglite",
  "provider_base_urls": {
    "openai": "https://api.siliconflow.cn/v1/"
  },
  "embedding_model": "openai:Qwen/Qwen3-Embedding-8B",
  "embedding_dimensions": 1536
}

Then set OPENAI_API_KEY to your SiliconFlow API key, and gbrain will route all OpenAI requests through SiliconFlow with correct base URL, model name, and dimension handling.

Testing

  • bun run verify passes (tsc, privacy checks, admin build, all linting)
  • Verified end-to-end: gbrain embed successfully embeds pages using SiliconFlow + Qwen3-Embedding-8B → 1536 dimensions

Scope

This PR only changes behavior when provider_base_urls is explicitly configured. Default behavior (routing directly to OpenAI) is completely unchanged.


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

When provider_base_urls.openai is configured in ~/.gbrain/config.json,
gbrain now correctly routes requests through the custom base URL for
all native-openai touchpoints (embedding, expansion, chat).

Previously, provider_base_urls was only used by the openai-compatible
recipe tier, causing requests to go directly to OpenAI's API even when
a custom endpoint was configured for the native-openai recipe.

Three changes:

1. gateway.ts: Pass cfg.base_urls[recipe.id] as baseURL to createOpenAI()
   in the native-openai embedding instantiation path (expansion and chat
   paths already had this). Also pass hasCustomBaseUrl to assertTouchpoint()
   and dimsProviderOptions() for all three touchpoints.

2. model-resolver.ts: assertTouchpoint() accepts hasCustomBaseUrl param.
   When true, skips the model-name whitelist check for native-tier recipes,
   since custom endpoints may offer models not in the OpenAI recipe list.

3. dims.ts: dimsProviderOptions() accepts hasCustomBaseUrl param.
   When true, passes the dimensions parameter for native-openai embeddings
   even for non-text-embedding-3 models, since OpenAI-compatible endpoints
   (e.g. SiliconFlow, Azure OpenAI) typically support this parameter.

Enables using providers like SiliconFlow, Azure OpenAI, vLLM, or any
OpenAI-compatible endpoint through the native-openai recipe with proper
base URL routing, model name flexibility, and dimension control.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant