Allow AI agent invoke to target versions#8233
Conversation
Add --version to azd ai agent invoke so remote invokes can create or reuse a session backed by a specific hosted agent version. Keep default invoke behavior unchanged and isolate persisted session/conversation state by version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
There was a problem hiding this comment.
Pull request overview
Adds hosted agent version targeting to azd ai agent invoke, allowing users to select a deployed agent version while keeping persisted state isolated per version.
Changes:
- Adds
--versionhelp, flag registration, and validation for incompatible flag combinations. - Resolves version-specific remote session IDs by creating/reusing hosted sessions.
- Adds tests for flag validation, version-specific session creation, and endpoint-derived version keys.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go |
Implements --version support, validation, remote context version keys, and version-backed session creation/reuse. |
cli/azd/extensions/azure.ai.agents/internal/cmd/invoke_test.go |
Adds coverage for the new flag and session resolution behavior. |
cli/azd/extensions/azure.ai.agents/internal/cmd/agent_endpoint_test.go |
Adds coverage for endpoint mode with version-specific persistence keys. |
wbreza
left a comment
There was a problem hiding this comment.
Code Review — Automated Assist
Thanks for adding version targeting! A few findings to consider — posted as a non-blocking comment.
🔴 Blocking-level concerns
1. --version + --conversation-id / --new-conversation are not rejected. validateInvokeVersionFlags rejects --local and --session-id combos, but not the conversation flags. The PR description states "reject unsafe flag combinations" — this appears incomplete and is related to (2) below. Suggest adding explicit rejection (or, alternatively, plumbing the flags through to the version-backed flow if they are intended to work together).
2. Conversation state is not isolated by version. Session keys correctly use buildAgentKey(..., rc.version, ...), but the conversation-ID lookup in responsesRemote() still calls legacyKeysForRemote(rc.name) directly rather than rc.legacyKeys(). Result: running --version 2 and then --version 3 against the same agent will resolve to the same stored conversation ID, which contradicts the "isolate persisted session and conversation state by version" claim. Suggest routing conversation lookup through rc.legacyKeys() so the version segment participates in the key.
🟠 High
3. --new-session is effectively ignored when a version-backed session already exists. In the rc.version != "" branch of resolveRemoteSessionID, after resolveStoredID returns a non-empty sid, the function returns it without consulting a.flags.newSession. A user passing --version 3 --new-session on the second invocation will get the cached session. Suggest gating the early return on sid != "" && !a.flags.newSession.
4. Missing test coverage for the isolation claim. New tests cover session creation and the new validation errors, but nothing exercises (a) cross-version conversation isolation or (b) rejection of --version + conversation flags (tied to findings 1 and 2). A small table-driven test using the existing fake stores would close this.
🟡 Medium
5. Version-string validation is quite permissive. validateKeySegment only rejects / and \. A value like 3?api-version=evil, or an unreasonably long string, will be embedded into both the URL path segment and the on-disk storage key. Consider a stricter character class (e.g. ^[A-Za-z0-9._-]+$) or document the contract and rely on server-side rejection.
6. Minor duplication. rc.version is assigned in both the ephemeral and project-mode branches of resolveRemoteContext. Not a bug, but easy to drift — consider hoisting it.
Generated with assistance from an automated reviewer; please apply judgment. Defaults look preserved and the version-session creation path itself reads cleanly — the findings above are mostly around completeness of the "isolation + rejection" contract stated in the PR description.
Tighten --version validation, reject explicit conversation IDs for versioned invokes, and make the versioned new-session path skip cached sessions explicitly. Add tests for versioned conversation isolation and cached-session reset behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed wbreza's review feedback in follow-up commit
Validation:
|
| return exterrors.Validation( | ||
| exterrors.CodeInvalidParameter, | ||
| "cannot use --version with --conversation-id; conversations can contain version-specific context", | ||
| "use --version without --conversation-id to create or reuse a version-specific conversation, "+ |
There was a problem hiding this comment.
I don't understand this; how can a user reuse a version-specific conversation, if they can't specify the conversation-id?
If conversations are version-specific, then we should allow the conversation to be provided and either have a way to check on our end, or expect the backend to check, that the conversation does correlate with the provided version.
If conversations are not version-specific, then I see what is meant by them containing version-specific context, but I still think we shouldn't block on it, otherwise how could a user revisit a prior conversation on an older version (as an example)?
| rc.apiVersion = a.endpoint.APIVersion | ||
| } | ||
| rc.agentKey = buildAgentKey(a.endpoint.ProjectEndpoint, a.endpoint.AgentName, "", false) | ||
| if rc.version != "" { |
There was a problem hiding this comment.
NIT: this if/else is unnecessary, since buildAgentKey handles an emptry string, it doesn't matter if rc.version is empty.
Summary
--versiontoazd ai agent invokefor hosted agent version selection.Testing
go test .\internal\cmd\... -count=1go test .\... -count=1Fixes #8054