feat(toolboxes): support RemoteA2A and GroundingWithCustomSearch tool types#8322
Conversation
… types Adds 2 new project-connection categories as toolbox tools: - RemoteA2A -> tools[].type=a2a_preview - GroundingWithCustomSearch -> tools[].type=web_search with custom_search_configuration Adds --instance-name flag (and connections[].instance_name on --from-file) for the GroundingWithCustomSearch input, mirroring --index for CognitiveSearch. Also fixes toolEntryReferences to recognize the new web_search shape (project_connection_id nested under custom_search_configuration), so connection remove / duplicate detection work for those tools.
There was a problem hiding this comment.
Pull request overview
This PR extends the azure.ai.toolboxes azd extension to support attaching two additional Foundry project-connection categories as toolbox tools: RemoteA2A (emitted as a2a_preview) and GroundingWithCustomSearch (emitted as web_search with custom_search_configuration.instance_name).
Changes:
- Adds new connection category constants and corresponding
buildToolEntrycases, including--instance-namesupport and centralized cross-category flag validation. - Expands tool connection reference detection to include
custom_search_configuration.project_connection_idso remove/duplicate detection works forweb_search. - Updates file input schema/help and adds/updates unit tests to cover new tool entry shapes and validation paths.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/extensions/azure.ai.toolboxes/internal/foundry/connections/client.go | Adds new connection category constants for tool-capable connections. |
| cli/azd/extensions/azure.ai.toolboxes/internal/exterrors/codes.go | Introduces error codes for missing/unsupported --instance-name. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_shared.go | Extends connection-id reference scanning to cover web_search nested configuration. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_helpers_test.go | Updates helper tests for new tool shapes and removal/duplicate detection. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_help.go | Updates --from-file examples and supported category documentation. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_files.go | Extends connection spec schema with instance_name. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_create.go | Wires InstanceName through when building tool entries from file specs. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_connection.go | Adds new tool entry builders and centralizes flag/category validation. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_connection_add.go | Adds --instance-name flag and validates incompatibility with --from-file. |
| cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_commands_test.go | Updates buildToolEntry callsites for new signature. |
- Fix stale 'azd ai toolbox add' usage strings and examples (the command is registered under 'toolbox connection add'); pre-existing typo, worsened by this PR's new examples - Flag help for --index and --instance-name says 'Only valid for ...; required there' to match buildToolEntry's actual rejection behavior (was misleading 'ignored otherwise') - Normalize --index and --instance-name with strings.TrimSpace at the top of buildToolEntry so whitespace-only values are treated consistently (previously rejected as 'unsupported flag' instead of treated as empty) - TestFilterOutConnection: assert removed connection IDs no longer appear in any tool-entry shape, not just slice length
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
- extractConnectionTools (toolbox connection list) now handles a2a_preview (top-level project_connection_id) and the connection-backed web_search variant (custom_search_configuration.project_connection_id). Distinguishes the connection-backed web_search from the built-in by presence of custom_search_configuration. - describeToolDetail (toolbox show) now decides between '(connection:<id>)' and '(builtin)' purely from the entry's shape (via firstConnectionID -> toolEntryReferences). Drops the unused toolType parameter. New connection-backed tool shapes recognized by toolEntryReferences are surfaced automatically without touching this helper.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_show.go:180
- The comment for firstConnectionID is now stale: the function delegates to toolEntryReferences, which also recognizes top-level project_connection_id on a2a_preview and nested custom_search_configuration.project_connection_id on web_search. Update the comment so it matches the actual recognized shapes (or refer to toolEntryReferences’ doc) to avoid misleading future changes.
// firstConnectionID returns the first project_connection_id referenced by a
// tool entry — top-level on `mcp` tools, or nested under
// azure_ai_search.indexes[] for search tools.
func firstConnectionID(tool map[string]any) string {
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_connection_list.go:99
- The new a2a_preview extraction path isn’t covered by tests. Consider extending the existing connection list tests (e.g., TestRunConnectionListWith_EmitsAllShapes) to include an a2a_preview tool entry and assert it appears in the JSON/table output rows, so regressions in this switch are caught.
toolType, _ := t["type"].(string)
toolName, _ := t["name"].(string)
switch toolType {
case "mcp", "a2a_preview":
if id, ok := t["project_connection_id"].(string); ok && id != "" {
rows = append(rows, map[string]string{
"name": toolName,
"connection": shortConnectionName(id),
"connection_id": id,
"type": toolType,
})
- TestExtractConnectionTools: pins one row per connection-backed entry for mcp, azure_ai_search, a2a_preview, and the GroundingWithCustomSearch web_search variant; asserts the per-row fields (connection_id, index, instance_name). - TestExtractConnectionTools_SkipsMalformedEntries: confirms built-in web_search (no custom_search_configuration) and entries with empty/missing project_connection_id never produce a row, locking in the gating logic that distinguishes connection-backed web_search from the built-in variant.
|
/check-enforcer override |
Summary
Extends
azd ai toolboxwith two additional project-connection categories so they can be attached as toolbox tools. Follow-up to #8203, which shipped the toolbox surface withRemoteTool(MCP) andCognitiveSearch(Azure AI Search).tools[].typeRemoteA2Aa2a_previewGroundingWithCustomSearchweb_search(withcustom_search_configuration)--instance-name(Bing custom-search instance)Changes
New tool types
ConnectionTypeconstantsRemoteA2AandGroundingWithCustomSearchininternal/foundry/connections.buildToolEntrygains two cases plus aninstanceNameparameter; cross-category flag validation (--indexrejected outside CognitiveSearch,--instance-namerejected outside GroundingWithCustomSearch) is centralized at the top of the function and trims whitespace once so--index " "is treated as empty.--instance-nameflag ontoolbox connection add; newinstance_namefield on the--from-fileconnection spec;--from-filemode rejects both flags with a clear error.--from-fileJSON/YAML examples, and the "unsupported category" error message. Fixed pre-existing staleazd ai toolbox addusage strings toazd ai toolbox connection add.missing_instance_name,unsupported_instance_name_flag.Display-layer plumbing
toolEntryReferencesnow recognizescustom_search_configuration.project_connection_id, soconnection removeand duplicate detection work forweb_searchtools.extractConnectionTools(toolbox connection list) emits rows fora2a_previewand the connection-backedweb_searchvariant; built-inweb_search(nocustom_search_configuration) is still skipped.describeToolDetail(toolbox showtable) is now type-agnostic: any entry with a connection ID surfaces as(connection:<id>), otherwise(builtin). New connection-backed tool shapes recognized bytoolEntryReferencesare surfaced automatically.Validation
extractConnectionToolsrows for all five entry shapes including malformed cases (internal/cmd/toolbox_helpers_test.go).azd ai toolbox create --from-filepublished a single version withmcp+a2a_preview+web_searchentries; subsequentconnection removecalls peeled each off (thetoolEntryReferencesfix was caught by this run).BrowserToolis intentionally not included: the service-side ARM contract for that category is not yet deployed in test regions; tracked separately.Out of scope
BrowserTool(browser_automation_preview) — pending service rollout.BingCustomSearch(bing_custom_search_preview) — separate category with its ownsearch_configurations[]shape.A2APreviewTool.base_url/agent_card_path— defer until requested.