Skip to content

rollout: shared miles-side layer for agent-function legs (session URL, sandbox credentials) - #2805

Merged
nblintao merged 9 commits into
mainfrom
tao/agentic-shared-layer
Sep 2, 2026
Merged

rollout: shared miles-side layer for agent-function legs (session URL, sandbox credentials)#2805
nblintao merged 9 commits into
mainfrom
tao/agentic-shared-layer

Conversation

@nblintao

@nblintao nblintao commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Moves the logic that the OpenEnv, NeMo Gym and Harbor agent-function legs had in identical copies into a shared package, miles/rollout/agentic/, and gives it direct unit tests that need no provider account or real key. Zero behaviour change; independent of #2801/#2802 (base: main). Tracking: #2804.

  • session.pyresolve_session_url (append /v1, rewrite the host to MILES_ROUTER_EXTERNAL_HOST): three byte-identical copies become one; the legs import it.
  • credentials.py — the sandbox-provider credential contract from the OpenEnv launcher: PROVIDER_CREDENTIALS, sandbox_key_supply (forward the key file's path, never the value — the value would ride ray's runtime_env in plaintext), forward_address, preflight_sdk, and the worker-side resolve_provider_api_key.

The package stays torch-free (asserted by a test): the NeMo Gym adapter must load on CPU-only hosts.

Tests — no real keys

Everything here is env vars + files, so tests/fast/rollout/agentic/ covers the whole contract with tmp files and monkeypatch: the spec table's shape, forwarded vars never credential-shaped, userinfo-URL rejection, every sandbox_key_supply branch (incl. empty/unreadable key files and Modal's token pair), preflight_sdk both outcomes, resolve_provider_api_key all four supplies, session-URL shaping, torch-free import. The OpenEnv example keeps only its own obligations (every registered backend has a spec naming a real launcher arg).

Mechanical move — reproducible

8 commits per .claude/skills/mechanical-refactor-verify: the 3 relocations are mechanical_provable with byte-for-byte reproduce proofs (chain verdict PASS, 3/3); the 5 non_mechanical_provable commits are small and single-purpose (two pre-move renames, the dedupe that points the legs at the shared functions, a message-prefix cleanup, the tests).

Proof folder: https://gist.github.com/nblintao/6e3d73bdbf74044244fd1d2cdea1f31d — re-run with:

gh gist clone 6e3d73bdbf74044244fd1d2cdea1f31d proof && mkdir -p proof/repro_scripts && mv proof/[0-9a-f]*.py proof/repro_scripts/
python3 .claude/skills/mechanical-refactor-verify/scripts/mechanical_refactor_reproduction_cli.py \
    --base main --branch tao/agentic-shared-layer --proof proof

Two proofs are hand-written Repros (the generator mis-inferred those recipes); both compose only whitelisted primitives. One repo fact the proofs surfaced: [tool.isort] ignore_whitespace = true means isort never inserts the section blank line before first-party imports, so the new imports use the adjacent form the tooling reproduces.

@nblintao
nblintao marked this pull request as ready for review August 31, 2026 21:10

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

nblintao and others added 8 commits August 31, 2026 17:10
…e helpers about to become shared, in place

The launcher's credential helpers (PROVIDER_CREDENTIALS, sandbox_key_supply,
forward_address, preflight_sdk) and the two legs' resolve_session_url lose
their leading underscore ahead of moving into miles/rollout/agentic/, so the
move commits relocate them unchanged. The comment block above
PROVIDER_CREDENTIALS is dropped here; the move rewrites it as the new
module's docstring (a relocation cannot carry a comment). Also adds the empty
package marker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…er credential contract into miles.rollout.agentic.credentials

PROVIDER_CREDENTIALS, forward_address, sandbox_key_supply and preflight_sdk
leave openenv_launch_common.py unchanged; the launcher imports them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e): rename the recipe's key resolver ahead of moving it

tb2_sandbox_daytona / tb2_sandbox_e2b each define a zero-argument
resolve_api_key() wrapper around the recipe's three-argument one; once the
latter is imported into those modules it would be shadowed by the wrapper.
Rename it to resolve_provider_api_key in place first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ve the worker-side key resolution next to the launcher-side contract

resolve_provider_api_key (env var, else key file) leaves tb2_sandbox_recipe.py
unchanged and joins miles.rollout.agentic.credentials; the per-provider
wrappers in tb2_sandbox_daytona / tb2_sandbox_e2b import it from there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ssion_url into miles.rollout.agentic.session

The session-URL shaping (append /v1, rewrite the host to
MILES_ROUTER_EXTERNAL_HOST) leaves openenv_agent_function.py unchanged; the
OpenEnv leg imports it. The NeMo Gym and Harbor legs switch to it next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…and Harbor legs use the shared resolve_session_url

The NeMo Gym adapter's byte-identical copy is deleted; the Harbor client's
inline copy of the same shaping becomes a call (its rewrite of
session_server_id stays, that is Harbor-specific). Adds tests for the shared
package, including that it imports without torch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… the openenv prefix from the credential-supply messages

The messages moved in from the OpenEnv launcher; in the shared module the
provider name is the subject, not one leg's name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…st the credential contract where it lives

The contract tests move from the OpenEnv example's test package (where they
reached the module through the launcher's re-exports) to
tests/fast/rollout/agentic/test_credentials.py, importing it directly, and
grow the coverage the module lacked: preflight_sdk on both outcomes,
resolve_provider_api_key (env wins / file fallback / default-path expansion /
missing names both supplies), and an unreadable key path counting as absent.
The example keeps only its own obligations: every registered backend has a
spec, and every spec names a real launcher arg.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nblintao
nblintao force-pushed the tao/agentic-shared-layer branch from 7873319 to 8cb2be7 Compare August 31, 2026 21:11
… the semantic-default register_cpu_ci headers

tests/ci enforces that the default form is not spelled out under tests/fast/;
collect_tests synthesises the equivalent registry entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Shi-Dong

Shi-Dong commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@claude review always

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code review found no issues

No high-confidence issues detected in this change.

@Shi-Dong Shi-Dong 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.

LGTM!

@nblintao
nblintao merged commit 6f6ecfd into main Sep 2, 2026
26 checks passed
@nblintao
nblintao deleted the tao/agentic-shared-layer branch September 2, 2026 03:17
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