feat(agents): support invoke over the activity protocol#8824
Conversation
Adds activity protocol support to `azd ai agent invoke`, alongside the existing responses and invocations protocols (issue #7493). - Make activity_protocol invocable: include it in InvocableProtocols() and IsInvocable(); A2A remains deployment-only. - Route --protocol activity_protocol (and agent.yaml auto-detection) to new activityLocal/activityRemote handlers, modeled on the invocations protocol (structured body + agent-session-based memory). - Wrap a plain message as a minimal message Activity ({type:message,text}); forward --input-file contents verbatim as a complete Activity payload. - Parse the response Activity for the agent's reply text, with JSON pretty-print and raw-body fallbacks; --output raw dumps verbatim. - Add activity endpoint URL builder/parsing (.../protocols/activity) and update --protocol help, validation messages, and command examples. The activity wire format (path tail, Activity body, response shape) follows the codebase's existing responses/invocations conventions and is centralized in buildActivityURL / buildActivityRequestBody / handleActivityResponse so it can be adjusted in one place if the Foundry contract differs. `--output raw` provides a format-independent escape hatch. Fixes #7493 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 activity protocol support to the azd ai agent invoke flow in the azure.ai.agents extension, making activity_protocol a first-class invocable protocol alongside responses and invocations.
Changes:
- Make
activity_protocolinvocable (InvocableProtocols()/IsInvocable()), and routeinvoketo new activity local/remote handlers. - Add Activity-protocol endpoint parsing/building (
.../endpoint/protocols/activity) and update protocol validation/help text. - Add targeted unit tests for request wrapping / passthrough, response text extraction, and endpoint URL building.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models.go | Marks activity_protocol as invocable. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models_test.go | Updates protocol invocability tests for activity_protocol. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go | Routes --protocol activity_protocol and updates help/validation strings. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/invoke_activity.go | Implements activity-protocol invoke (local + Foundry) including request/response shaping. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/invoke_activity_test.go | Adds unit tests for activity request wrapping/passthrough and response parsing helpers. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/helpers.go | Updates protocol auto-detection guidance text for activity protocol. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/helpers_test.go | Adds agent.yaml auto-detect coverage for activity_protocol. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/agent_endpoint.go | Extends --agent-endpoint parsing and URL builder to support activity. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/agent_endpoint_test.go | Adds tests for parsing/building activity-protocol URLs (escaping + default api-version). |
| cli/azd/extensions/azure.ai.agents/CHANGELOG.md | Adds unreleased changelog entry for activity-protocol invoke support. |
jongio
left a comment
There was a problem hiding this comment.
This PR adds activity protocol support following the established invocations protocol patterns closely. The implementation is well-organized: request body building, local/remote handlers, response text extraction, and error handling are all centralized and testable.
A few observations:
buildActivityURLcorrectly appliesDefaultAgentAPIVersionas a fallback (matchingbuildResponsesURL).buildInvocationsURLactually lacks this default, so the activity handler is slightly more robust than its sibling.- The response text extraction (
extractActivityText) handles three response shapes gracefully. The fallback chain (single Activity -> InvokeResponse envelope -> array of Activities -> JSON pretty-print -> raw bytes) is solid. - The
DefaultPortusage inbuildLocalAgentKeyis consistent withinvocationsLocal(invoke.go:1084). This is intentional: the session storage key uses a stable port so sessions persist regardless of which port the user happens to pass on any given invocation. - The PR clearly documents the unspecced Foundry wire format assumptions and centralizes them for easy correction.
Two minor inline observations below.
jongio
left a comment
There was a problem hiding this comment.
This PR adds activity protocol support following the established invocations protocol patterns closely. The implementation is well-organized: request body building, local/remote handlers, response text extraction, and error handling are all centralized and testable.
A few observations:
buildActivityURLcorrectly appliesDefaultAgentAPIVersionas a fallback (matchingbuildResponsesURL).buildInvocationsURLactually lacks this default, so the activity handler is slightly more robust than its sibling.- The response text extraction (
extractActivityText) handles three response shapes gracefully. The fallback chain (single Activity -> InvokeResponse envelope -> array of Activities -> JSON pretty-print -> raw bytes) is solid. - The
DefaultPortusage inbuildLocalAgentKeyis consistent withinvocationsLocal(invoke.go:1084). This is intentional: the session storage key uses a stable port so sessions persist regardless of which port the user happens to pass on any given invocation. - The PR clearly documents the unspecced Foundry wire format assumptions and centralizes them for easy correction.
Two minor inline observations below.
- Reword the non-invocable-protocol suggestion to avoid the 'protocol protocols' stutter (responses, invocations, or activity protocols). - Document why the local session key uses DefaultPort (parity with invocationsLocal) and why no OpenAPI spec is fetched for the unspecced activity protocol. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks for the review! Pushed 277cf49 addressing the feedback:
All builds/tests/lint/cspell remain green. |
jongio
left a comment
There was a problem hiding this comment.
Incremental review: my two prior inline comments (the "protocol protocols" stutter in helpers.go and the DefaultPort/OpenAPI-skip observations in invoke_activity.go) are both addressed in 277cf49.
No new issues found in the incremental diff or the full changeset. The implementation follows the invocations protocol patterns closely, has solid test coverage across the key functions (URL building, request body construction, response text extraction, error envelope detection), and the routing/validation updates are consistent with siblings.
One open item for other reviewers: the PR explicitly asks for confirmation of the Foundry hosted-agent activity endpoint contract (path tail, request body shape, response shape) before merge. The assumptions are centralized in buildActivityURL, buildActivityRequestBody, and handleActivityResponse, so corrections would be localized if the contract differs.
Closes #7493
What
Adds activity protocol support to
azd ai agent invoke, alongside the existingresponsesandinvocationsprotocols.Changes
activity_protocolinvocable — included inInvocableProtocols()/IsInvocable().a2aremains deployment-only.--protocol activity_protocolandagent.yamlprotocol auto-detection now route to newactivityLocal/activityRemotehandlers (new fileinvoke_activity.go). They are modeled on the invocations protocol: structured/opaque body + agent-session-based memory (agent_session_id),--new-sessionto reset,--new-conversationis a no-op (noted on stderr).messageActivity ({"type":"message","text":...});--input-filecontents are forwarded verbatim as a complete Activity payload.text, InvokeResponsebody.text, or an array of activities), with JSON pretty-print and raw-body fallbacks. An{"error":{...}}envelope surfaces as an agent error.--output rawdumps the response verbatim.buildActivityURLand--agent-endpointparsing for the.../endpoint/protocols/activitytail; updated--protocolhelp, the unsupported-protocol validation message, the multi-protocol guidance, and command examples.Tests
models_test.go:activity_protocolnowIsInvocable() == true.agent_endpoint_test.go: parse +buildActivityURL(api-version/session-id escaping, default api-version).helpers_test.go: singleactivity_protocolauto-detects.invoke_activity_test.go: message wrapping, file passthrough, response text extraction across shapes, error-envelope detection, request-URL fallback.Validation
go build ./..., fullgo test ./...,go vet,gofmt,golangci-lint run(0 issues), andcspell— all clean.There is no public spec for the Foundry hosted-agent activity invoke endpoint, and the repo had no prior reference (the
activity/activity_protocolconstants were previously deployment-only). This PR follows the codebase's establishedresponses/invocationsconventions:{projectEndpoint}/agents/{name}/endpoint/protocols/activity?api-version=...[&agent_session_id=...](remote) andhttp://localhost:{port}/activity(local).text.These assumptions are centralized in
buildActivityURL,buildActivityRequestBody, andhandleActivityResponse, so if the Foundry contract differs they can be corrected in one place.--output rawis a format-independent escape hatch that works regardless. Please confirm the exact endpoint path and Activity request/response shape against the Foundry hosted-agent activity contract before merge.