Skip to content

Commit 339d929

Browse files
authored
[Cognitiveservices] Add agent create to az cognitiveservices command for hosted agents: az cognitiveservices agent create (#32430)
1 parent fb44b6e commit 339d929

File tree

5 files changed

+2362
-6
lines changed

5 files changed

+2362
-6
lines changed

src/azure-cli/azure/cli/command_modules/cognitiveservices/_help.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,160 @@
483483
short-summary: Control foundry agents.
484484
"""
485485

486+
helps[
487+
"cognitiveservices agent create"
488+
] = """
489+
type: command
490+
short-summary: Create a new hosted agent from a container image or source code.
491+
long-summary: |
492+
Create a new hosted agent deployment by either specifying a pre-built container image
493+
or by building one from source code. When using --source, the container image is
494+
automatically built and pushed to Azure Container Registry. Configure compute resources,
495+
scaling behavior, environment variables, and communication protocols.
496+
parameters:
497+
- name: --account-name -a
498+
short-summary: Name of the Cognitive Services account.
499+
- name: --project-name -p
500+
short-summary: Name of the AI Foundry project.
501+
- name: --name -n
502+
short-summary: Name of the agent to create.
503+
- name: --image
504+
short-summary: Docker image URI with tag to use for the agent.
505+
long-summary: |
506+
Full Docker image URI including tag (e.g., myregistry.azurecr.io/myagent:v1.0).
507+
The tag identifies which container image version to use. The AI Foundry service
508+
automatically creates and manages the agent version independently.
509+
Mutually exclusive with --source.
510+
- name: --source
511+
short-summary: Path to source directory containing Dockerfile.
512+
long-summary: |
513+
When provided, builds the Docker image from source code and pushes to ACR.
514+
The image is built either locally (if Docker is available) or remotely using ACR Task.
515+
Mutually exclusive with --image.
516+
- name: --dockerfile
517+
short-summary: Name of the Dockerfile in source directory (default is 'Dockerfile').
518+
long-summary: Only used when --source is specified.
519+
- name: --build-remote
520+
short-summary: Force remote build using Azure Container Registry Task.
521+
long-summary: |
522+
By default, the CLI attempts to build locally if Docker is available,
523+
otherwise builds remotely. Use this flag to force remote build.
524+
Only used when --source is specified.
525+
- name: --registry
526+
short-summary: Azure Container Registry name or full URI.
527+
long-summary: |
528+
Short name (e.g., 'myregistry') will be expanded to myregistry.azurecr.io.
529+
Full URIs (myregistry.azurecr.io) are also accepted.
530+
Required when using --source.
531+
- name: --cpu
532+
short-summary: CPU allocation (default is 1 core).
533+
- name: --memory
534+
short-summary: Memory allocation with unit (default is 2Gi).
535+
long-summary: Use units like '2Gi' for 2 gibibytes or '512Mi' for 512 mebibytes.
536+
- name: --min-replicas
537+
short-summary: Minimum number of replicas for scaling (default is 0).
538+
- name: --max-replicas
539+
short-summary: Maximum number of replicas for scaling (default is 3).
540+
- name: --env --environment-variables
541+
short-summary: Environment variables in key=value format.
542+
long-summary: Space-separated list in format 'key1=value1 key2=value2'.
543+
- name: --protocol
544+
short-summary: Communication protocol (responses or streaming).
545+
- name: --protocol-version
546+
short-summary: Protocol version (default is v1).
547+
- name: --timeout
548+
short-summary: Maximum time in seconds to wait for deployment to be ready.
549+
long-summary: |
550+
Default is 600 seconds (10 minutes). Increase for large container images
551+
or slow network conditions. The deployment process includes pulling the
552+
container image, starting the container, and health checks.
553+
examples:
554+
- name: Create agent from existing container image
555+
text: |
556+
az cognitiveservices agent create \\
557+
--account-name myAccount \\
558+
--project-name myProject \\
559+
--name my-agent \\
560+
--image myregistry.azurecr.io/my-agent:v1.0
561+
- name: Create agent by building from source (auto-detect build method)
562+
text: |
563+
az cognitiveservices agent create \\
564+
--account-name myAccount \\
565+
--project-name myProject \\
566+
--name my-agent \\
567+
--source ./my-agent-code \\
568+
--registry myregistry
569+
- name: Create agent by building from source with custom Dockerfile name
570+
text: |
571+
az cognitiveservices agent create \\
572+
--account-name myAccount \\
573+
--project-name myProject \\
574+
--name my-agent \\
575+
--source ./my-agent-code \\
576+
--dockerfile Dockerfile.prod \\
577+
--registry myregistry
578+
- name: Create agent by building remotely with ACR Task
579+
text: |
580+
az cognitiveservices agent create \\
581+
--account-name myAccount \\
582+
--project-name myProject \\
583+
--name my-agent \\
584+
--source ./my-agent-code \\
585+
--registry myregistry \\
586+
--build-remote
587+
- name: Create agent with custom CPU and memory
588+
text: |
589+
az cognitiveservices agent create \\
590+
--account-name myAccount \\
591+
--project-name myProject \\
592+
--name my-agent \\
593+
--image myregistry.azurecr.io/my-agent:v2.0 \\
594+
--cpu 2 \\
595+
--memory 4Gi
596+
- name: Create agent with scaling configuration
597+
text: |
598+
az cognitiveservices agent create \\
599+
--account-name myAccount \\
600+
--project-name myProject \\
601+
--name my-agent \\
602+
--image myregistry.azurecr.io/my-agent:v1.0 \\
603+
--min-replicas 2 \\
604+
--max-replicas 10
605+
- name: Create agent with environment variables
606+
text: |
607+
az cognitiveservices agent create \\
608+
--account-name myAccount \\
609+
--project-name myProject \\
610+
--name my-agent \\
611+
--image myregistry.azurecr.io/my-agent:v1.0 \\
612+
--env MODEL_NAME=gpt-4 API_TIMEOUT=30 LOG_LEVEL=info
613+
- name: Create agent with streaming protocol
614+
text: |
615+
az cognitiveservices agent create \\
616+
--account-name myAccount \\
617+
--project-name myProject \\
618+
--name my-agent \\
619+
--image myregistry.azurecr.io/my-agent:v1.0 \\
620+
--protocol streaming \\
621+
--protocol-version v1
622+
- name: Create agent using short registry name
623+
text: |
624+
az cognitiveservices agent create \\
625+
--account-name myAccount \\
626+
--project-name myProject \\
627+
--name my-agent \\
628+
--image my-agent:v1.0 \\
629+
--registry myregistry
630+
- name: Create agent with extended timeout for large images
631+
text: |
632+
az cognitiveservices agent create \\
633+
--account-name myAccount \\
634+
--project-name myProject \\
635+
--name my-agent \\
636+
--image myregistry.azurecr.io/my-large-agent:v1.0 \\
637+
--timeout 1200
638+
"""
639+
486640
helps[
487641
"cognitiveservices agent start"
488642
] = """

src/azure-cli/azure/cli/command_modules/cognitiveservices/_params.py

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,41 @@
3232
name_arg_type = CLIArgumentType(options_list=["--name", "-n"], metavar="NAME")
3333

3434

35+
def _environment_variables_type(value: str) -> dict:
36+
"""
37+
Parse environment variable in key=value format.
38+
39+
Args:
40+
value: String in format 'KEY=value'
41+
42+
Returns:
43+
dict: Dictionary with 'key' and 'value' keys
44+
45+
Raises:
46+
ValueError: If format is invalid
47+
48+
Examples:
49+
>>> _environment_variables_type('FOO=bar')
50+
{'key': 'FOO', 'value': 'bar'}
51+
>>> _environment_variables_type('CONNECTION_STRING=Server=localhost;Database=mydb')
52+
{'key': 'CONNECTION_STRING', 'value': 'Server=localhost;Database=mydb'}
53+
"""
54+
if '=' not in value:
55+
raise ValueError(
56+
f"Environment variable must be in 'key=value' format. Got: '{value}'"
57+
)
58+
59+
# Split on first equals sign only (value might contain '=')
60+
key, _, val = value.partition('=')
61+
62+
if not key:
63+
raise ValueError(
64+
f"Environment variable key cannot be empty. Got: '{value}'"
65+
)
66+
67+
return {'key': key, 'value': val}
68+
69+
3570
def extract_key_values_pairs(api_properties):
3671
api_properties_dict = {}
3772
for item in api_properties:
@@ -340,14 +375,143 @@ def load_arguments(self, _):
340375
options_list=["--account-name", "-a"],
341376
help="cognitive service account name."
342377
)
343-
c.argument("project_name", help="AI Project name")
378+
c.argument(
379+
"project_name",
380+
options_list=["--project-name", "-p"],
381+
help="AI project name"
382+
)
344383
c.argument(
345384
"agent_name",
346385
options_list=["--name", "-n"],
347386
help="Cognitive Services hosted agent name",
348387
)
349388
c.argument("agent_version", help="Cognitive Services hosted agent version")
350389

390+
with self.argument_context('cognitiveservices agent create') as c:
391+
c.argument(
392+
'agent_name',
393+
options_list=['--name', '-n'],
394+
help='Name of the agent to create',
395+
required=True
396+
)
397+
c.argument(
398+
'image',
399+
help=(
400+
'Container image URI including tag '
401+
'(e.g., myregistry.azurecr.io/myagent:v1 or myagent:v1 if using --registry). '
402+
'The image tag becomes the agent version. Mutually exclusive with --source.'
403+
)
404+
)
405+
c.argument(
406+
'source',
407+
help=(
408+
'Path to source directory containing Dockerfile. '
409+
'When provided, the image will be built and pushed automatically. '
410+
'Mutually exclusive with --image.'
411+
)
412+
)
413+
c.argument(
414+
'dockerfile',
415+
help=(
416+
'Name of the Dockerfile in the source directory. '
417+
'Default: "Dockerfile". Only used with --source.'
418+
)
419+
)
420+
c.argument(
421+
'build_remote',
422+
options_list=['--build-remote'],
423+
action='store_true',
424+
help=(
425+
'Force remote build using Azure Container Registry Task. '
426+
'By default, builds locally if Docker is available, '
427+
'otherwise builds remotely. Only used with --source.'
428+
)
429+
)
430+
c.argument(
431+
'registry',
432+
help=(
433+
'Azure Container Registry name (e.g., myregistry). '
434+
'If provided, the full ACR URI will be constructed. '
435+
'Required when using --source.'
436+
)
437+
)
438+
c.argument(
439+
'cpu',
440+
help='CPU cores allocation (e.g., "1", "2", "0.5"). Default: "1"',
441+
default='1'
442+
)
443+
c.argument(
444+
'memory',
445+
help='Memory allocation with units (e.g., "2Gi", "4Gi", "512Mi"). Default: "2Gi"',
446+
default='2Gi'
447+
)
448+
c.argument(
449+
'environment_variables',
450+
options_list=['--environment-variables', '--env'],
451+
nargs='+',
452+
type=_environment_variables_type,
453+
help="Space-separated environment variables in 'key=value' format (e.g., FOO=bar LOG_LEVEL=debug)"
454+
)
455+
c.argument(
456+
'protocol',
457+
help='Agent communication protocol. Default: "responses"',
458+
arg_type=get_enum_type(['responses', 'streaming']),
459+
default='responses'
460+
)
461+
c.argument(
462+
'protocol_version',
463+
help='Protocol version. Default: "v1"',
464+
default='v1'
465+
)
466+
c.argument(
467+
'description',
468+
help='Human-readable description of the agent'
469+
)
470+
c.argument(
471+
'min_replicas',
472+
type=int,
473+
help='Minimum number of replicas for horizontal scaling. Default: 0'
474+
)
475+
c.argument(
476+
'max_replicas',
477+
type=int,
478+
help='Maximum number of replicas for horizontal scaling. Default: 3'
479+
)
480+
c.argument(
481+
'skip_acr_check',
482+
action='store_true',
483+
help=(
484+
'Skip validation that project managed identity has access to '
485+
'container registry. Use when access is configured via user-assigned '
486+
'identity, service principal, network-level permissions, or other methods '
487+
'the check cannot detect.'
488+
)
489+
)
490+
c.argument(
491+
'no_wait',
492+
action='store_true',
493+
help='Do not wait for the long-running operation to finish'
494+
)
495+
c.argument(
496+
'no_start',
497+
action='store_true',
498+
help=(
499+
'Skip automatic deployment after agent version creation. '
500+
'Use this to create the agent version without starting the deployment. '
501+
'Cannot be used with --min-replicas or --max-replicas.'
502+
)
503+
)
504+
c.argument(
505+
'timeout',
506+
type=int,
507+
help=(
508+
'Maximum time in seconds to wait for deployment to be ready. '
509+
'Default: 600 seconds (10 minutes). '
510+
'Increase for large container images or slow network conditions.'
511+
),
512+
default=600
513+
)
514+
351515
with self.argument_context("cognitiveservices agent update") as c:
352516
c.argument(
353517
"min_replicas",

src/azure-cli/azure/cli/command_modules/cognitiveservices/commands.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def load_command_table(self, _):
120120
g.command('list', 'list')
121121

122122
with self.command_group('cognitiveservices agent', client_factory=cf_ai_projects, is_preview=True) as g:
123+
g.custom_command('create', 'agent_create')
123124
g.custom_command('update', 'agent_update')
124125
g.custom_command('stop', 'agent_stop')
125126
g.custom_command('start', 'agent_start')

0 commit comments

Comments
 (0)