Repository navigation
feat(task): read recorded runs through task_instances and find_task_instance - #124
Merged
Merged
Conversation
…nstance Plugins that read a task's recorded runs (agentenv-hf's publish, for one) had only a raw task_instances query through the document store, which the README calls internal. agent_env.task.store gains three reads on the plugin surface: task_instances (a task's runs, newest first, with a task_version filter and limit/offset), count_task_instances, and find_task_instance (None for an unknown id), returning the existing TaskInstance. The explorer's instance list and lookup routes use them, which drops the store's own bookkeeping fields (journal_seq, run_generation, rerecorded_steps) from those responses; the UI reads none of them. The README lists the reads in the plugin surface and adds a Recorded runs section with usage, and check_plugin_api.py guards them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rlap A run records only the minute it started, so task_instances sorted runs of one minute in whatever order the store returned them, and a plugin paging with limit and offset could see one run twice and miss another. The instance id is now the second sort key, which every document store and the @Local routing merge honour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # README.md
Breaking ties with instance_id ascending under created_at_utc descending matched no index, so Mongo sorted every run of the task in memory: on 2,000 runs of ~150 KB, a page past the first sorted 301 MB and failed with "Sort exceeded memory limit" on a server that can't spill to disk. Both keys now descend, and the compound indexes end in instance_id ((task_id, created_at_utc, instance_id) and the task_version one), so Mongo reads the order from the index scanned backward with no sort stage; their leading fields still serve a sort on created_at_utc alone. Co-Authored-By: Claude Opus 5.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.
What and why
A plugin that reads a task's recorded runs has no supported way to do it. agentenv-hf's
agent-env hf publish, for one, runs a rawtask_instancesquery through the document store, which is off the plugin surface and so internal. The explorer's instance routes run the same query.agent_env.task.storegains three reads, added to the plugin surface:TaskInstanceand are backed by two newTaskInstanceStoremethods (find,count) next toget.limitandoffsetneither repeats nor skips a run.task_instancesindexes now end ininstance_id:(task_id, created_at_utc, instance_id)and(task_id, task_version, created_at_utc, instance_id).created_at_utcalone.GET /api/v1/tasks/{task_id}/instancesand.../instances/{instance_id}use the new functions, which gives the reads their in-repo consumer. Their responses are now theTaskInstancefields, so the store's own bookkeeping fields (journal_seq,run_generation,rerecorded_steps) drop out. The UI reads none of them.check_plugin_api.pyUSEDgainsTaskInstanceand the three functions, under "What a plugin reads of recorded runs".TaskInstanceStore's other methods and the run-group routes.TaskInstanceStoreitself stays off the surface, so its write methods aren't frozen.!.How it was tested
pytest tst/unit/task/task_instance_reads_test.py(new, 4 tests on a realLocalSqliteDocumentStore). They cover:task_versionfilter with limit and offset, and counts;find_task_instance, includingNonefor an unknown id;register_task_instancereading back.tst/unit/explorer/explorer_app_test.pygainstest_the_instance_routes_page_newest_first_and_answer_404_for_an_unknown_run. It covers newest-first paging withtotalandhas_more, the version filter, the dropped bookkeeping field, a lookup and a 404. The existing run-route tests pass unchanged.pytest tst/unit/test_check_plugin_api.py: every surface path, the new ones included, resolves in the checkout.python .github/scripts/check_plugin_api.py --base origin/main --title "<this title>": "no break to the plugin surface".make unit-teston the branch merged with main: 6858 passed, 13 skipped (the same skips as main).Chaos testing
Two parallel runs of about 15 minutes each.
@localrouting (SQLite with SQLite, and Mongo with SQLite), DynamoDB under moto and real MongoDB 7.LIMIT <- FETCH <- SKIP <- IXSCAN(..., backward)for both the plain and the version-filtered query.agent-env runrecords (passing, scored-0, failed and cancelled runs) were served by the old and new explorer on the same store.step_attempt_failureson runs that lacked the key.Notes for review
TaskInstance, asagent-env task get-instancealready does. A record that core never writes, such as one missingtotal_stepsor with an unknown step status, now gets a 500 from those routes, where it used to be passed through raw.TaskStepStatushas only ever beensuccess/failure.After release, agentenv-hf switches to these functions and raises its framework floor.
🤖 Generated with Claude Code

Confidence Score: 5/5
The PR appears safe to merge; no outstanding finding or new issue was established.Summary
The task store now offers typed reads for recorded runs, and Explorer uses them for its instance routes. This gives plugins a supported way to read runs and keeps the route responses to
TaskInstancefields.Reviews (4) · Last reviewed commit: "fix(task): serve the tie-broken run orde..." · Reviewed by Greptile