File size: 7,120 Bytes
65d7b9c
5f24137
65d7b9c
 
95fcc62
 
 
5f24137
95fcc62
5f24137
65d7b9c
95fcc62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f24137
d30ccfe
65d7b9c
 
 
ad32b40
 
 
 
65d7b9c
5f24137
95fcc62
65d7b9c
 
ad32b40
141c4ac
d30ccfe
65d7b9c
5f24137
65d7b9c
 
95fcc62
 
65d7b9c
 
a2c6e56
 
 
 
 
5f24137
c8d6d95
a2c6e56
 
 
 
 
 
1ce2aa4
 
a2c6e56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8d6d95
a2c6e56
c8d6d95
 
 
 
 
a2c6e56
 
95fcc62
c8d6d95
a2c6e56
 
 
 
 
 
 
 
 
1ce2aa4
a2c6e56
1ce2aa4
a2c6e56
 
6852c83
a2c6e56
 
95fcc62
c8d6d95
 
a2c6e56
d30ccfe
c8d6d95
a2c6e56
 
 
d30ccfe
9940960
c8d6d95
 
a2c6e56
 
 
 
 
 
 
 
 
c8d6d95
a2c6e56
 
 
95fcc62
 
a2c6e56
d30ccfe
 
 
 
95fcc62
d30ccfe
 
a2c6e56
d30ccfe
a2c6e56
d30ccfe
 
 
 
 
95fcc62
d30ccfe
 
a2c6e56
d30ccfe
a2c6e56
d30ccfe
 
a2c6e56
 
 
 
 
 
 
 
95fcc62
a2c6e56
 
 
95fcc62
 
 
a2c6e56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95fcc62
 
5f24137
c8d6d95
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import os
import gradio as gr
from langgraph_sdk import get_client
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
from langsmith import Client
import asyncio
import logging

LANGGRAPH_DEPLOYMENT = "https://le-chat-bottes-08847786c41355da87302fa1e0f41f4a.us.langgraph.app/"

client = get_client(url=LANGGRAPH_DEPLOYMENT)
langsmith_client = Client()

async def log_feedback(run_id, score, comment=""):
    """Log feedback to LangSmith"""
    try:
        langsmith_client.create_feedback(
            run_id=run_id,
            key="user_feedback",
            score=score,
            comment=comment
        )
        logging.info(f"Successfully logged feedback for run_id: {run_id} with score: {score}")
        return True
    except Exception as e:
        logging.error(f"Error logging feedback for run_id: {run_id}: {e}")
        return False

async def respond(message, history, thread_state):
    assistants = await client.assistants.search(
        graph_id="retrieval_graph", metadata={"created_by": "system"}
    )
    
    if not thread_state:
        thread = await client.threads.create()
        thread_state = thread["thread_id"]
    
    response = ""
    run_id = None
    
    async for chunk in client.runs.stream(
        thread_id=thread_state,
        assistant_id=assistants[0]["assistant_id"],
        input={"messages": message},
        stream_mode="events",
    ):
        if chunk.event == "events":
            if chunk.data["event"] == "on_chat_model_stream":
                if run_id is None and "run_id" in chunk.data:
                    run_id = chunk.data["run_id"]
                token = chunk.data["data"]["chunk"]["content"]
                response += token
                yield [
                    *history,
                    {"role": "user", "content": message},
                    {"role": "assistant", "content": response}
                ], thread_state, run_id

def clear_conversation():
    return [], None, gr.update(visible=False)

with gr.Blocks(theme=gr.themes.Soft(), css="""
h1 {
    text-align: center;
}
img {
    margin: 0 !important;
}
.feedback-card {
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 16px;
    margin-top: 12px;
}
.feedback-buttons {
    gap: 8px;
}
.selected-thumb {
    background: #e0e0e0 !important;
    border-color: #4CAF50 !important;
}
.examples .example {
    background: #f0f0f0;
    padding: 10px;
    margin: 5px;
    border-radius: 5px;
    cursor: pointer;
}
.examples .example:hover {
    background: #e0e0e0;
}
""") as demo:
    with gr.Column():
        with gr.Row():
            with gr.Column(scale=9):
                gr.Markdown("# Le Chat Bottes 👢😺👢")
        
        chatbot = gr.Chatbot(
            height=640,
            avatar_images=(
                "https://em-content.zobj.net/source/microsoft-teams/337/farmer_1f9d1-200d-1f33e.png",
                "https://em-content.zobj.net/source/microsoft-teams/363/robot_1f916.png"
            ),
            show_label=False,
            bubble_full_width=False,
            container=False,
            type="messages"
        )

        with gr.Column(visible=False) as feedback_card:
            with gr.Row():
                thumbs_up = gr.Button("👍", elem_classes="feedback-btn")
                thumbs_down = gr.Button("👎", elem_classes="feedback-btn")
            with gr.Row(visible=False) as feedback_input_row:
                feedback_comment = gr.Textbox(
                    placeholder="Commentaire (optionnel)",
                    show_label=False,
                    scale=3
                )
                feedback_send_btn = gr.Button("Envoyer", scale=1)
            
            thank_you_message = gr.HTML(
                "<div style='color: #4CAF50; margin-top: 8px;'>Merci pour votre retour !</div>",
                visible=False
            )
        
        with gr.Row():
            txt = gr.Textbox(
                placeholder="Posez votre question ici...",
                show_label=False,
                container=False,
                scale=7,
                autofocus=True,
                max_lines=3,
            )
            submit_btn = gr.Button("Envoyer", scale=1)
        
        with gr.Row():
            gr.Examples(
                examples=[
                    "Comment stocker l'eau de pluie sur une exploitation agricole ?",
                    "Quelles rotations culturales favorisent l'adaptation climatique ?",
                    "Comment réduire l'impact du gel printanier sur les vignes ?"
                ],
                inputs=txt,
                label=""
            )
        

        feedback_alert = gr.HTML(visible=False)

        thread_state = gr.State()
        current_run_id = gr.State()
        selected_thumb = gr.State()

    txt.submit(
        respond,
        [txt, chatbot, thread_state],
        [chatbot, thread_state, current_run_id],
        api_name=False
    ).then(
        lambda: ("", gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=True)),
        None,
        [txt, feedback_card, thank_you_message, thumbs_up, thumbs_down]
    )
    
    submit_btn.click(
        respond,
        [txt, chatbot, thread_state],
        [chatbot, thread_state, current_run_id],
        api_name=False
    ).then(
        lambda: ("", gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=True)),
        None,
        [txt, feedback_card, thank_you_message, thumbs_up, thumbs_down]
    )

    def show_feedback_input(thumb):
        return (
            gr.update(visible=True),  # feedback_input_row
            thumb,                    # selected_thumb
            gr.update(visible=False), # thumbs_up
            gr.update(visible=False)  # thumbs_down
        )

    thumbs_up.click(
        show_feedback_input,
        inputs=[gr.Number(1, visible=False)],
        outputs=[feedback_input_row, selected_thumb, thumbs_up, thumbs_down]
    )
    
    thumbs_down.click(
        show_feedback_input,
        inputs=[gr.Number(0, visible=False)],
        outputs=[feedback_input_row, selected_thumb, thumbs_up, thumbs_down]
    )

    def submit_feedback(run_id, score, comment):
        asyncio.run(log_feedback(run_id, score, comment))
        return (
            gr.update(visible=True),  # thank_you_message
            gr.update(value=""),      # feedback_comment
            gr.update(visible=False), # feedback_input_row
            gr.update(visible=False), # thumbs_up
            gr.update(visible=False)  # thumbs_down
        )

    feedback_send_btn.click(
        submit_feedback,
        [current_run_id, selected_thumb, feedback_comment],
        [thank_you_message, feedback_comment, feedback_input_row, thumbs_up, thumbs_down]
    )
    
    feedback_comment.submit(
        submit_feedback,
        [current_run_id, selected_thumb, feedback_comment],
        [thank_you_message, feedback_comment, feedback_input_row, thumbs_up, thumbs_down]
    )

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