fix(core): bump engine to ee31e81 — preserve marketplace offer prices#23
Conversation
Bumps the embedded Σ_pol engine submodule from 3d49132 (engine #18) to ee31e81, which includes unhardcoded-engine#20: price_in/price_out field observation now reads the candidate's own offer price before the provider-family EMA fallback. Before this the engine read ctx.state.ema[provider|family].price first, so multiple AntSeed seller offers sharing one provider/model-family collapsed to a single family price (seeded here via update_metrics in sources/__init__.py) and a price-ranking policy could not pick the cheapest seller. The host already forwards per-offer prices through the discover hook, so this pointer-only bump unlocks per-offer price selection with no host logic change. Engine suite green at ee31e81 (564/0). Host suite not run locally (no python3 here); CI validates.
|
Warning Review limit reached
More reviews will be available in 45 minutes and 26 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…bump) #3 of the operational-store migration: enrich the `calls` fact table with the two raw per-call facts the #4 route/analytics views will derive from — the executed route identity and the cache-token breakdown. Prerequisite for keying per-route stats off the ledger. - Submodule bump core 97d0333 -> 537e204 (unhardcoded-engine #23): the engine's `chosen` now carries `served_by` — the marketplace peer that served the call, or the provider itself for a direct route (never nil). Host suite green on it. - host_store.py: `calls` gains `served_by TEXT` + `tokens_cached BIGINT`, applied to existing tables via idempotent `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` (CREATE TABLE IF NOT EXISTS never alters an existing table — the store gains its first in-place migration). insert_call maps both. route_key is left unchanged: deriving a peer-granular route key from served_by is #4's job; this commit only captures the raw fact. - shim.py: `_build_x_router` surfaces `served_by` from `chosen` (tokens_cached was already there). - auth_proxy.py: the ingress threads served_by + tokens_cached off x_router into the recorded call (both stream and unary paths) -> insert_call. ttft was intentionally NOT added: nothing measures it yet, so the column would be idle (Axis 3). error_type was already a column. Verification: full suite 411 passed, 2 skipped, 0 failed against the compose Postgres; the ALTER migration applies in place on boot; a live chat records served_by + tokens_cached in `calls` end to end against engine #23.
… the filesystem (#38) * feat(host-store): peer_offers — antseed market book off the filesystem Move the antseed marketplace book from market.json (a file on a shared volume, unioned by hand in merge-market.js) into the Postgres host store — the next slice of the JSON/in-process migration after #36. Form delta: - Definition: a new `peer_offers` table holds one RAW row per (peer, service) — the seller's announced prices/cap/reputation as columns, not interpreted. The antseed sidecar is the sole writer (it runs `antseed network browse`); sources/antseed._load_market is the sole reader. The 15-min sliding window that merge-market.js unioned by hand is now a read-time filter on observed_at (WHERE observed_at >= now - window); the sidecar prunes rows past the window. - Invariants: store raw, derive by query — no scoring host-side; the negative / cached>input / reputation gates stay in offers_sync. Fail-soft: a DB error degrades to "no antseed candidates" exactly as a missing dump did. Behaviour preserved: offers_sync / market_book unchanged. - Irreversible: peer_offers is new DB state; market.json is retired. Changes: - host_store.py: peer_offers schema (PK (peer_id, service) + observed_at index) and a window-filtered peer_offers() reader; truncate hook updated. - antseed/write-market.js: replaces merge-market.js — flattens the browse dump to (peer, service) rows, UPSERTs into peer_offers (type-cleaning at the write, mirroring the old Python coercion), prunes past the window. - sources/antseed.py: _load_market reads host_store.peer_offers(); the file / staleness / flatten code and the now-dead coercion helpers are removed. - Dockerfile.antseed: pin pg@8.16.3 + NODE_PATH so the writer can require it. - compose.yml: DATABASE_URL + postgres dependency for the antseed service (it already shares the llm-router-internal network with postgres). - tests: seed peer_offers (shared conftest helper) instead of market.json; new host_store peer_offers round-trip + window tests. Sovereignty (Axis 4): pg is the boring standard Postgres client, pinned, and lives only in the sidecar; no new Python dependency (psycopg is from #36). Verification: full suite 409 passed, 2 skipped, 0 failed against the compose Postgres; the real Node writer -> Postgres -> Python reader round-trip, non-dump validation and window prune checked; the full stack boots healthy and /x/market surfaces a seeded antseed peer end to end. * feat(host-store): buyer_status — antseed buyer status off the filesystem Twin of the peer_offers move: the antseed buyer's status (session pin + escrow + wallet) goes from status-<id>.json on the shared volume to the Postgres host store. With both off the filesystem, sources/antseed.py no longer touches disk and the antseed-market volume is removed entirely. Form delta: - Definition: a new `buyer_status` table holds one row per buyer pid — the raw buyer-reported fields (pinned_peer_id, deposits_available/_reserved, wallet_address, connection_state) as columns. The antseed sidecar writes it (write-status.js on the poll loop + control.js after a wallet op); sources/antseed reads it (_pinned_peer + balances). - Invariants: store raw — deposits stay the strings the buyer reports and are coerced on read, exactly as the JSON status was. Fail-soft: a missing row / store error degrades to "no pin, no balance" as a missing status file did. Behaviour preserved: _pinned_peer / balances unchanged but for the source. - Irreversible: buyer_status is new DB state; status-<id>.json is retired and the antseed-market volume (+ both mounts) is dropped. Changes: - host_store.py: buyer_status schema + a buyer_status(pid) reader; truncate hook updated. - antseed/store.js: shared buyer_status row shape + UPSERT, used by both writers so they can't drift. - antseed/write-status.js: replaces the inline node -e + atomic_write; reads `buyer status --json`, UPSERTs buyer_status, validates (non-status -> no write). - antseed/control.js: refreshStatus UPSERTs buyer_status via a pg pool instead of writing the file; still returns the fresh status for the HTTP response. - antseed/entrypoint.sh: write_status calls write-status.js; the now-dead atomic_write helper is removed; comments updated. - sources/antseed.py: _pinned_peer + balances read host_store.buyer_status; the file / json / Path / market_dir machinery is removed (no disk access). - Dockerfile.antseed: COPY store.js + write-status.js. - compose.yml: drop the antseed-market volume and its router/antseed mounts. - tests: seed buyer_status (shared conftest helper) instead of status files; new host_store buyer_status round-trip/absent test. Verification: full suite 410 passed, 2 skipped, 0 failed against the compose Postgres; the real write-status.js -> Postgres -> Python reader round-trip and non-status validation checked; all four sidecar JS files pass node --check; the full stack boots healthy and creates buyer_status on boot. * feat(host-store): calls carries served_by + tokens_cached (engine #23 bump) #3 of the operational-store migration: enrich the `calls` fact table with the two raw per-call facts the #4 route/analytics views will derive from — the executed route identity and the cache-token breakdown. Prerequisite for keying per-route stats off the ledger. - Submodule bump core 97d0333 -> 537e204 (unhardcoded-engine #23): the engine's `chosen` now carries `served_by` — the marketplace peer that served the call, or the provider itself for a direct route (never nil). Host suite green on it. - host_store.py: `calls` gains `served_by TEXT` + `tokens_cached BIGINT`, applied to existing tables via idempotent `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` (CREATE TABLE IF NOT EXISTS never alters an existing table — the store gains its first in-place migration). insert_call maps both. route_key is left unchanged: deriving a peer-granular route key from served_by is #4's job; this commit only captures the raw fact. - shim.py: `_build_x_router` surfaces `served_by` from `chosen` (tokens_cached was already there). - auth_proxy.py: the ingress threads served_by + tokens_cached off x_router into the recorded call (both stream and unary paths) -> insert_call. ttft was intentionally NOT added: nothing measures it yet, so the column would be idle (Axis 3). error_type was already a column. Verification: full suite 411 passed, 2 skipped, 0 failed against the compose Postgres; the ALTER migration applies in place on boot; a live chat records served_by + tokens_cached in `calls` end to end against engine #23. * test(host-store): guard the peer_offers/buyer_status cross-language column contract peer_offers and buyer_status are CREATEd by the Python host store but WRITTEN by the Node antseed sidecar (write-market.js, antseed/store.js) and seeded by Python test mimics (conftest). Three places must agree on the column set and nothing at runtime makes them: the readers are fail-soft, so a renamed/added/dropped column degrades antseed to "no candidates" silently -- and the unit suite can't see it, because it seeds via the Python mimic, not the real Node writer (green proves the reader works, not that Node and Python agree). Add a static contract test that parses the column list out of all three sources and asserts it matches per table. Pure text parsing: no DB, no node runtime, runs in the ordinary unit suite; red on any drift (verified by injecting a rename). The live behave e2e stays the only thing exercising the real Node writer; this guards the part that drifts. * fix(antseed): guard a non-hex ANTSEED_IDENTITY_HEX in the entrypoint Prod runs the sidecar as the image now (not the inline node command), so the entrypoint must keep the inline's safety: a CHANGE_ME / unset-secret placeholder is not a valid identity and the CLI would reject it. Unset it when it isn't a 64-hex string so the buyer falls back to a generated key on the data volume (matching the previous inline behaviour); the prod secret is a real hot-wallet.
Summary
Pointer-only bump of the embedded Σ_pol engine submodule
core:3d49132(engine #18,provider_eq) →ee31e81, which includesunhardcoded-engine#20 — preserve marketplace offer prices in policy fields.
Why
Before #20, the engine's
fields.luaread the provider-family aggregate(
ctx.state.ema[provider|family].price_*) before the candidate's ownstamped offer price. For marketplace sources such as AntSeed, multiple seller
offers sharing one provider/model-family collapsed to a single family price, so
a price-ranking policy could not actually select the cheapest seller.
This host feeds that family price itself, via
host.update_metrics(provider, family, {price_in, price_out})(
sources/__init__.py,sources/codex.py) — exactly the aggregate the enginewas reading first. It also already forwards the per-offer prices through the
discoverhook (AntSeed routable offers, OpenRouter offers), which the enginestamps onto each candidate.
So the data path was already complete host-side; the bug lived entirely in the
embedded engine's read precedence. #20 flips it to candidate-first (EMA as
fallback), so this bump alone unlocks per-offer price selection — no host
logic change required.
Note: after this bump, the per-family
update_metricsprice seed becomes afallback for unstamped/static candidates only; it is no longer the ranking
source for marketplace offers (which now rank by their own stamped price). It is
left in place as the legitimate default — harmless, not dead.
Validation
core: 3d49132 → ee31e81); no other files touched.ee31e81: 564 passed, 0 failed, 0 errors (re-run under timeout).python3on this host); CI validates.