File size: 4,808 Bytes
7f45575
 
 
51c9d59
29f5753
51c9d59
 
7f45575
 
 
51c9d59
15eee06
51c9d59
7f45575
51c9d59
 
7f45575
15eee06
51c9d59
 
 
 
 
3521f3d
 
7f45575
51c9d59
29f5753
51c9d59
 
 
29f5753
 
 
 
 
7f45575
 
15eee06
51c9d59
15eee06
51c9d59
15eee06
51c9d59
 
15eee06
 
 
51c9d59
15eee06
51c9d59
 
 
 
 
 
 
 
 
 
 
 
15eee06
51c9d59
15eee06
51c9d59
 
15eee06
7f45575
51c9d59
 
 
 
 
3521f3d
7f45575
51c9d59
15eee06
 
51c9d59
 
15eee06
 
29f5753
51c9d59
 
15eee06
51c9d59
 
29f5753
15eee06
 
 
 
 
 
 
 
 
7f45575
15eee06
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29f5753
51c9d59
15eee06
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import os
from typing import Annotated
from typing_extensions import TypedDict

import gradio as gr
from langchain_groq import ChatGroq
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage, BaseMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


# ── State ─────────────────────────────────────────────

class State(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]


# ── Build Graph ───────────────────────────────────────

def build_graph(api_key: str, model: str, system_prompt: str):
    llm = ChatGroq(
        groq_api_key=api_key,
        model_name=model,
        temperature=0.7,
    )

    def chatbot_node(state: State) -> dict:
        full_messages = [SystemMessage(content=system_prompt)] + state["messages"]
        response = llm.invoke(full_messages)
        return {"messages": [response]}

    builder = StateGraph(State)
    builder.add_node("chatbot", chatbot_node)
    builder.add_edge(START, "chatbot")
    builder.add_edge("chatbot", END)
    return builder.compile()


# ── Chat Function ─────────────────────────────────────

def respond(message, history, api_key, model, system_prompt, max_history):
    if not api_key.strip():
        return "⚠️ Please enter your Groq API key."

    if not message.strip():
        return ""

    lc_messages = []

    # Convert history
    for entry in history[-(max_history * 2):]:
        if entry["role"] == "user":
            lc_messages.append(HumanMessage(content=entry["content"]))
        elif entry["role"] == "assistant":
            lc_messages.append(AIMessage(content=entry["content"]))

    lc_messages.append(HumanMessage(content=message))

    graph = build_graph(api_key, model, system_prompt)

    try:
        result = graph.invoke({"messages": lc_messages})
        return result["messages"][-1].content
    except Exception as e:
        return f"❌ Error: {str(e)}"


# ── Constants ─────────────────────────────────────────

MODELS = [
    "llama-3.3-70b-versatile",
    "llama-3.1-8b-instant",
    "mixtral-8x7b-32768",
    "gemma2-9b-it",
]

DEFAULT_SYSTEM = (
    "You are a helpful, friendly, and knowledgeable assistant. "
    "Answer clearly and concisely."
)


# ── UI ────────────────────────────────────────────────

with gr.Blocks(
    title="LangGraph Γ— Groq Assistant",
    theme=gr.themes.Soft(primary_hue="violet"),
) as demo:

    gr.Markdown("# πŸ€– LangGraph Γ— Groq Assistant")
    gr.Markdown("Chatbot using LangGraph + Groq")

    chatbot = gr.Chatbot(type="messages")

    with gr.Row():
        msg = gr.Textbox(placeholder="Type your message...", scale=4)
        send = gr.Button("Send ➀")

    clear = gr.Button("πŸ—‘οΈ Clear Chat")

    # Settings panel
    with gr.Accordion("βš™οΈ Settings", open=False):
        api_key = gr.Textbox(label="Groq API Key", type="password")
        model = gr.Dropdown(choices=MODELS, value=MODELS[0], label="Model")
        system_prompt = gr.Textbox(value=DEFAULT_SYSTEM, label="System Prompt")
        max_history = gr.Slider(1, 20, value=10, step=1, label="Max history")

    # Examples (FIXED βœ…)
    examples = [
        ["What is LangGraph?", "", MODELS[0], DEFAULT_SYSTEM, 10],
        ["Explain AI in simple terms", "", MODELS[0], DEFAULT_SYSTEM, 10],
        ["Write Python code for Fibonacci", "", MODELS[0], DEFAULT_SYSTEM, 10],
    ]

    gr.Examples(
        examples=examples,
        inputs=[msg, api_key, model, system_prompt, max_history],
    )

    # Send logic
    def user_input(user_message, chat_history):
        return "", chat_history + [{"role": "user", "content": user_message}]

    def bot_response(chat_history, api_key, model, system_prompt, max_history):
        user_message = chat_history[-1]["content"]
        response = respond(user_message, chat_history[:-1], api_key, model, system_prompt, max_history)
        chat_history.append({"role": "assistant", "content": response})
        return chat_history

    send.click(user_input, [msg, chatbot], [msg, chatbot]) \
        .then(bot_response, [chatbot, api_key, model, system_prompt, max_history], chatbot)

    msg.submit(user_input, [msg, chatbot], [msg, chatbot]) \
        .then(bot_response, [chatbot, api_key, model, system_prompt, max_history], chatbot)

    clear.click(lambda: [], None, chatbot)

demo.launch()