diff --git a/main.py b/main.py index e875c3c4..048d50e5 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ from decimal import Decimal import typer +from loguru import logger from prediction_market_agent_tooling.markets.agent_market import SortBy from prediction_market_agent_tooling.markets.markets import ( MarketType, @@ -43,7 +44,7 @@ def main( do_bet = user_input.lower().strip() == "y" if user_input else True if do_bet: - print( + logger.info( f"Placing bet with position {pma.utils.parse_result_to_str(result)} on market '{market.question}'" ) amount = Decimal( diff --git a/prediction_market_agent/agents/custom_agent.py b/prediction_market_agent/agents/custom_agent.py index 91bc03e5..590ab58b 100644 --- a/prediction_market_agent/agents/custom_agent.py +++ b/prediction_market_agent/agents/custom_agent.py @@ -2,6 +2,7 @@ from typing import Optional import requests +from loguru import logger from prediction_market_agent_tooling.markets.agent_market import AgentMarket from prediction_market_agent_tooling.tools.utils import ( check_not_none, @@ -62,9 +63,9 @@ def __init__(self, model: AbstractAiChatModel, max_cycles: int, verbose: bool): )(web_scrape_structured_and_summarized) self.model = model - def verbose_print(self, message: str) -> None: + def verbose_log(self, message: str) -> None: if self.verbose: - print(f"{message}\n") + logger.info(f"{message}\n") def answer_binary_market(self, market: AgentMarket) -> bool: cycle_count = 0 @@ -78,7 +79,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: cycle_count += 1 if cycle_count == self.max_cycles - 1: # If we reached the maximum number of cycles, ask to provide an answer based on available information. - self.verbose_print( + self.verbose_log( f"Agent: Reached {cycle_count} cycles, asking to provide answer now." ) messages.append( @@ -97,7 +98,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: completion_str = check_not_none( self.model.complete(messages), "Couldn't complete the prompt." ) - self.verbose_print(f"Completion: {completion_str}") + self.verbose_log(f"Completion: {completion_str}") try: completion_dict = json.loads(completion_str) except json.decoder.JSONDecodeError: @@ -108,7 +109,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: # - tool_name: Name of the tool to be used. # - answer: Final answer to the question. if thinking := completion_dict.get("thinking"): - self.verbose_print(f"Agent: Thinking about {thinking=}.") + self.verbose_log(f"Agent: Thinking about {thinking=}.") messages.append( Message( role="assistant", content=json.dumps({"thinking": thinking}) @@ -117,7 +118,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: elif tool_name := completion_dict.get("tool_name"): tool_params = completion_dict.get("tool_params") - self.verbose_print(f"Agent: Using {tool_name=} with {tool_params=}.") + self.verbose_log(f"Agent: Using {tool_name=} with {tool_params=}.") tool_output = ( # type: ignore # Untyped for the sake of simplicity when the LLM is used. self.google_search if tool_name == "GoogleSearchTool" @@ -129,7 +130,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: )( **tool_params ) - self.verbose_print(f"Tool: {tool_name=} returns {tool_output=}.") + self.verbose_log(f"Tool: {tool_name=} returns {tool_output=}.") messages.append( Message( role="assistant", @@ -140,7 +141,7 @@ def answer_binary_market(self, market: AgentMarket) -> bool: ) elif answer := completion_dict.get("answer"): - self.verbose_print(f"Agent: Answering {answer=}.") + self.verbose_log(f"Agent: Answering {answer=}.") messages.append( Message(role="assistant", content=json.dumps({"answer": answer})) ) diff --git a/prediction_market_agent/agents/known_outcome_agent/benchmark.py b/prediction_market_agent/agents/known_outcome_agent/benchmark.py index 5fe9008b..d5fbbb8c 100644 --- a/prediction_market_agent/agents/known_outcome_agent/benchmark.py +++ b/prediction_market_agent/agents/known_outcome_agent/benchmark.py @@ -3,6 +3,7 @@ from datetime import timedelta from dotenv import load_dotenv +from loguru import logger from prediction_market_agent_tooling.benchmark.agents import AbstractBenchmarkedAgent from prediction_market_agent_tooling.benchmark.benchmark import Benchmarker from prediction_market_agent_tooling.benchmark.utils import ( @@ -62,7 +63,9 @@ def predict(self, market_question: str) -> Prediction: question=market_question, max_tries=self.max_tries, ) - print(f"Answered {market_question=} with {answer.result=}, {answer.reasoning=}") + logger.info( + f"Answered {market_question=} with {answer.result=}, {answer.reasoning=}" + ) if not answer.has_known_result(): return Prediction( is_predictable=False, @@ -161,7 +164,7 @@ def predict(self, market_question: str) -> Prediction: output = f"./known_outcome_agent_benchmark_report.{int(time.time())}.md" with open(output, "w") as f: - print(f"Writing benchmark report to: {output}") + logger.info(f"Writing benchmark report to: {output}") f.write(md) # Check all predictions are correct, i.e. mean-squared-error == 0 diff --git a/prediction_market_agent/agents/known_outcome_agent/deploy.py b/prediction_market_agent/agents/known_outcome_agent/deploy.py index ed85667f..625282d3 100644 --- a/prediction_market_agent/agents/known_outcome_agent/deploy.py +++ b/prediction_market_agent/agents/known_outcome_agent/deploy.py @@ -2,6 +2,7 @@ import random from decimal import Decimal +from loguru import logger from prediction_market_agent_tooling.config import APIKeys from prediction_market_agent_tooling.deploy.agent import DeployableAgent from prediction_market_agent_tooling.deploy.constants import OWNER_KEY @@ -40,17 +41,17 @@ def pick_markets(self, markets: list[AgentMarket]) -> list[AgentMarket]: "This agent only supports predictions on Omen markets" ) - print(f"Looking at market {market.id=} {market.question=}") + logger.info(f"Looking at market {market.id=} {market.question=}") # Assume very high probability markets are already known, and have # been correctly bet on, and therefore the value of betting on them # is low. if market_is_saturated(market=market): - print( + logger.info( f"Skipping market {market.id=} {market.question=}, because it is already saturated." ) elif market.get_liquidity_in_xdai() < 5: - print( + logger.info( f"Skipping market {market.id=} {market.question=}, because it has insufficient liquidity." ) else: @@ -77,12 +78,12 @@ def answer_binary_market(self, market: AgentMarket) -> bool | None: max_tries=3, ) except Exception as e: - print( - f"Error: Failed to predict market {market.id=} {market.question=}: {e}" + logger.error( + f"Failed to predict market {market.id=} {market.question=}: {e}" ) answer = None if answer and answer.has_known_result(): - print( + logger.info( f"Picking market {market.id=} {market.question=} with answer {answer.result=}" ) return answer.result.to_boolean() diff --git a/prediction_market_agent/agents/known_outcome_agent/known_outcome_agent.py b/prediction_market_agent/agents/known_outcome_agent/known_outcome_agent.py index 8389abaf..795ea6cc 100644 --- a/prediction_market_agent/agents/known_outcome_agent/known_outcome_agent.py +++ b/prediction_market_agent/agents/known_outcome_agent/known_outcome_agent.py @@ -5,6 +5,7 @@ from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI +from loguru import logger from prediction_market_agent_tooling.tools.utils import utcnow from pydantic import BaseModel @@ -195,7 +196,9 @@ def has_question_event_happened_in_the_past(model: str, question: str) -> bool: if parsed_answer == 1: return True except Exception as e: - print("Exception occured, cannot assert if title happened in the past. ", e) + logger.error( + "Exception occured, cannot assert if title happened in the past. ", e + ) return False @@ -214,9 +217,9 @@ def get_known_outcome(model: str, question: str, max_tries: int) -> Answer: search_prompt = ChatPromptTemplate.from_template( template=GENERATE_SEARCH_QUERY_PROMPT ).format_messages(date_str=date_str, question=question) - print(f"Invoking LLM for {search_prompt=}") + logger.debug(f"Invoking LLM for {search_prompt=}") search_query = str(llm.invoke(search_prompt).content).strip('"') - print(f"Searching for {search_query=}") + logger.debug(f"Searching for {search_query=}") search_results = web_search(query=search_query, max_results=5) if not search_results: raise ValueError("No search results found.") diff --git a/prediction_market_agent/tools/web_scrape/markdown.py b/prediction_market_agent/tools/web_scrape/markdown.py index 6a7dbd72..6c5cdd66 100644 --- a/prediction_market_agent/tools/web_scrape/markdown.py +++ b/prediction_market_agent/tools/web_scrape/markdown.py @@ -1,6 +1,7 @@ import requests import tenacity from bs4 import BeautifulSoup +from loguru import logger from markdownify import markdownify from prediction_market_agent_tooling.tools.cache import persistent_inmemory_cache from requests import Response @@ -45,9 +46,9 @@ def web_scrape(url: str, timeout: int = 10) -> str: return text else: - print("Non-HTML content received") + logger.warning("Non-HTML content received") return "" except requests.RequestException as e: - print(f"HTTP request failed: {e}") + logger.error(f"HTTP request failed: {e}") return ""