File size: 9,029 Bytes
016be3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
223
224
225
226
227
228
229
230
231
232
233
234
235
import os
import sys
import chainlit as cl
from src.research_agent import run_agent, create_system_message
from langchain_core.messages import (
    AIMessage,
    HumanMessage,
    SystemMessage,
    ToolMessage,
)

# Set domain as global variable
DOMAIN = "General Research"
DEBUG_MODE = True  # Set to True to show detailed tool usage

# List of available domains
AVAILABLE_DOMAINS = [
    "General Research",
    "Computer Science",
    "Artificial Intelligence",
]

@cl.on_chat_start
async def on_chat_start():
    """
    Initialize the chat session
    """
    # Set up the session state
    cl.user_session.set("messages", [create_system_message(DOMAIN)])
    cl.user_session.set("debug_mode", DEBUG_MODE)
    
    # Send a welcome message
    await cl.Message(
        content=f"Hello! I'm your research assistant specialized in {DOMAIN}. How can I help you?\n\n"
                f"I have access to the following tools:\n"
                f"1. πŸ”Ž Web Search - For recent information and general queries\n"
                f"2. πŸ“„ Research Papers - For academic and scientific knowledge\n"
                f"3. πŸ“š Wikipedia - For background information and factual summaries\n"
                f"4. πŸ“Š Data Analysis - For analyzing data you provide\n\n"
                f"You can change the research domain by typing `/domain` followed by one of these options:\n"
                f"{', '.join(AVAILABLE_DOMAINS)}\n\n"
                f"You can toggle debug mode with `/debug on` or `/debug off` to see detailed tool usage.",
        author="Research Assistant"
    ).send()

@cl.on_settings_update
async def on_settings_update(settings):
    """
    Handle settings updates
    """
    global DOMAIN
    
    if "domain" in settings:
        DOMAIN = settings["domain"]
        # Reset messages with new domain
        cl.user_session.set("messages", [create_system_message(DOMAIN)])
        
        # Notify user of domain change
        await cl.Message(
            content=f"Domain changed to {DOMAIN}. My knowledge is now specialized for this domain.",
            author="System"
        ).send()

@cl.on_message
async def on_message(message: cl.Message):
    """
    Process incoming messages
    """
    global DOMAIN, DEBUG_MODE
    
    # Check for debug mode command
    if message.content.startswith("/debug"):
        command_parts = message.content.split()
        if len(command_parts) > 1:
            if command_parts[1].lower() == "on":
                DEBUG_MODE = True
                cl.user_session.set("debug_mode", True)
                await cl.Message(
                    content="Debug mode turned ON. You'll see detailed tool usage information.",
                    author="System"
                ).send()
            elif command_parts[1].lower() == "off":
                DEBUG_MODE = False
                cl.user_session.set("debug_mode", False)
                await cl.Message(
                    content="Debug mode turned OFF.",
                    author="System"
                ).send()
        else:
            current_state = "ON" if DEBUG_MODE else "OFF"
            await cl.Message(
                content=f"Debug mode is currently {current_state}. Use `/debug on` or `/debug off` to change.",
                author="System"
            ).send()
        return
    
    # Check for domain change command
    if message.content.startswith("/domain"):
        command_parts = message.content.split()
        if len(command_parts) == 1:
            # Display available domains
            domains_list = "\n".join([f"- {domain}" for domain in AVAILABLE_DOMAINS])
            await cl.Message(
                content=f"Please specify a domain. Available domains:\n{domains_list}\n\nExample: `/domain Artificial Intelligence`",
                author="System"
            ).send()
            return
        
        # Get the requested domain
        requested_domain = " ".join(command_parts[1:])
        
        # Check if it's in the available domains (case insensitive)
        found_domain = None
        for domain in AVAILABLE_DOMAINS:
            if domain.lower() == requested_domain.lower():
                found_domain = domain
                break
        
        if found_domain:
            DOMAIN = found_domain
            # Reset messages with new domain
            cl.user_session.set("messages", [create_system_message(DOMAIN)])
            
            # Notify user of domain change
            await cl.Message(
                content=f"Domain changed to {DOMAIN}. My knowledge is now specialized for this domain.",
                author="Research Assistant"
            ).send()
        else:
            # Domain not found
            domains_list = "\n".join([f"- {domain}" for domain in AVAILABLE_DOMAINS])
            await cl.Message(
                content=f"Domain '{requested_domain}' not found. Available domains:\n{domains_list}",
                author="System"
            ).send()
        return
    
    # Get current message history and debug mode setting
    messages = cl.user_session.get("messages")
    debug_mode = cl.user_session.get("debug_mode", DEBUG_MODE)
    
    # Add user message to history
    user_message = HumanMessage(content=message.content)
    
    # Create a temporary thinking message
    thinking = cl.Message(content="Researching your query...", author="Research Assistant")
    await thinking.send()
    
    try:
        # Call the agent
        response_messages = run_agent(
            user_input=message.content,
            domain=DOMAIN,
            messages=messages
        )
        
        # Update the thinking message
        await thinking.remove()
        
        # Track tool usage for summary
        tool_usage = []
        
        # Process and display messages
        for msg in response_messages:
            if not msg in messages:  # Only process new messages
                if isinstance(msg, AIMessage):
                    await cl.Message(
                        content=msg.content,
                        author="Research Assistant"
                    ).send()
                elif isinstance(msg, ToolMessage):
                    # Add to tool usage list
                    tool_usage.append(msg.name)
                    
                    # Create elements for tool output
                    elements = []
                    
                    # Format the tool output for better readability
                    formatted_content = msg.content
                    # Try to detect JSON and format it
                    if msg.content.strip().startswith('{') or msg.content.strip().startswith('['):
                        try:
                            import json
                            content_obj = json.loads(msg.content)
                            formatted_content = json.dumps(content_obj, indent=2)
                        except:
                            pass
                    
                    # Add tool output as an element
                    elements.append(
                        cl.Text(
                            name=f"Tool Result: {msg.name}",
                            content=formatted_content,
                            display="inline"
                        )
                    )
                    
                    # Only show detailed tool messages in debug mode
                    if debug_mode:
                        # Send tool message with more prominent styling
                        await cl.Message(
                            content=f"πŸ” **TOOL CALL**: `{msg.name}`\n\nI used this tool to find information about your query.",
                            author="Research Assistant",
                            elements=elements
                        ).send()
        
        # Display tool usage summary if tools were used
        if tool_usage and debug_mode:
            tool_counts = {}
            for tool in tool_usage:
                if tool in tool_counts:
                    tool_counts[tool] += 1
                else:
                    tool_counts[tool] = 1
            
            summary = "πŸ“Š **RESEARCH SUMMARY**\n\nTo answer your question, I used:\n"
            for tool, count in tool_counts.items():
                # Add emoji based on tool type
                emoji = "πŸ”Ž" if tool == "web_search" else "πŸ“„" if tool == "research_paper_search" else "πŸ“š" if tool == "wikipedia_search" else "πŸ“Š"
                summary += f"- {emoji} `{tool}`: {count} time{'s' if count > 1 else ''}\n"
            
            await cl.Message(
                content=summary,
                author="System"
            ).send()
        
        # Update session with new messages
        cl.user_session.set("messages", response_messages)
        
    except Exception as e:
        await thinking.remove()
        await cl.Message(
            content=f"Sorry, I encountered an error: {str(e)}",
            author="System"
        ).send()