Skip to content

feat(bird_interact): run BIRD-Interact Lite and Full on PostgreSQL - #5473

Draft
ffrujeri wants to merge 2 commits into
ffrujeri/bird-interact-environment-serverfrom
ffrujeri/bird-interact-postgres
Draft

ffrujeri wants to merge 2 commits into
ffrujeri/bird-interact-environment-serverfrom
ffrujeri/bird-interact-postgres

Conversation

@ffrujeri

@ffrujeri ffrujeri commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #5409 (BIRD-Interact in its Environment Server), in the BIRD-Interact stack: #5465 → #5409 → this PR → #5475 (the benchmark recipe), on the BaseEnvironmentServerWithTools stack (#5346 → #5350). This PR's diff against #5409 is environment_servers/bird_interact only, in two commits: the second moves the image to the recipe and refuses follow-up test cases.

What changed

BIRD-Interact Lite and Full keep their databases in PostgreSQL; #5409 runs only SQLite (Mini-Interact). With database_engine: postgresql, a task's database is <db>_template in the PostgreSQL server of the sandbox image, and each episode starts its own sandbox from that image, so a write in one episode never reaches another. The benchmark recipe (#5475) builds the image with the databases already restored, prepares the data and runs Lite and Full.

  • grading.py has a PostgreSQL engine beside SQLite, behind the same setup, execute and grade commands. setup starts the image's server (socket only) and applies preprocess_sql to <db>_template. Each query then runs in a transaction that is rolled back, as SQLite runs each on a scratch copy.
  • Normalization follows the benchmark's rules for PostgreSQL's types: decimals to two places, half-up; dates and timestamps as YYYY-MM-DD; JSON values as sorted JSON. SQLite never returns these types, so its grading does not change.
  • The server sends the engine and the database with every runner request, uploads no database for PostgreSQL, refuses postgresql without sandbox_config.image, and names the dialect in the instructions (PostgreSQL, a sql fence; a postgresql fence is also read).
  • Follow-up test cases. A task whose follow-up has custom test_cases now fails at seed, as one with its own already did. Every Lite and Full task has a follow-up, and its phase 2 would otherwise be graded by the default test case.
Mini-Interact (#5409) Lite and Full (this PR)
Database <db>.sqlite uploaded into each episode's sandbox <db>_template in the sandbox image's PostgreSQL
Episode start Copy the file Start PostgreSQL; the image's databases are already restored
A query On a scratch copy In a transaction that is rolled back

Why

A sandbox per episode keeps #5409's lifecycle and isolation, and an image with the databases restored at build time removes its cost: BIRD-Interact's official image restores 18 databases whenever a container first starts, which would repeat in every episode. A shared PostgreSQL per worker would be cheaper still in memory, but its sandbox would outlive episodes, need a database per episode cloned from a template, and fail every episode on the worker with it. Tracking: GYMINT-646 (Linear).

Validation

Command Result
pytest environment_servers/bird_interact/tests/test_app.py 56 passed, 3 skipped. New: a follow-up with custom test cases refused at seed; the normalization rules against rows typed as PostgreSQL's driver types them (decimals half-up, a timestamp as its date, JSON with sorted keys); the runner routing a postgresql request to the image's server, committing preprocess_sql and rolling back a query, and its preview; the server refusing postgresql without an image and running an episode on bookshop_template with the engine in every request, no database uploaded, and the dialect in the instructions
Same, with decimals rounded half-even The normalization test fails, so it checks the rounding mode
ng_test +entrypoint=environment_servers/bird_interact +should_validate_data=true 56 passed, 3 skipped in the server's own venv
pre-commit run --files on the changed files Passed

Not validated yet:

  • The runner against a real server. TestPostgresDatabase (rollback, statement timeout, numeric and date grading) skips without initdb, pg_ctl and psycopg2, which neither this machine nor CI has.

Rollout evidence

N/A for now: Lite and Full withhold sol_sql (GYMINT-592), so no task runs without the ground truth, and the recipe's image is not built yet. The SQLite path is unchanged; its 37 episode tests pass as before.

Compatibility

database_engine defaults to sqlite, and sandbox_config.image to python:3.12-slim for SQLite, so existing configs run as before. Management tasks, which have custom test_cases, still fail at seed: Lite runs 195 query tasks of 300, Full 410 of 600.

🤖 Generated with Claude Code

@ffrujeri ffrujeri added feature New capabilities, enhancements, or enablement work area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers labels Nov 3, 2026
@copy-pr-bot

copy-pr-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@ffrujeri
ffrujeri added this pull request to stack #5470 November 3, 2026 02:01
@ffrujeri

ffrujeri commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 1299b61

@ffrujeri

ffrujeri commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test d7e2431

@ffrujeri

ffrujeri commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test c4d1e49

ffrujeri and others added 2 commits November 6, 2026 17:19
Lite and Full keep their databases in PostgreSQL. With
database_engine: postgresql, each episode starts its own sandbox from an
image whose build restores every database of the release once
(postgres/Dockerfile), so an episode starts PostgreSQL instead of
restoring dumps, and a write in one episode never reaches another.

- grading.py has a PostgreSQL engine beside SQLite. setup starts the
  image's server and applies preprocess_sql to <db>_template; each query
  then runs in a transaction that is rolled back, as SQLite runs each on
  a scratch copy.
- Values are normalized by the benchmark's rules for PostgreSQL's
  types: decimals to two places, half-up; dates and timestamps as
  YYYY-MM-DD; JSON values as sorted JSON. SQLite never returns these
  types, so its grading does not change.
- The server sends the engine and the database with every request,
  uploads no database for PostgreSQL, refuses postgresql without a
  sandbox image, and names the dialect in the instructions.
- Management tasks still fail at seed: their custom test_cases do not
  run yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Felipe Vieira Frujeri <ffrujeri@nvidia.com>
…use follow-up test cases

The PostgreSQL image and the Lite and Full how-to move to the benchmark
recipe (benchmarks/bird_interact, next in the stack), which also
prepares the data and runs the benchmark. The server keeps what it needs
to run on any image that holds a release's databases as <db>_template.

A task whose follow-up has custom test_cases now fails at seed, as one
with its own already did: every Lite and Full task has a follow-up, and
its phase 2 would otherwise be graded by the default test case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Felipe Vieira Frujeri <ffrujeri@nvidia.com>
@ffrujeri
ffrujeri force-pushed the ffrujeri/bird-interact-postgres branch from c4d1e49 to 58c6c91 Compare November 6, 2026 17:23
@ffrujeri

ffrujeri commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 58c6c91

This branch was previously deployed

1 inactive deployment
public — 58c6c913 Deployed Nov 6, 2026 by copy-pr-bot[bot] via release / finalize / notify #10678
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers feature New capabilities, enhancements, or enablement work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant