Utilities for exporting (downloading) and importing (creating/updating) Azure AI Foundry Agents along with dependency awareness, normalization, and consistent logging.
export AZURE_TENANT_ID='your-tenant-id-here'
export PROJECT_ENDPOINT='your-ai-foundry-endpoint-here'Example:
export AZURE_TENANT_ID='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
export PROJECT_ENDPOINT='https://your-resource.services.ai.azure.com/api/projects/your-project'Note: You can also provide these values via CLI parameters (
--azure-tenant-idand--project-endpoint) which will take precedence over environment variables.
For development (editable install):
pip install -e .Or for production:
pip install .This will install all required dependencies automatically.
The CLI is available as a console script after installation.
aif-workflow-helper --download-all-agents --agents-dir agentsCommon examples:
# Download all agents with optional prefix/suffix filtering
aif-workflow-helper --download-all-agents --prefix dev- --suffix -v1
# Download a single agent
aif-workflow-helper --download-agent my_agent
# Upload all agents from JSON definitions in a directory
aif-workflow-helper --upload-all-agents --agents-dir agents
# Upload a single agent definition file
aif-workflow-helper --upload-agent my_agent --agents-dir agents
# Get the agent ID for a specific agent by name
aif-workflow-helper --get-agent-id my_agent
# Delete a single agent (with confirmation prompt)
aif-workflow-helper --delete-agent my_agent
# Delete a single agent without confirmation
aif-workflow-helper --delete-agent my_agent --force
# Delete all agents with prefix/suffix filtering (with confirmation)
aif-workflow-helper --delete-all-agents --prefix dev- --suffix -v1
# Delete all agents without confirmation (DANGEROUS!)
aif-workflow-helper --delete-all-agents --force
# Download agents in different formats
aif-workflow-helper --download-all-agents --format json # Default
aif-workflow-helper --download-all-agents --format yaml # YAML format
aif-workflow-helper --download-all-agents --format md # Markdown with frontmatter
# Upload agents from different formats
aif-workflow-helper --upload-all-agents --format yaml
aif-workflow-helper --upload-agent my_agent --format md
# Change log level
aif-workflow-helper --download-all-agents --log-level DEBUG
# Override environment variables with CLI parameters
aif-workflow-helper --download-all-agents \
--azure-tenant-id "your-tenant-id" \
--project-endpoint "https://your-endpoint.services.ai.azure.com/api/projects/your-project"
# Mix CLI parameters with environment variables (CLI takes precedence)
export AZURE_TENANT_ID="env-tenant-id"
aif-workflow-helper --download-all-agents --azure-tenant-id "cli-tenant-id" # Uses CLI value
# Get agent ID and use in scripts
AGENT_ID=$(aif-workflow-helper --get-agent-id my_agent)
echo "Agent ID: $AGENT_ID"You can import and compose the underlying functions directly:
from aif_workflow_helper import (
configure_logging,
download_agents,
download_agent,
create_or_update_agents,
create_or_update_agent,
create_or_update_agent_from_file,
create_or_update_agents_from_files,
)
from azure.ai.agents import AgentsClient
from azure.identity import DefaultAzureCredential
configure_logging()
client = AgentsClient(
credential=DefaultAzureCredential(
exclude_interactive_browser_credential=False,
interactive_tenant_id="your-tenant-id"
),
endpoint="your-endpoint"
)
# Bulk download
download_agents(client, file_path="./agents", prefix="", suffix="", format="json")
# Create/update from a directory (dependency ordered)
create_or_update_agents_from_files(path="./agents", agent_client=client, prefix="", suffix="", format="json")- Downloads existing agents to normalized files (JSON, YAML, or Markdown with frontmatter)
- Normalizes (generalizes) definitions for portability (removes resource-specific fields)
- Infers and resolves inter-agent dependencies (connected agent tools)
- Creates or updates agents in dependency-safe order
- Applies optional prefix/suffix for environment namespacing
- Supports multiple file formats for flexible workflow integration
download_agents(agent_client, file_path, prefix, suffix, format)β Download and generalize all agents (optional prefix/suffix filters, format selection)download_agent(agent_name, agent_client, file_path, prefix, suffix, format)β Download and generalize a single agentgeneralize_agent_dict(data, agent_client, prefix, suffix)β Normalize agent JSON for portability
create_or_update_agent(agent_data, agent_client, existing_agents, prefix, suffix)β Upsert a single agent objectcreate_or_update_agents(agents_data, agent_client, prefix, suffix)β Upsert multiple agents with dependency orderingcreate_or_update_agent_from_file(agent_name, path, agent_client, prefix, suffix, format)β Upsert from a specific filecreate_or_update_agents_from_files(path, agent_client, prefix, suffix, format)β Bulk load and upsert directory
read_agent_file(path)/read_agent_files(path, format)β Load definitions in any supported format (used internally by from_files wrappers)extract_dependencies(agents_data)β Build dependency graphdependency_sort(agents_data)β Topological sort of agentsget_agent_by_name(name, client)β Lookup agent objectget_agent_name(agent_id, client)β Reverse lookup by ID
aif-workflow-helper arguments:
--agents-dir DIR Directory for agent definition files (default: agents)
--download-all-agents Download all existing agents
--download-agent NAME Download a single agent by name
--upload-all-agents Create/update all agents from definition files
--upload-agent NAME Create/update a single agent from definition file
--get-agent-id NAME Get the agent ID for a given agent name
--delete-agent NAME Delete a single agent by name
--delete-all-agents Delete all agents (filtered by prefix/suffix if provided)
--force Skip confirmation prompts when deleting agents
--prefix TEXT Optional prefix applied during download/upload/delete
--suffix TEXT Optional suffix applied during download/upload/delete
--format FORMAT File format: json, yaml, or md (default: json)
--log-level LEVEL Logging level (CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET)
--azure-tenant-id TENANT_ID Azure tenant ID (overrides AZURE_TENANT_ID environment variable)
--project-endpoint ENDPOINT AI Foundry project endpoint URL (overrides PROJECT_ENDPOINT environment variable)
- CLI Parameters (highest priority):
--azure-tenant-idand--project-endpoint - Environment Variables (fallback):
AZURE_TENANT_IDandPROJECT_ENDPOINT
The --get-agent-id option allows you to retrieve the unique ID of an agent by its name. This is useful for scripting and automation scenarios where you need to reference an agent by its ID rather than its name.
Usage:
# Get agent ID
aif-workflow-helper --get-agent-id my-agent
# Use in a script
AGENT_ID=$(aif-workflow-helper --get-agent-id my-agent)
echo "Agent ID: $AGENT_ID"
# With explicit authentication
aif-workflow-helper --get-agent-id my-agent \
--azure-tenant-id "your-tenant-id" \
--project-endpoint "your-endpoint"Output:
- On success: Prints the agent ID to stdout (suitable for capturing in scripts)
- On failure: Logs an error message and exits with code 1
Example Output:
========== Looking up agent: my-agent ==========
asst_abc123xyz456
========== Agent 'my-agent' has ID: asst_abc123xyz456 ==========
Delete an agent by name with an interactive confirmation prompt:
# Delete with confirmation prompt
aif-workflow-helper --delete-agent my-agent
# Skip confirmation prompt with --force flag
aif-workflow-helper --delete-agent my-agent --force
# Delete agent with prefix/suffix
aif-workflow-helper --delete-agent my-agent --prefix dev- --suffix -v1Interactive Confirmation Example:
The following agents will be deleted:
- my-agent
Total: 1 agent(s)
Are you sure you want to delete these agents? (yes/no): yes
========== Successfully deleted agent 'my-agent' (ID: asst_abc123xyz) ==========
Delete all agents matching a prefix/suffix pattern:
# Delete all agents starting with "dev-" (with confirmation)
aif-workflow-helper --delete-all-agents --prefix dev-
# Delete all agents ending with "-v1" (with confirmation)
aif-workflow-helper --delete-all-agents --suffix -v1
# Delete all agents with both prefix and suffix (with confirmation)
aif-workflow-helper --delete-all-agents --prefix staging- --suffix -test
# Delete all agents without confirmation (DANGEROUS!)
aif-workflow-helper --delete-all-agents --force
# Delete all matching agents without confirmation
aif-workflow-helper --delete-all-agents --prefix dev- --suffix -v1 --forceInteractive Confirmation Example:
The following agents will be deleted:
- dev-agent-1-v1
- dev-agent-2-v1
- dev-worker-v1
Total: 3 agent(s)
Are you sure you want to delete these agents? (yes/no): yes
========== Deleted agent 'dev-agent-1-v1' (ID: asst_abc123) ==========
========== Deleted agent 'dev-agent-2-v1' (ID: asst_def456) ==========
========== Deleted agent 'dev-worker-v1' (ID: asst_ghi789) ==========
========== Successfully deleted 3 of 3 agent(s) ==========
Safety Features:
- Confirmation Prompt: By default, you'll be asked to confirm before any deletion
- --force Flag: Skip confirmation for automated scripts (use with caution!)
- Prefix/Suffix Filtering: Target specific agents by name pattern
- Detailed Logging: See exactly which agents will be deleted before confirming
The tool supports three file formats for agent definitions:
Standard JSON format with all agent properties in a single object:
{
"name": "my-agent",
"model": "gpt-4",
"instructions": "You are a helpful AI assistant...",
"tools": [],
"temperature": 0.7,
"top_p": 1.0
}Clean YAML format for better readability:
name: my-agent
model: gpt-4
instructions: |
You are a helpful AI assistant.
Please provide clear and concise responses.
tools: []
temperature: 0.7
top_p: 1.0Markdown format where the instructions field becomes the content and all other properties go into YAML frontmatter:
---
name: my-agent
model: gpt-4
tools: []
temperature: 0.7
top_p: 1.0
---
You are a helpful AI assistant.
Please provide clear and concise responses to user questions.Markdown Format Behavior:
- Trailing Newlines: The markdown format preserves trailing newlines in the instructions content to maintain exact formatting across upload/download cycles. All markdown files end with a newline character following Unix text file conventions.
- Frontmatter Library: The tool uses the
python-frontmatterlibrary, which strips trailing newlines from content when reading. The tool automatically detects and restores these newlines to ensure perfect roundtrip consistency. - Multi-line Fields: YAML frontmatter fields (like
description) can use multi-line string syntax for better readability.
File Extensions:
- JSON:
.json - YAML:
.yamlor.yml - Markdown:
.md
βββ pyproject.toml # Package configuration and dependencies
βββ requirements.txt # Core runtime dependencies
βββ README.md # Project documentation
βββ agents/ # Agent definition files
βββ tests/ # Test files
βββ src/aif_workflow_helper/ # Main package source code
βββ __init__.py # Public exports
βββ cli/
β βββ main.py # CLI entrypoint
βββ core/
β βββ upload.py # Upload + dependency logic
β βββ download.py # Download + generalization logic
β βββ formats.py # Format handling utilities
βββ utils/
βββ logging.py # Shared logging configuration
βββ validation.py # Agent name validation
- Authentication: Uses
DefaultAzureCredential(interactive fallback enabled) - Dependency Ordering: Creates/updates in safe order via topological sort
- Name Safety: Validation ensures only alphanumerics + hyphens (prefix/suffix applied consistently)
- Logging: Centralized configurable logger (
configure_logging) - Efficiency: Minimizes duplicate lookups by caching existing agents during batch operations
- Format Flexibility: Supports JSON, YAML, and Markdown with frontmatter for different workflow preferences
- Roundtrip Consistency: All formats support perfect roundtrip consistency - downloading and re-uploading an agent produces identical results. This includes:
- Preserving trailing newlines in markdown format
- Maintaining exact data types (numbers, booleans, nulls) in JSON/YAML
- Preserving complex nested structures and metadata
- Handling unicode characters and emojis correctly
# Install in development mode for local changes
pip install -e .
# Or install for production use
pip install .# Check environment variables
echo $AZURE_TENANT_ID
echo $PROJECT_ENDPOINT
# Or use CLI parameters (recommended for CI/CD or when environment variables conflict)
aif-workflow-helper --download-all-agents \
--azure-tenant-id "your-tenant-id" \
--project-endpoint "your-endpoint"
# Try interactive login
az login --tenant $AZURE_TENANT_IDIf aif-workflow-helper is not found after installation:
# Make sure you installed the package
pip install -e .
# Check if it's in your PATH
which aif-workflow-helper
# Or run directly with Python
python -m aif_workflow_helper.cli.main --helpTypical successful run output (truncated example):
π Testing connection...
β
Connected! Found X existing agents
π₯ Downloading agents...
Saved agent 'agent-name' to agent-name.json
π Reading agent files...
Found X agents
π Creating/updating agents...
Processing 1/X: agent-name
β
Successfully processed agent-name
This project includes a comprehensive CI/CD pipeline using GitHub Actions that ensures code quality and functionality.
- Multi-Python Version Testing: Tests on Python 3.10, 3.11, and 3.12
- Automated Testing: Runs all pytest tests with coverage reporting
- Code Quality: Includes linting with flake8
- Package Testing: Verifies the package can be built and installed correctly
- CLI Testing: Ensures the command-line interface works after installation
The main branch is protected with the following requirements:
- β Pull Request Required: Direct pushes to main are not allowed
- β Tests Must Pass: All CI checks must pass before merging
- β Code Review: At least 1 approval required
- β Up-to-date Branch: Branches must be current with main
Before submitting a PR, run tests locally to ensure they pass:
# Activate virtual environment
source .venv/bin/activate
# Install with dev dependencies
pip install -e .[dev]
# Run tests
pytest tests/ -v --tb=short
# Run with coverage
pytest tests/ -v --cov=src --cov-report=term-missing
# Check CLI functionality
aif-workflow-helper --help- Create a feature branch from
main - Make your changes
- Ensure all tests pass locally
- Submit a pull request
- Wait for CI to pass and get code review approval
- Merge when approved