Charles Azam commited on
Commit
892c58b
·
1 Parent(s): 1a1c419

clean: run linting and formating on repo

Browse files
gradio_app.py CHANGED
@@ -4,12 +4,12 @@ from deepengineer.common_path import DATA_DIR
4
 
5
  with gr.Blocks() as demo:
6
  gr.Markdown("# Agent Interface with Real‑Time Tool Logging")
7
- user_input = gr.Textbox(label="User Message")
8
-
9
  log_output = gr.Textbox(label="Tool Invocation Log", interactive=False)
10
-
11
  agent_output = gr.Markdown(
12
- label="Agent Response",
13
  )
14
 
15
  send = gr.Button("Send")
 
4
 
5
  with gr.Blocks() as demo:
6
  gr.Markdown("# Agent Interface with Real‑Time Tool Logging")
7
+ user_input = gr.Textbox(label="User Message")
8
+
9
  log_output = gr.Textbox(label="Tool Invocation Log", interactive=False)
10
+
11
  agent_output = gr.Markdown(
12
+ label="Agent Response",
13
  )
14
 
15
  send = gr.Button("Send")
src/deepengineer/backend/gradio_tools.py CHANGED
@@ -15,14 +15,14 @@ def parse_markdown_images(markdown_text: str, image_dir: Path) -> str:
15
  if not markdown_text or not image_dir:
16
  return markdown_text
17
 
18
- image_pattern = r'!\[([^\]]*)\]\(([^)]+)\)'
19
 
20
  def replace_image_path(match):
21
  alt_text = match.group(1)
22
  image_name = match.group(2)
23
  # Always use image_dir/image_name
24
- new_path = "gradio_api/file="+str(Path(image_dir) / image_name)
25
- return f'![{alt_text}]({new_path})'
26
 
27
  return re.sub(image_pattern, replace_image_path, markdown_text)
28
 
@@ -37,7 +37,7 @@ def run_agent_stream(user_input: str):
37
  Yields tuples: (agent_output, log_output)
38
  """
39
  log_queue = queue.Queue()
40
-
41
  # empty queue before each run
42
  while not log_queue.empty():
43
  print("Emptying log queue")
@@ -47,7 +47,9 @@ def run_agent_stream(user_input: str):
47
  done = threading.Event()
48
 
49
  def _worker():
50
- answer_container["text"], answer_container["image_dir"] = main_search(user_input, log_queue)
 
 
51
  done.set()
52
 
53
  threading.Thread(target=_worker, daemon=True).start()
@@ -70,13 +72,13 @@ def run_agent_stream(user_input: str):
70
  # Process the final answer to include images
71
  final_answer = answer_container["text"]
72
  image_dir = answer_container["image_dir"]
73
-
74
  if final_answer and image_dir:
75
  final_answer = parse_markdown_images(final_answer, image_dir)
76
-
77
  final_answer = final_answer.replace("```python", "")
78
  final_answer = final_answer.replace("```markdown", "")
79
  final_answer = final_answer.replace("```", "")
80
 
81
  # final yield: agent_output filled with processed markdown, log_output frozen
82
- yield (final_answer, log_buffer.rstrip())
 
15
  if not markdown_text or not image_dir:
16
  return markdown_text
17
 
18
+ image_pattern = r"!\[([^\]]*)\]\(([^)]+)\)"
19
 
20
  def replace_image_path(match):
21
  alt_text = match.group(1)
22
  image_name = match.group(2)
23
  # Always use image_dir/image_name
24
+ new_path = "gradio_api/file=" + str(Path(image_dir) / image_name)
25
+ return f"![{alt_text}]({new_path})"
26
 
27
  return re.sub(image_pattern, replace_image_path, markdown_text)
28
 
 
37
  Yields tuples: (agent_output, log_output)
38
  """
39
  log_queue = queue.Queue()
40
+
41
  # empty queue before each run
42
  while not log_queue.empty():
43
  print("Emptying log queue")
 
47
  done = threading.Event()
48
 
49
  def _worker():
50
+ answer_container["text"], answer_container["image_dir"] = main_search(
51
+ user_input, log_queue
52
+ )
53
  done.set()
54
 
55
  threading.Thread(target=_worker, daemon=True).start()
 
72
  # Process the final answer to include images
73
  final_answer = answer_container["text"]
74
  image_dir = answer_container["image_dir"]
75
+
76
  if final_answer and image_dir:
77
  final_answer = parse_markdown_images(final_answer, image_dir)
78
+
79
  final_answer = final_answer.replace("```python", "")
80
  final_answer = final_answer.replace("```markdown", "")
81
  final_answer = final_answer.replace("```", "")
82
 
83
  # final yield: agent_output filled with processed markdown, log_output frozen
84
+ yield (final_answer, log_buffer.rstrip())
src/deepengineer/deepsearch/main_agent.py CHANGED
@@ -25,9 +25,11 @@ def create_output_image_path(random_name_images: int | None = None):
25
  return output_image_path
26
 
27
 
28
-
29
  def create_main_search_agent(
30
- model_id="deepseek/deepseek-reasoner", database: DataBase | None = None, log_queue: queue.Queue | None = None, output_image_path: Path | None = None,
 
 
 
31
  ):
32
  """
33
  Simple agent that can search the web and answer the question. This is much faster and better for simple questions that do not require deep research.
@@ -36,20 +38,26 @@ def create_main_search_agent(
36
  model = LiteLLMModel(model_id=model_id)
37
  if database is None:
38
  database = DataBase()
39
-
40
  output_image_path = output_image_path or DATA_DIR / "images"
41
  output_image_path.mkdir(parents=True, exist_ok=True)
42
 
43
  # Web search and crawling tools
44
  WEB_SEARCH_TOOLS = [
45
- SearchTool(log_queue=log_queue,),
46
- ArxivSearchTool(log_queue=log_queue,),
47
- ScientificSearchTool(log_queue=log_queue,),
 
 
 
 
 
 
48
  GetTableOfContentsTool(log_queue=log_queue, database=database),
49
  GetMarkdownTool(log_queue=log_queue, database=database),
50
  GetPagesContentTool(log_queue=log_queue, database=database),
51
  FindInMarkdownTool(log_queue=log_queue, database=database),
52
- SaveMatplotlibFigTool(log_queue=log_queue,output_dir=output_image_path),
53
  ]
54
 
55
  search_agent = CodeAgent(
@@ -100,9 +108,13 @@ Failure or 'I cannot answer' or 'None found' will not be tolerated, success will
100
  Run verification steps if that's needed, you must make sure you find the correct answer! Here is the task:
101
  {task}
102
  """
103
- agent = create_main_search_agent(model_id="mistral/mistral-medium-latest", log_queue=log_queue, output_image_path=output_image_path)
 
 
 
 
104
  answer = agent.run(MAIN_PROMPT.format(task=task))
105
-
106
  return answer, output_image_path
107
 
108
 
 
25
  return output_image_path
26
 
27
 
 
28
  def create_main_search_agent(
29
+ model_id="deepseek/deepseek-reasoner",
30
+ database: DataBase | None = None,
31
+ log_queue: queue.Queue | None = None,
32
+ output_image_path: Path | None = None,
33
  ):
34
  """
35
  Simple agent that can search the web and answer the question. This is much faster and better for simple questions that do not require deep research.
 
38
  model = LiteLLMModel(model_id=model_id)
39
  if database is None:
40
  database = DataBase()
41
+
42
  output_image_path = output_image_path or DATA_DIR / "images"
43
  output_image_path.mkdir(parents=True, exist_ok=True)
44
 
45
  # Web search and crawling tools
46
  WEB_SEARCH_TOOLS = [
47
+ SearchTool(
48
+ log_queue=log_queue,
49
+ ),
50
+ ArxivSearchTool(
51
+ log_queue=log_queue,
52
+ ),
53
+ ScientificSearchTool(
54
+ log_queue=log_queue,
55
+ ),
56
  GetTableOfContentsTool(log_queue=log_queue, database=database),
57
  GetMarkdownTool(log_queue=log_queue, database=database),
58
  GetPagesContentTool(log_queue=log_queue, database=database),
59
  FindInMarkdownTool(log_queue=log_queue, database=database),
60
+ SaveMatplotlibFigTool(log_queue=log_queue, output_dir=output_image_path),
61
  ]
62
 
63
  search_agent = CodeAgent(
 
108
  Run verification steps if that's needed, you must make sure you find the correct answer! Here is the task:
109
  {task}
110
  """
111
+ agent = create_main_search_agent(
112
+ model_id="mistral/mistral-medium-latest",
113
+ log_queue=log_queue,
114
+ output_image_path=output_image_path,
115
+ )
116
  answer = agent.run(MAIN_PROMPT.format(task=task))
117
+
118
  return answer, output_image_path
119
 
120
 
src/deepengineer/deepsearch/main_deep_search.py CHANGED
@@ -1,4 +1,5 @@
1
  """work in progress"""
 
2
  from pathlib import Path
3
  import random
4
  from smolagents import CodeAgent, LiteLLMModel
@@ -7,11 +8,13 @@ from deepengineer.deepsearch.scawl_web_agent import create_web_search_agent
7
  from deepengineer.deepsearch.draw_agent import SaveMatplotlibFigTool
8
  from deepengineer.common_path import DATA_DIR
9
 
 
10
  def _create_output_image_path(image_folder_suffix: int | None = None):
11
  output_image_path = Path(DATA_DIR) / f"images_{image_folder_suffix}"
12
  output_image_path.mkdir(parents=True, exist_ok=True)
13
  return output_image_path
14
 
 
15
  def create_main_deep_search_agent(
16
  main_model_id="deepseek/deepseek-reasoner",
17
  web_search_model_id="deepseek/deepseek-reasoner",
@@ -25,10 +28,11 @@ def create_main_deep_search_agent(
25
  web_search_agent = create_web_search_agent(
26
  model_id=web_search_model_id, database=database
27
  )
28
-
29
-
30
  image_folder_suffix = random.randint(1000000, 9999999)
31
- output_image_path = _create_output_image_path(image_folder_suffix=image_folder_suffix)
 
 
32
 
33
  manager_agent = CodeAgent(
34
  model=main_model,
@@ -83,4 +87,4 @@ Run verification steps if that's needed, you must make sure you find the correct
83
 
84
  answer = agent.run(MAIN_PROMPT.format(task=task))
85
 
86
- print(answer)
 
1
  """work in progress"""
2
+
3
  from pathlib import Path
4
  import random
5
  from smolagents import CodeAgent, LiteLLMModel
 
8
  from deepengineer.deepsearch.draw_agent import SaveMatplotlibFigTool
9
  from deepengineer.common_path import DATA_DIR
10
 
11
+
12
  def _create_output_image_path(image_folder_suffix: int | None = None):
13
  output_image_path = Path(DATA_DIR) / f"images_{image_folder_suffix}"
14
  output_image_path.mkdir(parents=True, exist_ok=True)
15
  return output_image_path
16
 
17
+
18
  def create_main_deep_search_agent(
19
  main_model_id="deepseek/deepseek-reasoner",
20
  web_search_model_id="deepseek/deepseek-reasoner",
 
28
  web_search_agent = create_web_search_agent(
29
  model_id=web_search_model_id, database=database
30
  )
31
+
 
32
  image_folder_suffix = random.randint(1000000, 9999999)
33
+ output_image_path = _create_output_image_path(
34
+ image_folder_suffix=image_folder_suffix
35
+ )
36
 
37
  manager_agent = CodeAgent(
38
  model=main_model,
 
87
 
88
  answer = agent.run(MAIN_PROMPT.format(task=task))
89
 
90
+ print(answer)
src/deepengineer/deepsearch/scawl_web_agent.py CHANGED
@@ -20,6 +20,7 @@ from deepengineer.webcrawler.pdf_utils import (
20
  from deepengineer.logging_tools import LoggingTool
21
  import queue
22
 
 
23
  class ToolNames(Enum):
24
  # Search tools
25
  SEARCH_TOOL = "web_search_tool"
@@ -54,7 +55,7 @@ class SearchTool(LoggingTool):
54
  },
55
  }
56
  output_type = "object"
57
-
58
  def __init__(self, log_queue: queue.Queue | None = None):
59
  super().__init__(log_queue=log_queue)
60
 
@@ -80,7 +81,7 @@ class ArxivSearchTool(LoggingTool):
80
  }
81
  }
82
  output_type = "object"
83
-
84
  def __init__(self, log_queue: queue.Queue | None = None):
85
  super().__init__(log_queue=log_queue)
86
 
@@ -102,7 +103,7 @@ class PubmedSearchTool(LoggingTool):
102
  }
103
  }
104
  output_type = "object"
105
-
106
  def __init__(self, log_queue: queue.Queue | None = None):
107
  super().__init__(log_queue=log_queue)
108
 
@@ -225,7 +226,9 @@ class FindInMarkdownTool(LoggingTool):
225
 
226
 
227
  def create_web_search_agent(
228
- model_id="deepseek/deepseek-reasoner", database: DataBase | None = None, log_queue: queue.Queue | None = None
 
 
229
  ):
230
  """Create a web search agent with search, crawling, and PDF analysis capabilities."""
231
 
 
20
  from deepengineer.logging_tools import LoggingTool
21
  import queue
22
 
23
+
24
  class ToolNames(Enum):
25
  # Search tools
26
  SEARCH_TOOL = "web_search_tool"
 
55
  },
56
  }
57
  output_type = "object"
58
+
59
  def __init__(self, log_queue: queue.Queue | None = None):
60
  super().__init__(log_queue=log_queue)
61
 
 
81
  }
82
  }
83
  output_type = "object"
84
+
85
  def __init__(self, log_queue: queue.Queue | None = None):
86
  super().__init__(log_queue=log_queue)
87
 
 
103
  }
104
  }
105
  output_type = "object"
106
+
107
  def __init__(self, log_queue: queue.Queue | None = None):
108
  super().__init__(log_queue=log_queue)
109
 
 
226
 
227
 
228
  def create_web_search_agent(
229
+ model_id="deepseek/deepseek-reasoner",
230
+ database: DataBase | None = None,
231
+ log_queue: queue.Queue | None = None,
232
  ):
233
  """Create a web search agent with search, crawling, and PDF analysis capabilities."""
234
 
src/deepengineer/logging_tools.py CHANGED
@@ -2,14 +2,16 @@ import queue
2
  from typing import Any
3
  from smolagents import Tool
4
 
 
5
  class LoggingTool(Tool):
6
  """
7
  Base class for tools that can push logs to a queue.
8
  """
 
9
  def __init__(self, log_queue: queue.Queue | None = None):
10
  super().__init__()
11
  self.log_queue = log_queue
12
 
13
  def push_log(self, msg: str):
14
  if self.log_queue:
15
- self.log_queue.put(msg)
 
2
  from typing import Any
3
  from smolagents import Tool
4
 
5
+
6
  class LoggingTool(Tool):
7
  """
8
  Base class for tools that can push logs to a queue.
9
  """
10
+
11
  def __init__(self, log_queue: queue.Queue | None = None):
12
  super().__init__()
13
  self.log_queue = log_queue
14
 
15
  def push_log(self, msg: str):
16
  if self.log_queue:
17
+ self.log_queue.put(msg)
tests/deepsearch/test_main_agent.py CHANGED
@@ -15,6 +15,6 @@ def test_main_agent():
15
  main_search(
16
  task="""
17
  Search a paper called "High Energy Physics Opportunities Using Reactor Antineutrinos" on arXiv, download it and extract the table of contents
18
- """, log_queue=log_queue
 
19
  )
20
-
 
15
  main_search(
16
  task="""
17
  Search a paper called "High Energy Physics Opportunities Using Reactor Antineutrinos" on arXiv, download it and extract the table of contents
18
+ """,
19
+ log_queue=log_queue,
20
  )
 
tests/deepsearch/test_web_agent.py CHANGED
@@ -15,4 +15,3 @@ def test_run_web_search_agent():
15
  )
16
  is not None
17
  )
18
-
 
15
  )
16
  is not None
17
  )