Skip to content

feat(sandbox): decouple sandbox provider config from agent config - #1708

Merged
hemildesai merged 3 commits into
mainfrom
ansubramania/sandbox-config-decouple
Jun 29, 2026
Merged

hemildesai merged 3 commits into
mainfrom
ansubramania/sandbox-config-decouple

Conversation

@ananthsub

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1377 addressing the config-usability feedback (thread): the inline sandbox_provider: block welded provider connection/lifecycle config (and its secret) into the agent config, making it hard to swap providers.

This decouples the two. A sandbox is now a named block β€” <name>: { <provider>: {config} } β€” defined in its own provider config file, and an agent points at it by name (sandbox_provider: sandbox). The framework only ever resolves a name β†’ one provider config.

  • Single (default): ship a sandbox block; the agent defaults to sandbox_provider: sandbox.
  • Swap providers (no agent edit): every shipped provider config binds the same name sandbox, so swapping providers is swapping one +config_paths entry.
  • Multiple / mixed / same-type: give blocks distinct instance names and reference each explicitly β€” no framework change.

Changes

  • Add nemo_gym.sandbox.resolve_provider_config β€” resolves a sandbox name (from the merged config) or an inline single-key mapping to a single {provider: config} dict for create_provider.
  • Add nemo_gym/sandbox/providers/opensandbox/configs/opensandbox.yaml defining the named sandbox block.
  • Make responses_api_agents/mini_swe_agent_2 provider-neutral: sandbox_provider accepts a name (default) or inline mapping; the reference is resolved at runtime. Renamed mini_swe_agent_opensandbox.yaml β†’ mini_swe_agent_2.yaml.
  • README documents the single concept plus single / swap / multi-sandbox usage.
  • Unit tests for the resolver and the named-reference agent path.

Bottom of a 2-PR stack; the follow-up adds provider-contributed default sandbox metadata.

Refs #1377

Test plan

  • uv run pytest tests/unit_tests/test_sandbox.py tests/unit_tests/test_opensandbox_provider.py responses_api_agents/mini_swe_agent_2/tests/
  • uv run ruff check + ruff format --check clean
  • End-to-end config composition verified through GlobalConfigDictParser

close_timeout_s: 30
# Name of the sandbox to use; include a provider config that defines a
# `sandbox` block (e.g. nemo_gym/sandbox/providers/opensandbox/configs/opensandbox.yaml).
sandbox_provider: sandbox

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.

should this be sandbox_provider: opensandbox?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no this is intentional.

sandbox here is a provider-agnostic instance name, which acts as the handle that the agent references. it's not the provider type. the provider type is the inner key inside of the provider config

this is structured closer to the other gym configs

sandbox:            # instance name the agent references
  opensandbox:      # provider registry key
    connection: ...

if we ship every provider config under the same canonical name sandbox, then for the common use cases, users can swap sandbox providers without any edits to the agent config

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.

Hmm, I think it may be confusing to infer which sandbox provider was used if the agent config doesn't reference it explicitly right?

Wouldn't it be better to just switch using cli like --sandbox_provider opensandbox or --sandbox_provider daytona etc to keep it explicit?

@hemildesai
hemildesai force-pushed the ansubramania/sandbox-config-decouple branch from 95124ec to 6e51e5e Compare June 26, 2026 22:13
@copy-pr-bot

copy-pr-bot Bot commented Jun 26, 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.

hemildesai
hemildesai previously approved these changes Jun 27, 2026
@hemildesai
hemildesai force-pushed the ansubramania/sandbox-config-decouple branch from 6e51e5e to 41167a4 Compare June 27, 2026 05:22
Sandbox providers are now defined as named blocks in their own config
files (e.g. nemo_gym/sandbox/providers/opensandbox/configs/opensandbox.yaml)
that agents reference by name (sandbox_provider: sandbox). Swapping
providers becomes swapping one config path in +config_paths, with no edits
to the agent config.

- Add resolve_provider_config to resolve a sandbox name (or an inline
  single-key mapping) to a single provider config.
- Make mini_swe_agent_2's config provider-neutral and resolve the
  reference at runtime.
- Document single / swap / multiple-sandbox usage, including distinct
  instance names for mixing providers or running two configs of the same
  provider type.

Refs #1377

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
@hemildesai
hemildesai force-pushed the ansubramania/sandbox-config-decouple branch from 41167a4 to 0c907b9 Compare June 29, 2026 16:50
Signed-off-by: Hemil Desai <hemild@nvidia.com>
Signed-off-by: Hemil Desai <hemild@nvidia.com>
@hemildesai
hemildesai merged commit 3c745ff into main Jun 29, 2026
14 of 15 checks passed
kajalj22 added a commit that referenced this pull request Jun 30, 2026
…1709)

## Summary

Stacked on top of #1708.

Lets a sandbox provider config contribute default sandbox metadata* so
provider-identifying tags live with the provider rather than the
provider-neutral agent config. A sandbox block may carry an optional
`default_metadata` key:

```yaml
sandbox:
  default_metadata: { sandbox-api: opensandbox-sdk }
  opensandbox:
    connection: { ... }
```

Its entries are merged into each sandbox's `SandboxSpec.metadata`; the
agent's own `sandbox_spec.metadata` overrides them on conflict.

This restores the `sandbox-api: opensandbox-sdk` label that #1708
dropped from the agent config, now sourced from the provider config
instead.

### Changes

- Add `nemo_gym.sandbox.resolve_provider_metadata`; exclude reserved
keys (`default_metadata`) from `resolve_provider_config`.
- `mini_swe_agent_2` merges provider `default_metadata` into the sandbox
spec metadata at runtime.
- Add `default_metadata: { sandbox-api: opensandbox-sdk }` to the
opensandbox provider config; document it in the README.
- Unit tests for `resolve_provider_metadata` and the agent merge path.

Refs #1377

## Test plan

- [x] `uv run pytest tests/unit_tests/test_sandbox.py
responses_api_agents/mini_swe_agent_2/tests/test_app.py` (38 passed, 10
skipped)
- [x] `uv run ruff check` + `ruff format --check` clean
- [x] End-to-end resolution verified through `GlobalConfigDictParser`
(provider key + default_metadata)

---------

Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Signed-off-by: Hemil Desai <hemild@nvidia.com>
Signed-off-by: Kajal Jain <kajalj@nvidia.com>
Co-authored-by: Hemil Desai <hemild@nvidia.com>
Co-authored-by: Kajal Jain <kajalj@nvidia.com>
Glorf added a commit that referenced this pull request Jul 6, 2026
Rebased onto main, which merged #1708 (decouple sandbox provider config from the
agent config). Align the ECS Fargate provider with that pattern:

- Add a standalone provider config
  nemo_gym/sandbox/providers/ecs_fargate/configs/ecs_fargate.yaml -- a top-level
  `sandbox` block selected via `sandbox_provider: sandbox`, matching
  opensandbox/apptainer. Region-only; task cpu/memory/disk come from
  sandbox_spec.resources.
- Drop the agent-coupled configs/mini_swe_agent_ecs_fargate.yaml; the generic
  mini_swe_agent_2.yaml now runs on ECS by adding the provider config path.
- Bump the generic config's sandbox_spec.resources.disk_gib 20 -> 30 so it is
  valid on every provider (Fargate rejects an explicit 20; 21-200 only).
- Update the ECS Fargate docs (Fern page + agent README) to the config-paths recipe.
- Reconcile uv.lock (boto3 / botocore, sandbox extra) after the rebase.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants