Created
May 11, 2025 10:44
-
-
Save pavlovmilen/d328c083c02e9dd90c17b92d9ad83f6c to your computer and use it in GitHub Desktop.
complete_example.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
from dotenv import load_dotenv | |
from autogen_agentchat.agents import AssistantAgent | |
from autogen_agentchat.base import TaskResult | |
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination | |
from autogen_agentchat.messages import BaseChatMessage | |
from autogen_agentchat.teams import SelectorGroupChat | |
from autogen_core import SingleThreadedAgentRuntime | |
from autogen_core.tools import FunctionTool | |
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient | |
load_dotenv() | |
gpt_model_client = AzureOpenAIChatCompletionClient( | |
model="gpt-4.1-mini-2025-04-14", | |
api_version="2024-06-01", | |
azure_deployment="gpt-4.1-mini", | |
azure_endpoint=os.environ.get("AZURE_OPEN_AI_API_ENDPOINT_SWEDEN"), | |
#azure_ad_token_provider=token_provider, # Optional if you choose key-based authentication. | |
api_key=os.environ.get("AZURE_OPEN_AI_API_KEY_SWEDEN"), | |
) | |
notebook_dir = os.path.abspath('.') | |
app_dir = os.path.abspath(os.path.join(notebook_dir, '..')) | |
if app_dir not in sys.path: | |
sys.path.insert(0, app_dir) | |
from tools.valuation_modeling_tool import collect_valuation | |
from tools.tools import get_finance_data | |
from tools.fomc_files_service import download_fomc_summary | |
from tools.tools import get_finance_data | |
from tools.alpha_vantage_api import alpha_vantage_news_sentiment, fetch_company_data | |
from tools.file_upload_service import upload_ai_report | |
runtime = SingleThreadedAgentRuntime() | |
doji_tool = FunctionTool(get_finance_data, description="Download last 60 days of OHLCV data") | |
doji_agent = AssistantAgent( | |
name="doji_agent", | |
model_client=gpt_model_client, | |
description="Spot daily doji patterns", | |
system_message=""" | |
You retrieve OHLCV data via doji_tool and detect doji candlesticks. | |
A daily bar is a doji when abs(Open – Close) ≤ 0.10 × (High – Low). | |
Steps: (1) call the tool, (2) run the test, (3) return a list of dates or an empty list if none. | |
Output strictly: comma-separated ISO dates. Provide explanations for the doji dates""", | |
tools=[doji_tool]) | |
news_sentiment_data_tool= FunctionTool(alpha_vantage_news_sentiment, description="Searches for information from Alpha Vantage api about a stock.") | |
alpha_vantage_news_sentiment_agent = AssistantAgent( | |
name="alpha_vantage_news_sentiment_agent", | |
model_client=gpt_model_client, | |
description="Search for a news sentiment about a stock using the search tool", | |
system_message="You are a helpful assistant that can search and analyze news sentiment about a stock using alpha vantage api.", | |
tools=[news_sentiment_data_tool], | |
) | |
company_info_tool = FunctionTool(fetch_company_data, description="Retrieves stock data using the alpha vantage api.") | |
alpha_vantage_company_info_agent = AssistantAgent( | |
name="alpha_vantage_company_info_agent", | |
model_client=gpt_model_client, | |
description="Retrieve company data using the Alpha Vantage API", | |
system_message="You are a helpful assistant that can retrieve and analyze company data using alpha vantage api.", | |
tools=[company_info_tool], | |
) | |
fomc_summary_fetch_tool = FunctionTool(download_fomc_summary, description="Fetch FOMC file summary") | |
fomc_summary_fetch_agent = AssistantAgent( | |
name="fomc_summary_fetch_agent", | |
model_client=gpt_model_client, | |
description="Fetch FOMC file summary and analyze it for the current stock ticker", | |
system_message="You are a helpful assistant that can fetch and analyze FOMC file summary for the current stock ticker.", | |
tools=[fomc_summary_fetch_tool] | |
) | |
peer_valuation_modeling_tool = FunctionTool(collect_valuation, description="Get valuation model for a stock ticker") | |
peer_valuation_modeling_agent = AssistantAgent( | |
name="peer_valuation_modeling_agent", | |
model_client=gpt_model_client, | |
system_message=""" | |
You are Valuation-Summariser-Bot. | |
Input → a ValuationBundle JSON (see keys below). | |
Goal → produce a concise, facts-only digest that can be dropped verbatim into the final equity report. No recommendations, no formatting beyond plain text bullets. | |
ValuationBundle keys you’ll receive | |
• symbol – target ticker | |
• multiples – list of dicts with ticker, PE, EV/EBITDA, P/Sales | |
• multiples_median – peer medians for those three ratios | |
• pre_dcf – {per_share, date} or null | |
• sensitivity – dict of WACC-terminal-g grid; access with sensitivity["Value"] once converted back to DataFrame if needed | |
Tasks (keep strictly to this order) | |
State the ticker and peer count. | |
For each ratio (P/E, EV/EBITDA, P/Sales) say whether the target is above, inline, or below its peer median and give the numeric difference in % (one decimal). | |
Quote the FMP simple DCF per-share value and its date, if available. | |
Pick the sensitivity table value at WACC = 9 % & terminal-g = 2 % (if that coordinate exists) and label it “central sensitivity” value. | |
End with one sentence describing overall valuation stance (e.g., “Shares trade at a notable premium across all multiples while the DCF central point implies modest upside.”). | |
Output format – plain text, exactly five bullet points (•), each ≤ 25 words. No extra lines, no JSON, no markdown.""", | |
description="Get peer valuation model for a given stock ticker", | |
tools=[peer_valuation_modeling_tool] | |
) | |
report_generator_agent = AssistantAgent( | |
name="report_agent", | |
model_client=gpt_model_client, | |
description="Generate an answer based the search and results all of the previous agents from the team", | |
system_message=""" | |
You are **Equity-Report-Assembler**. | |
**Objectives** | |
1. Create a report for the ticker provided in all payloads. | |
2. Write in tight, professional prose; no marketing fluff. | |
3. Section order: | |
1) *Technical Snapshot Doji Patterns* summarise `doji_agent` also include the doji dates and the signal. | |
2) *News & Sentiment* summarise top 5 headlines and net bias. | |
3) *Fundamentals Company Snapshot* key numbers from `alpha_vantage_company_info_agent with detailed analysis. | |
4) *Macro Context* 3-sentence digest from `fomc_summary_fetch_agent`. | |
5) *Valuation Modeling* | |
• Compare target vs peer medians for P/E, EV/EBITDA, P/S (state % prem/discount). | |
• Quote FMP simple DCF per-share and its date. | |
• Give central-point value from sensitivity table (WACC = 9 %, g = 2 %). | |
• Provide analysis and explanation of the valuation model. | |
6) *Integrated View* comprehensive analysis of the stock; issue Buy/Hold/Sell, highlight upside or downside drivers. | |
4. Use plain Markdown headings (`###`) and short sentences. | |
5. Numerical formats: integers with commas, decimals with two digits. | |
6. Output **only** the finished Markdown report—no JSON, no metadata, no commentary. | |
7. If any of the agents fail to provide data, make sure its mentioned in the report. | |
""", | |
) | |
report_upload_tool = FunctionTool(upload_ai_report, description="Uploads summary provided by report agent to azure blob storage. Start with PlanningAgent to create an action plan first.") | |
report_upload_agent = AssistantAgent( | |
name="report_upload_agent", | |
model_client=gpt_model_client, | |
description="Upload the {ticker}_report file to azure blob storage", | |
tools=[report_upload_tool] | |
) | |
planning_agent = AssistantAgent( | |
"PlanningAgent", | |
description="An agent for planning tasks, this agent should be the first to engage when given a new task.", | |
model_client=gpt_model_client, | |
system_message=""" | |
You are a planning agent. | |
Your job is to break down complex tasks into smaller, manageable subtasks. | |
Your team members are: | |
doji_agent: Identify doji patterns in stock data using doji_tool | |
alpha_vantage_news_sentiment_agent: Search for a news sentiment about a stock using the search tool | |
alpha_vantage_company_info_agent: Retrieve company data using the Alpha Vantage API | |
fomc_summary_fetch_agent: Fetch FOMC file summary and analyze it for the current stock ticker | |
valuation_modeling_agent: Get valuation model for a given stock ticker | |
report_agent: Generate report based on doji patterns, alpha vantage news sentiment, company data, valuation model and fomc summary. | |
report_upload_agent: Upload the report to azure blob storage using report_upload_tool. | |
You only plan and delegate tasks - you do not execute them yourself. | |
When assigning tasks, use this format: | |
1. <agent> : <task> | |
After all tasks are complete, summarize the findings. Only when all tasks are complete, complete the workflow by responding with "TERMINATE". | |
""", | |
) | |
text_mention_termination = TextMentionTermination("TERMINATE") | |
max_messages_termination = MaxMessageTermination(max_messages=25) | |
termination = text_mention_termination | max_messages_termination | |
selector_prompt = """Select an agent to perform task. | |
{roles} | |
Current conversation context: | |
{history} | |
Read the above conversation, then select an agent from {participants} to perform the next task. | |
Make sure the planner agent has assigned tasks before other agents start working. | |
Only select one agent at a time. | |
""" | |
market_reserarch_agents_team = SelectorGroupChat( | |
[planning_agent, doji_agent, alpha_vantage_news_sentiment_agent, alpha_vantage_company_info_agent, fomc_summary_fetch_agent, peer_valuation_modeling_agent, report_generator_agent, report_upload_agent], | |
termination_condition=termination, | |
allow_repeated_speaker=True, | |
model_client=gpt_model_client, | |
selector_prompt=selector_prompt) | |
runtime.start() | |
message_count = 0 | |
total_prompt_tokens = 0 | |
total_completion_tokens = 0 | |
async for message in market_reserarch_agents_team.run_stream(task="Hello, I would like to know if a stock with ticker=MSFT is a good pick for me to invest in this year?"): | |
if isinstance(message, TaskResult): | |
print("Stop Reason:", message.stop_reason) | |
if isinstance(message, BaseChatMessage): | |
message_count += 1 | |
print(f'.................Message {message_count}.....................') | |
print(f"\033[93m........ Source: {message.source}\033[0m") | |
print(f"\033[94m{message.content}\033[0m") | |
if hasattr(message, 'models_usage') and message.models_usage is not None: | |
prompt = getattr(message.models_usage, 'prompt_tokens', 0) | |
completion = getattr(message.models_usage, 'completion_tokens', 0) | |
total_prompt_tokens += prompt | |
total_completion_tokens += completion | |
print(f"\033[91mInput tokens so far: {total_prompt_tokens}\033[0m") | |
print(f"\033[92mOutput tokens so far: {total_completion_tokens}\033[0m") | |
print(f"\033[91mTotal input tokens: {total_prompt_tokens}\033[0m") | |
print(f"\033[92mTotal output tokens: {total_completion_tokens}\033[0m") | |
await market_reserarch_agents_team.reset() | |
await runtime.stop() | |
print(f"\033[91mPrice of input tokens: £{total_prompt_tokens * 0.30 / 1000000}\033[0m") | |
print(f"\033[92mPrice of output tokens: £{total_completion_tokens * 1.20 / 1000000}\033[0m") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment