Open Agent Spec CLI for bootstrapping AI agent projects
Project description
_______ _______ _______ ______ _______ _______ _______ ______ _______ _______ _______ _______ _______
| _ | _ | _ | _ \ | _ | _ | _ | _ \| | | _ | _ | _ | _ |
|. | |. 1 |. 1___|. | | |. 1 |. |___|. 1___|. | |.| | | | 1___|. 1 |. 1___|. 1___|
|. | |. ____|. __)_|. | | |. _ |. | |. __)_|. | `-|. |-' |____ |. ____|. __)_|. |___
|: 1 |: | |: 1 |: | | |: | |: 1 |: 1 |: | | |: | |: 1 |: | |: 1 |: 1 |
|::.. . |::.| |::.. . |::.| | |::.|:. |::.. . |::.. . |::.| | |::.| |::.. . |::.| |::.. . |::.. . |
`-------`---' `-------`--- ---' `--- ---`-------`-------`--- ---' `---' `-------`---' `-------`-------'
Open Agent Spec (OAS) CLI
A command-line tool for generating AI agent projects based on Open Agent Spec YAML files. The OAS CLI supports multiple LLM engines including OpenAI, Anthropic, local models, and custom LLM routers.
Installation
pip install open-agent-spec
Usage
Basic Usage
# Show help
oas --help
# Initialize a new agent project
oas init --spec path/to/spec.yaml --output path/to/output
# Preview what would be created without writing files
oas init --spec path/to/spec.yaml --output path/to/output --dry-run
# Create a base working agent with minimal spec
oas init --template minimal --output path/to/output
Enable Verbose Logging
oas init --spec path/to/spec.yaml --output path/to/output --verbose
Spec File Format
The spec file should be in YAML format with the following structure. Each section is explained in detail below:
spec_version: "1.0.7" # OAS specification version
agent:
name: "hello-world-agent" # Unique identifier for the agent
description: "A simple agent that responds with a greeting" # Human-readable description
role: "assistant" # Agent role type (assistant, analyst, etc.)
intelligence:
engine: "openai" # LLM engine: openai, anthropic, local, or custom
endpoint: "https://api.openai.com/v1" # API endpoint URL
model: "gpt-4" # Model name/identifier
config: # Engine-specific configuration
temperature: 0.7
max_tokens: 150
module: "CustomRouter.CustomRouter" # For custom engines: module.class format
tasks:
greet: # Task name (will become function name)
description: "Say hello to a person by name" # Task description
timeout: 30 # Task timeout in seconds
input: # Input schema (JSON Schema format)
type: "object"
properties:
name:
type: "string"
description: "The name of the person to greet"
minLength: 1
maxLength: 100
required: ["name"]
output: # Output schema (JSON Schema format)
type: "object"
properties:
response:
type: "string"
description: "The greeting response"
minLength: 1
required: ["response"]
metadata: # Optional task metadata
category: "communication"
priority: "normal"
behavioural_contract: # Optional behavioural contract
version: "0.1.2"
description: "Simple contract requiring a greeting response"
behavioural_flags:
conservatism: "moderate"
verbosity: "compact"
response_contract:
output_format:
required_fields: ["response"]
Intelligence Engine Options
The OAS CLI supports multiple LLM engines through the intelligence.engine field:
1. OpenAI (engine: "openai")
Use OpenAI's API for LLM interactions.
intelligence:
engine: "openai"
endpoint: "https://api.openai.com/v1" # OpenAI API endpoint
model: "gpt-4" # OpenAI model (gpt-4, gpt-3.5-turbo, etc.)
config:
temperature: 0.7 # Response randomness (0.0-2.0)
max_tokens: 150 # Maximum response length
Requirements:
- OpenAI API key in environment variable
OPENAI_API_KEY - Valid OpenAI account and API access
2. Anthropic (engine: "anthropic")
Use Anthropic's Claude models for LLM interactions.
intelligence:
engine: "anthropic"
endpoint: "https://api.anthropic.com" # Anthropic API endpoint
model: "claude-3-sonnet-20240229" # Claude model name
config:
temperature: 0.7
max_tokens: 150
Requirements:
- Anthropic API key in environment variable
ANTHROPIC_API_KEY - Valid Anthropic account and API access
3. Local (engine: "local")
Use locally hosted LLM models (placeholder for future implementation).
intelligence:
engine: "local"
endpoint: "http://localhost:8000" # Local model server endpoint
model: "llama-2-7b" # Local model identifier
config:
temperature: 0.7
max_tokens: 150
Note: Local engine support is planned for future releases.
4. Custom (engine: "custom")
Use custom LLM routers for specialized use cases, custom APIs, or proprietary models.
intelligence:
engine: "custom"
endpoint: "http://localhost:1234/invoke" # Custom endpoint
model: "my-custom-model" # Model identifier
config: {} # Custom configuration
module: "CustomLLMRouter.CustomLLMRouter" # Python module.class to import
Custom Router Requirements:
- Python class with
__init__(endpoint, model, config)method run(prompt, **kwargs)method that returns a JSON string- Class must be importable from the specified module path
Example Custom Router:
# CustomLLMRouter.py
import json
class CustomLLMRouter:
def __init__(self, endpoint: str, model: str, config: dict):
self.endpoint = endpoint
self.model = model
self.config = config
def run(self, prompt: str, **kwargs) -> str:
# Your custom LLM logic here
# Must return a JSON string matching the task's output schema
return json.dumps({
"response": f"Custom response to: {prompt}"
})
YAML Field Explanations
spec_version
- Purpose: Version of the OAS specification being used
- Format: String (e.g., "1.0.4")
- Required: Yes
- Note: Ensures compatibility with the CLI version
agent Section
- Purpose: Defines the agent's identity and characteristics
agent.name
- Purpose: Unique identifier for the agent
- Format: String (kebab-case recommended)
- Required: Yes
- Example: "hello-world-agent", "financial-analyst"
agent.description
- Purpose: Human-readable description of what the agent does
- Format: String
- Required: Yes
- Example: "A friendly agent that greets people by name"
agent.role
- Purpose: Defines the agent's role type
- Format: String (enum)
- Required: No (optional)
- Options: "assistant", "analyst", "specialist", "coordinator", "researcher", "consultant"
intelligence Section
- Purpose: Configures the LLM engine and model settings
intelligence.engine
- Purpose: Specifies which LLM engine to use
- Format: String (enum)
- Required: Yes
- Options: "openai", "anthropic", "local", "custom"
intelligence.endpoint
- Purpose: API endpoint URL for the LLM service
- Format: Valid URI string
- Required: Yes
- Examples:
- OpenAI: "https://api.openai.com/v1"
- Anthropic: "https://api.anthropic.com"
- Custom: "http://localhost:1234/invoke"
intelligence.model
- Purpose: Model name or identifier to use
- Format: String
- Required: Yes
- Examples: "gpt-4", "claude-3-sonnet-20240229", "my-custom-model"
intelligence.config
- Purpose: Engine-specific configuration parameters
- Format: Object (key-value pairs)
- Required: No (optional)
- Common fields:
temperature: Response randomness (0.0-2.0)max_tokens: Maximum response lengthtop_p: Nucleus sampling parameterfrequency_penalty: Frequency penalty for repetition
intelligence.module
- Purpose: For custom engines, specifies the Python module and class to import
- Format: String ("module.class")
- Required: Only for
engine: "custom" - Example: "CustomLLMRouter.CustomLLMRouter"
tasks Section
- Purpose: Defines the agent's capabilities and functions
Each task becomes a function in the generated agent code. Task names should be descriptive and use kebab-case.
Task Structure
description: Human-readable description of what the task doestimeout: Maximum time (seconds) the task can runinput: JSON Schema defining the task's input parametersoutput: JSON Schema defining the task's expected outputmetadata: Optional metadata for categorization and organization
Input/Output Schemas
- Purpose: Define the structure and validation rules for task inputs and outputs
- Format: JSON Schema (JSON Schema Draft 2020-12)
- Features:
- Type validation (string, number, boolean, object, array)
- Required field specification
- Field descriptions
- Min/max length for strings
- Min/max values for numbers
- Enum values
- Nested object structures
behavioural_contract Section (Optional)
- Purpose: Defines behavioural constraints and response requirements
- Format: Object with behavioural contract specification
- Required: No (optional)
- Note: This is separate from the behavioural contracts repository and focuses on specification rather than enforcement
Generated Project Structure
output/
├── agent.py # Main agent implementation with all tasks
├── prompts/ # Jinja2 prompt templates
│ ├── greet.jinja2 # Task-specific prompt template
│ └── agent_prompt.jinja2 # Fallback prompt template
├── requirements.txt # Python dependencies
├── .env.example # Environment variables template
├── README.md # Generated documentation
└── CustomLLMRouter.py # Custom router (if using custom engine)
Development
Setup
# Clone the repository
git clone https://github.com/aswhitehouse/open-agent-spec.git
cd open-agent-spec
# Install development dependencies
pip install -e ".[dev]"
Running Tests
# Run all tests with basic reporting
pytest
# Run with comprehensive reporting
pytest tests/ -v --cov=oas_cli --cov-report=html --cov-report=term
# Run specific test categories
pytest -m contract tests/ # Behavioral contract validation
pytest -m multi_engine tests/ # Multi-engine compatibility
pytest -m generator tests/ # Generator functionality tests
# Generate detailed HTML report
pytest tests/ --html=test-report.html --self-contained-html
# Generate Allure report (requires allure-pytest)
pytest tests/ --alluredir=allure-results
allure serve allure-results
Test Reporting Features
- Coverage Reports: HTML and terminal coverage reports
- Test Categories: Organized by markers (contract, multi_engine, generator)
- Allure Reports: Beautiful interactive test reports
- CI Integration: Automatic reporting in GitHub Actions
- Artifact Upload: Test results and coverage reports saved
Test Categories
- Generator Tests: Validate code generation, file creation, and template rendering
- Contract Tests: Ensure behavioral contracts work correctly across engines
- Multi-Engine Tests: Verify OpenAI and Claude/Anthropic compatibility
- Integration Tests: End-to-end validation of agent generation
Building
python -m build
Creating a Release
To create a new release:
- Update the version number in
pyproject.toml - Commit and push your changes
- Create and push a new tag
# Update version in pyproject.toml, then:
git add pyproject.toml
git commit -m "Bump version to v1.0.8"
git push origin main
# Create and push the tag
git tag v1.0.8
git push origin v1.0.8
The GitHub Actions workflow will automatically:
- Run all tests
- Build the package
- Publish to PyPI
Your package will be available on PyPI within a few minutes.
Package Installation
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPLv3), which ensures that improvements and deployments of this codebase stay open and benefit the wider community.
If you're a business or enterprise and would like to:
- Use this tool in a proprietary or internal-only setting
- Avoid open-sourcing your modifications or integrations
- Receive custom implementation support or consulting
- Discuss a commercial license or enterprise partnership
➡️ Please feel free to reach out: 📧 andrewswhitehouse@gmail.com
Myself and my collaborators would be happy to support your journey with AI agents and ensure responsible, scalable use of this tooling in your stack.
Overview
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file open_agent_spec-1.0.8.tar.gz.
File metadata
- Download URL: open_agent_spec-1.0.8.tar.gz
- Upload date:
- Size: 53.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b26981b57097ce3ad16ad9995d702a399e21d1f71e49738a2a97828d5798075
|
|
| MD5 |
e5b425c9a19b4bcb0276d6789fd6f4ab
|
|
| BLAKE2b-256 |
9ebdfdc4676c1b257cf3efb78127fada760f12c3e02096b32489ee11e7262015
|
File details
Details for the file open_agent_spec-1.0.8-py3-none-any.whl.
File metadata
- Download URL: open_agent_spec-1.0.8-py3-none-any.whl
- Upload date:
- Size: 35.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa7b529aa9700ad8c34b982170668007e35c32b01e7a7bf6fb90cf16a254525c
|
|
| MD5 |
e172b2569de517fcfe19f31bc5e21880
|
|
| BLAKE2b-256 |
db1af3cc8dca0d56d37e532212c09fb0d46b8de1322e42b40c35ebd4fb76f6db
|