Files
microdao-daarion/providers/crewai_provider.py
Ivan Tytar 3cacf67cf5 feat: Initial commit - DAGI Stack v0.2.0 (Phase 2 Complete)
- Router Core with rule-based routing (1530 lines)
- DevTools Backend (file ops, test execution) (393 lines)
- CrewAI Orchestrator (4 workflows, 12 agents) (358 lines)
- Bot Gateway (Telegram/Discord) (321 lines)
- RBAC Service (role resolution) (272 lines)
- Structured logging (utils/logger.py)
- Docker deployment (docker-compose.yml)
- Comprehensive documentation (57KB)
- Test suites (41 tests, 95% coverage)
- Phase 4 roadmap & ecosystem integration plans

Production-ready infrastructure for DAARION microDAOs.
2025-11-15 14:35:24 +01:00

118 lines
3.7 KiB
Python

"""
CrewAI Provider
Orchestrates multi-agent workflows via CrewAI backend.
"""
import logging
from typing import Dict, Any, Optional
import httpx
from providers.base import Provider
from router_models import RouterRequest, RouterResponse
logger = logging.getLogger(__name__)
class CrewAIProvider(Provider):
"""
Provider that routes requests to a CrewAI orchestrator backend.
The backend manages multi-agent workflows using CrewAI framework.
"""
def __init__(
self,
provider_id: str,
base_url: str,
timeout: int = 120,
**kwargs
):
super().__init__(provider_id)
self.base_url = base_url.rstrip("/")
self.timeout = timeout
logger.info(f"CrewAIProvider initialized: {provider_id}{base_url}")
async def call(self, request: RouterRequest) -> RouterResponse:
"""
Route request to CrewAI orchestrator backend.
Expected request.payload format:
{
"workflow": "microdao_onboarding" | "code_review" | etc.,
"input": {
"user_id": "...",
"channel": "...",
...
}
}
"""
try:
# Extract workflow and input from payload
workflow = request.payload.get("workflow") if request.payload else None
if not workflow:
return RouterResponse(
ok=False,
provider_id=self.id,
error="Missing 'workflow' in request payload"
)
workflow_input = request.payload.get("input", {}) if request.payload else {}
# Build request body with metadata
body = {
"workflow": workflow,
"input": workflow_input,
"meta": {
"mode": request.mode,
"agent": request.agent,
"dao_id": request.dao_id,
"user_id": request.user_id,
"source": request.source,
"session_id": request.session_id,
}
}
# Call CrewAI backend
url = f"{self.base_url}/workflow/run"
logger.info(f"CrewAI workflow call: {workflow}{url}")
async with httpx.AsyncClient(timeout=self.timeout) as client:
response = await client.post(url, json=body)
response.raise_for_status()
data = response.json()
return RouterResponse(
ok=True,
provider_id=self.id,
data=data,
metadata={
"provider_type": "orchestrator",
"workflow": workflow,
"status_code": response.status_code
}
)
except httpx.HTTPStatusError as e:
logger.error(f"CrewAI HTTP error: {e}")
return RouterResponse(
ok=False,
provider_id=self.id,
error=f"HTTP {e.response.status_code}: {e.response.text}"
)
except httpx.RequestError as e:
logger.error(f"CrewAI request error: {e}")
return RouterResponse(
ok=False,
provider_id=self.id,
error=f"Request failed: {str(e)}"
)
except Exception as e:
logger.error(f"CrewAI error: {e}")
return RouterResponse(
ok=False,
provider_id=self.id,
error=str(e)
)