Repository navigation
M1: add /v1/literature/search, /literature/domains, /v1/usage, /v1/models - #24
Merged
Merged
Conversation
…models
Part of M1 (filling in the design doc's "most public endpoints are
missing" gap) on top of M0's contract-freeze/outbox work. Adds the
four remaining endpoints from the design doc's public API table:
- POST /v1/literature/search: billable ("1 search", ~1/10th of an
answer per the pricing table), retrieval-only -- forwards to
omnibioai-rag's new mode="search" (no LLM call at all). Shares the
exact same idempotency/quota/usage lifecycle as /literature/answers
via a new _handle_billable_literature_call helper, factored out so
the two billable endpoints can't silently drift apart on that
sequencing. Bills "literature.search", not "literature.answer".
- GET /literature/domains: the same omnibioai-rag study list
/literature/studies already exposes (left untouched for backward
compatibility), reshaped under the design doc's public name
("domain"). Free, rate-limited, never billed.
- GET /v1/usage: the gateway's first synchronous call into
omnibioai-billing, forwarding to its existing GET
.../subscription/usage-limits and translating included/used/
remaining per resource. Free. Gated on usage.read -- already
registered in omnibioai-auth's Permission Registry as "reserved,
not yet enforced by any route" (same state dataset.read/model.use/
workflow.execute were in before this gateway's own IAM Foundation
integration); this is its first real consumer. Estimated-charge-in-
dollars is deliberately omitted (would need billing's cost-summary
period math, not yet done -- reporting it wrong would be worse than
omitting it).
- GET /v1/models: a static one-entry catalog (no upstream call) for
the one model path that actually exists today. price is null, not a
placeholder number -- the design doc's own pricing section says to
measure real GPU cost first (M0, 1,000 representative questions),
and that hasn't been run yet.
Tests: 353 passed (was 349 + 4 pre-existing-but-newly-triggered
failures from test_pr13_role_tier_permission_forwarding.py, which
parametrizes over every SERVICE_MAP key and asserts a matching
SERVICE_PERMISSION_MAP entry -- adding "billing" to SERVICE_MAP
without usage.read would have broken that invariant). ruff clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Part of M1, building on M0's contract-freeze/outbox work. Adds the four remaining endpoints from the design doc's public API table ("most public endpoints are missing"):
POST /v1/literature/search— billable ("1 search", ~1/10th of an answer per the design's pricing table), retrieval-only. Forwards to the companion omnibioai-rag PR's newmode="search"(no LLM call at all). Shares the exact same idempotency/quota/usage lifecycle as/literature/answersvia a new_handle_billable_literature_callhelper, factored out so the two billable endpoints can't silently drift apart on that sequencing. Billsliterature.search, notliterature.answer.GET /literature/domains— the same omnibioai-rag study list/literature/studiesalready exposes (left untouched for backward compatibility), reshaped under the design doc's public name ("domain"). Free, rate-limited, never billed.GET /v1/usage— the gateway's first synchronous call into omnibioai-billing, forwarding to its existingGET .../subscription/usage-limitsand translating included/used/remaining per resource. Free. Gated onusage.read— already registered in omnibioai-auth's Permission Registry as "reserved, not yet enforced by any route" (the same statedataset.read/model.use/workflow.executewere in before this gateway's own IAM Foundation integration); this is its first real consumer. Estimated-charge-in-dollars is deliberately omitted — would need billing's cost-summary period math, not yet done, and reporting it wrong would be worse than omitting it.GET /v1/models— a static one-entry catalog (no upstream call) for the one model path that actually exists today.priceisnull, not a placeholder number — the design doc's pricing section says to measure real GPU cost first (M0, 1,000 representative questions), which hasn't been run.Known follow-up:
usage.readis newly wired intoSERVICE_PERMISSION_MAPas policy-engine context, matching the established pattern, but whether any role is actually grantedusage.readtoday is anomnibioai-policy-engineconfiguration question outside this repo — flagging so it isn't missed before/v1/usageis expected to work end-to-end for real callers.Depends on: the companion omnibioai-rag PR (
mode="search") for/v1/literature/searchto return real results — this gateway change is forward-compatible either way (it just forwardsmode: "search"and translates whatever comes back).Test plan
pytest— 353 passed, including a pre-existing test (test_pr13_role_tier_permission_forwarding.py) that parametrizes over everySERVICE_MAPkey and would have caught a missingSERVICE_PERMISSION_MAPentry forbillingruff check .— cleanbuild_rag_search_query/build_public_search, and route-level tests for all four new endpoints (auth, rate-limit, billing lifecycle, upstream-error mapping, free-vs-billed)🤖 Generated with Claude Code