refactor: improve documentation and error handling in crypto symbols tools
This commit is contained in:
@@ -27,8 +27,6 @@ models:
|
||||
- name: mistral-large-latest
|
||||
label: Mistral
|
||||
ollama:
|
||||
- name: gpt-oss:latest
|
||||
label: Ollama GPT
|
||||
- name: qwen3:8b
|
||||
label: Qwen 3 (8B)
|
||||
- name: qwen3:4b
|
||||
|
||||
@@ -4,6 +4,18 @@ from typing import TypedDict, Literal
|
||||
|
||||
|
||||
class Task(TypedDict):
|
||||
"""
|
||||
Represents a single task in the execution plan.
|
||||
|
||||
Attributes:
|
||||
name (str): The unique name of the task.
|
||||
status (Literal["pending", "completed", "failed"]): The current status of the task.
|
||||
- "pending": The task is yet to be executed.
|
||||
- "completed": The task has been successfully executed.
|
||||
- "failed": The task execution was unsuccessful.
|
||||
result (str | None): An optional field to store the result or outcome of the task.
|
||||
This could be a summary, an error message, or any relevant information.
|
||||
"""
|
||||
name: str
|
||||
status: Literal["pending", "completed", "failed"]
|
||||
result: str | None
|
||||
@@ -13,6 +25,7 @@ class PlanMemoryTool(Toolkit):
|
||||
def __init__(self):
|
||||
self.tasks: list[Task] = []
|
||||
Toolkit.__init__(self, # type: ignore[call-arg]
|
||||
name="Plan Memory Tool",
|
||||
instructions="Provides stateful, persistent memory for the Team Leader. " \
|
||||
"This is your primary to-do list and state tracker. " \
|
||||
"Use it to create, execute step-by-step, and record the results of your execution plan.",
|
||||
|
||||
@@ -18,9 +18,17 @@ You orchestrate data retrieval and synthesis using a tool-driven execution plan.
|
||||
- **NewsAgent**: Live news articles with sentiment analysis (NewsAPI, GoogleNews, CryptoPanic)
|
||||
- **SocialAgent**: Current social media discussions (Reddit, X, 4chan)
|
||||
|
||||
**YOUR PERSONAL TOOLS (FOR PLANNING & SYNTHESIS):**
|
||||
- **PlanMemoryTool**: MUST be used to manage your execution plan. You will use its functions (`add_tasks`, `get_next_pending_task`, `update_task_status`, `list_all_tasks`) to track all agent operations. This is your stateful memory.
|
||||
- **ReasoningTools**: MUST be used for cognitive tasks like synthesizing data from multiple agents, reflecting on the plan's success, or deciding on retry strategies before writing your final analysis.
|
||||
**YOUR PERSONAL TOOLS (FOR PLANNING, SYNTHESIS & UTILITIES):**
|
||||
*The framework will provide you with the exact functions for these tools. Your job is to use them according to these strategies.*
|
||||
|
||||
- **Planning & State (`PlanMemoryTool`)**:
|
||||
This is your stateful memory. You MUST use it to build your plan (`add_tasks`) *before* delegating, execute the plan step-by-step (`get_next_pending_task`), and record all outcomes (`update_task_status`).
|
||||
|
||||
- **Cognition & Synthesis (`ReasoningTools`)**:
|
||||
You MUST use this tool to reflect on the data gathered from your team and to synthesize the `Analysis` sections of your final report.
|
||||
|
||||
- **Data Utilities (`CryptoSymbolsTools`)**:
|
||||
You MUST use this tool to find the correct ticker (e.g., "BTC-USD") when the user asks for a name (e.g., "Bitcoin"). Do this *before* you create a task for the `MarketAgent`.
|
||||
|
||||
**AGENT OUTPUT SCHEMAS (MANDATORY REFERENCE):**
|
||||
You MUST parse the exact structures your agents provide:
|
||||
|
||||
@@ -5,7 +5,6 @@ from app.api.core.news import Article, NewsWrapper
|
||||
|
||||
def extract_article(result: dict[str, Any]) -> Article:
|
||||
article = Article()
|
||||
print(result)
|
||||
article.source = result.get("source", "")
|
||||
article.time = result.get("date", "")
|
||||
article.title = result.get("title", "")
|
||||
|
||||
@@ -13,48 +13,79 @@ logging = logging.getLogger("crypto_symbols")
|
||||
|
||||
BASE_URL = "https://finance.yahoo.com/markets/crypto/all/"
|
||||
|
||||
|
||||
class CryptoSymbolsTools(Toolkit):
|
||||
"""
|
||||
Classe per ottenere i simboli delle criptovalute tramite Yahoo Finance.
|
||||
Class for obtaining cryptocurrency symbols via Yahoo Finance.
|
||||
(This class-level docstring is for developers).
|
||||
"""
|
||||
|
||||
def __init__(self, cache_file: str = 'resources/cryptos.csv'):
|
||||
self.cache_file = cache_file
|
||||
self.final_table = pd.read_csv(self.cache_file) if os.path.exists(self.cache_file) else pd.DataFrame() # type: ignore
|
||||
Toolkit.__init__(self, # type: ignore
|
||||
name="Crypto Symbols Tool",
|
||||
instructions="Tool to get cryptocurrency symbols and search them by name.",
|
||||
tools=[
|
||||
self.get_all_symbols,
|
||||
self.get_symbols_by_name,
|
||||
],
|
||||
)
|
||||
try:
|
||||
self.final_table = pd.read_csv(self.cache_file) if os.path.exists(self.cache_file) else pd.DataFrame(
|
||||
columns=['Symbol', 'Name'])
|
||||
except Exception:
|
||||
self.final_table = pd.DataFrame(columns=['Symbol', 'Name'])
|
||||
|
||||
Toolkit.__init__(self, # type: ignore
|
||||
name="Crypto Symbols Tool",
|
||||
instructions="A utility tool to find and verify the correct cryptocurrency symbols (tickers). " \
|
||||
"Use this to translate a cryptocurrency name (e.g., 'Bitcoin') into its official symbol " \
|
||||
"(e.g., 'BTC-USD') *before* delegating tasks to the MarketAgent.",
|
||||
tools=[
|
||||
self.get_all_symbols,
|
||||
self.get_symbols_by_name,
|
||||
],
|
||||
)
|
||||
|
||||
def get_all_symbols(self) -> list[str]:
|
||||
"""
|
||||
Restituisce tutti i simboli delle criptovalute.
|
||||
Returns a complete list of all available cryptocurrency symbols (tickers).
|
||||
|
||||
Warning: This list can be very long. Prefer 'get_symbols_by_name'
|
||||
if you are searching for a specific asset.
|
||||
|
||||
Returns:
|
||||
list[str]: Lista di tutti i simboli delle criptovalute.
|
||||
list[str]: A comprehensive list of all supported crypto symbols (e.g., "BTC-USD", "ETH-USD").
|
||||
"""
|
||||
return self.final_table['Symbol'].tolist() if not self.final_table.empty else []
|
||||
|
||||
def get_symbols_by_name(self, query: str) -> list[tuple[str, str]]:
|
||||
"""
|
||||
Cerca i simboli che contengono la query.
|
||||
Searches the cryptocurrency database for assets matching a name or symbol.
|
||||
|
||||
Use this to find the exact, correct symbol for a cryptocurrency name.
|
||||
(e.g., query="Bitcoin" might return [("BTC-USD", "Bitcoin USD")]).
|
||||
|
||||
Args:
|
||||
query (str): Query di ricerca.
|
||||
query (str): The name, partial name, or symbol to search for (e.g., "Bitcoin", "ETH").
|
||||
|
||||
Returns:
|
||||
list[tuple[str, str]]: Lista di tuple (simbolo, nome) che contengono la query.
|
||||
list[tuple[str, str]]: A list of tuples, where each tuple contains
|
||||
the (symbol, full_name) of a matching asset.
|
||||
Returns an empty list if no matches are found.
|
||||
"""
|
||||
query_lower = query.lower()
|
||||
positions = self.final_table['Name'].str.lower().str.contains(query_lower)
|
||||
return self.final_table[positions][['Symbol', 'Name']].apply(tuple, axis=1).tolist()
|
||||
if self.final_table.empty or 'Name' not in self.final_table.columns or 'Symbol' not in self.final_table.columns:
|
||||
return []
|
||||
|
||||
try:
|
||||
# Cerca sia nel nome che nel simbolo, ignorando maiuscole/minuscole
|
||||
mask = self.final_table['Name'].str.contains(query, case=False, na=False) | \
|
||||
self.final_table['Symbol'].str.contains(query, case=False, na=False)
|
||||
|
||||
filtered_df = self.final_table[mask]
|
||||
|
||||
# Converte il risultato in una lista di tuple
|
||||
return list(zip(filtered_df['Symbol'], filtered_df['Name']))
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
async def fetch_crypto_symbols(self, force_refresh: bool = False) -> None:
|
||||
"""
|
||||
Recupera tutti i simboli delle criptovalute da Yahoo Finance e li memorizza in cache.
|
||||
It retrieves all cryptocurrency symbols from Yahoo Finance and caches them.
|
||||
Args:
|
||||
force_refresh (bool): Se True, forza il recupero anche se i dati sono già in cache.
|
||||
force_refresh (bool): If True, it forces the retrieval even if the data are already in the cache.
|
||||
"""
|
||||
if not force_refresh and not self.final_table.empty:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user