From 98d6fede4e0b1ef1a0fe3f84466827bad17198e2 Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Mon, 3 Nov 2025 11:25:47 -0800 Subject: [PATCH 1/7] Add skeleton commands for cognitiveservices agents operations. --- .../cognitiveservices/_params.py | 12 +++++ .../cognitiveservices/commands.py | 8 +++ .../cognitiveservices/custom.py | 51 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py index 7f6183eba58..e24c0722bd6 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py @@ -214,3 +214,15 @@ def load_arguments(self, _): with self.argument_context('cognitiveservices account commitment-plan', arg_group='Next CommitmentPeriod') as c: c.argument('next_count', help='Cognitive Services account commitment plan next commitment period count.') c.argument('next_tier', help='Cognitive Services account commitment plan next commitment period tier.') + + with self.argument_context('cognitiveservices agent') as c: + c.argument('agent_name', help='Cognitive Services hosted agent name') + c.argument('agent_version', help='Cognitive Services hosted agent version') + + with self.argument_context('cognitiveservices agent update') as c: + c.argument('min_replica', help='Minimum number of replicas for horizontal scaling') + c.argument('max_replica', help='Maximum number of replicas for horizontal scaling') + c.argument('description', help='Description of the agent') + + with self.argument_context('cognitiveservices agent delete') as c: + c.argument('agent_version', help='Cognitive Services hosted agent version. If not provided, deletes all versions.', required=False) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py index 53b736838c0..cdbb1af5a66 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py @@ -103,3 +103,11 @@ def load_command_table(self, _): with self.command_group('cognitiveservices usage', usages_type) as g: g.command('list', 'list') + + with self.command_group('cognitiveservices agent', client_factory=cf_accounts) as g: + g.custom_command('update', 'agent_update') + g.custom_command('stop', 'agent_stop') + g.custom_command('start', 'agent_start') + g.custom_command('delete-deployment', 'agent_delete_deployment') + g.custom_command('delete', 'agent_delete') + g.custom_command('list', 'agent_list') diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index fce86c7988f..aa756e46eef 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -325,3 +325,54 @@ def commitment_plan_create_or_update( plan.properties.next.count = next_count plan.properties.auto_renew = auto_renew return client.create_or_update(resource_group_name, account_name, commitment_plan_name, plan) + + +def agent_update(client, account_name, agent_name, agent_version, + min_replica=None, max_replica=None, description=None, tags=None): + """ + Update hosted agent deployment configuration. + Updates horizontal scale configuration (min and max replica), agent meta-data such as description and tags. + New version is not created for this update. + """ + raise NotImplementedError("agent_update command is not yet implemented") + + +def agent_stop(client, account_name, agent_name, agent_version): + """ + Stop hosted agent deployment. + """ + raise NotImplementedError("agent_stop command is not yet implemented") + + +def agent_start(client, account_name, agent_name, agent_version): + """ + Start hosted agent deployment. + """ + raise NotImplementedError("agent_start command is not yet implemented") + + +def agent_delete_deployment(client, account_name, agent_name, agent_version): + """ + Delete hosted agent deployment. + Deletes the agent deployment only, agent version associated with the deployment remains. + """ + raise NotImplementedError("agent_delete_deployment command is not yet implemented") + + +def agent_delete(client, account_name, agent_name, agent_version=None): + """ + Delete hosted agent version or all versions. + If agent_version is provided, deletes the agent instance and agent definition associated with that version. + If agent_version is not provided, deletes all agent instances and agent definitions associated with the agent name. + """ + raise NotImplementedError("agent_delete command is not yet implemented") + + +def agent_list(client, account_name, agent_name, agent_version=None): + """ + List hosted agent versions or deployments. + If agent_version is not provided, lists all versions for an agent. + If agent_version is provided, lists all deployments for that agent version. + """ + raise NotImplementedError("agent_list command is not yet implemented") + \ No newline at end of file From d2021876ad8775f9bc1088583ef914e009ec3766 Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Mon, 3 Nov 2025 18:24:02 -0800 Subject: [PATCH 2/7] Added commands using the v1 foundry project client library --- .../cognitiveservices/_client_factory.py | 43 +++++++++ .../cognitiveservices/_params.py | 40 ++++++++- .../cognitiveservices/commands.py | 7 +- .../cognitiveservices/custom.py | 88 +++++++++++++++---- src/azure-cli/setup.py | 1 + 5 files changed, 160 insertions(+), 19 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py index a31eed3f200..319d51c8207 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py @@ -40,3 +40,46 @@ def cf_models(cli_ctx, *_): def cf_usages(cli_ctx, *_): return get_cognitiveservices_management_client(cli_ctx).usages + + +def cf_ai_projects(cli_ctx, command_args): + """ + Create AI Projects client for data plane operations. + Similar to keyvault's data plane client factory pattern. + """ + from azure.ai.projects import AIProjectClient + from azure.cli.core.commands.client_factory import prepare_client_kwargs_track2 + from azure.cli.core._profile import Profile + + # Get credentials using Azure CLI login + profile = Profile(cli_ctx=cli_ctx) + credential, _, _ = profile.get_login_credentials( + subscription_id=cli_ctx.data.get('subscription_id') + ) + + # Get endpoint from command arguments (similar to keyvault's vault_url) + account_name = command_args.get('account_name', None) + endpoint = command_args.get('endpoint', None) + project = command_args.get('project_name', None) + + # If no explicit endpoint provided, construct from account name + if not endpoint and account_name: + # Construct endpoint URL from account name + # Format: https://{account_name}.cognitiveservices.azure.com + endpoint = f"https://{account_name}.services.ai.azure.com/api/projects/{project}" + + if not endpoint: + from azure.cli.core.azclierror import RequiredArgumentMissingError + raise RequiredArgumentMissingError( + 'Please specify --account-name or --endpoint' + ) + + # Prepare client kwargs with proper logging and telemetry + client_kwargs = prepare_client_kwargs_track2(cli_ctx) + + # Create and return the AI Projects client + return AIProjectClient( + endpoint=endpoint, + credential=credential, + **client_kwargs + ) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py index e24c0722bd6..52e220b17e8 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py @@ -121,6 +121,26 @@ def _validate_subnet(cmd, namespace): child_name_1=subnet) +def validate_agent_endpoint_or_account_name(namespace): + """ + Validate that either account_name or endpoint is provided, but not both. + """ + from azure.cli.core.azclierror import MutuallyExclusiveArgumentError, RequiredArgumentMissingError + + account_name = getattr(namespace, 'account_name', None) + endpoint = getattr(namespace, 'endpoint', None) + + if account_name and endpoint: + raise MutuallyExclusiveArgumentError( + 'Cannot specify both --name and --endpoint. Please provide only one.' + ) + + if not account_name and not endpoint: + raise RequiredArgumentMissingError( + 'Must specify either --name or --endpoint.' + ) + + @Completer def sku_name_completer(cmd, prefix, namespace, **kwargs): # pylint: disable=unused-argument names = {x.name for x in _sku_filter(cmd, namespace)} @@ -216,13 +236,29 @@ def load_arguments(self, _): c.argument('next_tier', help='Cognitive Services account commitment plan next commitment period tier.') with self.argument_context('cognitiveservices agent') as c: + c.argument('account_name', arg_type=name_arg_type, + help='cognitive service account name. Mutually exclusive with --endpoint.', + completer=get_resource_name_completion_list('Microsoft.CognitiveServices/accounts'), + required=False) + c.argument('project_name', help='AI Project name') c.argument('agent_name', help='Cognitive Services hosted agent name') c.argument('agent_version', help='Cognitive Services hosted agent version') + c.argument('endpoint', help='AI Projects endpoint URL. Mutually exclusive with --name.') with self.argument_context('cognitiveservices agent update') as c: - c.argument('min_replica', help='Minimum number of replicas for horizontal scaling') - c.argument('max_replica', help='Maximum number of replicas for horizontal scaling') + c.argument('min_replica', options_list=['--min-replica'], help='Minimum number of replicas for horizontal scaling') + c.argument('max_replica', options_list=['--max-replica'], help='Maximum number of replicas for horizontal scaling') c.argument('description', help='Description of the agent') with self.argument_context('cognitiveservices agent delete') as c: c.argument('agent_version', help='Cognitive Services hosted agent version. If not provided, deletes all versions.', required=False) + + with self.argument_context('cognitiveservices agent versions') as c: + c.argument('account_name', arg_type=name_arg_type, + help='cognitive service account name. Mutually exclusive with --endpoint.', + completer=get_resource_name_completion_list('Microsoft.CognitiveServices/accounts'), + required=False, + validator=validate_agent_endpoint_or_account_name) + c.argument('project_name', help='AI Project name') + c.argument('agent_name', help='Cognitive Services hosted agent name') + c.argument('endpoint', help='AI Projects endpoint URL. Mutually exclusive with --name.') diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py index cdbb1af5a66..1c0d723c49c 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py @@ -5,7 +5,8 @@ from azure.cli.core.commands import CliCommandType from azure.cli.command_modules.cognitiveservices._client_factory import cf_accounts, cf_resource_skus, \ - cf_deleted_accounts, cf_deployments, cf_commitment_plans, cf_commitment_tiers, cf_models, cf_usages + cf_deleted_accounts, cf_deployments, cf_commitment_plans, cf_commitment_tiers, cf_models, cf_usages, \ + cf_ai_projects def load_command_table(self, _): @@ -104,10 +105,12 @@ def load_command_table(self, _): with self.command_group('cognitiveservices usage', usages_type) as g: g.command('list', 'list') - with self.command_group('cognitiveservices agent', client_factory=cf_accounts) as g: + with self.command_group('cognitiveservices agent', client_factory=cf_ai_projects) as g: g.custom_command('update', 'agent_update') g.custom_command('stop', 'agent_stop') g.custom_command('start', 'agent_start') g.custom_command('delete-deployment', 'agent_delete_deployment') g.custom_command('delete', 'agent_delete') g.custom_command('list', 'agent_list') + g.custom_command('list-versions', 'agent_versions_list') + g.custom_command('show', 'agent_show') diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index aa756e46eef..87eeb9ce18e 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -4,10 +4,12 @@ # -------------------------------------------------------------------------------------------- import json +import urllib.parse from knack.util import CLIError from knack.log import get_logger +import azure.core.rest from azure.mgmt.cognitiveservices.models import Account as CognitiveServicesAccount, Sku, \ VirtualNetworkRule, IpRule, NetworkRuleSet, NetworkRuleAction, \ AccountProperties as CognitiveServicesAccountProperties, ApiProperties as CognitiveServicesAccountApiProperties, \ @@ -327,31 +329,46 @@ def commitment_plan_create_or_update( return client.create_or_update(resource_group_name, account_name, commitment_plan_name, plan) -def agent_update(client, account_name, agent_name, agent_version, - min_replica=None, max_replica=None, description=None, tags=None): +AGENT_API_VERSION_PARAMS = { 'api-version': '2025-11-15-preview' } + +def agent_update(client, account_name, project_name, agent_name, agent_version, + min_replica=None, max_replica=None, description=None, tags=None, endpoint=None): """ Update hosted agent deployment configuration. Updates horizontal scale configuration (min and max replica), agent meta-data such as description and tags. New version is not created for this update. """ - raise NotImplementedError("agent_update command is not yet implemented") - + request_body = {} + if min_replica is not None: + request_body['min_replica'] = min_replica + if max_replica is not None: + request_body['max_replica'] = max_replica + request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)}/containers/default:update', json = request_body, params=AGENT_API_VERSION_PARAMS) + response = client.send_request(request) + response.raise_for_status() + return response.json() -def agent_stop(client, account_name, agent_name, agent_version): +def agent_stop(client, account_name, project_name, agent_name, agent_version, endpoint=None): """ Stop hosted agent deployment. """ - raise NotImplementedError("agent_stop command is not yet implemented") + request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)/containers/default:start}', params=AGENT_API_VERSION_PARAMS) + response = client.send_request(request) + response.raise_for_status() + return response.json() -def agent_start(client, account_name, agent_name, agent_version): +def agent_start(client, account_name, project_name, agent_name, agent_version, endpoint=None): """ Start hosted agent deployment. """ - raise NotImplementedError("agent_start command is not yet implemented") + request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)/containers/default:start}', params=AGENT_API_VERSION_PARAMS) + response = client.send_request(request) + response.raise_for_status() + return response.json() -def agent_delete_deployment(client, account_name, agent_name, agent_version): +def agent_delete_deployment(client, account_name, project_name, agent_name, agent_version, endpoint=None): """ Delete hosted agent deployment. Deletes the agent deployment only, agent version associated with the deployment remains. @@ -359,20 +376,61 @@ def agent_delete_deployment(client, account_name, agent_name, agent_version): raise NotImplementedError("agent_delete_deployment command is not yet implemented") -def agent_delete(client, account_name, agent_name, agent_version=None): +def agent_delete(client, account_name, project_name, agent_name, agent_version=None, endpoint=None): """ Delete hosted agent version or all versions. - If agent_version is provided, deletes the agent instance and agent definition associated with that version. + If agent_version is provided, deletes the agent instance and agent definition associated with `that version. If agent_version is not provided, deletes all agent instances and agent definitions associated with the agent name. """ - raise NotImplementedError("agent_delete command is not yet implemented") + request = azure.core.rest.HttpRequest('DELETE', f'/agents/{urllib.parse.quote(agent_name)}', params = AGENT_API_VERSION_PARAMS) + response = client.send_request(request) + response.raise_for_status() + return response.json() -def agent_list(client, account_name, agent_name, agent_version=None): +def agent_list(client, account_name, project_name, endpoint=None): """ List hosted agent versions or deployments. If agent_version is not provided, lists all versions for an agent. If agent_version is provided, lists all deployments for that agent version. """ - raise NotImplementedError("agent_list command is not yet implemented") - \ No newline at end of file + agents = [] + params = AGENT_API_VERSION_PARAMS.copy() + while True: + request = azure.core.rest.HttpRequest('GET', f'/agents', params=params) + response = client.send_request(request) + response.raise_for_status() + body = response.json() + agents.extend(body.get('data', [])) + if body.get('has_more'): + params['after'] = body.get('last_id') + else: + return agents + + +def agent_versions_list(client, account_name, project_name, agent_name, endpoint=None): + """ + List all versions of a hosted agent. + """ + versions = [] + params = AGENT_API_VERSION_PARAMS.copy() + while True: + request = azure.core.rest.HttpRequest('GET', f'/agents/{urllib.parse.quote(agent_name)}/versions', params=params) + response = client.send_request(request) + response.raise_for_status() + body = response.json() + versions.extend(body.get('data', [])) + if body.get('has_more'): + params['after'] = body.get('last_id') + else: + return versions + + +def agent_show(client, account_name, project_name, agent_name, endpoint=None): + """ + Show details of a hosted agent. + """ + request = azure.core.rest.HttpRequest('GET', f'/agents/{urllib.parse.quote(agent_name)}', params=AGENT_API_VERSION_PARAMS) + response = client.send_request(request) + response.raise_for_status() + return response.json() diff --git a/src/azure-cli/setup.py b/src/azure-cli/setup.py index be7ef4777d8..25e90248115 100644 --- a/src/azure-cli/setup.py +++ b/src/azure-cli/setup.py @@ -53,6 +53,7 @@ DEPENDENCIES = [ "antlr4-python3-runtime~=4.13.1", 'azure-appconfiguration~=1.7.1', + 'azure-ai-projects~=1.0.0', 'azure-batch==15.0.0b1', 'azure-cli-core=={}'.format(VERSION), 'azure-cosmos~=3.0,>=3.0.2', From 9ff803b26c2c62ca530168806eda269e8d2ba735 Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Wed, 5 Nov 2025 16:52:05 -0800 Subject: [PATCH 3/7] Remove endpoint argument to agent command, mark them as preview --- .../cognitiveservices/_client_factory.py | 32 +- .../cognitiveservices/_params.py | 375 +++++++++++------- .../cognitiveservices/commands.py | 2 +- .../cognitiveservices/custom.py | 348 +++++++++++----- 4 files changed, 509 insertions(+), 248 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py index 319d51c8207..2a93f0a9477 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py @@ -7,6 +7,7 @@ def get_cognitiveservices_management_client(cli_ctx, *_): from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.mgmt.cognitiveservices import CognitiveServicesManagementClient + return get_mgmt_service_client(cli_ctx, CognitiveServicesManagementClient) @@ -50,36 +51,35 @@ def cf_ai_projects(cli_ctx, command_args): from azure.ai.projects import AIProjectClient from azure.cli.core.commands.client_factory import prepare_client_kwargs_track2 from azure.cli.core._profile import Profile - + # Get credentials using Azure CLI login profile = Profile(cli_ctx=cli_ctx) credential, _, _ = profile.get_login_credentials( - subscription_id=cli_ctx.data.get('subscription_id') + subscription_id=cli_ctx.data.get("subscription_id") ) - + # Get endpoint from command arguments (similar to keyvault's vault_url) - account_name = command_args.get('account_name', None) - endpoint = command_args.get('endpoint', None) - project = command_args.get('project_name', None) + account_name = command_args.get("account_name", None) + endpoint = command_args.get("endpoint", None) + project = command_args.get("project_name", None) # If no explicit endpoint provided, construct from account name if not endpoint and account_name: # Construct endpoint URL from account name # Format: https://{account_name}.cognitiveservices.azure.com - endpoint = f"https://{account_name}.services.ai.azure.com/api/projects/{project}" - + endpoint = ( + f"https://{account_name}.services.ai.azure.com/api/projects/{project}" + ) + if not endpoint: from azure.cli.core.azclierror import RequiredArgumentMissingError + raise RequiredArgumentMissingError( - 'Please specify --account-name or --endpoint' + "Please specify --account-name or --endpoint" ) - + # Prepare client kwargs with proper logging and telemetry client_kwargs = prepare_client_kwargs_track2(cli_ctx) - + # Create and return the AI Projects client - return AIProjectClient( - endpoint=endpoint, - credential=credential, - **client_kwargs - ) + return AIProjectClient(endpoint=endpoint, credential=credential, **client_kwargs) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py index 52e220b17e8..591eafce749 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py @@ -13,18 +13,23 @@ get_three_state_flag, resource_group_name_type, get_resource_name_completion_list, - get_location_type) -from azure.cli.core.util import (shell_safe_json_parse, CLIError) + get_location_type, +) +from azure.cli.core.util import shell_safe_json_parse, CLIError from azure.cli.core.commands.validators import validate_tag from azure.cli.core.decorators import Completer from azure.cli.command_modules.cognitiveservices._client_factory import cf_resource_skus -from azure.mgmt.cognitiveservices.models import KeyName, DeploymentScaleType, HostingModel +from azure.mgmt.cognitiveservices.models import ( + KeyName, + DeploymentScaleType, + HostingModel, +) logger = get_logger(__name__) -name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME') +name_arg_type = CLIArgumentType(options_list=["--name", "-n"], metavar="NAME") def extract_key_values_pairs(api_properties): @@ -35,7 +40,7 @@ def extract_key_values_pairs(api_properties): def validate_api_properties(ns): - """ Extracts JSON format or 'a=b c=d' format as api properties """ + """Extracts JSON format or 'a=b c=d' format as api properties""" api_properties = ns.api_properties if api_properties is None: @@ -51,17 +56,20 @@ def validate_api_properties(ns): except CLIError: result = extract_key_values_pairs([string]) if _is_suspected_json(string): - logger.warning('Api properties looks like a JSON format but not valid, interpreted as key=value pairs:' - ' %s', str(result)) + logger.warning( + "Api properties looks like a JSON format but not valid, interpreted as key=value pairs:" + " %s", + str(result), + ) ns.api_properties = result return def _is_suspected_json(string): - """ If the string looks like a JSON """ - if string.startswith('{') or string.startswith('\'{') or string.startswith('\"{'): + """If the string looks like a JSON""" + if string.startswith("{") or string.startswith("'{") or string.startswith('"{'): return True - if string.startswith('[') or string.startswith('\'[') or string.startswith('\"['): + if string.startswith("[") or string.startswith("'[") or string.startswith('"['): return True if re.match(r"^['\"\s]*{.+}|\[.+\]['\"\s]*$", string): return True @@ -72,8 +80,8 @@ def _is_suspected_json(string): api_properties_type = CLIArgumentType( validator=validate_api_properties, help="Api properties in JSON format or a=b c=d format. Some cognitive services (i.e. QnA Maker) " - "require extra api properties to create the account.", - nargs='*' + "require extra api properties to create the account.", + nargs="*", ) @@ -81,9 +89,9 @@ def _sku_filter(cmd, namespace): """ Get a list of ResourceSku and filter by existing conditions: 'kind', 'location' and 'sku_name' """ - kind = getattr(namespace, 'kind', None) - location = getattr(namespace, 'location', None) - sku_name = getattr(namespace, 'sku_name', None) + kind = getattr(namespace, "kind", None) + location = getattr(namespace, "location", None) + sku_name = getattr(namespace, "sku_name", None) def _filter_sku(_sku): if sku_name is not None: @@ -114,35 +122,18 @@ def _validate_subnet(cmd, namespace): namespace.subnet = resource_id( subscription=get_subscription_id(cmd.cli_ctx), resource_group=namespace.resource_group_name, - namespace='Microsoft.Network', - type='virtualNetworks', + namespace="Microsoft.Network", + type="virtualNetworks", name=vnet, - child_type_1='subnets', - child_name_1=subnet) - - -def validate_agent_endpoint_or_account_name(namespace): - """ - Validate that either account_name or endpoint is provided, but not both. - """ - from azure.cli.core.azclierror import MutuallyExclusiveArgumentError, RequiredArgumentMissingError - - account_name = getattr(namespace, 'account_name', None) - endpoint = getattr(namespace, 'endpoint', None) - - if account_name and endpoint: - raise MutuallyExclusiveArgumentError( - 'Cannot specify both --name and --endpoint. Please provide only one.' - ) - - if not account_name and not endpoint: - raise RequiredArgumentMissingError( - 'Must specify either --name or --endpoint.' + child_type_1="subnets", + child_name_1=subnet, ) @Completer -def sku_name_completer(cmd, prefix, namespace, **kwargs): # pylint: disable=unused-argument +def sku_name_completer( + cmd, prefix, namespace, **kwargs +): # pylint: disable=unused-argument names = {x.name for x in _sku_filter(cmd, namespace)} # TODO: For deployment return sorted(list(names)) @@ -155,110 +146,212 @@ def kind_completer(cmd, prefix, namespace, **kwargs): # pylint: disable=unused- @Completer -def location_completer(cmd, prefix, namespace, **kwargs): # pylint: disable=unused-argument +def location_completer( + cmd, prefix, namespace, **kwargs +): # pylint: disable=unused-argument names = {location for x in _sku_filter(cmd, namespace) for location in x.locations} return [x.lower() for x in sorted(list(names))] def load_arguments(self, _): - with self.argument_context('cognitiveservices') as c: - c.argument('account_name', arg_type=name_arg_type, help='cognitive service account name', - completer=get_resource_name_completion_list('Microsoft.CognitiveServices/accounts')) - c.argument('location', arg_type=get_location_type(self.cli_ctx), - completer=location_completer) - c.argument('resource_group_name', arg_type=resource_group_name_type) - c.argument('sku_name', options_list=['--sku', '--sku-name'], - help='Name of the Sku of Cognitive Services account/deployment', - completer=sku_name_completer) - c.argument('sku_capacity', options_list=['--capacity', '--sku-capacity'], - help='Capacity value of the Sku of Cognitive Services account/deployment.') - c.argument('kind', help='the API name of cognitive services account', - completer=kind_completer) - c.argument('tags', tags_type) - c.argument('key_name', required=True, help='Key name to generate', arg_type=get_enum_type(KeyName)) - c.argument('api_properties', api_properties_type) - c.argument('custom_domain', help='User domain assigned to the account. Name is the CNAME source.') - c.argument('storage', help='The storage accounts for this resource, in JSON array format.') - c.argument('encryption', help='The encryption properties for this resource, in JSON format.') - - with self.argument_context('cognitiveservices account', arg_group="AI Services") as c: - c.argument('allow_project_management', - options_list=['--manage-projects', '--allow-project-management'], - arg_type=get_three_state_flag(), - help='AIServices kind only. Enables project management. Default true.') - - with self.argument_context('cognitiveservices account create') as c: - c.argument('assign_identity', help='Generate and assign an Azure Active Directory Identity for this account.') - c.argument('yes', action='store_true', help='Do not prompt for terms confirmation') - - with self.argument_context('cognitiveservices account update', arg_group="AI Services") as c: - c.argument('kind', - arg_type=get_enum_type(data=['AIServices', 'OpenAI']), - help='The target API name to transform the existing account into.') - - with self.argument_context('cognitiveservices account network-rule') as c: - c.argument('ip_address', help='IPv4 address or CIDR range.') - c.argument('subnet', help='Name or ID of subnet. If name is supplied, `--vnet-name` must be supplied.') - c.argument('vnet_name', help='Name of a virtual network.', validator=_validate_subnet) - - with self.argument_context('cognitiveservices account deployment') as c: - c.argument('deployment_name', help='Cognitive Services account deployment name') - - with self.argument_context('cognitiveservices account deployment', arg_group='DeploymentModel') as c: - c.argument('model_name', help='Cognitive Services account deployment model name.') - c.argument('model_format', help='Cognitive Services account deployment model format.') - c.argument('model_version', help='Cognitive Services account deployment model version.') - c.argument('model_source', help='Cognitive Services account deployment model source.') - - with self.argument_context('cognitiveservices account deployment', arg_group='DeploymentScaleSettings') as c: - c.argument( - 'scale_settings_scale_type', get_enum_type(DeploymentScaleType), - options_list=['--scale-type', '--scale-settings-scale-type'], - help='Cognitive Services account deployment scale settings scale type.') - c.argument( - 'scale_settings_capacity', options_list=['--scale-capacity', '--scale-settings-capacity'], - help='Cognitive Services account deployment scale settings capacity.') - - with self.argument_context('cognitiveservices account commitment-plan') as c: - c.argument('commitment_plan_name', help='Cognitive Services account commitment plan name') - c.argument('plan_type', help='Cognitive Services account commitment plan type') - c.argument('hosting_model', get_enum_type(HostingModel), help='Cognitive Services account hosting model') - c.argument( - 'auto_renew', arg_type=get_three_state_flag(), - help='A boolean indicating whether to apply auto renew.') - - with self.argument_context('cognitiveservices account commitment-plan', arg_group='Current CommitmentPeriod') as c: - c.argument('current_count', help='Cognitive Services account commitment plan current commitment period count.') - c.argument('current_tier', help='Cognitive Services account commitment plan current commitment period tier.') - - with self.argument_context('cognitiveservices account commitment-plan', arg_group='Next CommitmentPeriod') as c: - c.argument('next_count', help='Cognitive Services account commitment plan next commitment period count.') - c.argument('next_tier', help='Cognitive Services account commitment plan next commitment period tier.') - - with self.argument_context('cognitiveservices agent') as c: - c.argument('account_name', arg_type=name_arg_type, - help='cognitive service account name. Mutually exclusive with --endpoint.', - completer=get_resource_name_completion_list('Microsoft.CognitiveServices/accounts'), - required=False) - c.argument('project_name', help='AI Project name') - c.argument('agent_name', help='Cognitive Services hosted agent name') - c.argument('agent_version', help='Cognitive Services hosted agent version') - c.argument('endpoint', help='AI Projects endpoint URL. Mutually exclusive with --name.') - - with self.argument_context('cognitiveservices agent update') as c: - c.argument('min_replica', options_list=['--min-replica'], help='Minimum number of replicas for horizontal scaling') - c.argument('max_replica', options_list=['--max-replica'], help='Maximum number of replicas for horizontal scaling') - c.argument('description', help='Description of the agent') - - with self.argument_context('cognitiveservices agent delete') as c: - c.argument('agent_version', help='Cognitive Services hosted agent version. If not provided, deletes all versions.', required=False) - - with self.argument_context('cognitiveservices agent versions') as c: - c.argument('account_name', arg_type=name_arg_type, - help='cognitive service account name. Mutually exclusive with --endpoint.', - completer=get_resource_name_completion_list('Microsoft.CognitiveServices/accounts'), - required=False, - validator=validate_agent_endpoint_or_account_name) - c.argument('project_name', help='AI Project name') - c.argument('agent_name', help='Cognitive Services hosted agent name') - c.argument('endpoint', help='AI Projects endpoint URL. Mutually exclusive with --name.') + with self.argument_context("cognitiveservices") as c: + c.argument( + "account_name", + arg_type=name_arg_type, + help="cognitive service account name", + completer=get_resource_name_completion_list( + "Microsoft.CognitiveServices/accounts" + ), + ) + c.argument( + "location", + arg_type=get_location_type(self.cli_ctx), + completer=location_completer, + ) + c.argument("resource_group_name", arg_type=resource_group_name_type) + c.argument( + "sku_name", + options_list=["--sku", "--sku-name"], + help="Name of the Sku of Cognitive Services account/deployment", + completer=sku_name_completer, + ) + c.argument( + "sku_capacity", + options_list=["--capacity", "--sku-capacity"], + help="Capacity value of the Sku of Cognitive Services account/deployment.", + ) + c.argument( + "kind", + help="the API name of cognitive services account", + completer=kind_completer, + ) + c.argument("tags", tags_type) + c.argument( + "key_name", + required=True, + help="Key name to generate", + arg_type=get_enum_type(KeyName), + ) + c.argument("api_properties", api_properties_type) + c.argument( + "custom_domain", + help="User domain assigned to the account. Name is the CNAME source.", + ) + c.argument( + "storage", + help="The storage accounts for this resource, in JSON array format.", + ) + c.argument( + "encryption", + help="The encryption properties for this resource, in JSON format.", + ) + + with self.argument_context( + "cognitiveservices account", arg_group="AI Services" + ) as c: + c.argument( + "allow_project_management", + options_list=["--manage-projects", "--allow-project-management"], + arg_type=get_three_state_flag(), + help="AIServices kind only. Enables project management. Default true.", + ) + + with self.argument_context("cognitiveservices account create") as c: + c.argument( + "assign_identity", + help="Generate and assign an Azure Active Directory Identity for this account.", + ) + c.argument( + "yes", action="store_true", help="Do not prompt for terms confirmation" + ) + + with self.argument_context( + "cognitiveservices account update", arg_group="AI Services" + ) as c: + c.argument( + "kind", + arg_type=get_enum_type(data=["AIServices", "OpenAI"]), + help="The target API name to transform the existing account into.", + ) + + with self.argument_context("cognitiveservices account network-rule") as c: + c.argument("ip_address", help="IPv4 address or CIDR range.") + c.argument( + "subnet", + help="Name or ID of subnet. If name is supplied, `--vnet-name` must be supplied.", + ) + c.argument( + "vnet_name", help="Name of a virtual network.", validator=_validate_subnet + ) + + with self.argument_context("cognitiveservices account deployment") as c: + c.argument("deployment_name", help="Cognitive Services account deployment name") + + with self.argument_context( + "cognitiveservices account deployment", arg_group="DeploymentModel" + ) as c: + c.argument( + "model_name", help="Cognitive Services account deployment model name." + ) + c.argument( + "model_format", help="Cognitive Services account deployment model format." + ) + c.argument( + "model_version", help="Cognitive Services account deployment model version." + ) + c.argument( + "model_source", help="Cognitive Services account deployment model source." + ) + + with self.argument_context( + "cognitiveservices account deployment", arg_group="DeploymentScaleSettings" + ) as c: + c.argument( + "scale_settings_scale_type", + get_enum_type(DeploymentScaleType), + options_list=["--scale-type", "--scale-settings-scale-type"], + help="Cognitive Services account deployment scale settings scale type.", + ) + c.argument( + "scale_settings_capacity", + options_list=["--scale-capacity", "--scale-settings-capacity"], + help="Cognitive Services account deployment scale settings capacity.", + ) + + with self.argument_context("cognitiveservices account commitment-plan") as c: + c.argument( + "commitment_plan_name", + help="Cognitive Services account commitment plan name", + ) + c.argument("plan_type", help="Cognitive Services account commitment plan type") + c.argument( + "hosting_model", + get_enum_type(HostingModel), + help="Cognitive Services account hosting model", + ) + c.argument( + "auto_renew", + arg_type=get_three_state_flag(), + help="A boolean indicating whether to apply auto renew.", + ) + + with self.argument_context( + "cognitiveservices account commitment-plan", + arg_group="Current CommitmentPeriod", + ) as c: + c.argument( + "current_count", + help="Cognitive Services account commitment plan current commitment period count.", + ) + c.argument( + "current_tier", + help="Cognitive Services account commitment plan current commitment period tier.", + ) + + with self.argument_context( + "cognitiveservices account commitment-plan", arg_group="Next CommitmentPeriod" + ) as c: + c.argument( + "next_count", + help="Cognitive Services account commitment plan next commitment period count.", + ) + c.argument( + "next_tier", + help="Cognitive Services account commitment plan next commitment period tier.", + ) + + with self.argument_context("cognitiveservices agent") as c: + c.argument( + "account_name", + options_list=["--account-name", "-a"], + help="cognitive service account name." + ) + c.argument("project_name", help="AI Project name") + c.argument( + "agent_name", + options_list=["--name", "-n"], + help="Cognitive Services hosted agent name", + ) + c.argument("agent_version", help="Cognitive Services hosted agent version") + + with self.argument_context("cognitiveservices agent update") as c: + c.argument( + "min_replicas", + type=int, + options_list=["--min-replicas"], + help="Minimum number of replicas for horizontal scaling", + ) + c.argument( + "max_replicas", + type=int, + options_list=["--max-replicas"], + help="Maximum number of replicas for horizontal scaling", + ) + c.argument("description", help="Description of the agent") + + with self.argument_context("cognitiveservices agent delete") as c: + c.argument( + "agent_version", + help="Cognitive Services hosted agent version. If not provided, deletes all versions.", + required=False, + ) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py index 1c0d723c49c..fa7d6ca15c8 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py @@ -105,7 +105,7 @@ def load_command_table(self, _): with self.command_group('cognitiveservices usage', usages_type) as g: g.command('list', 'list') - with self.command_group('cognitiveservices agent', client_factory=cf_ai_projects) as g: + with self.command_group('cognitiveservices agent', client_factory=cf_ai_projects, is_preview=True) as g: g.custom_command('update', 'agent_update') g.custom_command('stop', 'agent_stop') g.custom_command('start', 'agent_start') diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index 87eeb9ce18e..069930d1119 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -10,13 +10,29 @@ from knack.log import get_logger import azure.core.rest -from azure.mgmt.cognitiveservices.models import Account as CognitiveServicesAccount, Sku, \ - VirtualNetworkRule, IpRule, NetworkRuleSet, NetworkRuleAction, \ - AccountProperties as CognitiveServicesAccountProperties, ApiProperties as CognitiveServicesAccountApiProperties, \ - Identity, ResourceIdentityType as IdentityType, \ - Deployment, DeploymentModel, DeploymentScaleSettings, DeploymentProperties, \ - CommitmentPlan, CommitmentPlanProperties, CommitmentPeriod -from azure.cli.command_modules.cognitiveservices._client_factory import cf_accounts, cf_resource_skus +from azure.mgmt.cognitiveservices.models import ( + Account as CognitiveServicesAccount, + Sku, + VirtualNetworkRule, + IpRule, + NetworkRuleSet, + NetworkRuleAction, + AccountProperties as CognitiveServicesAccountProperties, + ApiProperties as CognitiveServicesAccountApiProperties, + Identity, + ResourceIdentityType as IdentityType, + Deployment, + DeploymentModel, + DeploymentScaleSettings, + DeploymentProperties, + CommitmentPlan, + CommitmentPlanProperties, + CommitmentPeriod, +) +from azure.cli.command_modules.cognitiveservices._client_factory import ( + cf_accounts, + cf_resource_skus, +) from azure.cli.core.azclierror import BadRequestError logger = get_logger(__name__) @@ -63,16 +79,19 @@ def list_kinds(client): return sorted(list(kinds)) -def list_skus(cmd, kind=None, location=None, resource_group_name=None, account_name=None): +def list_skus( + cmd, kind=None, location=None, resource_group_name=None, account_name=None +): """ List skus for Azure Cognitive Services account. """ if resource_group_name is not None or account_name is not None: logger.warning( - 'list-skus with an existing account has been deprecated and will be removed in a future release.') + "list-skus with an existing account has been deprecated and will be removed in a future release." + ) if resource_group_name is None: # account_name must not be None - raise CLIError('--resource-group is required when --name is specified.') + raise CLIError("--resource-group is required when --name is specified.") # keep the original behavior to avoid breaking changes return cf_accounts(cmd.cli_ctx).list_skus(resource_group_name, account_name) @@ -90,22 +109,30 @@ def _filter_sku(_sku): def _is_valid_kind_change(current_kind, target_kind): - valid_upgrades = { - 'AIServices': ['OpenAI'], - 'OpenAI': ['AIServices'] - } + valid_upgrades = {"AIServices": ["OpenAI"], "OpenAI": ["AIServices"]} return target_kind in valid_upgrades.get(current_kind, []) def _kind_uses_project_management(kind): - return kind in ['AIServices'] + return kind in ["AIServices"] def create( - client, resource_group_name, account_name, sku_name, kind, location, custom_domain=None, - tags=None, api_properties=None, assign_identity=False, storage=None, encryption=None, - allow_project_management=None, - yes=None): # pylint: disable=unused-argument + client, + resource_group_name, + account_name, + sku_name, + kind, + location, + custom_domain=None, + tags=None, + api_properties=None, + assign_identity=False, + storage=None, + encryption=None, + allow_project_management=None, + yes=None, +): # pylint: disable=unused-argument """ Create an Azure Cognitive Services account. """ @@ -117,13 +144,16 @@ def create( properties = CognitiveServicesAccountProperties() if api_properties is not None: - api_properties = CognitiveServicesAccountApiProperties.deserialize(api_properties) + api_properties = CognitiveServicesAccountApiProperties.deserialize( + api_properties + ) properties.api_properties = api_properties if custom_domain: properties.custom_sub_domain_name = custom_domain properties.allow_project_management = allow_project_management - params = CognitiveServicesAccount(sku=sku, kind=kind, location=location, - properties=properties, tags=tags) + params = CognitiveServicesAccount( + sku=sku, kind=kind, location=location, properties=properties, tags=tags + ) if assign_identity or allow_project_management: params.identity = Identity(type=IdentityType.system_assigned) @@ -136,9 +166,19 @@ def create( return client.begin_create(resource_group_name, account_name, params) -def update(client, resource_group_name, account_name, sku_name=None, custom_domain=None, - tags=None, api_properties=None, storage=None, encryption=None, - allow_project_management=None, kind=None): +def update( + client, + resource_group_name, + account_name, + sku_name=None, + custom_domain=None, + tags=None, + api_properties=None, + storage=None, + encryption=None, + allow_project_management=None, + kind=None, +): """ Update an Azure Cognitive Services account. """ @@ -151,7 +191,9 @@ def update(client, resource_group_name, account_name, sku_name=None, custom_doma properties = CognitiveServicesAccountProperties() if api_properties is not None: - api_properties = CognitiveServicesAccountApiProperties.deserialize(api_properties) + api_properties = CognitiveServicesAccountApiProperties.deserialize( + api_properties + ) properties.api_properties = api_properties if custom_domain: properties.custom_sub_domain_name = custom_domain @@ -164,7 +206,11 @@ def update(client, resource_group_name, account_name, sku_name=None, custom_doma if sa is None: sa = client.get(resource_group_name, account_name) if kind != sa.kind and not _is_valid_kind_change(sa.kind, kind): - raise BadRequestError("Changing the account kind from '{}' to '{}' is not supported.".format(sa.kind, kind)) + raise BadRequestError( + "Changing the account kind from '{}' to '{}' is not supported.".format( + sa.kind, kind + ) + ) params.kind = kind if _kind_uses_project_management(kind) and allow_project_management is None: params.properties.allow_project_management = True @@ -197,8 +243,14 @@ def list_network_rules(client, resource_group_name, account_name): return rules -def add_network_rule(client, resource_group_name, account_name, subnet=None, - vnet_name=None, ip_address=None): # pylint: disable=unused-argument +def add_network_rule( + client, + resource_group_name, + account_name, + subnet=None, + vnet_name=None, + ip_address=None, +): # pylint: disable=unused-argument """ Add a network rule for Azure Cognitive Services account. """ @@ -209,12 +261,17 @@ def add_network_rule(client, resource_group_name, account_name, subnet=None, if subnet: from azure.mgmt.core.tools import is_valid_resource_id + if not is_valid_resource_id(subnet): - raise CLIError("Expected fully qualified resource ID: got '{}'".format(subnet)) + raise CLIError( + "Expected fully qualified resource ID: got '{}'".format(subnet) + ) if not rules.virtual_network_rules: rules.virtual_network_rules = [] - rules.virtual_network_rules.append(VirtualNetworkRule(id=subnet, ignore_missing_vnet_service_endpoint=True)) + rules.virtual_network_rules.append( + VirtualNetworkRule(id=subnet, ignore_missing_vnet_service_endpoint=True) + ) if ip_address: if not rules.ip_rules: rules.ip_rules = [] @@ -227,8 +284,14 @@ def add_network_rule(client, resource_group_name, account_name, subnet=None, return client.begin_update(resource_group_name, account_name, params) -def remove_network_rule(client, resource_group_name, account_name, ip_address=None, subnet=None, - vnet_name=None): # pylint: disable=unused-argument +def remove_network_rule( + client, + resource_group_name, + account_name, + ip_address=None, + subnet=None, + vnet_name=None, +): # pylint: disable=unused-argument """ Remove a network rule for Azure Cognitive Services account. """ @@ -239,8 +302,9 @@ def remove_network_rule(client, resource_group_name, account_name, ip_address=No return client.update(resource_group_name, account_name) if subnet: - rules.virtual_network_rules = [x for x in rules.virtual_network_rules - if not x.id.endswith(subnet)] + rules.virtual_network_rules = [ + x for x in rules.virtual_network_rules if not x.id.endswith(subnet) + ] if ip_address: rules.ip_rules = [x for x in rules.ip_rules if x.value != ip_address] @@ -279,10 +343,19 @@ def identity_show(client, resource_group_name, account_name): def deployment_begin_create_or_update( - client, resource_group_name, account_name, deployment_name, - model_format, model_name, model_version, model_source=None, - sku_name=None, sku_capacity=None, - scale_settings_scale_type=None, scale_settings_capacity=None): + client, + resource_group_name, + account_name, + deployment_name, + model_format, + model_name, + model_version, + model_source=None, + sku_name=None, + sku_capacity=None, + scale_settings_scale_type=None, + scale_settings_capacity=None, +): """ Create a deployment for Azure Cognitive Services account. """ @@ -302,14 +375,24 @@ def deployment_begin_create_or_update( dpy.properties.scale_settings.scale_type = scale_settings_scale_type dpy.properties.scale_settings.capacity = scale_settings_capacity - return client.begin_create_or_update(resource_group_name, account_name, deployment_name, dpy, polling=False) + return client.begin_create_or_update( + resource_group_name, account_name, deployment_name, dpy, polling=False + ) def commitment_plan_create_or_update( - client, resource_group_name, account_name, commitment_plan_name, - hosting_model, plan_type, auto_renew, - current_tier=None, current_count=None, - next_tier=None, next_count=None): + client, + resource_group_name, + account_name, + commitment_plan_name, + hosting_model, + plan_type, + auto_renew, + current_tier=None, + current_count=None, + next_tier=None, + next_count=None, +): """ Create a commitment plan for Azure Cognitive Services account. """ @@ -317,120 +400,205 @@ def commitment_plan_create_or_update( plan.properties = CommitmentPlanProperties() plan.properties.hosting_model = hosting_model plan.properties.plan_type = plan_type - if (current_tier is not None or current_count is not None): + if current_tier is not None or current_count is not None: plan.properties.current = CommitmentPeriod() plan.properties.current.tier = current_tier plan.properties.current.count = current_count - if (next_tier is not None or next_count is not None): + if next_tier is not None or next_count is not None: plan.properties.next = CommitmentPeriod() plan.properties.next.tier = next_tier plan.properties.next.count = next_count plan.properties.auto_renew = auto_renew - return client.create_or_update(resource_group_name, account_name, commitment_plan_name, plan) - + return client.create_or_update( + resource_group_name, account_name, commitment_plan_name, plan + ) + + +AGENT_API_VERSION_PARAMS = {"api-version": "2025-11-15-preview"} + + +def _create_agent_request( + method: str, + agent_name: str, + agent_version: str = None, + *, + container: bool = False, + action: str = None, + body: dict = None, +): + if container and not agent_version: + raise ValueError("container=True requires agent_version to be specified") + + if agent_version: + url = f"/agents/{urllib.parse.quote(agent_name)}/versions/{urllib.parse.quote(agent_version)}" + if container: + url += "/containers/default" + else: + url = f"/agents/{urllib.parse.quote(agent_name)}" + + if action: + url += f":{action}" + return azure.core.rest.HttpRequest( + method, url, json=body, params=AGENT_API_VERSION_PARAMS + ) + + +def _invoke_agent_container_operation( + client, + agent_name, + agent_version, + *, + action: str, + min_replicas=None, + max_replicas=None, +): + request_body = {} + if min_replicas is not None: + request_body["min_replicas"] = min_replicas + if max_replicas is not None: + request_body["max_replicas"] = max_replicas + request = _create_agent_request( + "POST", + agent_name, + agent_version, + action=action, + container=True, + body=request_body, + ) + response = client.send_request(request) + response.raise_for_status() + return response.json() -AGENT_API_VERSION_PARAMS = { 'api-version': '2025-11-15-preview' } -def agent_update(client, account_name, project_name, agent_name, agent_version, - min_replica=None, max_replica=None, description=None, tags=None, endpoint=None): +def agent_update( + client, + account_name, + project_name, + agent_name, + agent_version, + min_replicas=None, + max_replicas=None, + description=None, + tags=None, + endpoint=None, +): # pylint: disable=unused-argument """ Update hosted agent deployment configuration. Updates horizontal scale configuration (min and max replica), agent meta-data such as description and tags. New version is not created for this update. """ - request_body = {} - if min_replica is not None: - request_body['min_replica'] = min_replica - if max_replica is not None: - request_body['max_replica'] = max_replica - request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)}/containers/default:update', json = request_body, params=AGENT_API_VERSION_PARAMS) - response = client.send_request(request) - response.raise_for_status() - return response.json() + return _invoke_agent_container_operation( + client, + agent_name, + agent_version, + action="update", + min_replicas=min_replicas, + max_replicas=max_replicas, + ) -def agent_stop(client, account_name, project_name, agent_name, agent_version, endpoint=None): + +def agent_stop( + client, account_name, project_name, agent_name, agent_version +): # pylint: disable=unused-argument """ Stop hosted agent deployment. """ - request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)/containers/default:start}', params=AGENT_API_VERSION_PARAMS) - response = client.send_request(request) - response.raise_for_status() - return response.json() + return _invoke_agent_container_operation( + client, agent_name, agent_version, action="stop" + ) -def agent_start(client, account_name, project_name, agent_name, agent_version, endpoint=None): +def agent_start( + client, account_name, project_name, agent_name, agent_version +): # pylint: disable=unused-argument """ Start hosted agent deployment. """ - request = azure.core.rest.HttpRequest('POST', f'/agents/{urllib.parse.quote(agent_name)/containers/default:start}', params=AGENT_API_VERSION_PARAMS) - response = client.send_request(request) - response.raise_for_status() - return response.json() + return _invoke_agent_container_operation( + client, agent_name, agent_version, action="start" + ) -def agent_delete_deployment(client, account_name, project_name, agent_name, agent_version, endpoint=None): +def agent_delete_deployment( + client, account_name, project_name, agent_name, agent_version +): # pylint: disable=unused-argument """ Delete hosted agent deployment. Deletes the agent deployment only, agent version associated with the deployment remains. """ - raise NotImplementedError("agent_delete_deployment command is not yet implemented") + request = _create_agent_request("DELETE", agent_name, agent_version, container=True) + response = client.send_request(request) + response.raise_for_status() + return response.json() -def agent_delete(client, account_name, project_name, agent_name, agent_version=None, endpoint=None): +def agent_delete( + client, account_name, project_name, agent_name, agent_version=None +): # pylint: disable=unused-argument """ Delete hosted agent version or all versions. - If agent_version is provided, deletes the agent instance and agent definition associated with `that version. + If agent_version is provided, deletes the agent instance and agent definition associated with that version. If agent_version is not provided, deletes all agent instances and agent definitions associated with the agent name. """ - request = azure.core.rest.HttpRequest('DELETE', f'/agents/{urllib.parse.quote(agent_name)}', params = AGENT_API_VERSION_PARAMS) + request = _create_agent_request("DELETE", agent_name, agent_version) response = client.send_request(request) response.raise_for_status() return response.json() -def agent_list(client, account_name, project_name, endpoint=None): +def agent_list( + client, account_name, project_name +): # pylint: disable=unused-argument """ - List hosted agent versions or deployments. - If agent_version is not provided, lists all versions for an agent. - If agent_version is provided, lists all deployments for that agent version. + List agents. """ agents = [] params = AGENT_API_VERSION_PARAMS.copy() while True: - request = azure.core.rest.HttpRequest('GET', f'/agents', params=params) + request = azure.core.rest.HttpRequest("GET", "/agents", params=params) response = client.send_request(request) response.raise_for_status() body = response.json() - agents.extend(body.get('data', [])) - if body.get('has_more'): - params['after'] = body.get('last_id') + agents.extend(body.get("data", [])) + if body.get("has_more"): + params["after"] = body.get("last_id") else: return agents -def agent_versions_list(client, account_name, project_name, agent_name, endpoint=None): +def agent_versions_list( + client, account_name, project_name, agent_name +): # pylint: disable=unused-argument """ List all versions of a hosted agent. """ versions = [] params = AGENT_API_VERSION_PARAMS.copy() while True: - request = azure.core.rest.HttpRequest('GET', f'/agents/{urllib.parse.quote(agent_name)}/versions', params=params) + request = azure.core.rest.HttpRequest( + "GET", f"/agents/{urllib.parse.quote(agent_name)}/versions", params=params + ) response = client.send_request(request) response.raise_for_status() body = response.json() - versions.extend(body.get('data', [])) - if body.get('has_more'): - params['after'] = body.get('last_id') + versions.extend(body.get("data", [])) + if body.get("has_more"): + params["after"] = body.get("last_id") else: return versions -def agent_show(client, account_name, project_name, agent_name, endpoint=None): +def agent_show( + client, account_name, project_name, agent_name +): # pylint: disable=unused-argument """ Show details of a hosted agent. """ - request = azure.core.rest.HttpRequest('GET', f'/agents/{urllib.parse.quote(agent_name)}', params=AGENT_API_VERSION_PARAMS) + request = azure.core.rest.HttpRequest( + "GET", + f"/agents/{urllib.parse.quote(agent_name)}", + params=AGENT_API_VERSION_PARAMS, + ) response = client.send_request(request) response.raise_for_status() return response.json() From b7b9595028d717c7c59d2530c5d862ab98e4d434 Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Thu, 6 Nov 2025 10:25:49 -0800 Subject: [PATCH 4/7] Fix linter violations for cognitiveservices agents commands --- .../cognitiveservices/_help.py | 29 +++++++++++++++++++ .../cognitiveservices/commands.py | 2 +- .../cognitiveservices/custom.py | 1 - 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py index d6c72bce99f..d240d6918d8 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py @@ -392,3 +392,32 @@ - name: Show all usages for Azure Cognitive Services. text: az cognitiveservices usage list -l centraluseuap """ + +helps['cognitiveservices agent'] = """ +type: group +short-summary: Control foundry agents. +""" + +helps['cognitiveservices agent start'] = """ +type: command +short-summary: Start a hosted agent deployment. +examples: + - name: Start hosted agent deployment. + text: az cognitiveservices agent start --account-name myAccount --project-name myProject --name myAgent --agent-version 1 +""" + +helps['cognitiveservices agent stop'] = """ +type: command +short-summary: Stop a hosted agent deployment. +examples: + - name: Start hosted agent deployment. + text: az cognitiveservices agent stop --account-name myAccount --project-name myProject --name myAgent --agent-version 1 +""" + +helps['cognitiveservices agent update'] = """ +type: command +short-summary: Update a hosted agent deployment. +examples: + - name: Start hosted agent deployment. + text: az cognitiveservices agent update --account-name myAccount --project-name myProject --name myAgent --agent-version 1 --min-replicas 1 --max-replicas 2 +""" \ No newline at end of file diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py index fa7d6ca15c8..0c7c221e68e 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py @@ -113,4 +113,4 @@ def load_command_table(self, _): g.custom_command('delete', 'agent_delete') g.custom_command('list', 'agent_list') g.custom_command('list-versions', 'agent_versions_list') - g.custom_command('show', 'agent_show') + g.custom_show_command('show', 'agent_show') diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index 069930d1119..1cb3bf88036 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -480,7 +480,6 @@ def agent_update( max_replicas=None, description=None, tags=None, - endpoint=None, ): # pylint: disable=unused-argument """ Update hosted agent deployment configuration. From a6093f7e228f08253ecffda0168daded58c7168c Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Thu, 6 Nov 2025 10:45:44 -0800 Subject: [PATCH 5/7] Format file --- .../cognitiveservices/_help.py | 183 +++++++++++++----- 1 file changed, 137 insertions(+), 46 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py index d240d6918d8..7b31acbb76b 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py @@ -5,21 +5,28 @@ # -------------------------------------------------------------------------------------------- from knack.help_files import helps # pylint: disable=unused-import + # pylint: disable=line-too-long, too-many-lines -helps['cognitiveservices'] = """ +helps[ + "cognitiveservices" +] = """ type: group short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. """ -helps['cognitiveservices account'] = """ +helps[ + "cognitiveservices account" +] = """ type: group short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. """ -helps['cognitiveservices account create'] = """ +helps[ + "cognitiveservices account create" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -57,7 +64,9 @@ }' """ -helps['cognitiveservices account delete'] = """ +helps[ + "cognitiveservices account delete" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -66,13 +75,17 @@ text: az cognitiveservices account delete --name myresource-luis -g cognitive-services-resource-group """ -helps['cognitiveservices account keys'] = """ +helps[ + "cognitiveservices account keys" +] = """ type: group short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. """ -helps['cognitiveservices account keys list'] = """ +helps[ + "cognitiveservices account keys list" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -84,7 +97,9 @@ crafted: true """ -helps['cognitiveservices account keys regenerate'] = """ +helps[ + "cognitiveservices account keys regenerate" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -93,7 +108,9 @@ text: az cognitiveservices account keys regenerate --name myresource -g cognitive-services-resource-group --key-name key1 """ -helps['cognitiveservices account list'] = """ +helps[ + "cognitiveservices account list" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -102,7 +119,9 @@ text: az cognitiveservices account list -g MyResourceGroup """ -helps['cognitiveservices account list-skus'] = """ +helps[ + "cognitiveservices account list-skus" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -122,7 +141,9 @@ text: az cognitiveservices account list-skus --kind Face --location westus """ -helps['cognitiveservices account list-models'] = """ +helps[ + "cognitiveservices account list-models" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -131,12 +152,16 @@ text: az cognitiveservices account list-models -n myresource -g cognitive-services-resource-group """ -helps['cognitiveservices account network-rule'] = """ +helps[ + "cognitiveservices account network-rule" +] = """ type: group short-summary: Manage network rules. """ -helps['cognitiveservices account network-rule add'] = """ +helps[ + "cognitiveservices account network-rule add" +] = """ type: command short-summary: Add a network rule. long-summary: > @@ -148,7 +173,9 @@ text: az cognitiveservices account network-rule add -g myRg --name MyAccount --vnet myvnet --subnet mysubnet """ -helps['cognitiveservices account network-rule list'] = """ +helps[ + "cognitiveservices account network-rule list" +] = """ type: command short-summary: List network rules. examples: @@ -157,7 +184,9 @@ crafted: true """ -helps['cognitiveservices account network-rule remove'] = """ +helps[ + "cognitiveservices account network-rule remove" +] = """ type: command short-summary: Remove a network rule. examples: @@ -169,7 +198,9 @@ crafted: true """ -helps['cognitiveservices account show'] = """ +helps[ + "cognitiveservices account show" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -178,7 +209,9 @@ text: az cognitiveservices account show --name myresource --resource-group cognitive-services-resource-group """ -helps['cognitiveservices account update'] = """ +helps[ + "cognitiveservices account update" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -191,7 +224,9 @@ text: az cognitiveservices account update --name myresource -g cognitive-services-resource-group --sku S0 --tags external-app=chatbot-HR azure-web-app-bot=HR-external azure-app-service=HR-external-app-service """ -helps['cognitiveservices list'] = """ +helps[ + "cognitiveservices list" +] = """ type: command short-summary: Manage Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -200,12 +235,16 @@ text: az cognitiveservices list -g MyResourceGroup """ -helps['cognitiveservices account identity'] = """ +helps[ + "cognitiveservices account identity" +] = """ type: group short-summary: Manage identity of Cognitive Services accounts. """ -helps['cognitiveservices account identity assign'] = """ +helps[ + "cognitiveservices account identity assign" +] = """ type: command short-summary: Assign an identity of a Cognitive Services account. long-summary: Assign an identity object of a Cognitive Services account. An system assigned identity will be generate and assigned to the account. @@ -214,7 +253,9 @@ text: az cognitiveservices account identity assign --name myresource --resource-group cognitive-services-resource-group """ -helps['cognitiveservices account identity show'] = """ +helps[ + "cognitiveservices account identity show" +] = """ type: command short-summary: Show the identity of a Cognitive Services account. long-summary: Show the identity object of a Cognitive Services account, empty object might be returned if the account has no assigned identity. @@ -223,7 +264,9 @@ text: az cognitiveservices account identity show --name myresource --resource-group cognitive-services-resource-group """ -helps['cognitiveservices account identity remove'] = """ +helps[ + "cognitiveservices account identity remove" +] = """ type: command short-summary: Remove the identity from a Cognitive Services account. long-summary: Remove the identity (if exists) from a Cognitive Services account. @@ -232,7 +275,9 @@ text: az cognitiveservices account identity remove --name myresource --resource-group cognitive-services-resource-group """ -helps['cognitiveservices account list-deleted'] = """ +helps[ + "cognitiveservices account list-deleted" +] = """ type: command short-summary: List soft-deleted Azure Cognitive Services accounts. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -242,7 +287,9 @@ """ -helps['cognitiveservices account show-deleted'] = """ +helps[ + "cognitiveservices account show-deleted" +] = """ type: command short-summary: Show a soft-deleted Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -251,7 +298,9 @@ text: az cognitiveservices account show-deleted --location eastus --resource-group cognitive-services-resource-group --name cognitive-services-account-name """ -helps['cognitiveservices account recover'] = """ +helps[ + "cognitiveservices account recover" +] = """ type: command short-summary: Recover a soft-deleted Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -260,7 +309,9 @@ text: az cognitiveservices account recover --location eastus --resource-group cognitive-services-resource-group --name cognitive-services-account-name """ -helps['cognitiveservices account purge'] = """ +helps[ + "cognitiveservices account purge" +] = """ type: command short-summary: Purge a soft-deleted Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -269,12 +320,16 @@ text: az cognitiveservices account purge --location eastus --resource-group cognitive-services-resource-group --name cognitive-services-account-name """ -helps['cognitiveservices account deployment'] = """ +helps[ + "cognitiveservices account deployment" +] = """ type: group short-summary: Manage deployments for Azure Cognitive Services accounts. """ -helps['cognitiveservices account deployment create'] = """ +helps[ + "cognitiveservices account deployment create" +] = """ type: command short-summary: Create a deployment for Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -283,7 +338,9 @@ text: az cognitiveservices account deployment create -g yuanyang-test-sdk -n yytest-oai --deployment-name dpy --model-name ada --model-version "1" --model-format OpenAI --sku-capacity 1 --sku-name "Standard" """ -helps['cognitiveservices account deployment delete'] = """ +helps[ + "cognitiveservices account deployment delete" +] = """ type: command short-summary: Delete a deployment from Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -292,7 +349,9 @@ text: az cognitiveservices account deployment delete -g yuanyang-test-sdk -n yytest-oai --deployment-name dpy """ -helps['cognitiveservices account deployment show'] = """ +helps[ + "cognitiveservices account deployment show" +] = """ type: command short-summary: Show a deployment for Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -301,7 +360,9 @@ text: az cognitiveservices account deployment show -g yuanyang-test-sdk -n yytest-oai --deployment-name dpy """ -helps['cognitiveservices account deployment list'] = """ +helps[ + "cognitiveservices account deployment list" +] = """ type: command short-summary: Show all deployments for Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -310,12 +371,16 @@ text: az cognitiveservices account deployment list -g yuanyang-test-sdk -n yytest-oai """ -helps['cognitiveservices commitment-tier'] = """ +helps[ + "cognitiveservices commitment-tier" +] = """ type: group short-summary: Manage commitment tiers for Azure Cognitive Services. """ -helps['cognitiveservices commitment-tier list'] = """ +helps[ + "cognitiveservices commitment-tier list" +] = """ type: command short-summary: Show all commitment tiers for Azure Cognitive Services. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -324,12 +389,16 @@ text: az cognitiveservices commitment-tier list -l centraluseuap """ -helps['cognitiveservices account commitment-plan'] = """ +helps[ + "cognitiveservices account commitment-plan" +] = """ type: group short-summary: Manage commitment plans for Azure Cognitive Services accounts. """ -helps['cognitiveservices account commitment-plan create'] = """ +helps[ + "cognitiveservices account commitment-plan create" +] = """ type: command short-summary: Create a commitment plan for Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -338,7 +407,9 @@ text: az cognitiveservices account commitment-plan create -g yuanyang-test-sdk -n yytest-ta --commitment-plan-name "plan" --hosting-model "Web" --plan-type "TA" --auto-renew false --current-tier "T1" --next-tier "T2" """ -helps['cognitiveservices account commitment-plan delete'] = """ +helps[ + "cognitiveservices account commitment-plan delete" +] = """ type: command short-summary: Delete a commitment plan from Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -347,7 +418,9 @@ text: az cognitiveservices account commitment-plan delete -g yuanyang-test-sdk -n yytest-ta --commitment-plan-name "plan" """ -helps['cognitiveservices account commitment-plan show'] = """ +helps[ + "cognitiveservices account commitment-plan show" +] = """ type: command short-summary: Show a commitment plan from Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -356,7 +429,9 @@ text: az cognitiveservices account commitment-plan show -g yuanyang-test-sdk -n yytest-ta --commitment-plan-name "plan" """ -helps['cognitiveservices account commitment-plan list'] = """ +helps[ + "cognitiveservices account commitment-plan list" +] = """ type: command short-summary: Show all commitment plans from Azure Cognitive Services account. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -365,12 +440,16 @@ text: az cognitiveservices account commitment-plan list -g yuanyang-test-sdk -n yytest-ta """ -helps['cognitiveservices model'] = """ +helps[ + "cognitiveservices model" +] = """ type: group short-summary: Manage model for Azure Cognitive Services. """ -helps['cognitiveservices model list'] = """ +helps[ + "cognitiveservices model list" +] = """ type: command short-summary: Show all models for Azure Cognitive Services. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -379,12 +458,16 @@ text: az cognitiveservices model list -l centraluseuap """ -helps['cognitiveservices usage'] = """ +helps[ + "cognitiveservices usage" +] = """ type: group short-summary: Manage usage for Azure Cognitive Services. """ -helps['cognitiveservices usage list'] = """ +helps[ + "cognitiveservices usage list" +] = """ type: command short-summary: Show all usages for Azure Cognitive Services. long-summary: This article lists the Azure CLI commands for Azure Cognitive Services account and subscription management only. Refer to the documentation at https://learn.microsoft.com/azure/cognitive-services/ for individual services to learn how to use the APIs and supported SDKs. @@ -393,12 +476,16 @@ text: az cognitiveservices usage list -l centraluseuap """ -helps['cognitiveservices agent'] = """ +helps[ + "cognitiveservices agent" +] = """ type: group short-summary: Control foundry agents. """ -helps['cognitiveservices agent start'] = """ +helps[ + "cognitiveservices agent start" +] = """ type: command short-summary: Start a hosted agent deployment. examples: @@ -406,7 +493,9 @@ text: az cognitiveservices agent start --account-name myAccount --project-name myProject --name myAgent --agent-version 1 """ -helps['cognitiveservices agent stop'] = """ +helps[ + "cognitiveservices agent stop" +] = """ type: command short-summary: Stop a hosted agent deployment. examples: @@ -414,10 +503,12 @@ text: az cognitiveservices agent stop --account-name myAccount --project-name myProject --name myAgent --agent-version 1 """ -helps['cognitiveservices agent update'] = """ +helps[ + "cognitiveservices agent update" +] = """ type: command short-summary: Update a hosted agent deployment. examples: - name: Start hosted agent deployment. text: az cognitiveservices agent update --account-name myAccount --project-name myProject --name myAgent --agent-version 1 --min-replicas 1 --max-replicas 2 -""" \ No newline at end of file +""" From 4ba7af2f065e32b712b738b39314896d6708d52a Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Thu, 6 Nov 2025 16:59:47 -0800 Subject: [PATCH 6/7] Fix route + verb for container agent container delete command --- .../azure/cli/command_modules/cognitiveservices/custom.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index 1cb3bf88036..5fff7ad5591 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -525,7 +525,9 @@ def agent_delete_deployment( Delete hosted agent deployment. Deletes the agent deployment only, agent version associated with the deployment remains. """ - request = _create_agent_request("DELETE", agent_name, agent_version, container=True) + request = _create_agent_request( + "POST", agent_name, agent_version, action="delete", container=True + ) response = client.send_request(request) response.raise_for_status() return response.json() @@ -545,9 +547,7 @@ def agent_delete( return response.json() -def agent_list( - client, account_name, project_name -): # pylint: disable=unused-argument +def agent_list(client, account_name, project_name): # pylint: disable=unused-argument """ List agents. """ From 68df3c1bcd1a2d8816c787a383f9a95d7a64bdca Mon Sep 17 00:00:00 2001 From: Johan Stenberg Date: Thu, 6 Nov 2025 17:14:48 -0800 Subject: [PATCH 7/7] Fix broken merge commit --- .../cognitiveservices/_client_factory.py | 2 ++ .../cognitiveservices/_help.py | 2 ++ .../cognitiveservices/custom.py | 25 +------------------ 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py index 67d46f2b019..0cafbb7aaa5 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_client_factory.py @@ -83,6 +83,8 @@ def cf_ai_projects(cli_ctx, command_args): # Create and return the AI Projects client return AIProjectClient(endpoint=endpoint, credential=credential, **client_kwargs) + + def cf_projects(cli_ctx, *_): return get_cognitiveservices_management_client(cli_ctx).projects diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py index c38f910c7d5..c19737ff184 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py @@ -511,6 +511,8 @@ examples: - name: Start hosted agent deployment. text: az cognitiveservices agent update --account-name myAccount --project-name myProject --name myAgent --agent-version 1 --min-replicas 1 --max-replicas 2 +""" + helps['cognitiveservices account connection'] = """ type: group short-summary: Manage Azure Cognitive Services connection and its more specific derivatives. diff --git a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py index e9a22ab8f2b..0feb3a76be1 100644 --- a/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py @@ -10,29 +10,7 @@ from knack.log import get_logger import azure.core.rest -from azure.mgmt.cognitiveservices.models import ( - Account as CognitiveServicesAccount, - Sku, - VirtualNetworkRule, - IpRule, - NetworkRuleSet, - NetworkRuleAction, - AccountProperties as CognitiveServicesAccountProperties, - ApiProperties as CognitiveServicesAccountApiProperties, - Identity, - ResourceIdentityType as IdentityType, - Deployment, - DeploymentModel, - DeploymentScaleSettings, - DeploymentProperties, - CommitmentPlan, - CommitmentPlanProperties, - CommitmentPeriod, -) -from azure.cli.command_modules.cognitiveservices._client_factory import ( - cf_accounts, - cf_resource_skus, -) + from azure.mgmt.cognitiveservices.models import Account as CognitiveServicesAccount, Sku, \ VirtualNetworkRule, IpRule, NetworkRuleSet, NetworkRuleAction, \ AccountProperties as CognitiveServicesAccountProperties, ApiProperties as CognitiveServicesAccountApiProperties, \ @@ -595,7 +573,6 @@ def agent_show( response = client.send_request(request) response.raise_for_status() return response.json() - return client.create_or_update(resource_group_name, account_name, commitment_plan_name, plan) def project_create(