Skip to content

fix optimize for managed agent- #9954 - #10002

Open
Jessie Li (YoYoJa) wants to merge 52 commits into
Azure:mainfrom
YoYoJa:jessli/fixManagedOptimization
Open

fix optimize for managed agent- #9954#10002
Jessie Li (YoYoJa) wants to merge 52 commits into
Azure:mainfrom
YoYoJa:jessli/fixManagedOptimization

Conversation

@YoYoJa

@YoYoJa Jessie Li (YoYoJa) commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes prompt-agent optimization behavior for both job submission and candidate application.

Prompt agents use the definition already deployed to the Foundry service, so azd ai agent optimize no longer requires local copies of the agent model, instructions, tools, or skills. Applying a candidate now persists its supported mutations to the inline prompt-agent definition in azure.yaml.

Hosted and voice-agent behavior remains unchanged.

Changes

Optimize job submission

For kind: prompt agents:

  • Detect the agent kind using the shared agentkind.Kind resolver.
  • Skip local baseline discovery and creation.
  • Skip prompts for:
    • Agent instructions
    • Skills directory
    • Tools file
    • Target agent model
  • Avoid reading local instruction, skill, and tool files.
  • Omit service-owned fields from optimization_config:
    • model
    • system_prompt
    • skills
    • tools
  • Preserve unrelated settings such as model_search_space.
  • Build the request from a sanitized copy without modifying the original configuration.

Dataset, evaluator, evaluation-model, and optimization-model handling is unchanged.

Apply an optimization candidate

For prompt agents, azd ai agent optimize apply now:

  • Loads the selected candidate’s mutation metadata.
  • Finds candidates by candidate ID or name.
  • Uses mutation keys to identify fields changed by the candidate.
  • Reads final values from the candidate configuration.
  • Writes supported mutations to the inline agent definition in azure.yaml.

Supported mappings:

Candidate configuration azure.yaml
system_prompt, systemPrompt, or instructions instructions
model model
tools tools

Mutation metadata is used only to determine which fields changed because its values may have different response shapes. Final values come from the candidate configuration endpoint.

Hosted agents do not enter this new inline-definition update path.

Tests

Added regression coverage for:

  • Starting prompt-agent optimization without local instructions, skills, tools, or model.
  • Omitting service-owned fields from prompt-agent optimization requests.
  • Preserving unrelated optimization settings and the original configuration.
  • Preserving hosted-agent request behavior.
  • Candidate lookup and missing-candidate errors.
  • Applying prompt-agent instruction and tool mutations.
  • Updating only fields listed in the candidate mutation metadata.
  • Explicitly excluding voice agents from prompt-agent mutation persistence.

Validation

  • go test ./internal/cmd
  • go build ./...

Fixes #10003

Jessie Li (YoYoJa) and others added 30 commits August 24, 2026 14:35
…zure#9754)

* feat(ai-agents): agent.yaml model and Foundry service clients

First of four stacked changes adding managed harness agent support.
This one is the data model and the HTTP clients; it adds no commands
and performs no deployment, so it can be read on its own.

agent_yaml gains the prompt agent manifest: the harness block and its
skills, environment and built-in tool controls, the memory block, tool
declarations, and the feature gate that decides which manifest features
a given harness accepts. Blocks azd interprets reject unknown keys, so
a typo such as builtin_tool for builtin_tools fails the parse instead of
deploying an agent with capabilities the author believed were off. Tools
stay untyped and pass through, so a tool newer than this build still
deploys.

agent_api gains the managed agent contract and its operations. pkg/azure
gains the Foundry data plane clients for files, projects, connections
and RAI policies; the toolsets client is removed because the service
replaced it with the connections control plane.

New spelling terms stay in the extension cspell config rather than the
shared core one, which this branch does not touch.

* fix(ai-agents): preserve inline RAI policy fields

* refactor(ai-agents): reuse unified prompt agent client

* refactor(ai-agents): reference supported sibling resources

---------

Co-authored-by: hund030 <zhihuan@microsoft.com>
* feat(ai-agents): agent.yaml model and Foundry service clients

First of four stacked changes adding managed harness agent support.
This one is the data model and the HTTP clients; it adds no commands
and performs no deployment, so it can be read on its own.

agent_yaml gains the prompt agent manifest: the harness block and its
skills, environment and built-in tool controls, the memory block, tool
declarations, and the feature gate that decides which manifest features
a given harness accepts. Blocks azd interprets reject unknown keys, so
a typo such as builtin_tool for builtin_tools fails the parse instead of
deploying an agent with capabilities the author believed were off. Tools
stay untyped and pass through, so a tool newer than this build still
deploys.

agent_api gains the managed agent contract and its operations. pkg/azure
gains the Foundry data plane clients for files, projects, connections
and RAI policies; the toolsets client is removed because the service
replaced it with the connections control plane.

New spelling terms stay in the extension cspell config rather than the
shared core one, which this branch does not touch.

* feat(ai-agents): provision and deploy prompt agents

Second of four stacked changes. Builds on the model and clients from the
previous change and adds the service target that turns a prompt agent
manifest into deployed Foundry resources.

Deployment is graph driven. The manifest is resolved into nodes for the
agent and for every resource it depends on -- memory store, connections,
skills, RAI policy -- and the graph decides creation order and reports
per node progress. Sibling resources are reconciled rather than
recreated, so a redeploy that changes nothing makes no writes.

This package is submitted whole rather than split further. The graph
types are shared by every node implementation and the nodes are
mutually referential, so any smaller cut does not compile without a
refactor that would itself need review.

* fix(ai-agents): preserve inline RAI policy fields

* refactor(ai-agents): reuse unified prompt agent client

* refactor(ai-agents): reference supported sibling resources

* refactor(ai-agents): align prompt deployment dependencies

* fix(ai-agents): constrain prompt deployment to Foundry

* fix(ai-agents): scope prompt deployment state

* fix(ai-agents): bypass tagged lookup for prompt agents

* fix(ai-agents): align prompt schema and policy contract

* fix(ai-agents): remove unshipped prompt config fallback

---------

Co-authored-by: hund030 <zhihuan@microsoft.com>
…9756)

* feat(ai-agents): agent.yaml model and Foundry service clients

First of four stacked changes adding managed harness agent support.
This one is the data model and the HTTP clients; it adds no commands
and performs no deployment, so it can be read on its own.

agent_yaml gains the prompt agent manifest: the harness block and its
skills, environment and built-in tool controls, the memory block, tool
declarations, and the feature gate that decides which manifest features
a given harness accepts. Blocks azd interprets reject unknown keys, so
a typo such as builtin_tool for builtin_tools fails the parse instead of
deploying an agent with capabilities the author believed were off. Tools
stay untyped and pass through, so a tool newer than this build still
deploys.

agent_api gains the managed agent contract and its operations. pkg/azure
gains the Foundry data plane clients for files, projects, connections
and RAI policies; the toolsets client is removed because the service
replaced it with the connections control plane.

New spelling terms stay in the extension cspell config rather than the
shared core one, which this branch does not touch.

* feat(ai-agents): provision and deploy prompt agents

Second of four stacked changes. Builds on the model and clients from the
previous change and adds the service target that turns a prompt agent
manifest into deployed Foundry resources.

Deployment is graph driven. The manifest is resolved into nodes for the
agent and for every resource it depends on -- memory store, connections,
skills, RAI policy -- and the graph decides creation order and reports
per node progress. Sibling resources are reconciled rather than
recreated, so a redeploy that changes nothing makes no writes.

This package is submitted whole rather than split further. The graph
types are shared by every node implementation and the nodes are
mutually referential, so any smaller cut does not compile without a
refactor that would itself need review.

* feat(ai-agents): CLI surface for managed harness agents

Third of four stacked changes. Adds the commands that sit on top of the
model and the deployment engine from the previous two.

azd ai agent init gains a kind and harness selection and writes the
matching manifest, including discovery of an existing Responsible AI
policy with a warn and fall back path when none can be read. list, show,
delete and invoke gain managed agent handling, with invoke supporting
streamed responses. Infrastructure synthesis learns the project endpoint
so a generated module resolves it from the environment.

Also carries the extension CHANGELOG for all four changes in this stack,
since the entries describe features that only exist once the stack is
complete.

* fix(ai-agents): preserve inline RAI policy fields

* refactor(ai-agents): reuse unified prompt agent client

* refactor(ai-agents): reference supported sibling resources

* refactor(ai-agents): align prompt deployment dependencies

* fix(ai-agents): constrain prompt deployment to Foundry

* fix(ai-agents): scope prompt deployment state

* fix(ai-agents): align prompt CLI with Foundry

* fix(ai-agents): enforce managed prompt CLI contract

* fix(ai-agents): unify prompt project context

* fix(ai-agents): bypass tagged lookup for prompt agents

* fix(ai-agents): complete managed prompt invocation

* fix(ai-agents): finalize prompt init contract

* fix(ai-agents): finalize prompt agent lifecycle

---------

Co-authored-by: hund030 <zhihuan@microsoft.com>
…ss-agents

# Conflicts:
#	cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra.go
#	cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/yaml.go
#	cli/azd/extensions/azure.ai.agents/internal/pkg/azure/foundry_toolsets_client.go
#	cli/azd/extensions/azure.ai.agents/internal/pkg/azure/foundry_toolsets_client_test.go
#	cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI 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.

🟡 Changes recommended

Unresolved compatibility, candidate lookup, environment persistence, and test-capture issues remain.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Updates managed prompt-agent optimization to use deployed definitions and persist candidate mutations to inline azure.yaml definitions.

Changes:

  • Sanitizes prompt-agent optimization requests and skips unnecessary local inputs.
  • Applies instruction, model, and tool mutations to inline definitions.
  • Adds regression coverage for optimization and candidate application behavior.
File summaries
File Review notes
cli/azd/extensions/azure.ai.agents/internal/cmd/optimize.go Critical (2 votes): Legacy file-based prompt agents are treated like inline agents, so optimization and application do not update the deployed definition.
cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_test.go No findings.
cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go Moderate (3 votes): Candidate names are sent to ID-only API paths before lookup. Moderate (1 vote): Legacy config fields are updated at the wrong YAML path. Moderate (1 vote): Prompt-agent bookkeeping is persisted as deployed runtime environment variables.
cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply_test.go Nit (2 votes): The test recorder drops array values, causing tool persistence assertions to use zero values and fail.
Review details

Suppressed comments (2)

cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go:360

  • This writes instructions, model, and tools at the service root even when the prompt definition was found under the legacy config: block. SetServiceConfigValue will therefore create unrelated top-level fields, while PromptAgentFromResolvedService continues reading the unchanged config.* values on the next deploy, so applying a candidate silently has no effect for legacy prompt-agent projects. Use the definition source to write config.<field> for the legacy shape (or explicitly migrate it before updating).
		if _, err := azdClient.Project().SetServiceConfigValue(
			ctx,
			&azdext.SetServiceConfigValueRequest{
				ServiceName: svc.Name,
				Path:        path,
				Value:       value,

cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go:224

  • envUpdates is still persisted for prompt agents. That writes .agent_configs and the candidate ID into the service's env: block; deployPromptAgent passes all service env values into the managed agent API as runtime environment variables. Since prompt deployments now use the inline mutations and do not consume local config paths, this leaks local apply bookkeeping into the deployed prompt agent; skip this local-env update for isPromptAgent while retaining the azd environment tracking.
	// Step 4: Persist OPTIMIZATION_LOCAL_DIR and OPTIMIZATION_CANDIDATE_ID onto the
	// agent definition so the deploy pipeline knows which local optimization
	// config to use. New projects carry the definition inline in azure.yaml;
	// older projects still keep it in an on-disk agent.yaml.
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/optimize.go
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go
Comment on lines +384 to +387
require.Equal(t, "Optimized instructions.", server.configValues["instructions"].value)
require.Equal(t, []any{
map[string]any{"type": "code_interpreter"},
}, server.configValues["tools"].value)

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.

recorder fixed

Copilot AI review requested due to automatic review settings September 11, 2026 09:14

Copilot AI 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.

🔵 Needs a closer look

One or more issues must be addressed before approval.

Review details

Suppressed comments (3)

Previously missed (1) — in code that hasn't changed since the last review.

cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go:208

  • Prompt-agent apply now also persists supported instructions, model, and tools mutations into the inline azure.yaml service, but the command help and file-level description still only explain writing files under .agent_configs/ and updating environment variables. Update the user-facing help to disclose this additional inline-definition change so users understand what optimize apply modifies before running azd deploy.

This issue also appears on line 339 of the same file.

cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go:342

  • The prompt-agent path advertises model as a supported mutation and has a dedicated branch here, but the added persistence test deliberately omits model from the mutation metadata and asserts that it is not written. Add a regression case with a model mutation and verify the candidate model is persisted to azure.yaml, otherwise this new update path can regress without detection.
	if hasCandidateMutation(mutations, "model") {
		if value, found := candidateConfigValue(config, "model"); found {
			updates["model"] = value
		}

cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_apply.go:360

  • When the prompt definition is in the supported deprecated service.config shape, PromptAgentFromResolvedService still returns found=true, so this branch runs, but these paths are written at the service root. The deploy resolver continues to read config.* for that shape, so the mutation is ignored and azd deploy uses the old instructions/model/tools. Select the definition source and prefix these paths with config. for AgentDefinitionSourceLegacyConfig (and cover that shape with a test).
		if _, err := azdClient.Project().SetServiceConfigValue(
			ctx,
			&azdext.SetServiceConfigValueRequest{
				ServiceName: svc.Name,
				Path:        path,
				Value:       value,
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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.

Managed agent optimize need fix

4 participants