fix: resolve toolbox $ref config before deploy#9148
Conversation
🔗 Linked Issue RequiredThanks for the contribution! Please link a GitHub issue to this PR by adding |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 21 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Resolves local $ref configurations for Azure AI toolbox services before deployment.
Changes:
- Adds project-root-aware
$refresolution. - Preserves inline and legacy config parsing.
- Adds referenced-file test coverage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
README.md |
Removes trailing whitespace. |
service_target.go |
Resolves toolbox configuration references. |
service_target_test.go |
Tests referenced toolbox configuration parsing. |
| b, err := json.Marshal(props.AsMap()) | ||
| values := props.AsMap() | ||
| if projectRoot != "" { | ||
| resolved, err := foundry.ResolveFileRefs(values, projectRoot) |
| return nil, fmt.Errorf( | ||
| "resolving toolbox service %q config: %w", | ||
| svc.GetName(), | ||
| err, | ||
| ) |
jongio
left a comment
There was a problem hiding this comment.
Two things in the new $ref resolution are worth sorting before this merges.
-
parseToolboxServiceConfigAtRootwraps theResolveFileRefserror withfmt.Errorf("...: %w")(service_target.go:360).ResolveFileRefsalready returns a structured*azdext.LocalError(foundry/errors.go:15-21), and this extension's own AGENTS.md:93-98 says not to wrap an already-structured error: during gRPC serialization azd keeps the inner error's message/code/category and drops the outer text, so theresolving toolbox service %q configcontext is lost anyway. Returnerrdirectly, or fold the toolbox name into a fresh structured error. -
containsToolboxFileRefplusResolveFileRefsresolve every$refanywhere in the config, not just the service-entry include (service_target.go:388, foundry/includes.go:84-113). The schema allowstoolswithtype: openapiandadditionalProperties: true(schemas/azure.ai.toolbox.json:17-27), and real OpenAPI documents carry JSON-pointer refs like#/components/schemas/Foo.refTargetPathdoesn't treat those as remote, so they get joined onto projectRoot andloadRefFilefails withcannot read $ref file. Before this change those inline specs were passed through verbatim, so this is a deploy regression for openapi tools. Can resolution be scoped to the include points you actually support (service entry, deployment array items) instead of walking into tool payloads?
Both reproduce against the current diff. Confirmed the extension builds and the parse tests pass locally, so this is behavior and convention, not a compile break.
Why this PR is needed
Toolbox service configuration can be written inline in
azure.yamlor loaded from a local file with$ref. The deploy path previously parsed the$refobject as the toolbox configuration instead of loading the referenced file. As a result, deployments using file-based toolbox configuration could omit the description and tools defined in that file, or fail to deploy with the expected configuration.This fix resolves local
$reffiles relative to the project root before parsing the toolbox configuration. Inline configuration and the legacyconfig:shape continue to use the existing behavior. This keeps file-based and inline configuration consistent at deploy time.Changes
$reffile includes withfoundry.ResolveFileRefswhen a reference is present anywhere in the service configuration.config:parsing behavior when no$refis present.Testing
go build ./...incli/azd/extensions/azure.ai.toolboxesgo test ./internal/cmd/...incli/azd/extensions/azure.ai.toolboxes