-
Notifications
You must be signed in to change notification settings - Fork 561
Use Prime CLI config for v1 eval #1703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+35
−11
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,43 +1,59 @@ | ||
| """Client configs: describe an OpenAI-compatible endpoint and resolve it to a Client. | ||
|
|
||
| A `BaseClientConfig` is an OpenAI-compatible endpoint (base_url + API-key env var | ||
| + extra headers) that `resolve_client` turns into a `Client`. Prime team-billing | ||
| is baked in via a validator, so it's handled in one place. Both the eval entrypoint | ||
| (its model client) and in-env LLM calls (e.g. a judge reward) build clients from | ||
| these — inherit `BaseClientConfig` to get the endpoint/header handling for free. | ||
| + extra headers) that `resolve_client` turns into a `Client`. The default Prime | ||
| endpoint, API key, and team fall back to the active Prime CLI config, so direct | ||
| `uv run eval` calls behave like `prime eval`. Both the eval entrypoint (its model | ||
| client) and in-env LLM calls (e.g. a judge reward) build clients from these. | ||
| `ClientConfig` is the CLI-selectable discriminated union (eval | train). | ||
| """ | ||
|
|
||
| import os | ||
| from typing import Annotated, Literal | ||
| from urllib.parse import urlparse | ||
|
|
||
| from openai import AsyncOpenAI | ||
| from pydantic import Field, model_validator | ||
| from pydantic_config import BaseConfig | ||
| from renderers import RendererConfig | ||
|
|
||
| from verifiers.utils.client_utils import load_prime_config | ||
| from verifiers.v1.clients.client import Client | ||
| from verifiers.v1.clients.eval import EvalClient | ||
| from verifiers.v1.clients.train import TrainClient | ||
|
|
||
| DEFAULT_PRIME_INFERENCE_URL = "https://api.pinference.ai/api/v1" | ||
| PRIME_INFERENCE_HOST = "pinference.ai" | ||
| PRIME_TEAM_ID_HEADER = "X-Prime-Team-ID" | ||
|
|
||
|
|
||
| class BaseClientConfig(BaseConfig): | ||
| """An OpenAI-compatible endpoint. The API key is read from an env var.""" | ||
|
|
||
| base_url: str = "https://api.pinference.ai/api/v1" | ||
| base_url: str = DEFAULT_PRIME_INFERENCE_URL | ||
| api_key_var: str = "PRIME_API_KEY" | ||
| headers: dict[str, str] = Field(default_factory=dict) | ||
| """Extra HTTP headers sent on every request.""" | ||
|
|
||
| @model_validator(mode="after") | ||
| def add_prime_team_id(self) -> "BaseClientConfig": | ||
| # Prime inference bills the personal balance unless a team is named; on | ||
| # that endpoint, route billing to PRIME_TEAM_ID when set (explicit wins). | ||
| team_id = os.environ.get("PRIME_TEAM_ID") | ||
| if PRIME_INFERENCE_HOST in self.base_url and team_id: | ||
| def apply_prime_config(self) -> "BaseClientConfig": | ||
| if self.api_key_var != "PRIME_API_KEY": | ||
| return self | ||
| prime_config = load_prime_config() | ||
| prime_base_url = ( | ||
| os.environ.get("PRIME_INFERENCE_URL") | ||
| or prime_config.get("inference_url") | ||
| or DEFAULT_PRIME_INFERENCE_URL | ||
| ) | ||
| if "base_url" not in self.model_fields_set: | ||
| self.base_url = prime_base_url | ||
| host = urlparse(self.base_url).hostname or "" | ||
| if host != PRIME_INFERENCE_HOST and not host.endswith( | ||
| f".{PRIME_INFERENCE_HOST}" | ||
| ): | ||
| return self | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| team_id = os.environ.get("PRIME_TEAM_ID") or prime_config.get("team_id") | ||
| if team_id: | ||
| self.headers.setdefault(PRIME_TEAM_ID_HEADER, team_id) | ||
| return self | ||
|
|
||
|
|
@@ -73,7 +89,15 @@ class TrainClientConfig(BaseClientConfig): | |
|
|
||
|
|
||
| def resolve_client(config: BaseClientConfig) -> Client: | ||
| api_key = os.environ.get(config.api_key_var, "EMPTY") | ||
| api_key = os.environ.get(config.api_key_var) | ||
| host = urlparse(config.base_url).hostname or "" | ||
| if ( | ||
| not api_key | ||
| and config.api_key_var == "PRIME_API_KEY" | ||
| and (host == PRIME_INFERENCE_HOST or host.endswith(f".{PRIME_INFERENCE_HOST}")) | ||
| ): | ||
| api_key = load_prime_config().get("api_key") | ||
|
Comment on lines
+93
to
+99
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. arfh, i hate this custom logic here. getting auth smell. how come no other provider requires this? |
||
| api_key = api_key or "EMPTY" | ||
| if isinstance(config, TrainClientConfig): | ||
| # The renderer calls a vLLM `/inference/v1/generate` engine through the OpenAI SDK. | ||
| openai = AsyncOpenAI( | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
model_fields_setonly contains values supplied by the caller, not defaults declared on aBaseClientConfigsubclass. With an environment config such asclass StagingJudge(BaseClientConfig): base_url = "https://staging.pinference.ai/api/v1"that intentionally keepsapi_key_var="PRIME_API_KEY", this branch treats the subclass default as missing and overwrites it with the active Prime/default URL, so the environment silently calls the wrong endpoint unless every caller explicitly passesbase_url.Useful? React with 👍 / 👎.