feat: ai rle v1#8782
Conversation
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.
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 👍
jongio
left a comment
There was a problem hiding this comment.
Re-approving after rebase onto main. No extension code changes since my prior approval. The implementation is solid: proper error handling with typed errors, path traversal protection, input validation, signal handling, and good test coverage.
jongio
left a comment
There was a problem hiding this comment.
The refactoring since my last review looks good. The split of invoke into run + invoke, the new project-layer abstractions (docker.go, runtime.go, identifiers.go, build.go), and the remote playground proxy are well-structured.
The separation of concerns is much cleaner now:
un.go owns local container lifecycle, invoke.go owns remote sandbox management, and the project package provides shared Docker/build/runtime infrastructure.
A couple of minor notes (non-blocking):
- loadLocalRunState is called twice in the run path (once in �nsureLocalContainerEndpoint, once in Run()). Not a bug since it just reads a file, but you could hoist the state to avoid the redundant read.
- projectRouteSegment(state) is called inside the retry loop in createSandboxWhenImageReady but won't change between attempts. Could be hoisted above the loop.
Neither warrants blocking. The code is clean, error handling is consistent, and the security validations (path traversal checks, operation allowlist in the proxy) are solid.
|
/check-enforcer evaluate |
From mining 48 recently-merged PRs, three recurring reviewer themes reached the promotion threshold: 1. Dead code removal (go.instructions.md) — jongio flagged unused functions/types 3× in #8782. 2. CRLF in generated files (extensions.instructions.md) — jongio flagged unconditional \\r\\n in generated files 3× in #8782. 3. URL startsWith bypass (extensions.instructions.md) — richardpark-msft flagged dot-segment path-traversal bypasses 3× in #9042. Co-authored-by: Copilot <[email protected]>
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