Add omnilingual-gaia2 to README and support easier evaluations launch - #106
Merged
Conversation
Evaluating facebook/omnilingual-gaia2 previously meant downloading the parquet
shards by hand, converting them with mt/scripts/data/parquet_to_json.py, and
pointing [target].dataset_root at the result. The runner already had a
HuggingFace auto-download path; the only thing missing was a language dimension.
The dataset's parquet columns (scenario_id, scenario) and HF split (test)
already match what download_hf_dataset() reads. The single mismatch was that the
HF config name was derived from the split alone, while this dataset publishes 40
configs named {language}_{split}.
[target]
dataset = "facebook/omnilingual-gaia2"
language = "spa_Latn"
- config.py: MULTILINGUAL_SPLITS, TargetConfig.language, language-aware
_normalize_splits so "all" means the four translated capabilities, and
rejection of language with scenario/dataset_root or a malformed code.
- hf_dataset.py: language parameter; the HF config name is prefixed while the
split directory keeps its bare name, which is what _infer_result_split relies
on; cache key suffixed per language.
- cli.py: threaded through run-config, a new run-dataset --language, the
--dry-run summary, and saved run metadata.
Omitting language leaves every path byte-for-byte unchanged, including the cache
directory name, so existing populated caches stay valid. Regression tests pin
that.
Also fixes a pre-existing bug: the split directory was created before the
download, so a failed or interrupted fetch left a partial directory that the
next run's cache check accepted, silently reusing an incomplete split. The
handler now removes it, and catches BaseException so Ctrl-C cleans up too.
Verified end to end with a pass@3 run on the published dataset: OpenClaw with a
local vLLM Qwen3.6-27B agent and a gpt-oss-120b judge, multilingual judge
prompts, correct per-split reporting, and language recorded in run_config.json.
caciolai
force-pushed
the
caciolai/omnilingual-gaia2-readme
branch
from
August 26, 2026 07:10
5f7c35d to
c4be02f
Compare
caciolai
marked this pull request as ready for review
August 26, 2026 07:11
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
[target].languageas a new TOML attribute to evaluate 🤗 facebook/omnilingual-gaia2 through the existing HuggingFace auto-download path.Before this change, running the dataset meant doing the data plumbing by hand:
hf download, thenmt/scripts/data/parquet_to_json.pyto convert the parquet shards, then[target].dataset_rootat the converted tree.The dataset's parquet columns are
scenario_id+scenarioand its HF split istest, exactly whatdownload_hf_dataset()already reads.The only mismatch was that the runner derived the HF config name from the split alone, while the dataset publishes 40 configs named
{language}_{split}(10 languages x 4 capabilities).Now:
Omitting
languageleaves every existing code path byte-for-byte unchanged, including theon-disk cache layout, so current users see no difference.
🎯 Type of Change
Also fixes one latent bug found along the way (see Incidental fixes).
🏗️ Meta Agents Research Environments Components Affected
are/simulation/environment.py,are/simulation/core/, environment setup/configuration)are/simulation/gui/, web interface, client-side components)are/simulation/scenarios/, scenario definitions, scenario runner)are/simulation/agents/, agent implementations)🔗 Related Issues
Follows #104, which added Omnilingual-GAIA2 translation and the multilingual judge prompts.
🧪 Testing Strategy
Test Details
Unit tests
249 pass in
gaia2-cli/runner(was 225; +24 new).New
tests/test_hf_dataset.py(12 new tests) that works offline, providing coverage for these cases:spa_Latn_search;<cache>/<language-keyed>/search/;tests/test_run_config.py(+11 additional tests) covers:languageround-tripping,"all"excludingtime,rejection of
time/scenario/dataset_root/malformed codes, the--dry-runoutput, andrun-dataset --languageforwarding and metadata.tests/test_cli_judge_config.py(+1 test) pinslanguageintorun_config.json.End-to-end
A full pass@3 run completed on a GPU node with podman, OpenClaw, a local vLLM serving
Qwen/Qwen3.6-27Bas the agent (port 8000) andgpt-oss-120bas the judge withreasoning_effort: low(port 8001):Cold download resolved the right config and materialized real data:
A second invocation logged
Using cached dataset at ...instead of re-downloading.Cache layout follows its design:
~/.cache/gaia2/hf_datasets/facebook_omnilingual-gaia2_spa_Latn/{execution,search}/.pass@3 completed across three runs, with the aggregation and per-split breakdown
both working:
The
executionlabel confirms_infer_result_splitstill resolves the split correctly from the language-keyed cache root.run_config.jsonrecords the new field, and notably carries notimesplit:Error path: a nonexistent language produced a
UsageErrornaming the config it tried,listing all 40 available configs, and leaving no partial cache directory.
🤖 AI Usage Declaration
Written with Claude Code (Opus 5) throughout: codebase exploration, the implementation plan,
the code and tests, and this description.
Author reviewed the code, ran the end-to-end evaluation, and edited this PR extensively.
📸 Screenshots/Recordings
N/A — no UI changes.
None.
languageis optional, and every branch it touches falls back to current behaviour when it is absent:~/.cache/gaia2/hf_datasets/stay valid and no one re-downloads.CANONICAL_SPLITS(includingtime) with no language.A dedicated regression test pins each of these.
Incidental fixes, addressed here
Partial cache directories after a failed or interrupted download.
A failed fetch left a directory that the next run accepted, silently resolving zero (or a truncated set of) scenarios for that split.
The download is now wrapped so the directory is removed on failure, and the error names the config and lists what is available.
The handler catches
BaseException, notException, specifically so that a Ctrl-C mid-download also cleans up rather than leaving a half-populated split cached andKeyboardInterruptis re-raised untouched.Pre-existing; not specific to this feature.
Known limitations, not addressed here
Three pre-existing issues surfaced while testing. All are out of scope; each is worth its own
issue.
openai/-prefixed model names are unreachable for the judge.judge/engine.py:60prefixesopenai/foropenai-compatproviders so litellm uses the OpenAI transport, and skips that when the name already starts withopenai/.But litellm strips that prefix as provider routing — so a model genuinely served as
openai/gpt-oss-120bgoes out asgpt-oss-120band 404s.The workaround is
model = "openai/openai/gpt-oss-120b", which is what the example config uses and what therefore lands verbatim in run metadata.Implementing a more robust in-code patch would be better for UX.
Ctrl-C leaves orphaned containers.
Containers are started detached without
--rm(launcher.py:440) and removed in afinallyinside the worker thread (runner.py:350).KeyboardInterruptreaches only the main thread, so those blocks never run and the containers keep driving their agent loops against the model server.Cleanup is manual:
podman rm -f $(podman ps -aq --filter name=gaia2-).A SIGINT handler that stops live containers would fix it.
run-datasetin HF mode globs the entire cache directoryThis is different from
run-config, that restricts to the selected splits.With per-language cache dirs this stays language-correct, but
--language spa_Latn --splits searchwill still pick up other splits previously cached for that language.📋 Checklist