|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os |
|
import threading |
|
from typing import Optional |
|
|
|
from dotenv import load_dotenv |
|
import gradio as gr |
|
from smolagents import ( |
|
CodeAgent, |
|
LiteLLMModel, |
|
DuckDuckGoSearchTool, |
|
) |
|
from smolagents.agent_types import AgentText, AgentImage, AgentAudio |
|
from smolagents.gradio_ui import pull_messages_from_step, handle_agent_output_types |
|
from huggingface_hub import InferenceClient |
|
|
|
|
|
from extra_search_tools import ( |
|
PrioritySearchTool, |
|
BraveSearchTool, |
|
GoogleCustomSearchTool, |
|
) |
|
|
|
|
|
def hf_chat(api_key, model, text): |
|
client = InferenceClient(api_key=api_key) |
|
messages = [ |
|
{ |
|
"role": "user", |
|
"content": text, |
|
} |
|
] |
|
|
|
stream = client.chat.completions.create( |
|
model=model, messages=messages, max_tokens=6000, stream=False |
|
) |
|
|
|
return stream.choices[0].message.content |
|
|
|
|
|
load_dotenv(override=True) |
|
|
|
|
|
append_answer_lock = threading.Lock() |
|
|
|
|
|
custom_role_conversions = {"tool-call": "assistant", "tool-response": "user"} |
|
|
|
model = LiteLLMModel( |
|
"groq/llama3-8b-8192", |
|
api_base="https://api.groq.com/openai/v1", |
|
max_completion_tokens=500, |
|
api_key=os.getenv("GROQ_API_KEY"), |
|
) |
|
|
|
search_tool = PrioritySearchTool( |
|
[ |
|
DuckDuckGoSearchTool(), |
|
GoogleCustomSearchTool("YOUR_ENGINE_KEY"), |
|
BraveSearchTool(), |
|
], |
|
"history.json", |
|
) |
|
WEB_TOOLS = [search_tool] |
|
|
|
max_steps = 1 |
|
|
|
|
|
|
|
def create_agent(): |
|
print("create agent") |
|
"""Creates a fresh agent instance for each session""" |
|
return CodeAgent( |
|
model=model, |
|
tools=WEB_TOOLS, |
|
max_steps=max_steps, |
|
verbosity_level=1, |
|
) |
|
|
|
|
|
def stream_to_gradio( |
|
agent, |
|
task: str, |
|
reset_agent_memory: bool = False, |
|
additional_args: Optional[dict] = None, |
|
): |
|
"""Runs an agent with the given task and streams the messages from the agent as gradio ChatMessages.""" |
|
steps = 0 |
|
for step_log in agent.run( |
|
task, stream=True, reset=reset_agent_memory, additional_args=additional_args |
|
): |
|
|
|
steps += 1 |
|
if steps <= max_steps: |
|
for message in pull_messages_from_step( |
|
step_log, |
|
): |
|
yield message |
|
|
|
final_answer = step_log |
|
final_answer = handle_agent_output_types(final_answer) |
|
|
|
if isinstance(final_answer, AgentText): |
|
yield gr.ChatMessage( |
|
role="assistant", |
|
content=f"**Final answer:**\n{final_answer.to_string()}", |
|
) |
|
elif isinstance(final_answer, AgentImage): |
|
yield gr.ChatMessage( |
|
role="assistant", |
|
content={"path": final_answer.to_string(), "mime_type": "image/png"}, |
|
) |
|
elif isinstance(final_answer, AgentAudio): |
|
yield gr.ChatMessage( |
|
role="assistant", |
|
content={"path": final_answer.to_string(), "mime_type": "audio/wav"}, |
|
) |
|
else: |
|
yield gr.ChatMessage( |
|
role="assistant", content=f"**Final answer:** {str(final_answer)}" |
|
) |
|
|
|
|
|
class GradioUI: |
|
"""A one-line interface to launch your agent in Gradio""" |
|
|
|
def __init__(self, file_upload_folder: str | None = None): |
|
self.file_upload_folder = file_upload_folder |
|
if self.file_upload_folder is not None: |
|
if not os.path.exists(file_upload_folder): |
|
os.mkdir(file_upload_folder) |
|
|
|
def interact_with_agent(self, prompt, messages, session_state): |
|
|
|
if "agent" not in session_state: |
|
session_state["agent"] = create_agent() |
|
|
|
messages.append(gr.ChatMessage(role="user", content=prompt)) |
|
yield messages |
|
|
|
|
|
for msg in stream_to_gradio( |
|
session_state["agent"], task=prompt, reset_agent_memory=False |
|
): |
|
messages.append(msg) |
|
pass |
|
yield messages |
|
yield messages |
|
|
|
def launch(self, **kwargs): |
|
with gr.Blocks(theme="ocean", fill_height=True) as demo: |
|
gr.Markdown("""# Smolagents - ExtraSearchtools! |
|
- [Google Custom Search](https://developers.google.com/custom-search/v1/overview) tool Free 100 per day |
|
- [Brave Search](https://brave.com/search/api/) tool Free 2000 per month |
|
- PrioritySearchTool - try duckduckgo fist and then use google |
|
- PrioritySearchTool - json-save function |
|
|
|
Built with [smolagents](https://github.com/huggingface/smolagents).This Demo only work duckduckgo if it's not rate-limited.Duplicate and set your own secret key |
|
""") |
|
|
|
session_state = gr.State({}) |
|
|
|
chatbot = gr.Chatbot( |
|
label="ExtraSearchtools", |
|
type="messages", |
|
avatar_images=( |
|
None, |
|
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/mascot_smol.png", |
|
), |
|
scale=1, |
|
) |
|
text_input = gr.Textbox( |
|
lines=1, label="Your request", value="What is smolagents?" |
|
) |
|
text_input.submit( |
|
self.interact_with_agent, |
|
|
|
[text_input, chatbot, gr.State({})], |
|
[chatbot], |
|
) |
|
|
|
demo.launch(debug=True, share=True, **kwargs) |
|
|
|
|
|
if __name__ == "__main__": |
|
GradioUI().launch() |
|
|