fix: auto-append /v1 suffix to embedding_api_base in OpenAI embedding provider#6912
fix: auto-append /v1 suffix to embedding_api_base in OpenAI embedding provider#6912BillionClaw wants to merge 1 commit intoAstrBotDevs:masterfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a critical regression that affected OpenAI-compatible embedding providers. A previous change had inadvertently removed the automatic appending of the /v1 suffix to the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="tests/unit/test_openai_embedding_source.py" line_range="64-37" />
<code_context>
+ provider = _make_provider({"embedding_api_base": "https://openai.example.com/v1"})
+ assert provider.client.base_url == "https://openai.example.com/v1"
+
+ def test_empty_api_base_uses_default(self) -> None:
+ """Empty api_base should use the default OpenAI endpoint."""
+ provider = _make_provider({"embedding_api_base": ""})
+ assert provider.client.base_url == "https://api.openai.com/v1"
+
+ def test_default_api_base_is_unchanged(self) -> None:
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test case for `embedding_api_base` with surrounding whitespace
Since the constructor applies `.strip()` to `embedding_api_base`, it would be useful to add a test that passes values with leading/trailing spaces (e.g. `' https://api.openai.com '` or `' https://api.openai.com/ '`) and asserts that `provider.client.base_url` is normalized to `https://api.openai.com/v1`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| """api_base like 'https://api.openai.com' should become 'https://api.openai.com/v1'.""" | ||
| provider = _make_provider({"embedding_api_base": "https://api.openai.com"}) | ||
| # The provider should auto-append /v1 | ||
| assert provider.client.base_url == "https://api.openai.com/v1" |
There was a problem hiding this comment.
suggestion (testing): Add a test case for embedding_api_base with surrounding whitespace
Since the constructor applies .strip() to embedding_api_base, it would be useful to add a test that passes values with leading/trailing spaces (e.g. ' https://api.openai.com ' or ' https://api.openai.com/ ') and asserts that provider.client.base_url is normalized to https://api.openai.com/v1.
There was a problem hiding this comment.
Code Review
This pull request reintroduces logic to automatically append the /v1 suffix to the OpenAI API base URL if it's not already present, addressing a regression. New unit tests have been added to cover various scenarios for this API base URL formatting. A high-severity issue was identified where the current implementation does not correctly handle an explicitly provided empty embedding_api_base, which would result in an invalid API base URL instead of defaulting to https://api.openai.com/v1.
| if api_base and not api_base.endswith("/v1") and not api_base.endswith("/v1/"): | ||
| api_base = api_base.rstrip("/") + "/v1" |
There was a problem hiding this comment.
The current logic for handling api_base does not correctly fall back to the default https://api.openai.com/v1 when embedding_api_base is explicitly provided as an empty string. If provider_config.get("embedding_api_base") returns an empty string, the if api_base condition evaluates to False, skipping the logic to append /v1. This results in self.client.base_url being set to an empty string, which is likely an invalid URL for AsyncOpenAI and would cause connection errors.
The unit test test_empty_api_base_uses_default in tests/unit/test_openai_embedding_source.py correctly identifies the desired behavior (falling back to the default), but the current implementation will cause that test to fail. The proposed change ensures that an empty api_base (after stripping whitespace) is treated as if it were not provided, and thus defaults to https://api.openai.com/v1.
if not api_base:
api_base = "https://api.openai.com/v1"
elif not api_base.endswith("/v1") and not api_base.endswith("/v1/"):
api_base = api_base.rstrip("/") + "/v1"
Summary
Fixes: #6887
PR #6669 removed the automatic
/v1suffix fromembedding_api_basebecause some non-OpenAI providers don't use standard/v1/embeddingsendpoints. However, this broke OpenAI-compatible providers (e.g., text-embedding-3-large on SiliconFlow) that require the/v1path. When/v1is absent, the SDK sends requests tohttps://api.openai.com/embeddingsinstead ofhttps://api.openai.com/v1/embeddings, returning an error string. Code then tries to call.dataon that string, causing'str' object has no attribute 'data'.Modifications
astrbot/core/provider/sources/openai_embedding_source.py: Ifembedding_api_baseis set but does not end with/v1or/v1/, automatically append/v1.tests/unit/test_openai_embedding_source.py: Unit tests covering all API base URL variants.Verification
/v1are unaffected.Summary by Sourcery
Restore correct handling of the OpenAI embedding API base URL by normalizing it to include the /v1 suffix when appropriate and add coverage for this behavior.
Bug Fixes:
Tests: