Skip to content

Releases: offpeak-ai/offpeak

v0.2.4 — two new venues, one of which settles

Choose a tag to compare

@theo-titonis theo-titonis released this 24 Aug 02:37
4da0357

Two new venue drivers. One of them settles at a batch tier and has the receipt
to prove it; the other is blocked on billing and has a receipt saying that.

Google Gemini — settles

| 2026-08-24-gemini-1 | 5 jobs | gemini:batch | $0.00919 | $0.00460
| $0.00460 (50.0%) | 5/5 |

Zero sync fallbacks, 2m36s end to end. The first venue outside OpenAI and
Anthropic here to capture the spread rather than record why it could not.

It is also the first venue that is not OpenAI-shaped, so the driver carries a
real translation layer:

  • messages → contents/parts, assistantmodel, and a system message
    lifted onto system_instruction rather than sent as a turn
  • params → a typed config (max_tokensmax_output_tokens), with unknown keys
    dropped rather than forwarded, because an unknown key is a hard error found
    hours after a batch is submitted
  • no custom_id: the job id rides in the request's metadata and comes back on
    the response
  • twelve job states, with PARTIALLY_SUCCEEDED treated as a completion so the
    work that succeeded is not discarded

Thinking tokens are billed as output and counted as output.
usageMetadata reports thoughtsTokenCount apart from candidatesTokenCount;
a receipt reading only the visible answer would have reported roughly a tenth of
this bill.

Mistral — driver complete, tier closed

POST /v1/batch/jobs answers 402 … enable billing via the console. Everything
else works: file upload with purpose=batch is reachable, sync completions
return 200, and all 24 jobs of 2026-08-24-mistral-1 settled through the sync
fallback at list, capturing nothing. That is on the ledger next to the rows that
captured 50%.

The driver handles Mistral's own shape: one model per batch (taken at create and
applied to the whole file, so a mixed batch is refused by name), timeout_hours
as the completion window, and seven job states with TIMEOUT_EXCEEDED mapped to
failed rather than cancelled.

Prices

Mistral and Google rows join the bundled sheet, keyed on family prefixes so a
dated SKU inherits its family. Gemini 3.7/3.6 Flash carry their introductory
rates with the 2027-01-01 step-up as PromoNotes.

Two prefix hazards are handled rather than left to be discovered:
gemini-3.5-flash would otherwise swallow gemini-3.5-flash-lite, and
gemini-3.1-flash-lite is left off entirely because its id is a prefix of an
image model whose rate is not on the text sheet.

Upgrading

pip install -U offpeak
pip install "offpeak[gemini]"   # or [mistral]

No API changes. Both new venues are opt-in — their own extras, outside all,
outside default_venues().

v0.2.3 — the Groq driver, validated by a real billed run

Choose a tag to compare

@theo-titonis theo-titonis released this 24 Aug 00:50
91c4a7e

The Groq batch venue shipped in 0.2.2 could not have worked. This release is the
fix, and a real billed run is what validated it.

What was wrong

supports() carried twelve model prefixes and not one matched a model on
Groq's production chat lineup
— so the venue answered "no" to the entire
catalogue it exists to reach, and everything it did match had already been shut
off (llama-3.3-70b-versatile and llama-3.1-8b-instant on 2026-08-16;
qwen/qwen3-32b and meta-llama/llama-4-scout on 2026-07-17; mixtral, gemma2
and the DeepSeek distills long before).

The price sheet had no Groq rows at all, so a Groq settlement rendered a
receipt with no cost and no captured spread: a run that really billed, looking as
though it had been free.

What changed

  • Routing audited against the live model list. Now claims
    openai/gpt-oss (120b, 20b, safeguard-20b) and groq/ (compound,
    compound-mini). Groq's batch docs page still lists the dead Llamas; it is
    stale, and the deprecations page is the truth.
  • openai/gpt-oss is spelled out, not reached for as a bare openai/ — that
    namespace is Groq's catalogue, and claiming all of it would poach every future
    OpenAI-authored model that lands there.
  • Whisper dropped, for a different reason than the rest: it is live on Groq
    and this driver still cannot run it. build_jsonl writes
    /v1/chat/completions with a messages body; transcription needs
    /v1/audio/transcriptions with a file.
  • Price rows addedopenai/gpt-oss-120b at $0.15/$0.60 and
    openai/gpt-oss-20b at $0.075/$0.30 per 1M, batch at the standard 50% rule.
    No fast-tier rows: Groq sells no fast tier, and a sheet should not imply an
    urgency spread nobody offers.
  • openai/gpt-oss joins the max_completion_tokens translation; Groq marks
    max_tokens deprecated in favour of it.
  • Published batch limits enforced before upload — 50,000 requests, 200MB. A
    rejection at the far end arrives once the file has already crossed the wire.

The batch tier is still unverified, and not because of this code

Groq gates its entire Batch API behind a plan. On this account
POST /openai/v1/files (purpose=batch) and GET /openai/v1/batches both answer
403 not_available_for_plan, so submit() cannot finish its first call.

The validating run went anyway and is published as
receipts/2026-08-23-groq-1.json: 24 jobs, 24 ok, $0.0023637 paid, $0.00
captured
, every one of them through the sync fallback at list price. The 0% is
the finding, and it sits on the public ledger next to three rows reading 50.0%.

What that run does prove with real money: the model routes to groq:batch, the
body renders in Groq's dialect, the new price rows settle a real receipt instead
of an unpriced one, and the SLA held at 24/24.

Also in this release

Documentation and naming: the night board is now the Spread Board, and the
copy leads with the deadline rather than the hour.

Upgrading

pip install -U offpeak

No API changes. Groq remains opt-in — its own extra, outside all, and not in
default_venues().

v0.2.2 — the max_completion_tokens fix reaches PyPI

Choose a tag to compare

@theo-titonis theo-titonis released this 23 Aug 02:57
92385ab

If you installed offpeak from PyPI, this is the release you want.

0.2.1 — the previous latest — does not contain #16. Every gpt-5.x OpenAI batch
job it submits comes back HTTP 400: Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead. The failure
arrives hours after submission, once per job, and the sync fallback does not
rescue it: the fallback covers jobs that never came back, not jobs that came
back failed.

0.2.2 puts the fix on the wire. It is the only src/ change since v0.2.1.

What changed

  • openai: send max_completion_tokens where the model demands it (#16) —
    body_params() renders a job's params in the venue's own dialect. o1/o3/
    o4/gpt-5.x get max_completion_tokens; older families keep max_tokens;
    an explicit provider spelling always wins; the caller's Job is never
    mutated, so a retry at another venue still carries what they wrote. The sync
    fallback goes through the same translation.

Also on main since 0.2.1, none of it shipping code: the reasoning-ceiling
documentation (#17), the settled ledger (#18), a shared push queue for
board-data (#19), the mechanics runner (#20), and the board becoming a
projection of its records (#21).

Upgrading

pip install -U offpeak

Nothing to change in your code. If you have been setting
max_completion_tokens yourself to work around 0.2.1, you can keep doing so —
an explicit spelling still wins — or drop back to max_tokens and let the
driver translate.

offpeak 0.2.1

Choose a tag to compare

@theo-titonis theo-titonis released this 22 Aug 03:51
fc7b147

Price sheet correction. The bundled OpenAI rows were that provider's batch tab stored as list prices — all three models, not just one. Receipts for OpenAI models in 0.1.1–0.2.0 therefore understated both the list cost they compared against and the batch price actually billed: a 1M-in/1M-out gpt-5.6-sol job derived $1.25/$7.50 against a true batch price of $2.00/$10.00. Anthropic's rows were unaffected, and the amounts run so far are sub-cent — recorded regardless, because a receipt that quietly moves is not a receipt.

Corrected standard rows (per developers.openai.com/api/docs/pricing, short context): gpt-5.6-sol 4.00/20.00, gpt-5.6-terra 2.00/12.00, gpt-5.6-luna 0.20/1.20. The −50% batch rule survives intact and now reproduces the provider's own batch tab exactly, asserted per model by test.

The fast tier, and the 4× urgency spread. The sheet now carries what a venue charges for haste as well as for patience: urgency_spread("gpt-5.6-sol") returns 4.0 — $8/$40 per 1M on OpenAI's fast tier against $2/$10 on its batch tier, the same model at the same venue, priced for the hour alone. Promotional list prices carry their own expiry (PROMO_NOTES, promo_decay()): sol's standard rate runs at least through 2026-11-21, $5/$30 after, so the ratio outlives the dollars.

Assumed output on quote(). quote(jobs, deadline=..., assumed_output_ratio=0.25), or metadata={"expected_output_tokens": n} per job, prices output that a pre-trade quote cannot know — marked EST on the card, distinct from FLOOR. Opt-in only: without one, nothing is assumed on your behalf and the default stays the floor.

Also: main carries a dev version between releases; the night board publishes the cited 4× alongside the 2.0× batch spread, and its docs page corrects two stale claims (US zones are wired; ERCOT Houston marked 3.94× on 2026-08-20).

offpeak 0.2.0

Choose a tag to compare

@theo-titonis theo-titonis released this 21 Aug 04:16
a206e84

The free quote: offpeak.quote(jobs, deadline=...) and python -m offpeak quote price a run against the published sheets with no API calls and no key — list vs batch per venue, plus the spread. Quotes with no output-token signal are marked a floor rather than priced at zero. Settlements gain a "left on table" line; receipts render per-job costs with sub-cent precision. Fixes Z-suffixed ISO deadlines on Python 3.10.

offpeak 0.1.2

Choose a tag to compare

@theo-titonis theo-titonis released this 21 Aug 01:39
98ec753

run() now returns a Result for every job — provider errors at submit no longer raise; sub-cent receipt precision on small runs; CI actions updated.

offpeak 0.1.1

Choose a tag to compare

@theo-titonis theo-titonis released this 21 Aug 01:21

Deadline-priced inference: run(jobs, deadline=...) against OpenAI/Anthropic batch tiers (−50%), with sync fallback for SLA risk and settlement receipts. See README + SPEC.md.

Ships the 2026-08 price sheet. 0.1.0 was published from one commit earlier and bundled a stale sheet — it has been yanked; use 0.1.1.

offpeak 0.1.0

Choose a tag to compare

@theo-titonis theo-titonis released this 20 Aug 23:37

Deadline-priced inference: run(jobs, deadline=...) against provider batch tiers (−50%), with sync fallback for SLA risk and settlement receipts.