DCAF - DuploCloud Agent Framework¶
DCAF (DuploCloud Agent Framework) is a Python framework for building LLM-powered AI agents with tool calling and human-in-the-loop approval.
Quick Start¶
from dcaf.core import Agent, serve
from dcaf.tools import tool
# 1. Define tools
@tool(description="List Kubernetes pods")
def list_pods(namespace: str = "default") -> str:
return kubectl(f"get pods -n {namespace}")
@tool(requires_approval=True, description="Delete a pod")
def delete_pod(name: str, namespace: str = "default") -> str:
return kubectl(f"delete pod {name} -n {namespace}")
# 2. Create an agent
agent = Agent(tools=[list_pods, delete_pod])
# 3. Serve it
serve(agent) # Running at http://0.0.0.0:8000
Test it:
curl -X POST http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "What pods are running?"}]}'
Key Features¶
| Feature | Description |
|---|---|
| π οΈ Tool Calling | Easy decorator-based tool definitions with auto-generated, dict, or Pydantic schemas |
| β Human-in-the-Loop | Built-in approval flow for dangerous operations |
| π Interceptors | Hook into request/response for validation, context, security |
| π Framework Adapters | Swap LLM frameworks (Agno, Strands, LangChain) with one parameter |
| π HelpDesk Protocol | Full compatibility with DuploCloud HelpDesk messaging |
| π REST API | One-line server with serve(agent) |
| π‘ Streaming | Real-time token-by-token responses |
| π Custom Logic | Build agents with any structure you need |
| π§ MCP Integration | Connect to external MCP servers and use their tools |
Architecture¶
How It Works¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Code β
β β
β agent = Agent(tools=[...]) OR def my_agent(messages, ctx)β
β serve(agent) serve(my_agent) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DCAF Core β
β β
β 1. Receives HTTP request from HelpDesk β
β 2. Converts to simple message format β
β 3. Runs your agent logic β
β 4. Handles tool approvals automatically β
β 5. Returns response in HelpDesk protocol β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLM (AWS Bedrock) β
β β
β Claude 3.5 Sonnet / Claude 4 / etc. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Request/Response Flow¶
DuploCloud HelpDesk Your Agent
β β
β POST /api/chat β
β {"messages": [...]} β
β ββββββββββββββββββββββββββββββββββββΊ β
β β
β βββββββββ΄ββββββββ
β β Agent.run() β
β β calls LLM β
β β with tools β
β βββββββββ¬ββββββββ
β β
β Tool needs approval? β
β ββββββββββββββββββββββββββββββββββ β
β {"tool_calls": [...]} β
β β
ββββββ΄βββββ β
β User β β
β Approvesβ β
ββββββ¬βββββ β
β β
β POST /api/chat β
β {tool_calls: [execute: true]} β
β ββββββββββββββββββββββββββββββββββββΊ β
β β
β βββββββββ΄ββββββββ
β β Execute tool β
β β Return result β
β βββββββββ¬ββββββββ
β β
β {"content": "Done!", ...} β
β ββββββββββββββββββββββββββββββββββ β
Component Overview¶
| Component | What It Does |
|---|---|
| Agent | Your LLM-powered assistant with tools |
| Tools | Functions the agent can call (with optional approval) |
| serve() | Runs your agent as a REST API |
| HelpDesk Protocol | Message format for DuploCloud integration |
For internal architecture details, see Engineering Handoff.
Two Ways to Build Agents¶
Option 1: Simple (Agent Class)¶
For most use cases:
from dcaf.core import Agent, serve
agent = Agent(
tools=[list_pods, delete_pod],
system="You are a Kubernetes assistant.",
)
serve(agent)
Option 2: Custom Function¶
For complex logic (multiple LLM calls, branching, etc.):
from dcaf.core import Agent, AgentResult, serve
def my_agent(messages: list, context: dict) -> AgentResult:
# Classify intent
classifier = Agent(system="Classify as: query or action")
intent = classifier.run(messages)
if "action" in intent.text:
# Use tools for actions
executor = Agent(tools=[...])
result = executor.run(messages)
return AgentResult(text=result.text, ...)
return AgentResult(text=intent.text)
serve(my_agent)
See Custom Agents Guide for patterns.
Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/api/chat |
POST | Synchronous chat |
/api/chat-stream |
POST | Streaming (NDJSON) |
Tool Approval¶
Tools that modify state should require approval:
@tool(requires_approval=True, description="Delete a pod")
def delete_pod(name: str) -> str:
return kubectl(f"delete pod {name}")
The agent will pause and ask for approval before executing.
Documentation¶
Getting Started¶
Core Framework¶
- Core Overview - The Agent class and API
- Server - Running agents as REST APIs
- HelpDesk Protocol - Full DuploCloud HelpDesk compatibility
- Framework Adapters - Swap between Agno, Strands, LangChain
- Interceptors Guide - Hook into request/response pipeline
- Custom Agents Guide - Building complex agents
Reference¶
- Tools - Creating tools with
@tool - MCP Tools - Connect to external MCP servers
- Schemas - Message format reference
- Streaming - Streaming responses
Architecture¶
- Architecture Guide - How DCAF works internally
- Engineering Handoff - Team handoff documentation
- Architecture Decision Records - Design decisions
Legacy (v1)¶
The original API is still available for existing integrations:
- BedrockLLM - Direct Bedrock access
- Agents (v1) - Legacy agent classes
- Agent Server - Legacy server setup
Installation¶
# From GitHub
pip install git+https://github.com/duplocloud/service-desk-agents.git
# For development
git clone https://github.com/duplocloud/service-desk-agents.git
cd service-desk-agents
pip install -r requirements.txt
Requirements¶
- Python 3.12+
- AWS credentials with Bedrock access
- Dependencies:
fastapi,pydantic,uvicorn,boto3
License¶
MIT License - See LICENSE for details.
Support¶
- GitHub Issues: service-desk-agents
- DuploCloud Support: support@duplocloud.com