Declarative Agent Communication Protocol - A protocol for managing LLM/agent communications and tool function calls
Project description
DACP - Declarative Agent Communication Protocol
A Python library for managing LLM/agent communications and tool function calls following the OAS Open Agent Specification.
Installation
pip install -e .
Quick Start
import dacp
# Create an orchestrator to manage agents
orchestrator = dacp.Orchestrator()
# Create and register an agent
class MyAgent:
def handle_message(self, message):
return {"response": f"Hello {message.get('name', 'World')}!"}
agent = MyAgent()
orchestrator.register_agent("my-agent", agent)
# Send a message to the agent
response = orchestrator.send_message("my-agent", {"name": "Alice"})
print(response) # {"response": "Hello Alice!"}
# Use built-in tools
result = dacp.file_writer("./output/greeting.txt", "Hello, World!")
print(result["message"]) # "Successfully wrote 13 characters to ./output/greeting.txt"
# Use intelligence providers (supports multiple LLM providers)
intelligence_config = {
"engine": "anthropic",
"model": "claude-3-haiku-20240307",
"api_key": "your-api-key" # or set ANTHROPIC_API_KEY env var
}
response = dacp.invoke_intelligence("What is the weather like today?", intelligence_config)
# Or use the legacy call_llm function for OpenAI
response = dacp.call_llm("What is the weather like today?")
Features
- Agent Orchestration: Central management of multiple agents with message routing
- Tool Registry: Register and manage custom tools for LLM agents
- Built-in Tools: Includes a
file_writertool that automatically creates parent directories - LLM Integration: Built-in support for OpenAI models (extensible)
- Protocol Parsing: Parse and validate agent responses
- Tool Execution: Safe execution of registered tools
- Conversation History: Track and query agent interactions
- OAS Compliance: Follows Open Agent Specification standards
API Reference
Orchestrator
Orchestrator(): Create a new orchestrator instanceregister_agent(agent_id: str, agent) -> None: Register an agentunregister_agent(agent_id: str) -> bool: Remove an agentsend_message(agent_id: str, message: Dict) -> Dict: Send message to specific agentbroadcast_message(message: Dict, exclude_agents: List[str] = None) -> Dict: Send message to all agentsget_conversation_history(agent_id: str = None) -> List[Dict]: Get conversation historyclear_history() -> None: Clear conversation historyget_session_info() -> Dict: Get current session information
Tools
register_tool(tool_id: str, func): Register a new toolrun_tool(tool_id: str, args: Dict) -> dict: Execute a registered toolTOOL_REGISTRY: Access the current tool registryfile_writer(path: str, content: str) -> dict: Write content to file, creating directories automatically
Intelligence (Multi-Provider LLM Support)
invoke_intelligence(prompt: str, config: dict) -> str: Call any supported LLM providervalidate_config(config: dict) -> bool: Validate intelligence configurationget_supported_engines() -> list: Get list of supported engines
LLM (Legacy)
call_llm(prompt: str, model: str = "gpt-4") -> str: Call OpenAI (legacy function)
Protocol
parse_agent_response(response: str | dict) -> dict: Parse agent responseis_tool_request(msg: dict) -> bool: Check if message is a tool requestget_tool_request(msg: dict) -> tuple[str, dict]: Extract tool request detailswrap_tool_result(name: str, result: dict) -> dict: Wrap tool result for agentis_final_response(msg: dict) -> bool: Check if message is a final responseget_final_response(msg: dict) -> dict: Extract final response
Agent Development
Creating an Agent
Agents must implement a handle_message method:
import dacp
class GreetingAgent:
def handle_message(self, message):
name = message.get("name", "World")
task = message.get("task")
if task == "greet":
return {"response": f"Hello, {name}!"}
elif task == "farewell":
return {"response": f"Goodbye, {name}!"}
else:
return {"error": f"Unknown task: {task}"}
# Register the agent
orchestrator = dacp.Orchestrator()
agent = GreetingAgent()
orchestrator.register_agent("greeter", agent)
# Use the agent
response = orchestrator.send_message("greeter", {
"task": "greet",
"name": "Alice"
})
print(response) # {"response": "Hello, Alice!"}
Agent Base Class
You can also inherit from the Agent base class:
import dacp
class MyAgent(dacp.Agent):
def handle_message(self, message):
return {"processed": message}
Tool Requests from Agents
Agents can request tool execution by returning properly formatted responses:
class ToolUsingAgent:
def handle_message(self, message):
if message.get("task") == "write_file":
return {
"tool_request": {
"name": "file_writer",
"args": {
"path": "./output/agent_file.txt",
"content": "Hello from agent!"
}
}
}
return {"response": "Task completed"}
# The orchestrator will automatically execute the tool and return results
orchestrator = dacp.Orchestrator()
agent = ToolUsingAgent()
orchestrator.register_agent("file-agent", agent)
response = orchestrator.send_message("file-agent", {"task": "write_file"})
# Tool will be executed automatically
Intelligence Configuration
DACP supports multiple LLM providers through the invoke_intelligence function. Configure different providers using a configuration dictionary:
OpenAI
import dacp
openai_config = {
"engine": "openai",
"model": "gpt-4", # or "gpt-3.5-turbo", "gpt-4-turbo", etc.
"api_key": "your-openai-key", # or set OPENAI_API_KEY env var
"endpoint": "https://api.openai.com/v1", # optional, uses default
"temperature": 0.7, # optional, default 0.7
"max_tokens": 150 # optional, default 150
}
response = dacp.invoke_intelligence("Explain quantum computing", openai_config)
Anthropic (Claude)
anthropic_config = {
"engine": "anthropic",
"model": "claude-3-haiku-20240307", # or other Claude models
"api_key": "your-anthropic-key", # or set ANTHROPIC_API_KEY env var
"endpoint": "https://api.anthropic.com", # optional, uses default
"temperature": 0.7,
"max_tokens": 150
}
response = dacp.invoke_intelligence("Write a poem about AI", anthropic_config)
Azure OpenAI
azure_config = {
"engine": "azure",
"model": "gpt-4", # Your deployed model name
"api_key": "your-azure-key", # or set AZURE_OPENAI_API_KEY env var
"endpoint": "https://your-resource.openai.azure.com", # or set AZURE_OPENAI_ENDPOINT env var
"api_version": "2024-02-01" # optional, default provided
}
response = dacp.invoke_intelligence("Analyze this data", azure_config)
Local LLMs (Ollama, etc.)
# For Ollama (default local setup)
local_config = {
"engine": "local",
"model": "llama2", # or any model available in Ollama
"endpoint": "http://localhost:11434/api/generate", # Ollama default
"temperature": 0.7,
"max_tokens": 150
}
# For custom local APIs
custom_local_config = {
"engine": "local",
"model": "custom-model",
"endpoint": "http://localhost:8080/generate", # Your API endpoint
"temperature": 0.7,
"max_tokens": 150
}
response = dacp.invoke_intelligence("Tell me a story", local_config)
Configuration from OAS YAML
You can load configuration from OAS (Open Agent Specification) YAML files:
import yaml
import dacp
# Load config from YAML file
with open('agent_config.yaml', 'r') as f:
config = yaml.safe_load(f)
intelligence_config = config.get('intelligence', {})
response = dacp.invoke_intelligence("Hello, AI!", intelligence_config)
Installation for Different Providers
Install optional dependencies for the providers you need:
# For OpenAI
pip install dacp[openai]
# For Anthropic
pip install dacp[anthropic]
# For all providers
pip install dacp[all]
# For local providers (requests is already included in base install)
pip install dacp[local]
Built-in Tools
file_writer
The file_writer tool automatically creates parent directories and writes content to files:
import dacp
# This will create the ./output/ directory if it doesn't exist
result = dacp.file_writer("./output/file.txt", "Hello, World!")
if result["success"]:
print(f"File written: {result['path']}")
print(f"Message: {result['message']}")
else:
print(f"Error: {result['error']}")
Features:
- ✅ Automatically creates parent directories
- ✅ Handles Unicode content properly
- ✅ Returns detailed success/error information
- ✅ Safe error handling
Development
# Install development dependencies
pip install -e .[dev]
# Run tests
pytest
# Format code
black .
# Lint code
flake8
License
MIT License
Project details
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 dacp-0.3.0.tar.gz.
File metadata
- Download URL: dacp-0.3.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3aa053e37c6102c4971c89a6f5f70a5ceb38d0d955fdff8aad4711fde09cf53d
|
|
| MD5 |
6dcff3b00bcae7e252dcecc38765a373
|
|
| BLAKE2b-256 |
662bd1b3b3c479f3fff8aedc82ac891ce99bd07255be84f09aad1aa246d9da4c
|
File details
Details for the file dacp-0.3.0-py3-none-any.whl.
File metadata
- Download URL: dacp-0.3.0-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93da717408d0cf79d9ea28ae65ac3e19f14a5c9047610cae15999bc91d69c49a
|
|
| MD5 |
b5ed8bb7b1a490cd0cf3d58147e6ebc6
|
|
| BLAKE2b-256 |
6deeb967af777024c89ea1f96fe24dcfab916c73ac0c37f950c35b5aef663bea
|