step 6 complete: four specialized agents, all registered and tested
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
96
app/agents/task_agent.py
Normal file
96
app/agents/task_agent.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Task agent — create, update, list, and suggest tasks."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from langchain_core.tools import tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from app.config.settings import settings
|
||||
from app.core.agent_registry import ChatAgent, registry
|
||||
|
||||
_SYSTEM_PROMPT = (
|
||||
"You are a task management assistant (PM-oriented). Help the user create, "
|
||||
"update, list, and suggest tasks.\n"
|
||||
"Rules:\n"
|
||||
" - priority must be one of: low, medium, high, urgent\n"
|
||||
" - infer priority from context clues (deadlines, urgency language, dependencies)\n"
|
||||
" - due_date as ISO 8601 string when provided\n"
|
||||
" - context fields beyond user_profile are optional; use them when present\n"
|
||||
"Use the available tools to act, then confirm what was done in plain language."
|
||||
)
|
||||
|
||||
|
||||
@tool
|
||||
async def create_task(
|
||||
title: str,
|
||||
description: str = "",
|
||||
priority: str = "medium",
|
||||
due_date: str = "",
|
||||
) -> str:
|
||||
"""Create a new task. priority: low | medium | high | urgent. due_date: ISO 8601."""
|
||||
return json.dumps({
|
||||
"action": "create_record",
|
||||
"table": "tasks",
|
||||
"data": {
|
||||
"title": title,
|
||||
"description": description,
|
||||
"priority": priority,
|
||||
"due_date": due_date,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@tool
|
||||
async def update_task(task_id: str, updates: str) -> str:
|
||||
"""Update fields on an existing task. Pass updates as a JSON string, e.g. '{"priority":"high"}'."""
|
||||
return json.dumps({
|
||||
"action": "update_record",
|
||||
"table": "tasks",
|
||||
"data": {"id": task_id, "updates": updates},
|
||||
})
|
||||
|
||||
|
||||
@tool
|
||||
async def list_tasks(status: str = "", priority: str = "") -> str:
|
||||
"""List tasks. Optionally filter by status (open|done|archived) or priority level."""
|
||||
return json.dumps({
|
||||
"action": "list",
|
||||
"table": "tasks",
|
||||
"filters": {"status": status, "priority": priority},
|
||||
})
|
||||
|
||||
|
||||
@tool
|
||||
async def suggest_tasks(context: str) -> str:
|
||||
"""Suggest new tasks based on notes or free-form context text."""
|
||||
return json.dumps({
|
||||
"action": "suggest",
|
||||
"table": "tasks",
|
||||
"context": context,
|
||||
})
|
||||
|
||||
|
||||
@registry.register
|
||||
class TaskAgent(ChatAgent):
|
||||
def get_name(self) -> str:
|
||||
return "task_agent"
|
||||
|
||||
def get_description(self) -> str:
|
||||
return "Manages tasks: create, update, list, suggest"
|
||||
|
||||
def get_tools(self) -> list[Any]:
|
||||
return [create_task, update_task, list_tasks, suggest_tasks]
|
||||
|
||||
async def handle(self, query: str, context: dict[str, Any]) -> str:
|
||||
llm = ChatOpenAI(model="gpt-4o", temperature=0, api_key=settings.OPENAI_API_KEY)
|
||||
messages = [
|
||||
SystemMessage(content=_SYSTEM_PROMPT),
|
||||
HumanMessage(
|
||||
content=f"User query: {query}\nContext: {json.dumps(context)[:1000]}"
|
||||
),
|
||||
]
|
||||
return await self._tool_loop(llm, messages, self.get_tools())
|
||||
Reference in New Issue
Block a user