feat: ai rle v1#8782
Conversation
|
Thank you for your contribution @farhann1! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Pull request overview
Adds a new first-party azure.ai.rle azd extension scaffold, establishing the initial command surface area and packaging/build plumbing so the extension can be built, packed, and tested prior to implementing the real RLE workflow.
Changes:
- Introduces the
azd ai rlecommand group withcreate,modify,version, and hiddenmetadatacommands (stubbed with structured “not implemented” errors). - Adds extension packaging metadata (
extension.yaml,version.txt,CHANGELOG.md) plus docs and lint/spellcheck configs for the new module. - Adds cross-platform build scripts and the Go module (
go.mod/go.sum) for the extension.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/extensions/azure.ai.rle/version.txt | Declares initial extension version. |
| cli/azd/extensions/azure.ai.rle/README.md | Documents commands and private testing workflow. |
| cli/azd/extensions/azure.ai.rle/main.go | Extension entrypoint wiring azdext.Run to the root command. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/root.go | Root command setup and subcommand registration. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/create.go | Adds create command stub + shared not-implemented error helper. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/modify.go | Adds modify command stub. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/version.go | Adds version command wiring for standard version output. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/metadata.go | Adds hidden metadata command for discovery/IntelliSense. |
| cli/azd/extensions/azure.ai.rle/internal/cmd/root_test.go | Basic test asserting expected commands are registered. |
| cli/azd/extensions/azure.ai.rle/go.mod | New Go module for the extension and dependency set. |
| cli/azd/extensions/azure.ai.rle/go.sum | Dependency checksums for the new module. |
| cli/azd/extensions/azure.ai.rle/extension.yaml | Extension manifest (id/namespace/usage/examples/version). |
| cli/azd/extensions/azure.ai.rle/cspell.yaml | Extension-local cspell configuration. |
| cli/azd/extensions/azure.ai.rle/CHANGELOG.md | Initial changelog entry for the preview scaffold. |
| cli/azd/extensions/azure.ai.rle/build.sh | Bash build script for multi-platform binaries + ldflags version injection. |
| cli/azd/extensions/azure.ai.rle/build.ps1 | PowerShell build script for multi-platform binaries + ldflags version injection. |
| cli/azd/extensions/azure.ai.rle/.golangci.yaml | Extension-local lint config (matching other extensions’ pattern). |
| cli/azd/extensions/azure.ai.rle/.gitignore | Ignores build and packaging artifact directories. |
jongio
left a comment
There was a problem hiding this comment.
Review: azure.ai.rle extension (new)
Thanks for contributing a new extension! A few items to address before this is ready.
Overview
This adds a new azd ai rle command group for managing RLE (Reinforcement Learning Environment) resources. The implementation is clean and follows the extension SDK patterns well. Tests pass and it builds cleanly.
Key items
-
Missing PR description. A 2949-line new extension needs a description explaining what RLE is, the motivation, the commands it adds, and any design decisions. Right now the body is empty.
-
Unreachable code. Five files define commands (
create,list,show,sandbox,versions) that are never registered inroot.go. These add ~500 lines of untestable surface area. Either wire them up (if intended for this PR) or remove them and add in a follow-up when they're needed. -
Cross-platform line endings.
scaffold.go:67unconditionally converts\nto\r\n. Generated Dockerfiles and Python files will have Windows line endings on Linux/macOS, which can cause issues with container builds and shebangs. -
Unquoted paths in user-facing output.
init.go:55printscd %swithout quoting. Paths containing spaces will break the suggested command. This repo's conventions require quoting paths (see AGENTS.md). -
Bearer token over HTTP. The client sends
RLE_BEARER_TOKENregardless of the endpoint scheme. Consider logging a warning (or refusing) when sending credentials over non-TLS connections to non-localhost endpoints.
See inline comments for specifics.
jongio
left a comment
There was a problem hiding this comment.
Incremental review (commit d621e52)
New deploy enhancements look well-structured. The splitImageHost/normalizeRegistryLoginServer composition is clean, and using errors.AsType for the 404 check is idiomatic Go 1.26. A few items:
Previous review items (5 findings from my earlier pass) are still unresolved: unreachable command constructors, cross-platform line endings in scaffold.go, unquoted paths in init.go, bearer token over HTTP. Please address those alongside the new work.
jongio
left a comment
There was a problem hiding this comment.
Incremental review (commits 9dc600d, 6772f58)
The invoke implementation is taking shape. The approach of fetching Loom via shallow clone plus bundled wheel is reasonable for a dev workflow. A few items need attention before this can merge.
Prior review items: 3 of 5 findings from my earlier passes remain unresolved (unreachable command constructors in root.go, cross-platform CRLF in scaffold.go, unquoted path in init.go). The bearer-token item was addressed by removal.
New findings (this commit):
-
Binary wheel without provenance (
assets/rle_sdk-0.1.3-py3-none-any.whl): Committing a pre-built.whlmakes the package un-auditable. Add a README or comment documenting where this wheel is built, what source repo/tag it corresponds to, and how a reviewer can reproduce it. Alternatively, reference a published package feed so CI can fetch it at build time instead of vendoring the binary. -
Deploy ignores stored endpoint (
deploy.go):resolveControlPlaneEndpoint("")replacedresolveControlPlaneEndpoint(state.Endpoint). If a user had an endpoint saved in.azd-rle.jsonfrom the manifest, it's now silently ignored. Was this intentional? If so, note it in the changelog. -
Fragile TOML patching (
invoke.go:ensureLoomLocalSources): String-contains checks + append-to-EOF doesn't guarantee the new lines land inside the[tool.uv.sources]section when one already exists elsewhere in the file. Consider using a TOML library or at minimum insert after the existing header line rather than at EOF. -
Most training flags are not exposed: Only 4 of ~15 parameters have CLI flags. The rest can't be overridden without editing source. Expose them or document why they're fixed.
-
ADO clone URL may require auth:
defaultLoomRecipeRepopoints tomsdata.visualstudio.com. Will this work without credentials for users outside the org? If auth is needed, surface a clear error message.
deploy doesn't need init anymore
jongio
left a comment
There was a problem hiding this comment.
The new commit (a95e826) reworks image resolution to derive per-environment image names from the environment name, with --image as an explicit override on both init and deploy. The self-bootstrapping deploy (works without prior init when rle.yaml exists) is a nice UX improvement. The errors.AsType usage and azdext.LocalError error handling are correct and idiomatic.
Three items from my earlier reviews remain unresolved:
-
scaffold.go:74
strings.ReplaceAll(content, "\n", "\r\n")forces Windows line endings on all platforms. Generated Dockerfiles and Python files will carry\r\ninto Linux containers, which can break shebang parsing and cause git diff noise on non-Windows hosts. Remove this line; let files keep native\nendings. -
init.go:57
cd %sshould use%qto quote paths that may contain spaces (per the repo's path safety convention). -
root.go Five command source files (
create.go,list.go,show.go,sandbox.go,versions.go) are included in the PR but their constructors are never registered inNewRootCommand. If planned for a follow-up, remove them from this PR to reduce the diff.
jongio
left a comment
There was a problem hiding this comment.
New commit (f3ab2d2) restores deploy changes lost in the merge conflict. The ACR build integration and image host-qualification helpers work correctly for the described use case.
One new finding: az acr build is called without verifying that az is installed (see inline comment). The invoke command checks for git and uv with exec.LookPath before calling them; the same pattern should apply here.
Three items from earlier reviews remain unresolved:
-
scaffold.go:74
strings.ReplaceAll(content, "\\n", "\\r\\n")forces CRLF on all platforms. Dockerfiles and Python files with\r\nwill break shebang parsing in Linux containers. Remove this line. -
init.go:57
cd %sneeds%qto quote paths with spaces (AGENTS.md convention). -
root.go Five command source files (
create.go,list.go,show.go,sandbox.go,versions.go) define constructors never called fromNewRootCommand. Wire them in or remove them from this PR.
Dismissing: this review was incorrectly posted as changes-requested due to an automation bug. The findings remain valid as comments.
jongio
left a comment
There was a problem hiding this comment.
Checking in on this PR. My CHANGES_REQUESTED from the previous review cycle is still active. The three core items remain unaddressed, and there's been no author response in the thread.
Still blocking (from prior reviews):
-
scaffold.go:74- forces Windows line endings on all generated files unconditionally. Dockerfiles and Python scripts with CRLF will break shebang parsing and cause issues in Linux containers. Remove thestrings.ReplaceAll(content, "\\n", "\\r\\n")call. -
init.go:57- thecdpath in user-facing output isn't quoted. Paths with spaces will break the suggested command. Use%qinstead of%s(explicit repo convention in AGENTS.md). -
root.go- five command source files (create.go, list.go, show.go, sandbox.go, versions.go) define constructors that are never registered. The test in root_test.go explicitly asserts they are NOT registered, confirming this is intentional dead code. Remove them from this PR and add them when they are ready to ship. -
deploy.go-az acr buildis invoked without verifyingazis on PATH. The invoke command checks forgitanduvbefore calling them; apply the same pattern here.
Additional item (see inline):
invoke.go(ensureLoomLocalSources) - the TOML patching approach appends lines to EOF rather than inserting under the existing[tool.uv.sources]header. If other TOML sections follow, the appended keys land in the wrong section.
@farhann1 - could you acknowledge these items or let me know if there's a reason they can't be addressed? Happy to discuss tradeoffs.
jongio
left a comment
There was a problem hiding this comment.
Checked the 2 new commits since my last review (cli optimizations + cross-platform path fixes). Clean improvements: dead code removal, better error messages with endpoint visibility, max retry cap on sandbox lease, addEventListener over inline onclick, relative paths in init output, and deploy image naming now includes project prefix to prevent collisions. Tests updated appropriately. Looks good.
@microsoft-github-policy-service agree company="Microsoft" |
jongio
left a comment
There was a problem hiding this comment.
Incremental review of 1 new commit (e8cfe20 - README update). Editorial improvements only: simplified wording, reorganized .azd-rle.json docs. No code changes. Prior approval stands.
Minor nit: file is missing a trailing newline, but not blocking.
trangevi
left a comment
There was a problem hiding this comment.
Leaving a blocking comment for now, pending review of both the code and broader spec review
RickWinter
left a comment
There was a problem hiding this comment.
This adds the preview azd ai rle extension: an OpenEnv-style init/run/deploy/invoke flow gated behind AZD_AI_RLE_ENABLE. The overall structure is sound. The command tree follows the extension SDK conventions, path handling in build.go/scaffold.go is careful (Dockerfile paths are validated against the source root, symlinks and .git are skipped on copy), and the sandbox lifecycle in invoke.go is well built. In particular releaseRemoteSandbox deliberately uses a fresh context.Background() with its own timeout, so the deferred release still runs when the user exits the shell with Ctrl-C and the request context is already cancelled. That is the right call and avoids a sandbox leak.
The one item to resolve before merge is in client.go: isLocalControlPlaneEndpoint is defined but never called. With unused enabled in the extension's .golangci.yaml, this should fail the lint gate, which means the "golangci-lint 0 issues" run in the description did not cover this path. It also reads like a dropped guard, since the control plane client sends no auth and RLE_ENDPOINT can point at a remote host. See the inline note for the specifics and the two ways to resolve it.
No other blockers. Given the dead code should break the unused linter, you may prefer to submit this as REQUEST_CHANGES rather than a comment; I have left the draft as COMMENT so you can decide. Everything else can follow as normal preview iteration.
RickWinter
left a comment
There was a problem hiding this comment.
This adds the preview azd ai rle extension, hidden behind AZD_AI_RLE_ENABLE, for source-first OpenEnv/RLE workflows: init copies a sample into a session folder, run builds and runs it locally in Docker, deploy pushes an image to ACR and creates or updates the environment on the control plane, and invoke leases a remote sandbox and opens an OpenEnv shell plus a local proxy UI. The overall shape is right: it is self-contained under extensions/, the LocalError and path-safety helpers (isSafeRelativePath, isPathWithinRoot) are consistent with the framework, and the command surface is gated correctly.
A few things worth resolving. The init clone pins to the upstream main branch of a third-party repo (huggingface/OpenEnv), so init is non-reproducible and that code is then built into the runtime image and pushed to the user's ACR on deploy; pinning to a tag or commit SHA would remove both the reproducibility gap and the supply-chain surface. Separately, the control-plane client sends no authentication, which is fine for the http://localhost:5000 default but is worth a decision for a remote RLE_ENDPOINT.
Two nits that are correct to leave for a preview: the banner art spells FOUNDRY, and openEnvInvokeFlags carries several fields the invoke command never wires.
None of this blocks a preview surface. The unpinned clone is the one I would address before merge; the rest can follow.
trangevi
left a comment
There was a problem hiding this comment.
Generally I approve the code for a PrPr
JeffreyCA
left a comment
There was a problem hiding this comment.
In the future, you can use azd x init --internal to automatically scaffold all the required 1P specific extension files
jongio
left a comment
There was a problem hiding this comment.
Incremental review of bab9130 (fix: address review comments).
Flag type split into
emoteInvokeFlags, localRunFlags, and openEnvCallFlags is clean. The new project_endpoint.go module validates and normalizes the Foundry endpoint correctly, with good test coverage for both happy path and error cases. State migration from Project to ProjectEndpoint is consistent across deploy and invoke.
No new issues.
|
In terms of general housekeeping we may want to create a separate GitHub label like |
jongio
left a comment
There was a problem hiding this comment.
Incremental review of f5798ac (addressing prior feedback). The refactoring looks good: local container lifecycle cleanly separated into run.go, utility code extracted to focused modules (docker.go, runtime.go, identifiers.go), and tests are thorough. CODEOWNERS and CI added. One note: actionlint CI is failing on the new workflow file.
JeffreyCA
left a comment
There was a problem hiding this comment.
Thanks, scaffolding files look good 👍
Summary
Adds the preview
azd ai rleextension for source-first RLE/OpenEnv environment workflows.The extension supports initializing an OpenEnv-style sample, running it locally in Docker, deploying/registering it with the RLE control plane, and invoking a remote sandbox for interactive testing.
Changes
AZD_AI_RLE_ENABLE=true.azd ai rle init [environment-name]to copy the default OpenEnv echo sample and create.azd-rle.json.azd ai rle runfor local Docker build/run,/healthreadiness,/weblaunch, OpenEnv shell, and optional--watch.azd ai rle deployto build/push an ACR image and create/update the RLE environment.azd ai rle invoketo lease a remote sandbox, open the sandbox/proxy UI, start the OpenEnv shell, and release the sandbox on exit.name,project,environmentId, andenvironmentVersion.Notes
AZD_AI_RLE_ENABLE=true.RLE_ENDPOINTand defaults tohttp://localhost:5000.AZURE_CONTAINER_REGISTRY_ENDPOINTand publishes images as<registry>/<project-id>-<environment>:latest.Validation
go test .\internal\cmdgo build -o bin\azure-ai-rle-windows-amd64.exe .cspell lint 'extensions/**/*.go' 'extensions/**/*.md' --config ./.vscode/cspell.yaml --no-progressgit diff --check