File size: 2,511 Bytes
ed3f939
b179dde
ed3f939
 
 
 
115aedf
 
b179dde
cc05cad
115aedf
 
 
 
64493bb
f5af257
b179dde
3b9262f
b179dde
 
 
3b9262f
115aedf
 
 
12c777d
115aedf
b179dde
115aedf
b179dde
115aedf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b179dde
 
 
 
 
 
 
 
 
 
115aedf
 
 
b179dde
 
 
 
 
 
 
 
 
 
115aedf
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import os
import uuid
from dotenv import load_dotenv

load_dotenv()

from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
from langgraph.checkpoint.memory import MemorySaver
from langchain_core.messages import AnyMessage, HumanMessage
from langgraph.prebuilt import ToolNode
from langgraph.graph import START, StateGraph
from langgraph.prebuilt import tools_condition
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
import gradio as gr

from langchain_community.tools import DuckDuckGoSearchRun
from retriever import guest_info_tool
from tools import weather_info_tool, hub_stats_tool

search_tool = DuckDuckGoSearchRun()

# Generate the chat interface, including the tools
llm = HuggingFaceEndpoint(
    repo_id="Qwen/Qwen2.5-Coder-32B-Instruct",
    huggingfacehub_api_token=os.environ.get("HF_TOKEN"),
)

chat = ChatHuggingFace(llm=llm, verbose=True)
tools = [guest_info_tool, search_tool, weather_info_tool, hub_stats_tool]
chat_with_tools = chat.bind_tools(tools)

# Generate the AgentState and Agent graph
class AgentState(TypedDict):
    messages: Annotated[list[AnyMessage], add_messages]

def assistant(state: AgentState):
    return {
        "messages": [chat_with_tools.invoke(state["messages"])],
    }

## The graph
builder = StateGraph(AgentState)

builder.add_node("assistant", assistant)
builder.add_node("tools", ToolNode(tools))

builder.add_edge(START, "assistant")
builder.add_conditional_edges(
    "assistant",
    tools_condition,
)
builder.add_edge("tools", "assistant")

# MemorySaver checkpoints the full graph state after each step,
# keyed by thread_id — so each session gets its own conversation history
memory = MemorySaver()
alfred = builder.compile(checkpointer=memory)


def respond(message, history, thread_id):
    config = {"configurable": {"thread_id": thread_id}}
    # Only send the new message — LangGraph loads the history from the checkpoint
    response = alfred.invoke({"messages": [HumanMessage(content=message)]}, config=config)
    return response["messages"][-1].content


with gr.Blocks() as demo:
    # gr.State with a factory creates a fresh UUID per browser session
    thread_id = gr.State(lambda: str(uuid.uuid4()))

    gr.ChatInterface(
        fn=respond,
        additional_inputs=[thread_id],
        title="Alfred - Your Gala Assistant",
        description="Ask Alfred about your gala guests. Try: 'Tell me about Lady Ada Lovelace.'",
    )

if __name__ == "__main__":
    demo.launch()