Charles Azam commited on
Commit
0d89931
·
1 Parent(s): fe6be00

feat: add support for images

Browse files
data/images_4351840/nuclear_reactor_diagram.png ADDED
gradio_app.py CHANGED
@@ -1,21 +1,24 @@
1
  import gradio as gr
2
  from deepengineer.backend.gradio_tools import run_agent_stream
 
3
 
4
  with gr.Blocks() as demo:
5
  gr.Markdown("# Agent Interface with Real‑Time Tool Logging")
6
  user_input = gr.Textbox(label="User Message")
 
 
 
7
  agent_output = gr.Markdown(
8
  label="Agent Response",
9
  )
10
- log_output = gr.Textbox(label="Tool Invocation Log", interactive=False)
11
 
12
  send = gr.Button("Send")
13
  send.click(
14
  fn=run_agent_stream,
15
  inputs=[user_input],
16
- outputs=[log_output, agent_output],
17
  concurrency_limit=2,
18
  )
19
 
20
  if __name__ == "__main__":
21
- demo.launch()
 
1
  import gradio as gr
2
  from deepengineer.backend.gradio_tools import run_agent_stream
3
+ 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")
16
  send.click(
17
  fn=run_agent_stream,
18
  inputs=[user_input],
19
+ outputs=[agent_output, log_output],
20
  concurrency_limit=2,
21
  )
22
 
23
  if __name__ == "__main__":
24
+ demo.launch(allowed_paths=[DATA_DIR])
src/deepengineer/backend/gradio_tools.py CHANGED
@@ -10,45 +10,20 @@ from deepengineer.common_path import DATA_DIR
10
 
11
  def parse_markdown_images(markdown_text: str, image_dir: Path) -> str:
12
  """
13
- Parse markdown text and convert image references to absolute file paths
14
- that Gradio can display.
15
-
16
- Args:
17
- markdown_text: The markdown text containing image references
18
- image_dir: The directory containing the generated images
19
-
20
- Returns:
21
- Modified markdown text with absolute file paths for images
22
  """
23
  if not markdown_text or not image_dir:
24
  return markdown_text
25
-
26
- # Pattern to match markdown image syntax: ![alt text](image_path)
27
  image_pattern = r'!\[([^\]]*)\]\(([^)]+)\)'
28
-
29
  def replace_image_path(match):
30
  alt_text = match.group(1)
31
- image_path = match.group(2)
32
-
33
- # If the path is already absolute, return as is
34
- if Path(image_path).is_absolute():
35
- return f'![{alt_text}]({image_path})'
36
-
37
- # If it's a relative path, try to find it in the image directory
38
- if image_dir.exists():
39
- # Look for the image file in the image directory
40
- for img_file in image_dir.glob('*'):
41
- if img_file.name == Path(image_path).name:
42
- return f'![{alt_text}]({img_file.absolute()})'
43
-
44
- # If not found by name, try to find any image file
45
- image_files = list(image_dir.glob('*.png')) + list(image_dir.glob('*.jpg')) + list(image_dir.glob('*.jpeg'))
46
- if image_files:
47
- return f'![{alt_text}]({image_files[0].absolute()})'
48
-
49
- # If no image found, return the original reference
50
- return match.group(0)
51
-
52
  return re.sub(image_pattern, replace_image_path, markdown_text)
53
 
54
 
@@ -98,6 +73,10 @@ def run_agent_stream(user_input: str):
98
 
99
  if final_answer and image_dir:
100
  final_answer = parse_markdown_images(final_answer, image_dir)
 
 
 
 
101
 
102
  # final yield: agent_output filled with processed markdown, log_output frozen
103
  yield (final_answer, log_buffer.rstrip())
 
10
 
11
  def parse_markdown_images(markdown_text: str, image_dir: Path) -> str:
12
  """
13
+ Replace image references ![Title](image_name.png) with ![Title](image_dir/image_name.png)
 
 
 
 
 
 
 
 
14
  """
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 = 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
 
29
 
 
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())
src/deepengineer/deepsearch/main_agent.py CHANGED
@@ -18,8 +18,8 @@ from pathlib import Path
18
  import queue
19
 
20
 
21
- def create_output_image_path():
22
- random_name_images = random.randint(1000000, 9999999)
23
  output_image_path = Path(DATA_DIR) / f"images_{random_name_images}"
24
  output_image_path.mkdir(parents=True, exist_ok=True)
25
  return output_image_path
 
18
  import queue
19
 
20
 
21
+ def create_output_image_path(random_name_images: int | None = None):
22
+ random_name_images = random_name_images or random.randint(1000000, 9999999)
23
  output_image_path = Path(DATA_DIR) / f"images_{random_name_images}"
24
  output_image_path.mkdir(parents=True, exist_ok=True)
25
  return output_image_path
tests/backend/test_gradio_tools.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ from deepengineer.backend.gradio_tools import parse_markdown_images
3
+ from deepengineer.deepsearch.main_agent import create_output_image_path
4
+
5
+ markdown = """
6
+ # Nuclear Reactor: Structure and Components
7
+
8
+ A nuclear reactor is a complex system designed to initiate and control a sustained nuclear chain reaction. The primary purpose of a
9
+ nuclear reactor is to generate heat through nuclear fission, which is then used to produce electricity. Below is a detailed explanation
10
+ of the main components and their functions, along with a simplified diagram.
11
+
12
+ ## Simplified Diagram of a Nuclear Reactor
13
+
14
+ ![Simplified Diagram of a Nuclear Reactor](nuclear_reactor_diagram.png)
15
+
16
+ ## Main Components and Their Functions
17
+
18
+ ### 1. Reactor Core
19
+ The reactor core is the central part of the nuclear reactor where nuclear fission occurs. It contains:
20
+ - **Nuclear Fuel**: Typically uranium oxide pellets arranged in fuel rods.
21
+ - **Control Rods**: Made of materials like cadmium or boron, these rods absorb neutrons and regulate the fission rate.
22
+ - **Moderator**: A material (often water) that slows down neutrons to sustain the chain reaction.
23
+
24
+ ### 2. Pressure Vessel
25
+ A robust container that houses the reactor core and coolant under high pressure. It ensures the integrity and safety of the reactor core.
26
+
27
+ ### 3. Coolant
28
+ A fluid (usually water) that circulates through the core to absorb the heat generated by fission. The heated coolant is then used to
29
+ produce steam.
30
+
31
+ ### 4. Steam Generator
32
+ The heat from the coolant is transferred to a secondary water loop, which turns into steam. This steam is used to drive turbines.
33
+
34
+ ### 5. Turbine
35
+ The steam produced in the steam generator is directed onto the blades of a turbine, causing it to spin. The turbine is connected to a
36
+ generator, which produces electricity.
37
+
38
+ ### 6. Cooling Tower
39
+ Excess heat that is not converted into electricity is dissipated in the cooling tower. The cooling tower releases this heat into the
40
+ atmosphere.
41
+
42
+ ### 7. Containment Structure
43
+ A steel-reinforced concrete dome or enclosure that isolates the reactor from the environment. It is designed to contain any radioactive
44
+ materials and prevent their release.
45
+
46
+ ## How a Nuclear Reactor Works
47
+
48
+ 1. **Nuclear Fission**: In the reactor core, uranium atoms undergo fission, releasing a significant amount of heat energy.
49
+ 2. **Heat Transfer**: The coolant absorbs this heat and transfers it to the steam generator.
50
+ 3. **Steam Production**: In the steam generator, water is converted into steam using the heat from the coolant.
51
+ 4. **Electricity Generation**: The steam drives the turbine, which is connected to a generator, producing electricity.
52
+ 5. **Cooling**: Excess heat is dissipated in the cooling tower, and the cycle repeats.
53
+
54
+ ## Sources
55
+
56
+ - [World Nuclear Association - Nuclear Power
57
+ Reactors](https://world-nuclear.org/information-library/nuclear-fuel-cycle/nuclear-power-reactors/nuclear-power-reactors.aspx)
58
+ - [Britannica - Nuclear Reactor](https://www.britannica.com/technology/nuclear-reactor)
59
+ - [U.S. Department of Energy - How Does a Nuclear Reactor
60
+ Work?](https://www.energy.gov/ne/articles/nuclear-101-how-does-nuclear-reactor-work)
61
+ - [Wikipedia - Nuclear Reactor](https://en.wikipedia.org/wiki/Nuclear_reactor)
62
+ - [BYJU'S - Introduction to Nuclear Reactor](https://byjus.com/physics/nuclear-reactor-based-on-nuclear-fission/)
63
+
64
+ This simplified diagram and explanation provide a basic understanding of the structure and function of a nuclear reactor.
65
+ """
66
+
67
+
68
+ def test_parse_markdown_images():
69
+ image_dir = create_output_image_path(4351840)
70
+ real_image_path = image_dir / "nuclear_reactor_diagram.png"
71
+ output_image_path = "data/images_4351840/nuclear_reactor_diagram.png"
72
+ assert real_image_path.exists()
73
+ parsed_markdown = parse_markdown_images(markdown, image_dir)
74
+ assert output_image_path in parsed_markdown
75
+