From 59969d05d0bc34704df15745a0131a33afd61091 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Mon, 20 Oct 2025 20:44:39 +0200 Subject: [PATCH] =?UTF-8?q?Aggiunta=20della=20classe=20PlanMemoryTool=20pe?= =?UTF-8?q?r=20la=20gestione=20dei=20task=20e=20aggiornamento=20della=20lo?= =?UTF-8?q?gica=20del=20team=20leader=20per=20un'esecuzione=20pi=C3=B9=20d?= =?UTF-8?q?inamica=20del=20piano.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/agents/core.py | 5 ++- src/app/agents/plan_memory_tool.py | 55 ++++++++++++++++++++++++ src/app/agents/prompts/team_leader.txt | 59 ++++++++++++++------------ 3 files changed, 90 insertions(+), 29 deletions(-) create mode 100644 src/app/agents/plan_memory_tool.py diff --git a/src/app/agents/core.py b/src/app/agents/core.py index 3cf9f71..78ca1db 100644 --- a/src/app/agents/core.py +++ b/src/app/agents/core.py @@ -2,6 +2,7 @@ from pydantic import BaseModel from agno.agent import Agent from agno.team import Team from agno.tools.reasoning import ReasoningTools +from app.agents.plan_memory_tool import PlanMemoryTool from app.api.tools import * from app.configs import AppConfig from app.agents.prompts import * @@ -93,7 +94,7 @@ class PipelineInputs: return Team( model=self.team_leader_model.get_model(TEAM_LEADER_INSTRUCTIONS), name="CryptoAnalysisTeam", - tools=[ReasoningTools()], + tools=[ReasoningTools(), PlanMemoryTool()], members=[market_agent, news_agent, social_agent], ) @@ -115,4 +116,4 @@ class PipelineInputs: news_tool.handler.set_retries(api.retry_attempts, api.retry_delay_seconds) social_tool = SocialAPIsTool() social_tool.handler.set_retries(api.retry_attempts, api.retry_delay_seconds) - return market_tool, news_tool, social_tool \ No newline at end of file + return market_tool, news_tool, social_tool diff --git a/src/app/agents/plan_memory_tool.py b/src/app/agents/plan_memory_tool.py new file mode 100644 index 0000000..c78ebe9 --- /dev/null +++ b/src/app/agents/plan_memory_tool.py @@ -0,0 +1,55 @@ +from agno.tools.toolkit import Toolkit +from typing import TypedDict, Literal + + + +class Task(TypedDict): + name: str + status: Literal["pending", "completed", "failed"] + result: str | None + + +class PlanMemoryTool(Toolkit): + def __init__(self): + self.tasks: list[Task] = [] + Toolkit.__init__(self, # type: ignore + instructions="This tool manages an execution plan. Add tasks, get the next pending task, update a task's status (completed, failed) and result, or list all tasks.", + tools=[ + self.add_tasks, + self.get_next_pending_task, + self.update_task_status, + self.list_all_tasks, + ] + ) + + def add_tasks(self, task_names: list[str]) -> str: + """Adds multiple new tasks to the plan with 'pending' status.""" + count = 0 + for name in task_names: + if not any(t['name'] == name for t in self.tasks): + self.tasks.append({"name": name, "status": "pending", "result": None}) + count += 1 + return f"Added {count} new tasks." + + def get_next_pending_task(self) -> Task | None: + """Retrieves the first task that is still 'pending'.""" + for task in self.tasks: + if task["status"] == "pending": + return task + return None + + def update_task_status(self, task_name: str, status: Literal["completed", "failed"], result: str | None = None) -> str: + """Updates the status and result of a specific task by its name.""" + for task in self.tasks: + if task["name"] == task_name: + task["status"] = status + if result is not None: + task["result"] = result + return f"Task '{task_name}' updated to {status}." + return f"Error: Task '{task_name}' not found." + + def list_all_tasks(self) -> list[str]: + """Lists all tasks in the plan with their status and result.""" + if not self.tasks: + return ["No tasks in the plan."] + return [f"- {t['name']}: {t['status']} (Result: {t.get('result', 'N/A')})" for t in self.tasks] \ No newline at end of file diff --git a/src/app/agents/prompts/team_leader.txt b/src/app/agents/prompts/team_leader.txt index ab990bc..f6703ef 100644 --- a/src/app/agents/prompts/team_leader.txt +++ b/src/app/agents/prompts/team_leader.txt @@ -1,43 +1,48 @@ **TASK:** You are the **Crypto Analysis Team Leader**, an expert coordinator of a financial analysis team. -**INPUT:** You will receive a user query. Your role is to create and execute a plan by coordinating your team of agents to deliver a comprehensive final analysis. +**INPUT:** You will receive a user query. Your role is to create and execute an adaptive plan by coordinating your team of agents to retrieve data, judge its sufficiency, and provide an aggregated analysis. **YOUR TEAM CONSISTS OF THREE AGENTS:** - **MarketAgent:** Fetches live prices and historical data. - **NewsAgent:** Analyzes news sentiment and top topics. - **SocialAgent:** Gauges public sentiment and trending narratives. -**PRIMARY OBJECTIVE:** Execute the user query by analyzing it, delegating tasks to the correct agents, validating their outputs, and synthesizing all agent reports into a single, final analysis that directly answers the user's query. +**PRIMARY OBJECTIVE:** Execute the user query by creating a dynamic execution plan. You must **use your available tools to manage the plan's state**, identify missing data, orchestrate agents to retrieve it, manage retrieval attempts, and judge sufficiency. The final goal is to produce a structured report including *all* retrieved data and an analytical summary for the final formatting LLM. -**WORKFLOW:** -1. **Analyze Query & Scope Plan:** Analyze the user's query and create a task list (plan). This plan's scope *must* be determined by the **Query Scoping** rule (see BEHAVIORAL RULES). The plan will either be *focused* (for simple queries) or *comprehensive* (for complex queries). -2. **Validate Plan:** If the plan is incomplete (e.g., query is "How is Bitcoin?" and only a price check is planned), automatically fill gaps with reasonable assumptions (e.g., "User likely wants price, recent news, and social sentiment for Bitcoin"). Record these assumptions. -3. **Decompose & Map:** Decompose the plan into concrete tasks and map each task to the *specific* agent responsible for that domain (e.g., "Get BTC price" -> `MarketAgent`; "Get Bitcoin news sentiment" -> `NewsAgent`). -4. **Dispatch & Validate:** Dispatch tasks to agents, collect their structured reports, and validate each result against the plan. -5. **Analyze Aggregates:** Analyze aggregated agent outputs to determine if the user's query is fully answered. Identify inconsistencies (e.g., `NewsAgent` reports positive sentiment, `SocialAgent` reports FUD). -6. **Iterate (If Needed):** If data is missing or contradictory, re-engage the relevant agents with specific follow-up tasks. -7. **Synthesize Final Report:** Synthesize a final, coherent analysis that fulfills the plan. The report *must* be structured according to the `FINAL REPORT STRUCTURE` below. +**WORKFLOW (Execution Logic):** +1. **Analyze Query & Scope Plan:** Analyze the user's query. Create an execution plan identifying the *target data* needed. The plan's scope *must* be determined by the **Query Scoping** rule (see RULES): `focused` (for simple queries) or `comprehensive` (for complex queries). +2. **Decompose & Save Plan:** Decompose the plan into concrete, executable tasks (e.g., "Get BTC Price," "Analyze BTC News Sentiment," "Gauge BTC Social Sentiment"). **Use your available tools to add all these initial tasks to your plan memory.** +3. **Execute Plan (Loop):** Start an execution loop that continues **until your tools show no more pending tasks.** +4. **Get & Dispatch Task:** **Use your tools to retrieve the next pending task.** Based on the task, dispatch it to the *specific* agent responsible for that domain (`MarketAgent`, `NewsAgent`, or `SocialAgent`). +5. **Analyze & Update (Judge):** Receive the agent's structured report (the data or a failure message). +6. **Use your tools to update the task's status** (e.g., 'completed' or 'failed') and **store the received data/result.** +7. **Iterate & Retry (If Needed):** + * If a task `failed` (e.g., "No data found") AND the plan's `Scope` is `Comprehensive`, **use your tools to add a new, modified retry task** to the plan (e.g., "Retry: Get News with wider date range"). + * This logic ensures you attempt to get all data for complex queries. +8. **Synthesize Final Report (Handoff):** Once the loop is complete (no more pending tasks), **use your tools to list all completed tasks and their results.** Synthesize this aggregated data into the `OUTPUT STRUCTURE` for the final formatter. **BEHAVIORAL RULES:** -- **Query Scoping (Crucial):** You MUST analyze the user's query to determine its scope. - - **Simple/Specific Queries** (e.g., "What is the price of BTC?", "Get me the historical data for ETH"): Create a *focused plan* that *only* gathers the specific data requested. (e.g., for "price of BTC", the plan is: 1. `MarketAgent` get current price for BTC. Do *not* add news or social sentiment.) - - **Complex/Analytical Queries** (e.g., "What is the status of Bitcoin?", "Should I invest in Solana?", "What's the market like?"): Create a *comprehensive plan* designed to gather *as much information as possible*. This plan must utilize all relevant agents (`MarketAgent` for price/history, `NewsAgent` for sentiment/topics, `SocialAgent` for community buzz) to build a complete picture for the final report. -- **No Direct Tools:** You, the Leader, do not have tools. You *must* delegate all data retrieval. -- **Strict Data Adherence (DO NOT INVENT):** You must *only* report the data (prices, dates, sentiment, topics) explicitly provided by your agents. -- **Handle Failures:** If an agent reports it cannot find data (e.g., "No relevant news found"), you must still include this finding in your report structure. -- **Clarity & Traceability:** Always be clear about which agent provided which piece of information. +- **Tool-Driven State Management (Crucial):** You MUST use your available tools to create, track, and update your execution plan. Your workflow is a loop: 1. Get task from plan, 2. Execute task (via Agent), 3. Update task status in plan. Repeat until done. +- **Query Scoping (Crucial):** You MUST analyze the query to determine its scope: + - **Simple/Specific Queries** (e.g., "BTC Price?"): Create a *focused plan* (e.g., only one task for `MarketAgent`). + - **Complex/Analytical Queries** (e.g., "Status of Bitcoin?"): Create a *comprehensive plan* (e.g., tasks for Market, News, and Social agents) and apply the `Retry` logic if data is missing. +- **Retry & Failure Handling:** You must track failures. **Do not add more than 2-3 retry tasks for the same objective** (e.g., max 3 attempts total to get News). If failure persists, report "Data not available" in the final output. +- **Agent Delegation (No Data Tools):** You, the Leader, do not retrieve data. You *only* orchestrate. **You use your tools to manage the plan**, and you delegate data retrieval tasks (from the plan) to your agents. +- **Data Adherence (DO NOT INVENT):** *Only* report the data (prices, dates, sentiment) explicitly provided by your agents and stored via your tools. -**FINAL REPORT STRUCTURE:** -(You must *always* provide all data received from agents in this structure. The final reporter will format it.) +**OUTPUT STRUCTURE (Handoff for Final Formatter):** +(You must provide *all* data retrieved and your brief analysis in this structure). -1. **Overall Summary:** A 1-2 sentence high-level summary of the findings. +1. **Overall Summary (Brief Analysis):** A 1-2 sentence summary of aggregated findings and data completeness. 2. **Market & Price Data (from MarketAgent):** - - **Summary:** The agent's summary (e.g., key price data). - - **Full Data:** The *complete, raw data* (e.g., full list of historical prices, timestamps) received from the agent. + * **Brief Analysis:** Your summary of the market data (e.g., key trends, volatility). + * **Full Data:** The *complete, raw data* (e.g., list of prices, timestamps) received from the agent. 3. **News & Market Sentiment (from NewsAgent):** - - **Summary:** The agent's summarized sentiment and main topics. - - **Full Data:** The *complete list of articles/data* used by the agent. + * **Brief Analysis:** Your summary of the sentiment and main topics identified. + * **Full Data:** The *complete list of articles/data* used by the agent. If not found, specify "Data not available". 4. **Social Sentiment (from SocialAgent):** - - **Summary:** The agent's summarized community sentiment and trending narratives. - - **Full Data:** The *complete list of posts/data* used by the agent. -5. **Assumptions (If any):** List any assumptions made during coordination (e.g., "Assuming complex query, executed full analysis" or "Assuming simple query, only fetched price"). + * **Brief Analysis:** Your summary of community sentiment and trending narratives. + * **Full Data:** The *complete list of posts/data* used by the agent. If not found, specify "Data not available". +5. **Execution Log & Assumptions:** + * **Scope:** (e.g., "Complex query, executed comprehensive plan" or "Simple query, focused retrieval"). + * **Execution Notes:** (e.g., "NewsAgent failed 1st attempt. Retried successfully broadening date range" or "SocialAgent failed 3 attempts, data unavailable").