osrforge.providers.clef
The Clef adapter: Cloudflare's decision model on Workers AI, over its REST endpoint.
It fills the tracing stage's decision role
(DecisionProvider). Each
request is one HTTP POST to the model-in-path endpoint with the System One
body Clef extends: one image, the state, and one choice question. The body is
encode_request: the image
as PNG, or as JPEG when the PNG body is too large. The adapter reserves each
request's estimated cost on the Clef ledger before sending and settles it
from the usage the answer reports. No vendor SDK: the transport is a
function the constructor takes, so tests give it a fake. A recording of a
private corpus member's map stays in the owner's private corpus directory,
never in the repository.
ENDPOINT
module-attribute
ENDPOINT = 'https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/run/@cf/cloudflare/{model}'
The endpoint with the model in the path. The universal /ai/run endpoint rejects the body's model field.
PRICE_PER_TOKEN
module-attribute
List prices in dollars per input token. Clef charges no output tokens.
Transport
module-attribute
Sends one POST, (url, body, headers), and returns (status, response body). May raise OSError.
ClefProvider
ClefProvider(
settings: ClefSettings,
transport: Transport | None = None,
sleep: Callable[[float], None] = sleep,
today: Callable[[], str] | None = None,
)
Clef on Workers AI, with the ledger and the retries the service needs.
The constructor performs no I/O. Transport policy: at most five attempts
per request in all, whatever mix of failures uses them. A 413, which the
service returns when it estimates a body past a token limit, is retried
with backoff, because the probe saw a 413 at a limit far below the
model's pass on retry, but no more than three of the five attempts may
follow a 413. 408, 409, 429, every 5xx, and connection failures get
bounded exponential backoff within the same five attempts. A 401 raises
ClefAuthError, whose message tells
the user to run wrangler login, and any other 4xx raises at once. The
attempts share the request's one reservation, settled once at the end.
An error message names the status, the body's size, and the service's
message, and never the token.
Bind to an account and a ledger.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
ClefSettings
|
The settings. |
required |
transport
|
Transport | None
|
The function that sends one POST, injectable for tests. When omitted, the adapter uses the standard library's HTTP client with a 120-second timeout. |
None
|
sleep
|
Callable[[float], None]
|
The backoff sleeper, injectable for tests. |
sleep
|
today
|
Callable[[], str] | None
|
Gives the ledger entry's |
None
|
decide
decide(request: DecisionRequest) -> DecisionResponse
Send one question and return its probabilities.
The first call opens this provider's ledger entry {"date", "what":
settings.run_label}, and every call reserves
estimate_cost against it
before sending and settles at
cost_usd of the usage's input
and output tokens after. A request whose sending was attempted is
settled at its estimate when no answer it can read arrives, also when no attempt
reached the service, so the ledger errs toward overcharging. If a
settle fails, the entry stays pending at the estimate. The POST goes
to ENDPOINT with an
Authorization: Bearer header and a JSON content type, and the
answer is read from the envelope's result: its model, the one
answer's probabilities, and usage.input_tokens.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
DecisionRequest
|
The question. |
required |
Returns:
| Type | Description |
|---|---|
DecisionResponse
|
The answer, with the format the image went as and the sha256 of |
DecisionResponse
|
the body sent. |
Raises:
| Type | Description |
|---|---|
LedgerStopError
|
If the reservation would pass the stop. |
ClefAuthError
|
If the service answers 401. |
ProviderError
|
On transport or rate-limit exhaustion, a 413 that stays after its retries, another 4xx, an answer the adapter can't read, or a settle of the ledger that fails after an answer. |
ClefSettings
Bases: BaseModel
The provider's settings: the account, the token, and the ledger.
Examples:
from pathlib import Path
from pydantic import SecretStr
from osrforge.providers.clef import ClefProvider, ClefSettings, wrangler_token
settings = ClefSettings(
account_id="...", token=SecretStr(wrangler_token()), ledger_path=Path("clef-ledger.json")
)
provider = ClefProvider(settings)
token
instance-attribute
token: SecretStr
The bearer token. Never written to a log, a recording, or an error message.
ledger_stop_usd
class-attribute
instance-attribute
ledger_stop_usd: float | None = None
The stop, or None to use the ledger file's own.
run_label
class-attribute
instance-attribute
run_label: str = 'osrforge'
The what of the ledger entry this provider's requests accrue to.
from_env
classmethod
from_env() -> ClefSettings
Build settings from the environment and the wrangler login.
Returns:
| Type | Description |
|---|---|
ClefSettings
|
Settings from |
ClefSettings
|
(both required), |
ClefSettings
|
|
ClefSettings
|
Raises:
| Type | Description |
|---|---|
ProviderError
|
If a required variable is missing or empty, the stop isn't a number, or no token can be found. |
cost_usd
Return what an answer cost at list price.
Clef reports no output tokens today. Any it reports are charged at the input price, as the probe charged them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
|
required |
input_tokens
|
int
|
The input tokens the usage reports. |
required |
output_tokens
|
int
|
The output tokens the usage reports. |
0
|
Returns:
| Type | Description |
|---|---|
float
|
|
Raises:
| Type | Description |
|---|---|
ProviderError
|
If the model has no price. |
estimate_cost
estimate_cost(request: DecisionRequest) -> float
Return a request's worst-case cost: its token estimate at list price, times 1.5.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
DecisionRequest
|
The request. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The estimate in dollars. |
estimate_tokens
estimate_tokens(request: DecisionRequest) -> int
Estimate a request's input tokens, with the probe's formula.
The image's tokens are ceil(width / 32) * ceil(height / 32), and when
width * height < 65536 they become max(that, 64) * 2, because the
service scales a small image up and the probe allowed for the rounding;
then 4 are added. To that the estimate adds len(json.dumps(state)) / 2
and len(json.dumps(questions)) / 1.5, where questions is the body's
questions mapping and json.dumps uses its default separators, and 200
for the prompt the service wraps around them. The sum is rounded up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
DecisionRequest
|
The request. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The estimate. |
wrangler_token
Return the OAuth token of the wrangler login.
wrangler login stores its token as oauth_token in
default.toml under wrangler's config directory:
~/Library/Preferences/.wrangler/config/ on macOS and
~/.config/.wrangler/config/ elsewhere.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_path
|
Path | None
|
The TOML file, or |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The token. |
Raises:
| Type | Description |
|---|---|
ProviderError
|
If the file is missing or can't be read, isn't
UTF-8, isn't valid TOML, or has no |