Spaces:
Running
Running
crcdng
commited on
Commit
·
8702545
1
Parent(s):
9b1bc1b
camera
Browse files- Gradio_UI.py +133 -53
Gradio_UI.py
CHANGED
@@ -22,11 +22,17 @@ from typing import Optional
|
|
22 |
import datetime
|
23 |
import pytz
|
24 |
|
25 |
-
from smolagents.agent_types import
|
|
|
|
|
|
|
|
|
|
|
26 |
from smolagents.agents import ActionStep, MultiStepAgent
|
27 |
from smolagents.memory import MemoryStep
|
28 |
from smolagents.utils import _is_package_available
|
29 |
|
|
|
30 |
def get_current_time_in_timezone(timezone: str) -> str:
|
31 |
"""A tool that fetches the current local time in a specified timezone.
|
32 |
Args:
|
@@ -41,6 +47,7 @@ def get_current_time_in_timezone(timezone: str) -> str:
|
|
41 |
except Exception as e:
|
42 |
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
43 |
|
|
|
44 |
def pull_messages_from_step(
|
45 |
step_log: MemoryStep,
|
46 |
):
|
@@ -49,7 +56,9 @@ def pull_messages_from_step(
|
|
49 |
|
50 |
if isinstance(step_log, ActionStep):
|
51 |
# Output the step number
|
52 |
-
step_number =
|
|
|
|
|
53 |
yield gr.ChatMessage(role="assistant", content=f"**{step_number}**")
|
54 |
|
55 |
# First yield the thought/reasoning from the LLM
|
@@ -57,9 +66,15 @@ def pull_messages_from_step(
|
|
57 |
# Clean up the LLM output
|
58 |
model_output = step_log.model_output.strip()
|
59 |
# Remove any trailing <end_code> and extra backticks, handling multiple possible formats
|
60 |
-
model_output = re.sub(
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
model_output = model_output.strip()
|
64 |
yield gr.ChatMessage(role="assistant", content=model_output)
|
65 |
|
@@ -79,8 +94,12 @@ def pull_messages_from_step(
|
|
79 |
|
80 |
if used_code:
|
81 |
# Clean up the content by removing any end code tags
|
82 |
-
content = re.sub(
|
83 |
-
|
|
|
|
|
|
|
|
|
84 |
content = content.strip()
|
85 |
if not content.startswith("```python"):
|
86 |
content = f"```python\n{content}\n```"
|
@@ -106,7 +125,11 @@ def pull_messages_from_step(
|
|
106 |
yield gr.ChatMessage(
|
107 |
role="assistant",
|
108 |
content=f"{log_content}",
|
109 |
-
metadata={
|
|
|
|
|
|
|
|
|
110 |
)
|
111 |
|
112 |
# Nesting any errors under the tool call
|
@@ -114,7 +137,11 @@ def pull_messages_from_step(
|
|
114 |
yield gr.ChatMessage(
|
115 |
role="assistant",
|
116 |
content=str(step_log.error),
|
117 |
-
metadata={
|
|
|
|
|
|
|
|
|
118 |
)
|
119 |
|
120 |
# Update parent message metadata to done status without yielding a new message
|
@@ -122,17 +149,25 @@ def pull_messages_from_step(
|
|
122 |
|
123 |
# Handle standalone errors but not from tool calls
|
124 |
elif hasattr(step_log, "error") and step_log.error is not None:
|
125 |
-
yield gr.ChatMessage(
|
|
|
|
|
|
|
|
|
126 |
|
127 |
# Calculate duration and token information
|
128 |
step_footnote = f"{step_number}"
|
129 |
-
if hasattr(step_log, "input_token_count") and hasattr(
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
step_footnote += token_str
|
134 |
if hasattr(step_log, "duration"):
|
135 |
-
step_duration =
|
|
|
|
|
|
|
|
|
136 |
step_footnote += step_duration
|
137 |
step_footnote = f"""<span style="color: #bbbbc2; font-size: 12px;">{step_footnote}</span> """
|
138 |
yield gr.ChatMessage(role="assistant", content=f"{step_footnote}")
|
@@ -155,7 +190,9 @@ def stream_to_gradio(
|
|
155 |
total_input_tokens = 0
|
156 |
total_output_tokens = 0
|
157 |
|
158 |
-
for step_log in agent.run(
|
|
|
|
|
159 |
# Track tokens if model provides them
|
160 |
if hasattr(agent.model, "last_input_token_count"):
|
161 |
total_input_tokens += agent.model.last_input_token_count
|
@@ -188,7 +225,9 @@ def stream_to_gradio(
|
|
188 |
content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
|
189 |
)
|
190 |
else:
|
191 |
-
yield gr.ChatMessage(
|
|
|
|
|
192 |
|
193 |
|
194 |
class GradioUI:
|
@@ -258,10 +297,14 @@ class GradioUI:
|
|
258 |
sanitized_name = "".join(sanitized_name)
|
259 |
|
260 |
# Save the uploaded file to the specified folder
|
261 |
-
file_path = os.path.join(
|
|
|
|
|
262 |
shutil.copy(file.name, file_path)
|
263 |
|
264 |
-
return gr.Textbox(
|
|
|
|
|
265 |
|
266 |
def log_user_message(self, text_input, file_uploads_log):
|
267 |
return (
|
@@ -287,10 +330,13 @@ class GradioUI:
|
|
287 |
def launch(self, **kwargs):
|
288 |
import gradio as gr
|
289 |
|
290 |
-
with gr.Blocks(
|
291 |
-
|
292 |
-
|
293 |
-
|
|
|
|
|
|
|
294 |
<style>
|
295 |
@font-face {
|
296 |
font-family: Cyberpunk;
|
@@ -303,81 +349,115 @@ class GradioUI:
|
|
303 |
<h1 style='font-family: Cyberpunk; font-size: 42px;'> Your Cyberpunk Local Time Terminal </h1>
|
304 |
</center>
|
305 |
"""
|
306 |
-
)
|
307 |
|
308 |
-
description_html=
|
309 |
-
"""
|
310 |
<center><p style='font-size: 24px;'>
|
311 |
Welcome to ChronoCore-77, the bleeding-edge time terminal jacked straight into the neon veins of Night City. Whether you're dodging corpos, chasing edgerunner gigs, or just trying to sync your implant clock, I've got the local time locked and loaded. No glitches [OK a few...], no lag—just pure, precise chrono-data ripped straight from the grid. Stay sharp, choom. Time waits for no one.
|
312 |
</p></center>
|
313 |
"""
|
314 |
-
)
|
315 |
|
316 |
-
banner_html=
|
317 |
-
"""
|
318 |
<div class="cyber-banner-short bg-purple fg-white cyber-glitch-1">
|
319 |
<div style="margin-left: auto; width: 80%;" id="scroll-container">
|
320 |
<div id="scroll-text"> ---- Tannhäuser Gate Approved ---- Special Offer Today Only ----- Free Access Credits </div>
|
321 |
</div>
|
322 |
</div>
|
323 |
"""
|
324 |
-
)
|
325 |
|
326 |
with gr.Row():
|
327 |
-
title=gr.HTML(banner_html)
|
328 |
with gr.Row():
|
329 |
timer = gr.Timer(1)
|
330 |
gr.Textbox(render=False)
|
331 |
time_display = gr.Textbox(label="Time", elem_classes="cyber-glitch-4")
|
332 |
gr.Textbox(render=False)
|
333 |
import time
|
334 |
-
|
|
|
|
|
|
|
|
|
335 |
with gr.Row():
|
336 |
-
title=gr.HTML(title_html)
|
337 |
with gr.Row():
|
338 |
-
description=gr.HTML(description_html)
|
339 |
stored_messages = gr.State([])
|
340 |
file_uploads_log = gr.State([])
|
341 |
with gr.Row(equal_height=True):
|
342 |
chatbot = gr.Chatbot(
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
)
|
353 |
-
gr.Model3D("terminal.glb", display_mode= "wireframe", label="A view of the ChronoCore-77")
|
354 |
# If an upload folder is provided, enable the upload feature
|
355 |
if self.file_upload_folder is not None:
|
356 |
upload_file = gr.File(label="Upload a file")
|
357 |
-
upload_status = gr.Textbox(
|
|
|
|
|
358 |
upload_file.change(
|
359 |
self.upload_file,
|
360 |
[upload_file, file_uploads_log],
|
361 |
[upload_status, file_uploads_log],
|
362 |
)
|
363 |
with gr.Row(equal_height=True):
|
364 |
-
steps_input = gr.Slider(
|
|
|
|
|
365 |
steps_input.change(self.agent_set_steps, steps_input, None)
|
366 |
-
tools_list = gr.Dropdown(
|
|
|
|
|
|
|
|
|
|
|
367 |
# tools_list.select(self.agent_get_tools, None, tools_list)
|
368 |
reset = gr.Button(value="Reset ChronoCore-77")
|
369 |
reset.click(self.agent_reset, None, None)
|
370 |
-
text_input = gr.Textbox(
|
|
|
|
|
|
|
|
|
|
|
371 |
text_input.submit(
|
372 |
self.log_user_message,
|
373 |
[text_input, file_uploads_log],
|
374 |
[stored_messages, text_input],
|
375 |
).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
|
376 |
examples = gr.Examples(
|
377 |
-
examples=[
|
378 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
)
|
380 |
-
|
381 |
-
demo.launch(debug=True, share=True, ssr_mode=False, allowed_paths=["Cyberpunk.otf"], **kwargs)
|
382 |
|
383 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
import datetime
|
23 |
import pytz
|
24 |
|
25 |
+
from smolagents.agent_types import (
|
26 |
+
AgentAudio,
|
27 |
+
AgentImage,
|
28 |
+
AgentText,
|
29 |
+
handle_agent_output_types,
|
30 |
+
)
|
31 |
from smolagents.agents import ActionStep, MultiStepAgent
|
32 |
from smolagents.memory import MemoryStep
|
33 |
from smolagents.utils import _is_package_available
|
34 |
|
35 |
+
|
36 |
def get_current_time_in_timezone(timezone: str) -> str:
|
37 |
"""A tool that fetches the current local time in a specified timezone.
|
38 |
Args:
|
|
|
47 |
except Exception as e:
|
48 |
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
49 |
|
50 |
+
|
51 |
def pull_messages_from_step(
|
52 |
step_log: MemoryStep,
|
53 |
):
|
|
|
56 |
|
57 |
if isinstance(step_log, ActionStep):
|
58 |
# Output the step number
|
59 |
+
step_number = (
|
60 |
+
f"Step {step_log.step_number}" if step_log.step_number is not None else ""
|
61 |
+
)
|
62 |
yield gr.ChatMessage(role="assistant", content=f"**{step_number}**")
|
63 |
|
64 |
# First yield the thought/reasoning from the LLM
|
|
|
66 |
# Clean up the LLM output
|
67 |
model_output = step_log.model_output.strip()
|
68 |
# Remove any trailing <end_code> and extra backticks, handling multiple possible formats
|
69 |
+
model_output = re.sub(
|
70 |
+
r"```\s*<end_code>", "```", model_output
|
71 |
+
) # handles ```<end_code>
|
72 |
+
model_output = re.sub(
|
73 |
+
r"<end_code>\s*```", "```", model_output
|
74 |
+
) # handles <end_code>```
|
75 |
+
model_output = re.sub(
|
76 |
+
r"```\s*\n\s*<end_code>", "```", model_output
|
77 |
+
) # handles ```\n<end_code>
|
78 |
model_output = model_output.strip()
|
79 |
yield gr.ChatMessage(role="assistant", content=model_output)
|
80 |
|
|
|
94 |
|
95 |
if used_code:
|
96 |
# Clean up the content by removing any end code tags
|
97 |
+
content = re.sub(
|
98 |
+
r"```.*?\n", "", content
|
99 |
+
) # Remove existing code blocks
|
100 |
+
content = re.sub(
|
101 |
+
r"\s*<end_code>\s*", "", content
|
102 |
+
) # Remove end_code tags
|
103 |
content = content.strip()
|
104 |
if not content.startswith("```python"):
|
105 |
content = f"```python\n{content}\n```"
|
|
|
125 |
yield gr.ChatMessage(
|
126 |
role="assistant",
|
127 |
content=f"{log_content}",
|
128 |
+
metadata={
|
129 |
+
"title": "📝 Execution Logs",
|
130 |
+
"parent_id": parent_id,
|
131 |
+
"status": "done",
|
132 |
+
},
|
133 |
)
|
134 |
|
135 |
# Nesting any errors under the tool call
|
|
|
137 |
yield gr.ChatMessage(
|
138 |
role="assistant",
|
139 |
content=str(step_log.error),
|
140 |
+
metadata={
|
141 |
+
"title": "💥 Error",
|
142 |
+
"parent_id": parent_id,
|
143 |
+
"status": "done",
|
144 |
+
},
|
145 |
)
|
146 |
|
147 |
# Update parent message metadata to done status without yielding a new message
|
|
|
149 |
|
150 |
# Handle standalone errors but not from tool calls
|
151 |
elif hasattr(step_log, "error") and step_log.error is not None:
|
152 |
+
yield gr.ChatMessage(
|
153 |
+
role="assistant",
|
154 |
+
content=str(step_log.error),
|
155 |
+
metadata={"title": "💥 Error"},
|
156 |
+
)
|
157 |
|
158 |
# Calculate duration and token information
|
159 |
step_footnote = f"{step_number}"
|
160 |
+
if hasattr(step_log, "input_token_count") and hasattr(
|
161 |
+
step_log, "output_token_count"
|
162 |
+
):
|
163 |
+
token_str = f" | Input-tokens:{step_log.input_token_count:,} | Output-tokens:{step_log.output_token_count:,}"
|
164 |
step_footnote += token_str
|
165 |
if hasattr(step_log, "duration"):
|
166 |
+
step_duration = (
|
167 |
+
f" | Duration: {round(float(step_log.duration), 2)}"
|
168 |
+
if step_log.duration
|
169 |
+
else None
|
170 |
+
)
|
171 |
step_footnote += step_duration
|
172 |
step_footnote = f"""<span style="color: #bbbbc2; font-size: 12px;">{step_footnote}</span> """
|
173 |
yield gr.ChatMessage(role="assistant", content=f"{step_footnote}")
|
|
|
190 |
total_input_tokens = 0
|
191 |
total_output_tokens = 0
|
192 |
|
193 |
+
for step_log in agent.run(
|
194 |
+
task, stream=True, reset=reset_agent_memory, additional_args=additional_args
|
195 |
+
):
|
196 |
# Track tokens if model provides them
|
197 |
if hasattr(agent.model, "last_input_token_count"):
|
198 |
total_input_tokens += agent.model.last_input_token_count
|
|
|
225 |
content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
|
226 |
)
|
227 |
else:
|
228 |
+
yield gr.ChatMessage(
|
229 |
+
role="assistant", content=f"**Final answer:** {str(final_answer)}"
|
230 |
+
)
|
231 |
|
232 |
|
233 |
class GradioUI:
|
|
|
297 |
sanitized_name = "".join(sanitized_name)
|
298 |
|
299 |
# Save the uploaded file to the specified folder
|
300 |
+
file_path = os.path.join(
|
301 |
+
self.file_upload_folder, os.path.basename(sanitized_name)
|
302 |
+
)
|
303 |
shutil.copy(file.name, file_path)
|
304 |
|
305 |
+
return gr.Textbox(
|
306 |
+
f"File uploaded: {file_path}", visible=True
|
307 |
+
), file_uploads_log + [file_path]
|
308 |
|
309 |
def log_user_message(self, text_input, file_uploads_log):
|
310 |
return (
|
|
|
330 |
def launch(self, **kwargs):
|
331 |
import gradio as gr
|
332 |
|
333 |
+
with gr.Blocks(
|
334 |
+
fill_height=True,
|
335 |
+
theme="crcdng/cyber",
|
336 |
+
css_paths=["cyberpunk.css", "scrolling_text.css"],
|
337 |
+
) as demo:
|
338 |
+
|
339 |
+
title_html = """
|
340 |
<style>
|
341 |
@font-face {
|
342 |
font-family: Cyberpunk;
|
|
|
349 |
<h1 style='font-family: Cyberpunk; font-size: 42px;'> Your Cyberpunk Local Time Terminal </h1>
|
350 |
</center>
|
351 |
"""
|
|
|
352 |
|
353 |
+
description_html = """
|
|
|
354 |
<center><p style='font-size: 24px;'>
|
355 |
Welcome to ChronoCore-77, the bleeding-edge time terminal jacked straight into the neon veins of Night City. Whether you're dodging corpos, chasing edgerunner gigs, or just trying to sync your implant clock, I've got the local time locked and loaded. No glitches [OK a few...], no lag—just pure, precise chrono-data ripped straight from the grid. Stay sharp, choom. Time waits for no one.
|
356 |
</p></center>
|
357 |
"""
|
|
|
358 |
|
359 |
+
banner_html = """
|
|
|
360 |
<div class="cyber-banner-short bg-purple fg-white cyber-glitch-1">
|
361 |
<div style="margin-left: auto; width: 80%;" id="scroll-container">
|
362 |
<div id="scroll-text"> ---- Tannhäuser Gate Approved ---- Special Offer Today Only ----- Free Access Credits </div>
|
363 |
</div>
|
364 |
</div>
|
365 |
"""
|
|
|
366 |
|
367 |
with gr.Row():
|
368 |
+
title = gr.HTML(banner_html)
|
369 |
with gr.Row():
|
370 |
timer = gr.Timer(1)
|
371 |
gr.Textbox(render=False)
|
372 |
time_display = gr.Textbox(label="Time", elem_classes="cyber-glitch-4")
|
373 |
gr.Textbox(render=False)
|
374 |
import time
|
375 |
+
|
376 |
+
timer.tick(
|
377 |
+
lambda: get_current_time_in_timezone(time.tzname[0]),
|
378 |
+
outputs=time_display,
|
379 |
+
)
|
380 |
with gr.Row():
|
381 |
+
title = gr.HTML(title_html)
|
382 |
with gr.Row():
|
383 |
+
description = gr.HTML(description_html)
|
384 |
stored_messages = gr.State([])
|
385 |
file_uploads_log = gr.State([])
|
386 |
with gr.Row(equal_height=True):
|
387 |
chatbot = gr.Chatbot(
|
388 |
+
label="Agent",
|
389 |
+
type="messages",
|
390 |
+
avatar_images=(
|
391 |
+
"https://huggingface.co/spaces/crcdng/First_agent_template/resolve/main/agent_b.jpg",
|
392 |
+
"https://huggingface.co/spaces/crcdng/First_agent_template/resolve/main/agent_a.jpg",
|
393 |
+
),
|
394 |
+
resizeable=True,
|
395 |
+
scale=2,
|
396 |
+
elem_classes="cyber-glitch-1",
|
397 |
+
)
|
398 |
+
gr.Model3D(
|
399 |
+
"terminal.glb",
|
400 |
+
display_mode="solid",
|
401 |
+
camera_position=(90, 180, 2),
|
402 |
+
label="A view of the ChronoCore-77",
|
403 |
)
|
|
|
404 |
# If an upload folder is provided, enable the upload feature
|
405 |
if self.file_upload_folder is not None:
|
406 |
upload_file = gr.File(label="Upload a file")
|
407 |
+
upload_status = gr.Textbox(
|
408 |
+
label="Upload Status", interactive=False, visible=False
|
409 |
+
)
|
410 |
upload_file.change(
|
411 |
self.upload_file,
|
412 |
[upload_file, file_uploads_log],
|
413 |
[upload_status, file_uploads_log],
|
414 |
)
|
415 |
with gr.Row(equal_height=True):
|
416 |
+
steps_input = gr.Slider(
|
417 |
+
1, 12, value=4, step=1, label="Max. Number of Steps"
|
418 |
+
)
|
419 |
steps_input.change(self.agent_set_steps, steps_input, None)
|
420 |
+
tools_list = gr.Dropdown(
|
421 |
+
self.agent_get_tools(),
|
422 |
+
interactive=True,
|
423 |
+
label="Tools",
|
424 |
+
info="(display only)",
|
425 |
+
)
|
426 |
# tools_list.select(self.agent_get_tools, None, tools_list)
|
427 |
reset = gr.Button(value="Reset ChronoCore-77")
|
428 |
reset.click(self.agent_reset, None, None)
|
429 |
+
text_input = gr.Textbox(
|
430 |
+
lines=1,
|
431 |
+
label="Chat Message",
|
432 |
+
elem_classes="cyber-glitch-2",
|
433 |
+
max_length=1000,
|
434 |
+
)
|
435 |
text_input.submit(
|
436 |
self.log_user_message,
|
437 |
[text_input, file_uploads_log],
|
438 |
[stored_messages, text_input],
|
439 |
).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
|
440 |
examples = gr.Examples(
|
441 |
+
examples=[
|
442 |
+
["Tell me a joke based on the current local time"],
|
443 |
+
["Given the current local time, what is a fun activity to do?"],
|
444 |
+
[
|
445 |
+
"When asked for the current local time, add 6 hours to it. What is the current local time?"
|
446 |
+
],
|
447 |
+
["Find significant events that happend exactly one year ago"],
|
448 |
+
["Compute the current local time glitch coeficients"],
|
449 |
+
["Generate a bold picture inspired by the current local time"],
|
450 |
+
],
|
451 |
+
inputs=[text_input],
|
452 |
)
|
|
|
|
|
453 |
|
454 |
+
demo.launch(
|
455 |
+
debug=True,
|
456 |
+
share=True,
|
457 |
+
ssr_mode=False,
|
458 |
+
allowed_paths=["Cyberpunk.otf"],
|
459 |
+
**kwargs,
|
460 |
+
)
|
461 |
+
|
462 |
+
|
463 |
+
__all__ = ["stream_to_gradio", "GradioUI"]
|