Skip to content

peteroden/aif-workflow-helper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Azure AI Foundry Workflow Helpers

Utilities for exporting (downloading) and importing (creating/updating) Azure AI Foundry Agents along with dependency awareness, normalization, and consistent logging.

πŸš€ Quick Start

1. Set Environment Variables

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-id and --project-endpoint) which will take precedence over environment variables.

2. Install the Package

For development (editable install):

pip install -e .

Or for production:

pip install .

This will install all required dependencies automatically.

3. Using the CLI (Recommended)

The CLI is available as a console script after installation.

aif-workflow-helper --download-all-agents --agents-dir agents

Common 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"

4. Direct Library Usage

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")

πŸ“ What the Tooling Does

  1. Downloads existing agents to normalized files (JSON, YAML, or Markdown with frontmatter)
  2. Normalizes (generalizes) definitions for portability (removes resource-specific fields)
  3. Infers and resolves inter-agent dependencies (connected agent tools)
  4. Creates or updates agents in dependency-safe order
  5. Applies optional prefix/suffix for environment namespacing
  6. Supports multiple file formats for flexible workflow integration

πŸ”§ Core Functions

Download Functions

  • 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 agent
  • generalize_agent_dict(data, agent_client, prefix, suffix) – Normalize agent JSON for portability

Upload Functions

  • create_or_update_agent(agent_data, agent_client, existing_agents, prefix, suffix) – Upsert a single agent object
  • create_or_update_agents(agents_data, agent_client, prefix, suffix) – Upsert multiple agents with dependency ordering
  • create_or_update_agent_from_file(agent_name, path, agent_client, prefix, suffix, format) – Upsert from a specific file
  • create_or_update_agents_from_files(path, agent_client, prefix, suffix, format) – Bulk load and upsert directory

Internal Helpers (Not all re-exported)

  • 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 graph
  • dependency_sort(agents_data) – Topological sort of agents
  • get_agent_by_name(name, client) – Lookup agent object
  • get_agent_name(agent_id, client) – Reverse lookup by ID

🎯 CLI Reference

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)

Authentication Priority

  1. CLI Parameters (highest priority): --azure-tenant-id and --project-endpoint
  2. Environment Variables (fallback): AZURE_TENANT_ID and PROJECT_ENDPOINT

οΏ½ Agent Lookup

Get Agent ID by Name

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 ==========

πŸ—‘οΈ Deleting Agents

Delete a Single Agent

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 -v1

Interactive 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 Multiple Agents

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 --force

Interactive 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

⚠️ Warning: Deletion is permanent and cannot be undone. Always double-check the agent names before confirming deletion.

οΏ½πŸ“„ Supported File Formats

The tool supports three file formats for agent definitions:

JSON Format (Default)

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
}

YAML Format

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.0

Markdown with Frontmatter

Markdown 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-frontmatter library, 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: .yaml or .yml
  • Markdown: .md

πŸ“‹ File Structure

β”œβ”€β”€ 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

⚠️ Important Notes

  1. Authentication: Uses DefaultAzureCredential (interactive fallback enabled)
  2. Dependency Ordering: Creates/updates in safe order via topological sort
  3. Name Safety: Validation ensures only alphanumerics + hyphens (prefix/suffix applied consistently)
  4. Logging: Centralized configurable logger (configure_logging)
  5. Efficiency: Minimizes duplicate lookups by caching existing agents during batch operations
  6. Format Flexibility: Supports JSON, YAML, and Markdown with frontmatter for different workflow preferences
  7. 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

πŸ” Troubleshooting

Installation Issues

# Install in development mode for local changes
pip install -e .

# Or install for production use
pip install .

Authentication Errors

# 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_ID

Command Not Found Error

If 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 --help

πŸŽ‰ Success Output

Typical 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

πŸ”„ CI/CD Pipeline

This project includes a comprehensive CI/CD pipeline using GitHub Actions that ensures code quality and functionality.

Pipeline Features

  • 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

Branch Protection

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

Running Tests Locally

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

Contributing

  1. Create a feature branch from main
  2. Make your changes
  3. Ensure all tests pass locally
  4. Submit a pull request
  5. Wait for CI to pass and get code review approval
  6. Merge when approved

About

Implement simple CI/CD for Azure AI Foundry

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors