feat: async + multi-source create_benchmark - #470
Open
luke-e-schaefer wants to merge 3 commits into
Open
Conversation
The server now creates a benchmark in a 'building' state and streams its
members in via a background job, responding 202 with {benchmark_id, job_id}
(this removes the previous item-count ceiling on slice/dataset-sourced
benchmarks). Update create_benchmark to match:
- POST, then by default poll the build job to completion (reusing AsyncJob)
and return the ready benchmark. Return type is unchanged, so existing
blocking callers are unaffected; a failed build raises JobError.
- Add wait_for_completion (default True) to return the 'building' benchmark
immediately for callers that want to poll themselves.
- Benchmark now exposes `status` ('building' | 'ready' | 'failed').
Bumps to 0.20.0. Stacked on #467.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror the server's multi-source benchmark creation: create_benchmark now accepts plural slice_ids and dataset_ids alongside the singular slice_id/ dataset_id/item_ids/items, and members from all provided sources are unioned and de-duplicated server-side. Requirement relaxed from "exactly one source" to "at least one source". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.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.
Stacked on #467.
What & why
Brings the SDK's
create_benchmark()in line with two server changes toPOST /nucleus/benchmarks:"building"state and streams members in via a background job, responding 202{ benchmark_id, job_id }(removes the old ~50k item cap on slice/dataset-sourced benchmarks).Changes
Async
create_benchmark()POSTs, reads{ benchmark_id, job_id }, and by default blocks on the build job (reusing the existingAsyncJobpoller) then returns the completed"ready"benchmark. Return type unchanged, so existing blocking callers are unaffected. A failed build raisesJobError(the poller already treatsErrored_Server/Errored_User/etc. as terminal).wait_for_completion=Falsereturns the"building"benchmark immediately for callers who poll themselves;verbosecontrols poll logging.Benchmarkgains astatusfield ("building"/"ready"/"failed"), parsed infrom_json.Multi-source
slice_idsanddataset_idsparams alongside the singularslice_id/dataset_id/item_ids/items. All sources combine (unioned + de-duped server-side).Meta
wait_for_completion=False,statusparsing, multi-source payload, and at-least-one-source validation.Notes
black/pre-commit/pytestweren't run locally (not installed in this env); CI's format/lint/test jobs are the authority.🤖 Generated with Claude Code
Greptile Summary
This PR updates
create_benchmark()to match two server-side changes: the endpoint now returns 202 with{benchmark_id, job_id}while a background job builds the benchmark asynchronously, and members can come from any combination ofitem_ids,items,slice_id/slice_ids, anddataset_id/dataset_ids.create_benchmark()now POSTs, extracts thejob_id, polls viaAsyncJob.sleep_until_complete(defaultwait_for_completion=True), then re-fetches the completed benchmark;wait_for_completion=Falseskips polling.Benchmarkgains astatusfield.job_id = response.get(\"job_id\")is missing from the method body —job_idis referenced but never assigned, so every default (wait_for_completion=True) call raisesNameErrorat runtime. Thewait_for_completion=Falsepath is unaffected.Confidence Score: 2/5
Not safe to merge: the default code path (wait_for_completion=True) raises NameError on every call because job_id is never assigned from the server response.
The method body references
job_idinside theif wait_for_completion:block but never extracts it fromresponse. Every call with the default arguments — the vast majority of production usage — will crash withNameError: name 'job_id' is not definedbefore any polling or benchmark fetch occurs. Thewait_for_completion=Falsepath is unaffected, but that is the minority case. The fix is a single missing line.Files Needing Attention: nucleus/init.py — the create_benchmark method body is missing
job_id = response.get("job_id"); tests/test_benchmarks.py — test_create_benchmark_from_slice_polls_then_returns_ready will also fail for the same reason.Important Files Changed
job_id = response.get("job_id")— every blocking call (wait_for_completion=True, the default) raises NameError at runtime.statusfield to the Benchmark dataclass; correctly parsed in from_json via payload.get("status").Sequence Diagram
sequenceDiagram participant Caller participant NucleusClient participant Server participant AsyncJob Caller->>NucleusClient: "create_benchmark(..., wait_for_completion=True)" NucleusClient->>Server: POST /nucleus/benchmarks Server-->>NucleusClient: "202 {benchmark_id, job_id}" Note over NucleusClient: job_id = response.get("job_id") ← MISSING LINE alt "wait_for_completion=True (default)" NucleusClient->>AsyncJob: get_job(job_id).sleep_until_complete() AsyncJob-->>NucleusClient: "job complete (status=ready)" NucleusClient->>Server: "GET /nucleus/benchmarks/{benchmark_id}" Server-->>NucleusClient: "Benchmark (status="ready")" NucleusClient-->>Caller: "Benchmark (status="ready")" else "wait_for_completion=False" NucleusClient->>Server: "GET /nucleus/benchmarks/{benchmark_id}" Server-->>NucleusClient: "Benchmark (status="building")" NucleusClient-->>Caller: "Benchmark (status="building")" endPrompt To Fix All With AI
Reviews (3): Last reviewed commit: "Update nucleus/__init__.py" | Re-trigger Greptile