XanderJC commited on
Commit
ed23622
Β·
1 Parent(s): 51f6814
src/proxy_lite/logger.py CHANGED
@@ -1,5 +1,7 @@
 
1
  import logging
2
  import sys
 
3
  from typing import Literal
4
  from uuid import uuid4
5
 
@@ -7,6 +9,29 @@ from rich.logging import RichHandler
7
 
8
 
9
  class StructuredLogger(logging.Logger):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  def _log(
11
  self,
12
  level,
@@ -31,6 +56,7 @@ class StructuredLogger(logging.Logger):
31
  json_fields["exception_message"] = str(exc_value)
32
 
33
  json_fields.update(extra)
 
34
  super()._log(
35
  level,
36
  msg,
@@ -50,32 +76,31 @@ def create_logger(
50
  unique_name = f"{name}-{str(uuid4())[:8]}"
51
  logger = logging.getLogger(unique_name)
52
  logger.setLevel(level)
53
- handler = RichHandler(
 
 
54
  rich_tracebacks=True,
55
  markup=True,
56
  show_path=False,
57
  show_time=False,
58
  log_time_format="[%s]",
59
  )
 
60
  if detailed_name:
61
- handler.setFormatter(logging.Formatter("%(name)s:\n%(message)s\n------"))
62
  else:
63
- handler.setFormatter(logging.Formatter("%(message)s\n------"))
64
- logger.addHandler(handler)
 
65
  logger.propagate = False
 
66
  return logger
67
 
68
 
69
  # Set StructuredLogger as the default logger class
70
  logging.setLoggerClass(StructuredLogger)
71
 
72
- logger = logging.getLogger(__name__)
73
- logger.setLevel(logging.INFO)
74
- logger.propagate = True
75
- handler = RichHandler(
76
- rich_tracebacks=True,
77
- markup=True,
78
- show_path=False,
79
- show_time=False,
80
- )
81
- logger.addHandler(handler)
 
1
+ import asyncio
2
  import logging
3
  import sys
4
+ import time # Added for time.sleep
5
  from typing import Literal
6
  from uuid import uuid4
7
 
 
9
 
10
 
11
  class StructuredLogger(logging.Logger):
12
+ def _stream_message_sync(self, message: str) -> None:
13
+ """Synchronous version of stream message to run in separate thread."""
14
+ try:
15
+ sys.stdout.write("\r") # Overwrite current line
16
+ for char in message:
17
+ sys.stdout.write(char)
18
+ sys.stdout.flush()
19
+ time.sleep(0.002) # Using regular sleep in thread
20
+ sys.stdout.write("\n")
21
+ except Exception:
22
+ pass
23
+
24
+ async def stream_message(self, message: str) -> None:
25
+ """Streams the message character by character in a separate thread."""
26
+ return await asyncio.to_thread(self._stream_message_sync, message)
27
+
28
+ # def info_stream(self, msg: str) -> Coroutine[Any, Any, None]:
29
+ # """Special method for streaming messages that returns a coroutine."""
30
+ # # Log the message normally first
31
+ # # self.info(msg)
32
+ # # Return the streaming coroutine
33
+ # return self.stream_message(msg)
34
+
35
  def _log(
36
  self,
37
  level,
 
56
  json_fields["exception_message"] = str(exc_value)
57
 
58
  json_fields.update(extra)
59
+
60
  super()._log(
61
  level,
62
  msg,
 
76
  unique_name = f"{name}-{str(uuid4())[:8]}"
77
  logger = logging.getLogger(unique_name)
78
  logger.setLevel(level)
79
+
80
+ # Standard RichHandler for structured logs
81
+ rich_handler = RichHandler(
82
  rich_tracebacks=True,
83
  markup=True,
84
  show_path=False,
85
  show_time=False,
86
  log_time_format="[%s]",
87
  )
88
+
89
  if detailed_name:
90
+ rich_handler.setFormatter(logging.Formatter("%(name)s:\n%(message)s"))
91
  else:
92
+ rich_handler.setFormatter(logging.Formatter("-----\n%(message)s"))
93
+
94
+ logger.addHandler(rich_handler)
95
  logger.propagate = False
96
+
97
  return logger
98
 
99
 
100
  # Set StructuredLogger as the default logger class
101
  logging.setLoggerClass(StructuredLogger)
102
 
103
+ # Initialize logger
104
+ logger = create_logger(__name__, level="INFO")
105
+
106
+ stream_logger = create_logger(__name__, level="INFO", detailed_name=False)
 
 
 
 
 
 
src/proxy_lite/solvers/simple_solver.py CHANGED
@@ -2,7 +2,7 @@
2
  import json
3
  import re
4
  from functools import cached_property
5
- from typing import Literal, Optional
6
 
7
  from proxy_lite.agents import AgentConfigTypes, Agents, BaseAgent
8
  from proxy_lite.environments.environment_base import Action, Observation
@@ -27,6 +27,7 @@ class SimpleSolverConfig(BaseSolverConfig):
27
  class SimpleSolver(BaseSolver):
28
  task: Optional[str] = None
29
  complete: bool = False
 
30
 
31
  @cached_property
32
  def tools(self) -> list[Tool]:
@@ -81,13 +82,17 @@ class SimpleSolver(BaseSolver):
81
  observation_match = re.search(r"<observation>(.*?)</observation>", text_content, re.DOTALL)
82
  observation_content = observation_match.group(1).strip() if observation_match else ""
83
 
84
- self.logger.info(f"🌐 [bold blue]Observation:[/] {observation_content}")
 
 
85
 
86
  # Extract text between thinking tags if present
87
  thinking_match = re.search(r"<thinking>(.*?)</thinking>", text_content, re.DOTALL)
88
  thinking_content = thinking_match.group(1).strip() if thinking_match else text_content
89
 
90
- self.logger.info(f"πŸ€– [bold purple]Action:[/] {thinking_content}")
 
 
91
 
92
  return Action(tool_calls=message.tool_calls, text=text_content)
93
 
 
2
  import json
3
  import re
4
  from functools import cached_property
5
+ from typing import Any, Coroutine, Literal, Optional
6
 
7
  from proxy_lite.agents import AgentConfigTypes, Agents, BaseAgent
8
  from proxy_lite.environments.environment_base import Action, Observation
 
27
  class SimpleSolver(BaseSolver):
28
  task: Optional[str] = None
29
  complete: bool = False
30
+ coroutines: list[Coroutine[Any, Any, None]] = []
31
 
32
  @cached_property
33
  def tools(self) -> list[Tool]:
 
82
  observation_match = re.search(r"<observation>(.*?)</observation>", text_content, re.DOTALL)
83
  observation_content = observation_match.group(1).strip() if observation_match else ""
84
 
85
+ self.logger.info("🌐 [bold blue]Observation:[/]")
86
+ # await self.logger.stream_message(observation_content)
87
+ self.logger._stream_message_sync(observation_content)
88
 
89
  # Extract text between thinking tags if present
90
  thinking_match = re.search(r"<thinking>(.*?)</thinking>", text_content, re.DOTALL)
91
  thinking_content = thinking_match.group(1).strip() if thinking_match else text_content
92
 
93
+ self.logger.info("🧠 [bold purple]Thinking:[/]")
94
+ # await self.logger.stream_message(thinking_content)
95
+ self.logger._stream_message_sync(thinking_content)
96
 
97
  return Action(tool_calls=message.tool_calls, text=text_content)
98