**Phase 1 — Agent Usage Sync to AgentHub Collector**
- Add agent_usage service: per-agent stats (messages, tokens, conversations, unique users, first/last used)
- Collector sync now includes usage data in payload; sync_agent accepts optional db session
- Celery beat task runs every 6h to sync all active agents with fresh usage stats
**Phase 2 — LibreCodeInterpreter Integration**
- Add code-interpreter, redis, minio services to docker-compose.prod.yml
- CodeInterpreterTool (BaseTool): sandboxed execution via /exec, 13 languages, Python session persistence via conversation_id
- ToolContext extended with conversation_id and agent_slug
- enable_code_interpreter boolean on Agent model (migration 027), tool seeded in tool_definitions (migration 026)
- Code interpreter auto-injected into agent tools when enabled
- Frontend: CodeExecutionResult component with terminal-style stdout/stderr/files rendering
**Phase 3 — Agent API Endpoints**
- GET /api/v1/agents/{slug}/analytics — per-agent usage stats + daily time series
- POST /api/v1/agents/{slug}/execute — synchronous programmatic agent execution (non-SSE)
- Sub-routes registered before /{slug} to avoid FastAPI route conflict
**Phase 4 — Fix Department & Region RAG Scoping**
- Department filter now OR-includes global (null department) docs, matching region filter behaviour
- retriever.search_documents/retrieve_and_prepare/query accept department_ids/region_codes lists
- MatchAny used for multi-value Qdrant filters; chat.py passes full arrays from knowledge_scope
- Admin PATCH /users/{id} now validates region_code against the regions table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
"""
|
|
Celery Application Configuration
|
|
|
|
Broker: Redis
|
|
Result backend: Redis
|
|
|
|
Usage (inside container):
|
|
celery -A celery_app worker --loglevel=info --queues=sharepoint,default
|
|
celery -A celery_app beat --loglevel=info
|
|
celery -A celery_app flower --port=5555
|
|
"""
|
|
from celery import Celery
|
|
from celery.schedules import crontab
|
|
from app.config import settings
|
|
|
|
celery_app = Celery(
|
|
"nexus",
|
|
broker=settings.CELERY_BROKER_URL,
|
|
backend=settings.CELERY_RESULT_BACKEND,
|
|
include=[
|
|
"app.tasks.sharepoint_sync",
|
|
"app.tasks.knowledge_processing",
|
|
"app.tasks.agent_sync",
|
|
],
|
|
)
|
|
|
|
celery_app.conf.update(
|
|
# Serialization
|
|
task_serializer="json",
|
|
result_serializer="json",
|
|
accept_content=["json"],
|
|
|
|
# Timezone
|
|
timezone="UTC",
|
|
enable_utc=True,
|
|
|
|
# Task time limits
|
|
task_time_limit=1800, # hard kill after 30 min
|
|
task_soft_time_limit=1500, # SoftTimeLimitExceeded after 25 min
|
|
|
|
# Concurrency (can be overridden by CLI --concurrency)
|
|
worker_concurrency=settings.WORKERS_COUNT,
|
|
|
|
# Task routing
|
|
task_routes={
|
|
"app.tasks.sharepoint_sync.*": {"queue": "sharepoint"},
|
|
"app.tasks.knowledge_processing.*": {"queue": "default"},
|
|
"app.tasks.agent_sync.*": {"queue": "default"},
|
|
},
|
|
|
|
# Result retention: keep results for 24 hours
|
|
result_expires=86400,
|
|
|
|
# Reliability
|
|
task_acks_late=True,
|
|
task_reject_on_worker_lost=True,
|
|
worker_prefetch_multiplier=1,
|
|
|
|
# Beat schedule
|
|
beat_schedule={
|
|
"renew-expiring-webhooks": {
|
|
"task": "app.tasks.sharepoint_sync.renew_expiring_webhooks",
|
|
"schedule": crontab(hour=3, minute=0),
|
|
},
|
|
"sync-sharepoint-sources": {
|
|
"task": "app.tasks.sharepoint_sync.sync_all_active_sources",
|
|
"schedule": crontab(minute=0), # hourly
|
|
},
|
|
"sync-agent-collector-usage": {
|
|
"task": "app.tasks.agent_sync.sync_agents_usage",
|
|
"schedule": crontab(minute=0, hour="*/6"), # every 6 hours
|
|
},
|
|
},
|
|
)
|
|
|
|
|
|
@celery_app.task(name="celery_healthcheck", bind=True)
|
|
def celery_healthcheck(self):
|
|
"""Simple task used to verify worker is alive."""
|
|
return {"status": "ok", "worker": self.request.hostname}
|