Commit e73a001
fix(azure.ai.agents): doctor next-step accuracy + comment correctness (review fix-ups)
Three fix-ups from the 3-reviewer consensus pass on commit 48de7e8
(range 4617dd9..48de7e8). All three reached 3/3 CONFIRM during
cross-pollination.
G1 (medium): `azd ai agent doctor` trailing block was ambiguous in
mixed deployed/undeployed projects.
resolveDoctorTrailing filtered state.Services to deployed-only BEFORE
calling ResolveAfterDeploy. The resolver then computed
`singleAgent := len(state.Services) == 1` against the filtered slice.
In a project with 2 agent services where only 1 is deployed, the
filtered slice has length 1 → singleAgent=true → resolver emits no-arg
`azd ai agent show` and `azd ai agent invoke '<payload>'`. But at
runtime, both `show` and `invoke` call resolveAgentService against the
full azure.yaml (helpers.go:577-596), which still sees both services
and either prompts interactively (TTY) or errors with
"multiple azure.ai.agent services found" (--no-prompt). The doctor's
copy-pasteable suggestion is therefore ambiguous — a foot-gun for the
user.
Fix: add a variadic AfterDeployOpts{ForceQualified bool} parameter to
ResolveAfterDeploy. Doctor passes ForceQualified=true whenever the
pre-filter azure.yaml has multiple agent services (totalServices > 1),
regardless of how many are deployed. The resolver then emits
service-qualified `show <name>` / `invoke <name> ...` commands
unconditionally in that scenario. The existing post-deploy callsite
(service_target_agent.go) and all 8 existing resolver tests continue
to work with the unchanged 3-arg form because the new parameter is
variadic.
S1 (medium): Misleading comment at doctor.go:106-107 falsely claimed
that `os.Exit(code)` runs the deferred logCleanup + azdClient.Close
("Defers above run via the explicit Close + flushed stdout writer").
Per Go semantics, os.Exit terminates immediately and deferred
functions do not run. The practical impact today is zero (the OS
reclaims the gRPC socket and log fd; neither defer has on-disk state
to flush), but a future contributor reading this comment would be
silently misled when adding cleanup-critical defers (e.g., flushing
telemetry, releasing a lock, closing a temp file).
Fix: rewrite the comment to acknowledge defers don't run, document
why it's safe today, and warn against adding cleanup-critical defers
without an explicit pre-os.Exit call.
G2 (low): doctorCachedPayload looked up the cached OpenAPI spec
keyed by serviceName (azure.yaml service name). But remote invoke
rewrites `name` to info.AgentName (the deployed Foundry name from
AGENT_<KEY>_NAME) BEFORE caching (invoke.go:694-758). When deploy
appends a suffix (the divergence documented at show.go:40-46), the
two strings differ and the cache lookup misses, causing the doctor's
trailing block to fall back to the protocol-generic literal payload.
Fix: doctorCachedPayload now first tries the deployed agent name
resolved from AGENT_<SERVICE>_NAME, then falls back to the service
name when the env var is absent or matches the service name (no
divergence). Mirrors the pattern already used by show.go and avoids a
silent cache miss in the suffix-appending case.
Rejected: G3 (GPT-5.5: extend README casing check to include
{readme.md, README.MD}). Sonnet and Opus both rejected during cross-
pollination with the same rationale: the resolver hardcodes "README.md"
in the rendered hint (`see <relPath>/README.md`), so emitting the hint
when only a non-canonical casing exists on disk would create a broken
pointer on case-sensitive filesystems. Suppressing the hint is the
correct defensive behavior.
Tests:
- nextstep/resolver_test.go: 6 new subtests covering ForceQualified
behavior (len==1+force, len==1+no-force, multi-agent force=no-op,
cached payload composition, variadic-opts behavior).
- Existing 8 ResolveAfterDeploy subtests unchanged — backward compat
verified.
Pre-flight:
- gofmt -s: clean
- go vet ./...: clean
- go build ./...: clean
- go test ./internal/cmd/...: pass (cmd 16.4s, doctor 6.7s, nextstep 6.2s)
- golangci-lint run ./...: 0 issues
- cspell: 0 issues
Smoke (single-service `hello-world-python-invocations`):
- `azd ai agent doctor`: 6 PASS, exit 0
- `azd ai agent doctor --output json`: valid envelope, schemaVersion 1.0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 3760172 commit e73a001
3 files changed
Lines changed: 151 additions & 4 deletions
File tree
- cli/azd/extensions/azure.ai.agents/internal/cmd
- nextstep
Lines changed: 65 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
107 | | - | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
108 | 115 | | |
109 | 116 | | |
110 | 117 | | |
| |||
211 | 218 | | |
212 | 219 | | |
213 | 220 | | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
214 | 234 | | |
215 | 235 | | |
216 | 236 | | |
217 | 237 | | |
218 | 238 | | |
| 239 | + | |
219 | 240 | | |
220 | 241 | | |
221 | 242 | | |
| |||
260 | 281 | | |
261 | 282 | | |
262 | 283 | | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
263 | 294 | | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
264 | 306 | | |
265 | 307 | | |
266 | 308 | | |
| |||
269 | 311 | | |
270 | 312 | | |
271 | 313 | | |
272 | | - | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
273 | 335 | | |
274 | 336 | | |
275 | 337 | | |
| |||
Lines changed: 26 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
288 | 288 | | |
289 | 289 | | |
290 | 290 | | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
291 | 307 | | |
292 | 308 | | |
293 | 309 | | |
| |||
301 | 317 | | |
302 | 318 | | |
303 | 319 | | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
304 | 323 | | |
305 | 324 | | |
306 | 325 | | |
307 | 326 | | |
| 327 | + | |
308 | 328 | | |
309 | 329 | | |
310 | 330 | | |
311 | 331 | | |
312 | 332 | | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
313 | 338 | | |
314 | | - | |
| 339 | + | |
315 | 340 | | |
316 | 341 | | |
317 | 342 | | |
| |||
Lines changed: 60 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
479 | 479 | | |
480 | 480 | | |
481 | 481 | | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
482 | 542 | | |
483 | 543 | | |
484 | 544 | | |
| |||
0 commit comments