Skip to content

feat:allow api_base (base_url) in .env#235

Open
saccharin98 wants to merge 1 commit intoVectifyAI:devfrom
saccharin98:dev
Open

feat:allow api_base (base_url) in .env#235
saccharin98 wants to merge 1 commit intoVectifyAI:devfrom
saccharin98:dev

Conversation

@saccharin98
Copy link
Copy Markdown
Collaborator

• ## Summary

Adds lightweight API base URL support for OpenAI-compatible providers through LiteLLM.

Changes

  • Pass OPENAI_BASE_URL / OPENAI_API_BASE / CHATGPT_API_BASE to LiteLLM as api_base
  • Add --base-url / --api-base CLI options in run_pageindex.py
  • Document OpenAI-compatible/Ollama usage in README
  • Add mock tests for sync and async LiteLLM API base forwarding

Test Plan

  • python3 -m pytest tests/test_litellm_api_base.py
  • python3 -m pytest tests/test_config.py tests/test_litellm_api_base.py
  • python3 run_pageindex.py --help
  • git diff --check

Closes #229

@rejojer
Copy link
Copy Markdown
Member

rejojer commented Apr 21, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@saccharin98
Copy link
Copy Markdown
Collaborator Author

Code review

Found 1 issue:

  1. Unconditional api_base applied to all LiteLLM providers_litellm_api_base_kwargs() passes the api_base parameter to every litellm.completion() / litellm.acompletion() call regardless of the model or provider. When OPENAI_BASE_URL is set (e.g. for Ollama or a local endpoint), non-OpenAI models like anthropic/claude-sonnet or gemini/... will also be routed to that endpoint, causing failures. Before this PR, no api_base was passed, so multi-provider usage worked correctly. The fix should conditionally apply api_base only for OpenAI-compatible models/providers.

def _litellm_api_base_kwargs():
api_base = (
os.getenv("OPENAI_BASE_URL")
or os.getenv("OPENAI_API_BASE")
or os.getenv("CHATGPT_API_BASE")
)
return {"api_base": api_base} if api_base else {}

def _litellm_api_base_kwargs():
api_base = (
os.getenv("OPENAI_BASE_URL")
or os.getenv("OPENAI_API_BASE")
or os.getenv("CHATGPT_API_BASE")
)
return {"api_base": api_base} if api_base else {}

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@saccharin98
Copy link
Copy Markdown
Collaborator Author

Review

Reviewed the current head (60d3184). No blocking issues found.

The earlier provider-routing concern looks addressed now: _litellm_api_base_kwargs(model) scopes OPENAI_BASE_URL / OPENAI_API_BASE / CHATGPT_API_BASE to OpenAI-compatible models instead of passing api_base to every LiteLLM provider. That should avoid incorrectly routing explicit non-OpenAI models such as anthropic/... and gemini/... through the OpenAI-compatible host.

The added regression coverage also checks the important cases:

  • bare OpenAI model still receives api_base
  • openai/... model still receives api_base
  • anthropic/... and gemini/... do not receive api_base
  • the legacy pageindex.utils path is covered

I also ran python3 -m pytest tests/test_litellm_api_base.py locally and it passed (8 passed).

@rejojer
Copy link
Copy Markdown
Member

rejojer commented Apr 21, 2026

Code review

Found 1 issue:

  1. PageIndexClient.__init__ does not accept a base_url parameter, so SDK users (local mode) must still set OPENAI_BASE_URL in their process env manually — while the CLI path mutates os.environ["OPENAI_BASE_URL"] on the user's behalf in run_pageindex.py. This configuration-surface inconsistency was concern initial run, key error #1 in the blocking review on predecessor PR fix: add --base_url CLI option for custom LLM endpoints #229 ("does not cover the Python SDK / PageIndexClient local-mode path, so the configuration surface would be inconsistent", fix: add --base_url CLI option for custom LLM endpoints #229 (comment)) and remains unaddressed here.

def __init__(self, api_key: str = None, model: str = None,
retrieve_model: str = None, storage_path: str = None,
storage=None, index_config: IndexConfig | dict = None):
if api_key:
self._init_cloud(api_key)
else:
self._init_local(model, retrieve_model, storage_path, storage, index_config)

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

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.

2 participants