Tbaberca commited on
Commit
a6c3a18
·
verified ·
1 Parent(s): 8396721

Update Gradio_UI.py

Browse files
Files changed (1) hide show
  1. Gradio_UI.py +181 -41
Gradio_UI.py CHANGED
@@ -1,51 +1,191 @@
1
- def upload_file(
2
- self,
3
- file,
4
- file_uploads_log,
5
- allowed_file_types=[
6
- "application/pdf",
7
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
8
- "text/plain",
9
- ],
10
- ):
11
- """
12
- Handle file uploads, default allowed types are .pdf, .docx, and .txt
13
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  import gradio as gr
15
 
16
- if file is None:
17
- return gr.Textbox("No file uploaded", visible=True), file_uploads_log
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- try:
20
- mime_type, _ = mimetypes.guess_type(file.name)
21
- except Exception as e:
22
- return gr.Textbox(f"Error: {e}", visible=True), file_uploads_log
23
 
24
- if mime_type not in allowed_file_types:
25
- return gr.Textbox("File type disallowed", visible=True), file_uploads_log
 
 
26
 
27
- # Sanitize file name
28
- original_name = os.path.basename(file.name)
29
- sanitized_name = re.sub(r"[^\w\-.]", "_", original_name)
30
 
31
- # Map mime type to extension
32
- type_to_ext = {}
33
- for ext, t in mimetypes.types_map.items():
34
- if t not in type_to_ext:
35
- type_to_ext[t] = ext
36
 
37
- name_without_ext = ".".join(sanitized_name.split(".")[:-1])
38
- ext = type_to_ext.get(mime_type, "")
39
- if not ext.startswith("."):
40
- ext = "." + ext if ext else ""
41
- sanitized_name = f"{name_without_ext}{ext}"
42
 
43
- # Save file
44
- file_path = os.path.join(self.file_upload_folder, sanitized_name)
45
- with open(file_path, "wb") as f:
46
- f.write(file.read())
 
47
 
48
- # Update log or return success message
49
- file_uploads_log.append(file_path)
50
- return gr.Textbox(f"File uploaded: {sanitized_name}", visible=True), file_uploads_log
51
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ # Copyright 2024 The HuggingFace Inc. team. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ import mimetypes
18
+ import os
19
+ import re
20
+ from typing import Optional
21
+
22
+ from smolagents.agent_types import AgentAudio, AgentImage, AgentText, handle_agent_output_types
23
+ from smolagents.agents import ActionStep
24
+ from smolagents.memory import MemoryStep
25
+ from smolagents.utils import _is_package_available
26
+
27
+
28
+ def pull_messages_from_step(step_log: MemoryStep):
29
  import gradio as gr
30
 
31
+ if isinstance(step_log, ActionStep):
32
+ step_number = f"Step {step_log.step_number}" if step_log.step_number is not None else ""
33
+ yield gr.ChatMessage(role="assistant", content=f"**{step_number}**")
34
+
35
+ if hasattr(step_log, "model_output") and step_log.model_output is not None:
36
+ model_output = step_log.model_output.strip()
37
+ model_output = re.sub(r"```\s*<end_code>", "```", model_output)
38
+ model_output = re.sub(r"<end_code>\s*```", "```", model_output)
39
+ model_output = re.sub(r"```\s*\n\s*<end_code>", "```", model_output)
40
+ model_output = model_output.strip()
41
+ yield gr.ChatMessage(role="assistant", content=model_output)
42
+
43
+ if hasattr(step_log, "tool_calls") and step_log.tool_calls is not None:
44
+ first_tool_call = step_log.tool_calls[0]
45
+ used_code = first_tool_call.name == "python_interpreter"
46
+ parent_id = f"call_{len(step_log.tool_calls)}"
47
+ args = first_tool_call.arguments
48
+ content = str(args.get("answer", str(args))) if isinstance(args, dict) else str(args).strip()
49
+
50
+ if used_code:
51
+ content = re.sub(r"```.*?\n", "", content)
52
+ content = re.sub(r"\s*<end_code>\s*", "", content).strip()
53
+ if not content.startswith("```python"):
54
+ content = f"```python\n{content}\n```"
55
+
56
+ parent_message_tool = gr.ChatMessage(
57
+ role="assistant",
58
+ content=content,
59
+ metadata={"title": f"🛠️ Used tool {first_tool_call.name}", "id": parent_id, "status": "pending"},
60
+ )
61
+ yield parent_message_tool
62
+
63
+ if hasattr(step_log, "observations") and step_log.observations and step_log.observations.strip():
64
+ log_content = step_log.observations.strip()
65
+ log_content = re.sub(r"^Execution logs:\s*", "", log_content)
66
+ yield gr.ChatMessage(
67
+ role="assistant",
68
+ content=log_content,
69
+ metadata={"title": "📝 Execution Logs", "parent_id": parent_id, "status": "done"},
70
+ )
71
+
72
+ if hasattr(step_log, "error") and step_log.error is not None:
73
+ yield gr.ChatMessage(
74
+ role="assistant",
75
+ content=str(step_log.error),
76
+ metadata={"title": "💥 Error", "parent_id": parent_id, "status": "done"},
77
+ )
78
+
79
+ parent_message_tool.metadata["status"] = "done"
80
+
81
+ elif hasattr(step_log, "error") and step_log.error is not None:
82
+ yield gr.ChatMessage(role="assistant", content=str(step_log.error), metadata={"title": "💥 Error"})
83
+
84
+ step_footnote = f"{step_number}"
85
+ if hasattr(step_log, "input_token_count") and hasattr(step_log, "output_token_count"):
86
+ token_str = (
87
+ f" | Input-tokens:{step_log.input_token_count:,} | Output-tokens:{step_log.output_token_count:,}"
88
+ )
89
+ step_footnote += token_str
90
+ if hasattr(step_log, "duration"):
91
+ duration = round(float(step_log.duration), 2)
92
+ step_footnote += f" | Duration: {duration}"
93
+
94
+ step_footnote = f"""<span style="color: #bbbbc2; font-size: 12px;">{step_footnote}</span> """
95
+ yield gr.ChatMessage(role="assistant", content=step_footnote)
96
+ yield gr.ChatMessage(role="assistant", content="-----")
97
+
98
+
99
+ def stream_to_gradio(agent, task: str, reset_agent_memory: bool = False, additional_args: Optional[dict] = None):
100
+ if not _is_package_available("gradio"):
101
+ raise ModuleNotFoundError(
102
+ "Please install 'gradio' extra to use the GradioUI: `pip install 'smolagents[gradio]'`"
103
+ )
104
+
105
+ import gradio as gr
106
+ total_input_tokens = 0
107
+ total_output_tokens = 0
108
+
109
+ for step_log in agent.run(task, stream=True, reset=reset_agent_memory, additional_args=additional_args):
110
+ if hasattr(agent.model, "last_input_token_count"):
111
+ total_input_tokens += agent.model.last_input_token_count
112
+ total_output_tokens += agent.model.last_output_token_count
113
+ if isinstance(step_log, ActionStep):
114
+ step_log.input_token_count = agent.model.last_input_token_count
115
+ step_log.output_token_count = agent.model.last_output_token_count
116
+
117
+ for message in pull_messages_from_step(step_log):
118
+ yield message
119
+
120
+ final_answer = handle_agent_output_types(step_log)
121
+
122
+ import gradio as gr
123
+ if isinstance(final_answer, AgentText):
124
+ yield gr.ChatMessage(role="assistant", content=f"**Final answer:**\n{final_answer.to_string()}\n")
125
+ elif isinstance(final_answer, AgentImage):
126
+ yield gr.ChatMessage(role="assistant", content={"path": final_answer.to_string(), "mime_type": "image/png"})
127
+ elif isinstance(final_answer, AgentAudio):
128
+ yield gr.ChatMessage(role="assistant", content={"path": final_answer.to_string(), "mime_type": "audio/wav"})
129
+ else:
130
+ yield gr.ChatMessage(role="assistant", content=f"**Final answer:** {str(final_answer)}")
131
+
132
+
133
+ class GradioUI:
134
+ def __init__(self, agent, file_upload_folder: str = "./uploads"):
135
+ self.agent = agent
136
+ self.file_upload_folder = file_upload_folder
137
+ if not os.path.exists(self.file_upload_folder):
138
+ os.makedirs(self.file_upload_folder)
139
+
140
+ def interact_with_agent(self, prompt, messages):
141
+ import gradio as gr
142
+ messages.append(gr.ChatMessage(role="user", content=prompt))
143
+ yield messages
144
+ for msg in stream_to_gradio(self.agent, task=prompt, reset_agent_memory=False):
145
+ messages.append(msg)
146
+ yield messages
147
+ yield messages
148
+
149
+ def upload_file(
150
+ self,
151
+ file,
152
+ file_uploads_log,
153
+ allowed_file_types=[
154
+ "application/pdf",
155
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
156
+ "text/plain",
157
+ ],
158
+ ):
159
+ import gradio as gr
160
 
161
+ if file is None:
162
+ return gr.Textbox("No file uploaded", visible=True), file_uploads_log
 
 
163
 
164
+ try:
165
+ mime_type, _ = mimetypes.guess_type(file.name)
166
+ except Exception as e:
167
+ return gr.Textbox(f"Error: {e}", visible=True), file_uploads_log
168
 
169
+ if mime_type not in allowed_file_types:
170
+ return gr.Textbox("File type disallowed", visible=True), file_uploads_log
 
171
 
172
+ original_name = os.path.basename(file.name)
173
+ sanitized_name = re.sub(r"[^\w\-.]", "_", original_name)
 
 
 
174
 
175
+ type_to_ext = {}
176
+ for ext, t in mimetypes.types_map.items():
177
+ if t not in type_to_ext:
178
+ type_to_ext[t] = ext
 
179
 
180
+ name_without_ext = ".".join(sanitized_name.split(".")[:-1])
181
+ ext = type_to_ext.get(mime_type, "")
182
+ if not ext.startswith("."):
183
+ ext = "." + ext if ext else ""
184
+ sanitized_name = f"{name_without_ext}{ext}"
185
 
186
+ file_path = os.path.join(self.file_upload_folder, sanitized_name)
187
+ with open(file_path, "wb") as f:
188
+ f.write(file.read())
189
 
190
+ file_uploads_log.append(file_path)
191
+ return gr.Textbox(f"File uploaded: {sanitized_name}", visible=True), file_uploads_log