Skip to content

feat(evaluator-sdk): typed workspace seed sources (inline/path/fileset)#563

Merged
SandyChapman merged 1 commit into
mainfrom
codex-seed-sources/schapman
Jul 6, 2026
Merged

feat(evaluator-sdk): typed workspace seed sources (inline/path/fileset)#563
SandyChapman merged 1 commit into
mainfrom
codex-seed-sources/schapman

Conversation

@SandyChapman

@SandyChapman SandyChapman commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

Follow-up to the general Codex runtime (#562). A task's inputs["files"] seed map now accepts three JSON-serializable seed shapes, chosen by a kind discriminator (a bare string stays sugar for inline text):

kind Source Resolvable where
inline contents in the task (encoding="base64" for binary) anywhere — fully portable
path a file on the authoring host only there (local-authoring convenience)
fileset a workspace/name#glob reference only where the Files service is reachable (service-side)

The three differ in where they resolve, which is what governs a task's portability — the reason a bare string alone (which can't tell content from a path from a ref) isn't enough.

Layering

  • inline + path resolve in the pure-SDK runtime (no platform dependency).
  • fileset raises a clear "cannot be resolved in local execution" error — the same pattern as metric-reference resolution. It's reserved for the service-side path; a later change will resolve filesets there and normalize inline/path seeds into a fileset at the local→remote submit boundary (mirroring inline-metric → derived-metric normalization).

Shape

  • New agent_eval/workspace_seeds.py: the SeedFile discriminated union (InlineSeed/PathSeed/FilesetSeed), parse_seed, and the seed_workspace resolver — with workspace-escape protection and binary (base64) support.
  • The Codex runtime delegates to seed_workspace; its private _seed_workspace is gone.
  • AgentEvalTask.inputs stays a generic dict[str, Any] — seeding remains a documented convention over inputs["files"], not a core task field.

Testing

  • New test_workspace_seeds.py (inline/base64/path/fileset/escape/unknown-kind); updated the Codex runtime's escape test (now WorkspaceSeedError).
  • Full agent_eval suite (91) + plugin test_agent_evaluate.py pass; ruff/format clean; CI lint-python-types.sh exit 0.

Stacked on #562 — targets codex-runtime-general-coding/schapman; review/merge after it.

Summary by CodeRabbit

  • New Features
    • Added a workspace seeding system supporting inline content, local file copies, and extensible custom seed handlers.
    • Added fileset seed support to load a single file from a referenced dataset into the workspace.
  • Bug Fixes
    • Improved workspace safety by rejecting seed paths that could escape the workspace.
    • Standardized invalid/unsupported seed failures under WorkspaceSeedError, and ensured seeding runs off the main event loop.
  • Tests
    • Added coverage for seed parsing, workspace writing, fileset handling, and Codex runtime thread/error behavior.

@SandyChapman
SandyChapman requested review from a team as code owners July 3, 2026 15:23
@github-actions github-actions Bot added the feat label Jul 3, 2026

@arpitsardhana arpitsardhana left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just ensuring that my understanding is correct: that SDK may have files awareness so that we don't have too many duplicates files between SDK and plugin but SDK won't have any dependency or do resolution of files.

Comment thread packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/workspace_seeds.py Outdated
@SandyChapman
SandyChapman force-pushed the codex-runtime-general-coding/schapman branch from cab7311 to 0928ad6 Compare July 3, 2026 17:09
Base automatically changed from codex-runtime-general-coding/schapman to main July 3, 2026 17:36
@SandyChapman
SandyChapman force-pushed the codex-seed-sources/schapman branch from 7e41506 to 73dc920 Compare July 3, 2026 18:00
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 99b7cedc-8dc6-4a16-8ffb-0235d2e7126c

📥 Commits

Reviewing files that changed from the base of the PR and between be2593b and 6fd4691.

⛔ Files ignored due to path filters (2)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/codex/runtime.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/workspace_seeds.py is excluded by !sdk/**
📒 Files selected for processing (7)
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/workspace_seeds.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_codex_runtime.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_workspace_seeds.py
  • plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/tests/test_agent_seeds.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py
  • plugins/nemo-evaluator/tests/test_agent_seeds.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/workspace_seeds.py

📝 Walkthrough

Walkthrough

Adds shared workspace seed parsing/writing, updates Codex runtime to use it, and registers a fileset seed handler plugin with tests.

Changes

Workspace Seed System

Layer / File(s) Summary
Workspace seed core module (types, registry, resolution, write)
packages/nemo_evaluator_sdk/.../workspace_seeds.py, packages/nemo_evaluator_sdk/tests/agent_eval/test_workspace_seeds.py
Defines InlineSeed/PathSeed, WorkspaceSeedError, SeedHandler, parse_seed, and seed_workspace; tests cover parsing, writing, custom handlers, and traversal rejection.
Codex runtime integration with seed_workspace
packages/nemo_evaluator_sdk/.../runtimes/codex/runtime.py, packages/nemo_evaluator_sdk/tests/agent_eval/test_codex_runtime.py
Runtime now imports and calls shared seed_workspace/SEED_FILES_INPUT_KEY, removes its local seeding helper, and updates the escaping-path test to expect WorkspaceSeedError.
Fileset seed handler plugin
plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py, plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py, plugins/nemo-evaluator/tests/test_agent_seeds.py
Adds FilesetSeed/FilesetSeedHandler, registers it on import, wires the import into job startup, and tests ref validation plus single- and multi-file resolution.

Possibly related PRs

Suggested reviewers: ngoncharenko, arpitsardhana

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: typed workspace seed sources for inline, path, and fileset inputs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex-seed-sources/schapman

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py (1)

108-119: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Offload workspace seeding from the event loop. seed_workspace(...) is sync, and the registered fileset handler does blocking Files-service I/O via download_dataset_sync(), so this coroutine can stall every task sharing the loop. await asyncio.to_thread(seed_workspace, ...) here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py`
around lines 108 - 119, The runtime setup in the Codex executor is doing
synchronous workspace seeding on the event loop, which can block other tasks.
Update the code in the run path around seed_workspace in the runtime class so
the seeding work is executed via asyncio.to_thread instead of directly calling
the sync function, and keep the existing guarded try block and process creation
flow intact.
🧹 Nitpick comments (1)
plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py (1)

38-46: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Ref validation allows .. as a segment.

"../name" passes the shape check (splits into ["..", "name"], length 2), letting a traversal-like workspace segment reach the Files service unvalidated.

🔧 Proposed fix
-        if len(parts) != 2:
+        if len(parts) != 2 or any(part in {".", ".."} for part in parts):
             raise ValueError(f"fileset ref must be 'workspace/name' or 'workspace/name#path', got {value!r}")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py` around lines 38 -
46, The _validate_ref_shape validator in agent_seeds.py only checks segment
count and still allows traversal-like segments such as ".." in ref. Update the
ref validation to reject "." and ".." (and any other unsafe path segments) after
splitting the base workspace/name part, while keeping the existing
workspace/name or workspace/name#path shape check. Use _validate_ref_shape as
the fix point and preserve the current ValueError style for invalid refs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py`:
- Around line 57-72: The FilesetSeedResolver.resolve path is blocking the Codex
async runtime by calling download_dataset_sync() during seed resolution. Update
resolve() to use the async download flow instead, or offload the download work
to a worker thread before reading the file bytes, so seed_workspace() does not
block the event loop while resolving FilesetSeed entries.

---

Outside diff comments:
In
`@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py`:
- Around line 108-119: The runtime setup in the Codex executor is doing
synchronous workspace seeding on the event loop, which can block other tasks.
Update the code in the run path around seed_workspace in the runtime class so
the seeding work is executed via asyncio.to_thread instead of directly calling
the sync function, and keep the existing guarded try block and process creation
flow intact.

---

Nitpick comments:
In `@plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py`:
- Around line 38-46: The _validate_ref_shape validator in agent_seeds.py only
checks segment count and still allows traversal-like segments such as ".." in
ref. Update the ref validation to reject "." and ".." (and any other unsafe path
segments) after splitting the base workspace/name part, while keeping the
existing workspace/name or workspace/name#path shape check. Use
_validate_ref_shape as the fix point and preserve the current ValueError style
for invalid refs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 9f20d2f0-6661-46ca-aa02-6a857a209f1c

📥 Commits

Reviewing files that changed from the base of the PR and between dbad966 and 73dc920.

⛔ Files ignored due to path filters (2)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/codex/runtime.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/workspace_seeds.py is excluded by !sdk/**
📒 Files selected for processing (7)
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/codex/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/workspace_seeds.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_codex_runtime.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_workspace_seeds.py
  • plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/tests/test_agent_seeds.py

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/agent_seeds.py
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 22965/30094 76.3% 61.2%
Integration Tests 13222/28774 46.0% 19.2%

@SandyChapman
SandyChapman force-pushed the codex-seed-sources/schapman branch from 73dc920 to be2593b Compare July 3, 2026 18:38
Extends the workspace seeding added for the general Codex runtime. A task's
inputs["files"] map now accepts three JSON-serializable seed shapes, chosen by a
`kind` discriminator (a bare string stays sugar for inline text):

- inline  — contents in the task; resolvable anywhere. `encoding="base64"` for binary.
- path    — a file on the authoring host; local-only.
- fileset — a workspace/name#glob reference; platform-resolved.

The three differ in *where* they resolve, which is what governs a task's
portability. inline + path resolve in the pure-SDK runtime; fileset raises a
clear "cannot be resolved in local execution" error (same pattern as metric-ref
resolution) and is reserved for the service-side path, where a follow-up will
resolve filesets and normalize inline/path seeds into a fileset at submit time.

Adds `agent_eval/workspace_seeds.py` (the SeedFile union + `seed_workspace`
resolver, with workspace-escape protection and binary support). The Codex runtime
delegates to it; AgentEvalTask.inputs stays a generic dict — seeding remains a
documented convention, not a core task field.

Signed-off-by: Sandy Chapman <schapman@nvidia.com>
@SandyChapman
SandyChapman force-pushed the codex-seed-sources/schapman branch from be2593b to 6fd4691 Compare July 6, 2026 12:31
@SandyChapman
SandyChapman added this pull request to the merge queue Jul 6, 2026
Merged via the queue into main with commit bcdcc22 Jul 6, 2026
55 checks passed
@SandyChapman
SandyChapman deleted the codex-seed-sources/schapman branch July 6, 2026 12:59
arpitsardhana pushed a commit that referenced this pull request Jul 9, 2026
…t) (#563)

Extends the workspace seeding added for the general Codex runtime. A task's
inputs["files"] map now accepts three JSON-serializable seed shapes, chosen by a
`kind` discriminator (a bare string stays sugar for inline text):

- inline  — contents in the task; resolvable anywhere. `encoding="base64"` for binary.
- path    — a file on the authoring host; local-only.
- fileset — a workspace/name#glob reference; platform-resolved.

The three differ in *where* they resolve, which is what governs a task's
portability. inline + path resolve in the pure-SDK runtime; fileset raises a
clear "cannot be resolved in local execution" error (same pattern as metric-ref
resolution) and is reserved for the service-side path, where a follow-up will
resolve filesets and normalize inline/path seeds into a fileset at submit time.

Adds `agent_eval/workspace_seeds.py` (the SeedFile union + `seed_workspace`
resolver, with workspace-escape protection and binary support). The Codex runtime
delegates to it; AgentEvalTask.inputs stays a generic dict — seeding remains a
documented convention, not a core task field.

Signed-off-by: Sandy Chapman <schapman@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants