nadaaaita commited on
Commit
dfbf21d
·
1 Parent(s): 43139c6

added ability to show passages

Browse files
app.py CHANGED
@@ -1,106 +1,130 @@
1
  import gradio as gr
 
 
 
2
 
3
- # Define some pre-written templates for Tab 1
4
- templates = {
5
- "Friendly Chatbot": "You are a helpful, friendly chatbot that engages in light-hearted conversations.",
6
- "Technical Assistant": "You are a technical assistant specialized in answering questions related to Python programming.",
7
- "Nutrition Advisor": "You provide evidence-based advice on nutrition and healthy eating habits.",
8
- }
9
 
10
- # Define some agentic workflows for Tab 2
11
- agentic_workflows = {
12
- "Blog Post Generator": "This agent is designed to help generate a blog post based on user input.",
13
- "Document Summarizer": "This agent summarizes long documents by extracting key points.",
14
- "Task Manager": "This agent helps you organize tasks and provides step-by-step guidance."
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- # Chatbot logic for custom instructions or pre-written templates
18
- def chatbot_response(system_instructions, user_query):
19
- if "friendly" in system_instructions.lower():
20
- return f"Friendly Chatbot says: Hi there! 😊 How can I assist you today?"
21
- elif "technical" in system_instructions.lower():
22
- return f"Technical Assistant says: Sure! Here's some information on Python: {user_query}"
23
- elif "nutrition" in system_instructions.lower():
24
- return f"Nutrition Advisor says: Here's some advice about healthy eating: {user_query}"
25
- else:
26
- return f"Custom Chatbot says: {user_query}"
27
 
28
- # Chatbot conversation function
29
- def chatbot_conversation(system_instructions, chat_history, user_query):
30
- response = chatbot_response(system_instructions, user_query)
31
- chat_history.append((user_query, response))
32
- return chat_history, ""
33
-
34
- # Chatbot conversation for predefined agentic workflows
35
- def agentic_chatbot_conversation(workflow_instructions, chat_history, user_query):
36
- response = f"Agent Workflow ({workflow_instructions}) says: {user_query}"
37
- chat_history.append((user_query, response))
38
- return chat_history, ""
39
-
40
- # Function to update the interface when a selection is made from the dropdown (Tab 1)
41
- def update_interface(template_name, custom_instructions):
42
- if template_name == "Custom Instructions":
43
- return gr.update(visible=True), gr.update(visible=False)
44
- else:
45
- template_content = templates.get(template_name, "")
46
- return gr.update(visible=False), gr.update(visible=True, value=template_content)
47
-
48
- # Build the Gradio interface with Tabs
49
- with gr.Blocks(css=".gradio-container {background-color: #F0F0F0;} .gr-button {background-color: #1E3A8A; color: white;} .gr-textbox textarea {font-size: 16px;} .gr-markdown {font-size: 18px; color: #1E3A8A;}") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- # Add Tabs
52
- with gr.Tabs():
53
-
54
- # Tab 1: Custom Instructions or Pre-Written Templates
55
- with gr.Tab("Custom Instructions Chatbot"):
56
- gr.Markdown("""
57
- <div style='background-color:#E0E0E0; padding: 20px; border-radius: 10px;'>
58
- <h1 style='text-align: center; color: #1E3A8A;'>SRF Innovation Labs - AI Chatbot Use Case Explorer</h1>
59
- <p style='font-size: 18px; text-align: center; color: #1E3A8A;'>
60
- This tool allows you to experiment with different system prompts,
61
- giving you control over how the chatbot behaves. You can either use pre-defined templates
62
- or write your own custom instructions.
63
- </p>
64
- </div>
65
- """)
66
-
67
- # Section to select system instructions from dropdown
68
- gr.Markdown("<h2 style='color: #1E3A8A;'>Chatbot Setup</h2>")
69
- template_name = gr.Dropdown(choices=["Custom Instructions"] + list(templates.keys()), label="Choose Instructions", value="Friendly Chatbot")
70
- custom_instructions = gr.Textbox(label="Custom Instructions", visible=False, placeholder="Write your own instructions here...")
71
- template_display = gr.Textbox(label="Template Content", interactive=False, visible=True)
72
-
73
  # Chatbot interface
74
- gr.Markdown("<h2 style='color: #1E3A8A;'>Chatbot Interaction</h2>")
75
- chatbot = gr.Chatbot(label="Chatbot Conversation", height=300, show_label=False)
76
- user_query = gr.Textbox(label="Your Query", placeholder="Ask a question or say something to the chatbot...")
77
- submit_button = gr.Button("Send", elem_classes=["gr-button"])
78
-
79
- # Update logic for Tab 1
80
- template_name.change(fn=update_interface, inputs=[template_name, custom_instructions], outputs=[custom_instructions, template_display])
81
- submit_button.click(fn=chatbot_conversation, inputs=[custom_instructions if template_name == "Custom Instructions" else template_display, chatbot, user_query], outputs=[chatbot, user_query])
82
-
83
- # Tab 2: Predefined Agentic Workflows
84
- with gr.Tab("Agentic Workflow Chatbots"):
 
 
 
 
 
 
 
 
 
 
85
  gr.Markdown("""
86
- <div style='background-color:#E0E0E0; padding: 20px; border-radius: 10px;'>
87
- <h1 style='text-align: center; color: #1E3A8A;'>Agentic Workflow Explorer</h1>
88
- <p style='font-size: 18px; text-align: center; color: #1E3A8A;'>
89
- Explore predefined agentic workflows that execute specific tasks, such as generating blog posts,
90
- summarizing documents, or managing tasks.
91
- </p>
 
92
  </div>
93
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- # Dropdown for selecting agentic workflows
96
- workflow_name = gr.Dropdown(choices=list(agentic_workflows.keys()), label="Choose Agent Workflow", value="Blog Post Generator")
97
- workflow_display = gr.Textbox(label="Workflow Description", interactive=False, visible=True)
98
- workflow_chatbot = gr.Chatbot(label="Agent Workflow Conversation", height=300, show_label=False)
99
- workflow_user_query = gr.Textbox(label="Your Query", placeholder="Ask the agent to perform a task...")
100
- workflow_submit_button = gr.Button("Send", elem_classes=["gr-button"])
101
-
102
- # Chatbot interaction for agentic workflows
103
- workflow_submit_button.click(fn=agentic_chatbot_conversation, inputs=[workflow_name, workflow_chatbot, workflow_user_query], outputs=[workflow_chatbot, workflow_user_query])
104
-
105
- # Launch the app
106
  demo.launch()
 
1
  import gradio as gr
2
+ import src.srf_bot as sb
3
+ import prompts.system_prompts as sp
4
+ from langchain_core.messages import HumanMessage
5
 
6
+ # Initialize chatbot
7
+ chatbot = sb.SRFChatbot()
 
 
 
 
8
 
9
+ # Define the respond function
10
+ def respond(query, history):
11
+ formatted_query = [HumanMessage(content=query)]
12
+ # Invoke the graph with properly formatted input
13
+ result = chatbot.graph.invoke({"messages": formatted_query}, chatbot.config)
14
+ # Get the passages from the graph and append to history if documents exist
15
+ state = chatbot.graph.get_state(config=chatbot.config).values
16
+ documents = state.get("documents")
17
+ passages = ''
18
+ if documents and len(documents) > 0:
19
+ for d in documents:
20
+ passages += f'<b>{d.metadata["publication_name"]} - {d.metadata["chapter_name"]}</b>\n{d.page_content}\n\n'
21
+ history.append((f'Passages: {query}', passages))
22
+ # Extract the assistant's response and append to history
23
+ response = result["messages"][-1].content
24
+ system_message_dropdown = state.get("system_message_dropdown")
25
+ history.append((query, f"<i>[{system_message_dropdown}]</i>\n" + response))
26
+ return history
27
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # Gradio interface with black and grey color scheme
30
+ with gr.Blocks(css="""
31
+ .gradio-container {
32
+ background-color: #F0F0F0;
33
+ font-family: 'Arial', sans-serif;
34
+ }
35
+ h1, h2, p {
36
+ color: black;
37
+ }
38
+ h1 {
39
+ font-size: 32px;
40
+ text-align: left;
41
+ }
42
+ h2 {
43
+ font-size: 24px;
44
+ }
45
+ p {
46
+ font-size: 18px;
47
+ margin-bottom: 15px;
48
+ }
49
+ .gr-button {
50
+ background-color: #333333;
51
+ color: white;
52
+ font-size: 18px;
53
+ padding: 10px;
54
+ }
55
+ .gr-textbox textarea {
56
+ font-size: 18px;
57
+ color: black;
58
+ }
59
+ .gr-dropdown {
60
+ font-size: 18px;
61
+ color: black;
62
+ }
63
+ .source-box {
64
+ background-color: white;
65
+ padding: 10px;
66
+ border-radius: 8px;
67
+ margin-top: 20px;
68
+ color: black;
69
+ border: 1px solid #D0D0D0;
70
+ }
71
+ @media (max-width: 600px) {
72
+ .gr-row { flex-direction: column !important; }
73
+ .gr-column { width: 100% !important; }
74
+ }
75
+ """) as demo:
76
 
77
+ # Title
78
+ gr.Markdown("# SRF Chatbot")
79
+
80
+ with gr.Row(elem_classes="gr-row"):
81
+ with gr.Column(scale=4, elem_classes="gr-column"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  # Chatbot interface
83
+ chatbot_output = gr.Chatbot(height=600) # Increased height for longer chat interface
84
+ user_input = gr.Textbox(placeholder="Type your question here...", label="Your Question", value="What is the meaning of life?")
85
+ submit_button = gr.Button("Submit")
86
+
87
+ with gr.Column(scale=1, elem_classes="gr-column"):
88
+ # Dropdown to select system prompts
89
+ system_prompt_dropdown = gr.Dropdown(
90
+ choices=list(sp.system_prompt_templates.keys()),
91
+ label="Select Chatbot Instructions",
92
+ value=list(sp.system_prompt_templates.keys())[0],
93
+ elem_classes="gr-dropdown"
94
+ )
95
+ # Display the selected system prompt
96
+ system_prompt_display = gr.Textbox(
97
+ value=sp.system_prompt_templates[list(sp.system_prompt_templates.keys())[0]],
98
+ label="Current Chatbot Instructions",
99
+ lines=5,
100
+ interactive=False
101
+ )
102
+
103
+ # Sources box (Now white, matching the other boxes)
104
  gr.Markdown("""
105
+ <div class="source-box">
106
+ <strong>Available sources:</strong>
107
+ <ul>
108
+ <li>Journey to Self-Realization</li>
109
+ <li>The Second Coming of Christ</li>
110
+ <li>Autobiography of a Yogi</li>
111
+ </ul>
112
  </div>
113
  """)
114
+
115
+ # Update system prompt display when a new prompt is selected
116
+ system_prompt_dropdown.change(
117
+ fn=chatbot.reset_system_prompt,
118
+ inputs=[system_prompt_dropdown],
119
+ outputs=[system_prompt_display]
120
+ )
121
+
122
+ # Submit button logic to handle chatbot conversation
123
+ submit_button.click(
124
+ fn=respond,
125
+ inputs=[user_input, chatbot_output],
126
+ outputs=[chatbot_output]
127
+ )
128
 
129
+ # Launch the interface
 
 
 
 
 
 
 
 
 
 
130
  demo.launch()
app2.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import src.srf_bot as sb
3
+ import prompts.system_prompts as sp
4
+ from langchain_core.messages import HumanMessage
5
+
6
+ # Initialize the chatbot
7
+ chatbot = sb.SRFChatbot()
8
+
9
+ # Dictionary to store passages with identifiers
10
+ retrieved_passages = {}
11
+
12
+ # Define the respond function
13
+ def respond(query, history):
14
+ formatted_query = [HumanMessage(content=query)]
15
+ # Invoke the chatbot
16
+ result = chatbot.graph.invoke({"messages": formatted_query}, chatbot.config)
17
+
18
+ # Extract the assistant's response
19
+ response = result["messages"][-1].content
20
+
21
+ # Retrieve passages from your vector database based on the query
22
+ # For the example, we'll use dummy passages
23
+ passages = [
24
+ "This is the full text of Passage 1.",
25
+ "This is the full text of Passage 2.",
26
+ "This is the full text of Passage 3."
27
+ ]
28
+
29
+ # Store passages with identifiers
30
+ passage_ids = []
31
+ for idx, passage in enumerate(passages):
32
+ identifier = f"Passage {idx+1}"
33
+ retrieved_passages[identifier] = passage
34
+ passage_ids.append(identifier)
35
+
36
+ # Reference passages in the response
37
+ linked_response = f"{response}\n\nReferences:"
38
+ for pid in passage_ids:
39
+ linked_response += f" [{pid}]"
40
+
41
+ # Append to history
42
+ history.append((query, linked_response))
43
+ return history, ""
44
+
45
+ # Function to get passage content based on selection
46
+ def get_passage_content(passage_id):
47
+ return retrieved_passages.get(passage_id, "Passage not found.")
48
+
49
+ # Function to update the system prompt
50
+ def update_system_prompt(selected_prompt):
51
+ # Update the chatbot's system prompt
52
+ chatbot.reset_system_prompt(selected_prompt)
53
+ # Update the displayed system prompt text
54
+ return sp.system_prompt_templates[selected_prompt]
55
+
56
+ # Gradio interface
57
+ with gr.Blocks() as demo:
58
+ gr.Markdown("# SRF Chatbot")
59
+
60
+ with gr.Row():
61
+ with gr.Column(scale=4):
62
+ # Chatbot interface
63
+ chatbot_output = gr.Chatbot()
64
+ user_input = gr.Textbox(placeholder="Type your question here...", label="Your Question")
65
+ submit_button = gr.Button("Submit")
66
+
67
+ with gr.Column(scale=1):
68
+ # Dropdown to select system prompts
69
+ system_prompt_dropdown = gr.Dropdown(
70
+ choices=list(sp.system_prompt_templates.keys()),
71
+ label="Select Chatbot Instructions",
72
+ value=list(sp.system_prompt_templates.keys())[0]
73
+ )
74
+ # Display the selected system prompt
75
+ system_prompt_display = gr.Textbox(
76
+ value=sp.system_prompt_templates[list(sp.system_prompt_templates.keys())[0]],
77
+ label="Current Chatbot Instructions",
78
+ lines=5,
79
+ interactive=False
80
+ )
81
+
82
+ # Update system prompt display when a new prompt is selected
83
+ system_prompt_dropdown.change(
84
+ fn=update_system_prompt,
85
+ inputs=[system_prompt_dropdown],
86
+ outputs=[system_prompt_display]
87
+ )
88
+
89
+ # Passage selection and display
90
+ gr.Markdown("### References")
91
+ passage_selector = gr.Dropdown(label="Select a passage to view", choices=[])
92
+ passage_display = gr.Markdown()
93
+
94
+ # Update the chatbot when the submit button is clicked
95
+ submit_button.click(
96
+ fn=respond,
97
+ inputs=[user_input, chatbot_output],
98
+ outputs=[chatbot_output, user_input]
99
+ )
100
+
101
+ # Update the passage selector options when the chatbot output changes
102
+ def update_passage_selector(chat_history):
103
+ # Get the latest passages
104
+ choices = list(retrieved_passages.keys())
105
+ return gr.update(choices=choices)
106
+
107
+ chatbot_output.change(
108
+ fn=update_passage_selector,
109
+ inputs=[chatbot_output],
110
+ outputs=[passage_selector]
111
+ )
112
+
113
+ # Display the selected passage
114
+ passage_selector.change(
115
+ fn=get_passage_content,
116
+ inputs=[passage_selector],
117
+ outputs=[passage_display]
118
+ )
119
+
120
+ demo.launch()
app_multi_tab.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from prompts.system_prompts import get_systemprompt, system_prompt_templates
3
+
4
+ # Define some pre-written templates for Tab 1
5
+ templates = {
6
+ "Friendly Chatbot": "You are a helpful, friendly chatbot that engages in light-hearted conversations.",
7
+ "Technical Assistant": "You are a technical assistant specialized in answering questions related to Python programming.",
8
+ "Nutrition Advisor": "You provide evidence-based advice on nutrition and healthy eating habits.",
9
+ }
10
+
11
+ # Define some agentic workflows for Tab 2
12
+ agentic_workflows = {
13
+ "Blog Post Generator": "This agent is designed to help generate a blog post based on user input.",
14
+ "Document Summarizer": "This agent summarizes long documents by extracting key points.",
15
+ "Task Manager": "This agent helps you organize tasks and provides step-by-step guidance."
16
+ }
17
+
18
+ # Chatbot logic for custom instructions or pre-written templates
19
+ def chatbot_response(system_instructions, user_query):
20
+ if "friendly" in system_instructions.lower():
21
+ return f"Friendly Chatbot says: Hi there! 😊 How can I assist you today?"
22
+ elif "technical" in system_instructions.lower():
23
+ return f"Technical Assistant says: Sure! Here's some information on Python: {user_query}"
24
+ elif "nutrition" in system_instructions.lower():
25
+ return f"Nutrition Advisor says: Here's some advice about healthy eating: {user_query}"
26
+ else:
27
+ return f"Custom Chatbot says: {user_query}"
28
+
29
+ # Chatbot conversation function
30
+ def chatbot_conversation(system_instructions, chat_history, user_query):
31
+ response = chatbot_response(system_instructions, user_query)
32
+ chat_history.append((user_query, response))
33
+ return chat_history, ""
34
+
35
+ # Chatbot conversation for predefined agentic workflows
36
+ def agentic_chatbot_conversation(workflow_instructions, chat_history, user_query):
37
+ response = f"Agent Workflow ({workflow_instructions}) says: {user_query}"
38
+ chat_history.append((user_query, response))
39
+ return chat_history, ""
40
+
41
+ # Function to update the interface when a selection is made from the dropdown (Tab 1)
42
+ def update_interface(template_name, custom_instructions):
43
+ if template_name == "Custom Instructions":
44
+ return gr.update(visible=True), gr.update(visible=False)
45
+ else:
46
+ template_content = templates.get(template_name, "")
47
+ return gr.update(visible=False), gr.update(visible=True, value=template_content)
48
+
49
+ # Build the Gradio interface with Tabs
50
+ with gr.Blocks(css=".gradio-container {background-color: #F0F0F0;} .gr-button {background-color: #1E3A8A; color: white;} .gr-textbox textarea {font-size: 16px;} .gr-markdown {font-size: 18px; color: #1E3A8A;}") as demo:
51
+
52
+ # Add Tabs
53
+ with gr.Tabs():
54
+
55
+ # Tab 1: Custom Instructions or Pre-Written Templates
56
+ with gr.Tab("Custom Instructions Chatbot"):
57
+ gr.Markdown("""
58
+ <div style='background-color:#E0E0E0; padding: 20px; border-radius: 10px;'>
59
+ <h1 style='text-align: center; color: #1E3A8A;'>SRF Innovation Labs - AI Chatbot Use Case Explorer</h1>
60
+ <p style='font-size: 18px; text-align: center; color: #1E3A8A;'>
61
+ This tool allows you to experiment with different system prompts,
62
+ giving you control over how the chatbot behaves. You can either use pre-defined templates
63
+ or write your own custom instructions.
64
+ </p>
65
+ </div>
66
+ """)
67
+
68
+ # Section to select system instructions from dropdown
69
+ gr.Markdown("<h2 style='color: #1E3A8A;'>Chatbot Setup</h2>")
70
+ template_name = gr.Dropdown(choices=["Custom Instructions"] + list(templates.keys()), label="Choose Instructions", value="Friendly Chatbot")
71
+ custom_instructions = gr.Textbox(label="Custom Instructions", visible=False, placeholder="Write your own instructions here...")
72
+ template_display = gr.Textbox(label="Template Content", interactive=False, visible=True)
73
+
74
+ # Chatbot interface
75
+ gr.Markdown("<h2 style='color: #1E3A8A;'>Chatbot Interaction</h2>")
76
+ chatbot = gr.Chatbot(label="Chatbot Conversation", height=300, show_label=False)
77
+ user_query = gr.Textbox(label="Your Query", placeholder="Ask a question or say something to the chatbot...")
78
+ submit_button = gr.Button("Send", elem_classes=["gr-button"])
79
+
80
+ # Update logic for Tab 1
81
+ template_name.change(fn=update_interface, inputs=[template_name, custom_instructions], outputs=[custom_instructions, template_display])
82
+ submit_button.click(fn=chatbot_conversation, inputs=[custom_instructions if template_name == "Custom Instructions" else template_display, chatbot, user_query], outputs=[chatbot, user_query])
83
+
84
+ # Tab 2: Predefined Agentic Workflows
85
+ with gr.Tab("Agentic Workflow Chatbots"):
86
+ gr.Markdown("""
87
+ <div style='background-color:#E0E0E0; padding: 20px; border-radius: 10px;'>
88
+ <h1 style='text-align: center; color: #1E3A8A;'>Agentic Workflow Explorer</h1>
89
+ <p style='font-size: 18px; text-align: center; color: #1E3A8A;'>
90
+ Explore predefined agentic workflows that execute specific tasks, such as generating blog posts,
91
+ summarizing documents, or managing tasks.
92
+ </p>
93
+ </div>
94
+ """)
95
+
96
+ # Dropdown for selecting agentic workflows
97
+ workflow_name = gr.Dropdown(choices=list(agentic_workflows.keys()), label="Choose Agent Workflow", value="Blog Post Generator")
98
+ workflow_display = gr.Textbox(label="Workflow Description", interactive=False, visible=True)
99
+ workflow_chatbot = gr.Chatbot(label="Agent Workflow Conversation", height=300, show_label=False)
100
+ workflow_user_query = gr.Textbox(label="Your Query", placeholder="Ask the agent to perform a task...")
101
+ workflow_submit_button = gr.Button("Send", elem_classes=["gr-button"])
102
+
103
+ # Chatbot interaction for agentic workflows
104
+ workflow_submit_button.click(fn=agentic_chatbot_conversation, inputs=[workflow_name, workflow_chatbot, workflow_user_query], outputs=[workflow_chatbot, workflow_user_query])
105
+
106
+ # Launch the app
107
+ demo.launch()
notebooks/01 Basic Chatbot.ipynb CHANGED
@@ -2,14 +2,16 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 1,
6
  "metadata": {},
7
  "outputs": [
8
  {
9
  "name": "stdout",
10
  "output_type": "stream",
11
  "text": [
12
- "langgraph-learning\n"
 
 
13
  ]
14
  }
15
  ],
@@ -38,20 +40,8 @@
38
  "%load_ext autoreload\n",
39
  "%autoreload 2\n",
40
  "\n",
41
- "import src.qdrant_manager as qm\n",
42
  "\n",
43
- "# Check available kernels\n",
44
- "from jupyter_client import kernelspec\n",
45
- "print(\"Available kernels:\")\n",
46
- "for kernel in kernelspec.find_kernel_specs():\n",
47
- " print(kernel)\n",
48
- "\n",
49
- "# If you still can't see your kernel, you might need to restart your Jupyter environment\n",
50
- "# or ensure that the kernel is properly installed and registered.\n",
51
- "# You can also try running the following in a terminal:\n",
52
- "# python -m ipykernel install --user --name=your_kernel_name\n",
53
- "\n",
54
- "# If issues persist, check your Jupyter configuration and environment setup.\n",
55
  "\n",
56
  "\n"
57
  ]
@@ -166,14 +156,14 @@
166
  },
167
  {
168
  "cell_type": "code",
169
- "execution_count": 4,
170
  "metadata": {},
171
  "outputs": [
172
  {
173
  "name": "stderr",
174
  "output_type": "stream",
175
  "text": [
176
- "/Users/nadaa/Documents/code/langgraph_learning/src/qdrant_manager.py:51: LangChainDeprecationWarning: The class `Qdrant` was deprecated in LangChain 0.1.2 and will be removed in 0.5.0. Use QdrantVectorStore instead.\n",
177
  " self.qdrant = Qdrant(\n"
178
  ]
179
  },
@@ -322,7 +312,7 @@
322
  },
323
  {
324
  "cell_type": "code",
325
- "execution_count": 9,
326
  "metadata": {},
327
  "outputs": [],
328
  "source": [
@@ -332,26 +322,34 @@
332
  },
333
  {
334
  "cell_type": "code",
335
- "execution_count": 10,
336
  "metadata": {},
337
  "outputs": [
338
  {
339
  "name": "stdout",
340
  "output_type": "stream",
341
  "text": [
342
- "Here are the full passages returned from the vector search on the importance of a true guru, with the most important quotes bolded:\n",
 
 
343
  "\n",
344
- "1. **\"It is admirable to lecture and teach good principles; but without possessing the qualifications of a real guru a teacher cannot redeem souls, nor should he presume to accept others as disciples until he himself has progressed far in his own Self-realization. True gurus train first their inner selves in the theologically advanced school of intuition and God-communion in meditation. They spiritually baptize themselves in Spirit before they aspire to initiate others. They teach not for mundane gain or glory, but for the singular purpose of leading souls to God. A guru never seeks for himself the devotion and obedience of his disciples, but transfers that reverence to God. It is not necessary for a disciple to be in the company of the guru in order to receive his blessings. What is most important is to be spiritually in tune with the guru, for his help is transferred to the disciple primarily on the inner spiritual plane rather than through material means. If the disciple is uncarping, unconditionally reverential and loving to the master, and faithful in following his precepts, his receptivity makes the task of the guru easier. Attunement links the help of the guru with the sincere striving of the disciple, even if the guru is no longer incarnate on earth.\"**\n",
345
  "\n",
346
- "2. **\"Baptized in a radiance as of a thousand suns, my whole being was blissfully enwrapped in God’s love and secured in the care of Guru’s wisdom. The Kriya Yoga sadhana imparted to me at that diksha was the “pearl of great price” with which all doors to the Divine Presence would be opened. A guru is not an ordinary spiritual teacher. One may have many teachers, but only one guru, who is the agent of salvation appointed by God in response to a devotee’s demands for release from the bondage of matter. Ministers in churches and priests in temples are oftentimes chosen only by a set standard of their intellectual knowledge of the scriptures, or by virtue of sacerdotal authority ceremonially conferred on them by a formally higher ecclesiastical superior. No guru can be developed only by years of study in the intellectual factory of a theological seminary, which deems it has attained its ends when it confers B.D. or D.D. degrees. Such titles can be won by men of good memory; but character, self-control, and the wisdom of soul intuition can be cultured only by knowledge and application of advanced methods of deep daily meditation that produce Self-realization and actual experience of God. Neither can one be a guru by self-choice. He must be ordained to serve and save others by a real guru, or else he must hear in reality the voice of God asking him to redeem others.\"**\n",
347
  "\n",
348
- "3. **\"Discretion and caution are particularly necessary in accepting a guru, one to whom explicit loyalty and trust are given. One may have many teachers in the beginning of his search, but when one’s heart and soul are confidently settled in a guru-disciple relationship ordained and blessed by God, the disciple has only one guru, and no other teachers thereafter. The devotee remains loyal to such a guru, being spiritually fulfilled by the God-sent messenger. To forsake the guru and his ideals is to spurn the help sent by God, the One Guru of gurus: “the Lord God of the holy prophets”; He whom alone “seers great, and heaven’s-path successful ones,” do worship. Unconditional love, loyalty, and obedience are hallmarks of the guru-disciple relationship. The spiritual soul contact between guru and disciple is one of eternal, unconditional divine love and friendship, bearing no taint of any selfish consideration. Human love is conditional and based upon merit and inborn attachments. Unconditional divine love is the Christ-love with which God embraces all His children, high or low, naughty or good, under all circumstances. Only a master, one who has cast off his ego with its biases and selfish expectations, is capable of serving as a perfect channel through which God’s divine love may flow without measure. In the spiritually receptive, loyalty to the guru rises spontaneously when the disciple’s heart is bathed in the aura of the guru’s unconditional love.\"**\n",
349
  "\n",
350
- "4. **\"Of the total requirement to achieve salvation, it is said that 25% is the disciple’s spiritual effort, 25% is the blessing of the guru, and the remaining 50% is the grace of God. The aspirant should not be tempted into complacency, however, waiting to be moved by the spirit of the blessings and grace, for it is the catalyst of the devotee’s effort that makes the formula work. As the devotee’s effort and the guru’s blessings are equally necessary to the disciple’s progress, we are taught in India the first requisite importance on the spiritual path of following faithfully one’s guru. He takes personal interest in the welfare of the devotee’s soul and lays before him a path of spiritual discipline that leads as far as the God-seeker wishes to go. In the early years of my spiritual search I was blessed to have frequent association with saintly souls whose God-consciousness transported my consciousness into supernal realms. But it was not until I met my own God-ordained guru, Swami Sri Yukteswar, and received initiation from him, that I understood fully the transforming power of the sacred guru-disciple tradition. Baptized in a radiance as of a thousand suns, my whole being was blissfully enwrapped in God’s love and secured in the care of Guru’s wisdom. The Kriya Yoga sadhana imparted to me at that diksha was the “pearl of great price” with which all doors to the Divine Presence would be opened. A guru is not an ordinary spiritual teacher.\"**\n",
351
  "\n",
352
- "5. **\"What is most important is to be spiritually in tune with the guru, for his help is transferred to the disciple primarily on the inner spiritual plane rather than through material means. If the disciple is uncarping, unconditionally reverential and loving to the master, and faithful in following his precepts, his receptivity makes the task of the guru easier. Attunement links the help of the guru with the sincere striving of the disciple, even if the guru is no longer incarnate on earth. My guru, Sri Yukteswarji, wrote: “To keep company with the Guru is not only to be in his physical presence (as this is sometimes impossible), but mainly means to keep him in our hearts and to be one with him in principle and to attune ourselves with him.…by keeping his appearance and attributes fully in mind, and by reflecting on the same and affectionately following his instructions, lamblike.” Many who were born centuries after Christ have attained God-realization through devotion to Jesus, the Good Shepherd, whom they followed as their guru or saviour. Jesus said, “Why call ye me Lord, Lord, and do not the things which I say?” The secret of the saints is that they practised what Jesus taught and exemplified; and by their single-hearted devotion they were able to attain ecstatic interiorization, as do adept yogis, which is necessary for communion with Christ.\"**\n",
 
 
 
353
  "\n",
354
- "These passages highlight the profound role of a true guru in spiritual development and the essential qualities that define this relationship. If you have any further questions or need additional insights, feel free to ask!\n"
 
 
 
355
  ]
356
  }
357
  ],
@@ -581,9 +579,9 @@
581
  ],
582
  "metadata": {
583
  "kernelspec": {
584
- "display_name": "langgraph_learning-fxXDDPLh",
585
  "language": "python",
586
- "name": "python3"
587
  },
588
  "language_info": {
589
  "codemirror_mode": {
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 8,
6
  "metadata": {},
7
  "outputs": [
8
  {
9
  "name": "stdout",
10
  "output_type": "stream",
11
  "text": [
12
+ "srf-chatbot\n",
13
+ "The autoreload extension is already loaded. To reload it, use:\n",
14
+ " %reload_ext autoreload\n"
15
  ]
16
  }
17
  ],
 
40
  "%load_ext autoreload\n",
41
  "%autoreload 2\n",
42
  "\n",
43
+ "import src.utils.qdrant_manager as qm\n",
44
  "\n",
 
 
 
 
 
 
 
 
 
 
 
 
45
  "\n",
46
  "\n"
47
  ]
 
156
  },
157
  {
158
  "cell_type": "code",
159
+ "execution_count": 9,
160
  "metadata": {},
161
  "outputs": [
162
  {
163
  "name": "stderr",
164
  "output_type": "stream",
165
  "text": [
166
+ "/Users/nadaa/Documents/code/py_innovations/srf_chatbot_v2/src/utils/qdrant_manager.py:51: LangChainDeprecationWarning: The class `Qdrant` was deprecated in LangChain 0.1.2 and will be removed in 0.5.0. Use :class:`~QdrantVectorStore` instead.\n",
167
  " self.qdrant = Qdrant(\n"
168
  ]
169
  },
 
312
  },
313
  {
314
  "cell_type": "code",
315
+ "execution_count": 10,
316
  "metadata": {},
317
  "outputs": [],
318
  "source": [
 
322
  },
323
  {
324
  "cell_type": "code",
325
+ "execution_count": 11,
326
  "metadata": {},
327
  "outputs": [
328
  {
329
  "name": "stdout",
330
  "output_type": "stream",
331
  "text": [
332
+ "Here are the full passages from the teachings of Paramhansa Yogananda regarding the importance of a true guru, with key quotes emphasized:\n",
333
+ "\n",
334
+ "1. **\"It is admirable to lecture and teach good principles; but without possessing the qualifications of a real guru a teacher cannot redeem souls, nor should he presume to accept others as disciples until he himself has progressed far in his own Self-realization.\"** True gurus train first their inner selves in the theologically advanced school of intuition and God-communion in meditation. They spiritually baptize themselves in Spirit before they aspire to initiate others. They teach not for mundane gain or glory, but for the singular purpose of leading souls to God. A guru never seeks for himself the devotion and obedience of his disciples, but transfers that reverence to God. It is not necessary for a disciple to be in the company of the guru in order to receive his blessings. What is most important is to be spiritually in tune with the guru, for his help is transferred to the disciple primarily on the inner spiritual plane rather than through material means.\n",
335
  "\n",
336
+ "2. **\"A guru is not an ordinary spiritual teacher.\"** One may have many teachers, but only one guru, who is the agent of salvation appointed by God in response to a devotee’s demands for release from the bondage of matter. Ministers in churches and priests in temples are oftentimes chosen only by a set standard of their intellectual knowledge of the scriptures, or by virtue of sacerdotal authority ceremonially conferred on them by a formally higher ecclesiastical superior. No guru can be developed only by years of study in the intellectual factory of a theological seminary, which deems it has attained its ends when it confers B.D. or D.D. degrees. Such titles can be won by men of good memory; but character, self-control, and the wisdom of soul intuition can be cultured only by knowledge and application of advanced methods of deep daily meditation that produce Self-realization and actual experience of God.\n",
337
  "\n",
338
+ "3. **\"Discretion and caution are particularly necessary in accepting a guru.\"** One may have many teachers in the beginning of his search, but when one’s heart and soul are confidently settled in a guru-disciple relationship ordained and blessed by God, the disciple has only one guru, and no other teachers thereafter. The devotee remains loyal to such a guru, being spiritually fulfilled by the God-sent messenger. To forsake the guru and his ideals is to spurn the help sent by God, the One Guru of gurus. **\"Unconditional love, loyalty, and obedience are hallmarks of the guru-disciple relationship.\"** The spiritual soul contact between guru and disciple is one of eternal, unconditional divine love and friendship, bearing no taint of any selfish consideration.\n",
339
  "\n",
340
+ "4. **\"Of the total requirement to achieve salvation, it is said that 25% is the disciple’s spiritual effort, 25% is the blessing of the guru, and the remaining 50% is the grace of God.\"** The aspirant should not be tempted into complacency, however, waiting to be moved by the spirit of the blessings and grace, for it is the catalyst of the devotee’s effort that makes the formula work. As the devotee’s effort and the guru’s blessings are equally necessary to the disciple’s progress, we are taught in India the first requisite importance on the spiritual path of following faithfully one’s guru.\n",
341
  "\n",
342
+ "5. **\"What is most important is to be spiritually in tune with the guru.\"** If the disciple is uncarping, unconditionally reverential and loving to the master, and faithful in following his precepts, his receptivity makes the task of the guru easier. Attunement links the help of the guru with the sincere striving of the disciple, even if the guru is no longer incarnate on earth.\n",
343
  "\n",
344
+ "### Recommended Reading:\n",
345
+ "- \"The Second Coming of Christ\" by Paramhansa Yogananda\n",
346
+ "- \"Autobiography of a Yogi\" by Paramhansa Yogananda\n",
347
+ "- \"The Yoga of Jesus\" by Paramhansa Yogananda\n",
348
  "\n",
349
+ "### Follow-Up Questions:\n",
350
+ "1. What qualities should one look for in a true guru?\n",
351
+ "2. How can a disciple cultivate a deeper connection with their guru?\n",
352
+ "3. Can the teachings of a guru be accessed without physical presence?\n"
353
  ]
354
  }
355
  ],
 
579
  ],
580
  "metadata": {
581
  "kernelspec": {
582
+ "display_name": "srf_chatbot_v2",
583
  "language": "python",
584
+ "name": "srf_chatbot_v2"
585
  },
586
  "language_info": {
587
  "codemirror_mode": {
notebooks/02 Chatbot with custom system prompt.ipynb CHANGED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 5,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "Running on local URL: http://127.0.0.1:7864\n",
13
+ "\n",
14
+ "To create a public link, set `share=True` in `launch()`.\n"
15
+ ]
16
+ },
17
+ {
18
+ "data": {
19
+ "text/html": [
20
+ "<div><iframe src=\"http://127.0.0.1:7864/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
21
+ ],
22
+ "text/plain": [
23
+ "<IPython.core.display.HTML object>"
24
+ ]
25
+ },
26
+ "metadata": {},
27
+ "output_type": "display_data"
28
+ },
29
+ {
30
+ "data": {
31
+ "text/plain": []
32
+ },
33
+ "execution_count": 5,
34
+ "metadata": {},
35
+ "output_type": "execute_result"
36
+ }
37
+ ],
38
+ "source": [
39
+ "import gradio as gr\n",
40
+ "\n",
41
+ "# Define some pre-written templates\n",
42
+ "templates = {\n",
43
+ " \"Friendly Chatbot\": \"You are a helpful, friendly chatbot that engages in light-hearted conversations.\",\n",
44
+ " \"Technical Assistant\": \"You are a technical assistant specialized in answering questions related to Python programming.\",\n",
45
+ " \"Nutrition Advisor\": \"You provide evidence-based advice on nutrition and healthy eating habits.\",\n",
46
+ "}\n",
47
+ "\n",
48
+ "# Chatbot logic: Takes system instructions and user query, returns a response\n",
49
+ "def chatbot_response(system_instructions, user_query):\n",
50
+ " if \"friendly\" in system_instructions.lower():\n",
51
+ " return f\"Friendly Chatbot says: Hi there! 😊 How can I assist you today?\"\n",
52
+ " elif \"technical\" in system_instructions.lower():\n",
53
+ " return f\"Technical Assistant says: Sure! Here's some information on Python: {user_query}\"\n",
54
+ " elif \"nutrition\" in system_instructions.lower():\n",
55
+ " return f\"Nutrition Advisor says: Here's some advice about healthy eating: {user_query}\"\n",
56
+ " else:\n",
57
+ " return f\"Custom Chatbot says: {user_query}\"\n",
58
+ "\n",
59
+ "# Function to update the interface when a selection is made from the dropdown\n",
60
+ "def update_interface(template_name, custom_instructions):\n",
61
+ " if template_name == \"Custom Instructions\":\n",
62
+ " return gr.update(visible=True), gr.update(visible(False))\n",
63
+ " else:\n",
64
+ " template_content = templates.get(template_name, \"\")\n",
65
+ " return gr.update(visible=False), gr.update(visible=True, value=template_content)\n",
66
+ "\n",
67
+ "# Chatbot conversation function\n",
68
+ "def chatbot_conversation(system_instructions, chat_history, user_query):\n",
69
+ " response = chatbot_response(system_instructions, user_query)\n",
70
+ " chat_history.append((user_query, response))\n",
71
+ " return chat_history, \"\"\n",
72
+ "\n",
73
+ "# Build the Gradio interface\n",
74
+ "with gr.Blocks() as demo:\n",
75
+ " \n",
76
+ " # Add the title and description\n",
77
+ " gr.Markdown(\"# **SRF Innovation Labs - AI Chatbot Use Case Explorer**\")\n",
78
+ " gr.Markdown(\"\"\"\n",
79
+ " Welcome to the SRF Innovation Labs AI Chatbot Use Case Explorer! \n",
80
+ " This tool allows you to experiment with different system prompts, \n",
81
+ " giving you control over how the chatbot behaves. You can either use pre-defined templates or write your own custom instructions.\n",
82
+ " \n",
83
+ " Additionally, the chatbot has access to a vector database where it can look up and retrieve learnings for various queries. \n",
84
+ " This makes it an excellent platform for exploring potential AI use cases in real-time.\n",
85
+ " \"\"\")\n",
86
+ "\n",
87
+ " # Section to select system instructions from dropdown\n",
88
+ " gr.Markdown(\"## **Chatbot Setup**\")\n",
89
+ "\n",
90
+ " # Dropdown for selecting a pre-written template or custom instructions\n",
91
+ " template_name = gr.Dropdown(choices=[\"Custom Instructions\"] + list(templates.keys()), label=\"Choose Instructions\", value=\"Friendly Chatbot\")\n",
92
+ " \n",
93
+ " # Textbox for custom chatbot instructions (only shown when \"Custom Instructions\" is selected)\n",
94
+ " custom_instructions = gr.Textbox(label=\"Custom Instructions\", visible=False, placeholder=\"Write your own instructions here...\")\n",
95
+ " \n",
96
+ " # Output field to display the selected pre-written template (not shown when Custom Instructions is selected)\n",
97
+ " template_display = gr.Textbox(label=\"Template Content\", interactive=False, visible=True)\n",
98
+ " \n",
99
+ " # Section for chat interface\n",
100
+ " gr.Markdown(\"## **Chatbot Interaction**\")\n",
101
+ "\n",
102
+ " # Chatbot interface with chat history\n",
103
+ " chatbot = gr.Chatbot(label=\"Chatbot Conversation\")\n",
104
+ " user_query = gr.Textbox(label=\"Your Query\", placeholder=\"Ask a question or say something to the chatbot...\")\n",
105
+ "\n",
106
+ " # Button to submit the query\n",
107
+ " submit_button = gr.Button(\"Send\")\n",
108
+ "\n",
109
+ " # Update logic to control the display based on the dropdown selection\n",
110
+ " template_name.change(fn=update_interface, \n",
111
+ " inputs=[template_name, custom_instructions], \n",
112
+ " outputs=[custom_instructions, template_display])\n",
113
+ "\n",
114
+ " # Chatbot interaction logic\n",
115
+ " submit_button.click(fn=chatbot_conversation, \n",
116
+ " inputs=[custom_instructions if template_name == \"Custom Instructions\" else template_display, chatbot, user_query], \n",
117
+ " outputs=[chatbot, user_query])\n",
118
+ "\n",
119
+ "# Launch the app\n",
120
+ "demo.launch()\n"
121
+ ]
122
+ },
123
+ {
124
+ "cell_type": "code",
125
+ "execution_count": 6,
126
+ "metadata": {},
127
+ "outputs": [
128
+ {
129
+ "name": "stdout",
130
+ "output_type": "stream",
131
+ "text": [
132
+ "Running on local URL: http://127.0.0.1:7865\n",
133
+ "\n",
134
+ "To create a public link, set `share=True` in `launch()`.\n"
135
+ ]
136
+ },
137
+ {
138
+ "data": {
139
+ "text/html": [
140
+ "<div><iframe src=\"http://127.0.0.1:7865/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
141
+ ],
142
+ "text/plain": [
143
+ "<IPython.core.display.HTML object>"
144
+ ]
145
+ },
146
+ "metadata": {},
147
+ "output_type": "display_data"
148
+ },
149
+ {
150
+ "data": {
151
+ "text/plain": []
152
+ },
153
+ "execution_count": 6,
154
+ "metadata": {},
155
+ "output_type": "execute_result"
156
+ }
157
+ ],
158
+ "source": [
159
+ "import gradio as gr\n",
160
+ "\n",
161
+ "# Define some pre-written templates for Tab 1\n",
162
+ "templates = {\n",
163
+ " \"Friendly Chatbot\": \"You are a helpful, friendly chatbot that engages in light-hearted conversations.\",\n",
164
+ " \"Technical Assistant\": \"You are a technical assistant specialized in answering questions related to Python programming.\",\n",
165
+ " \"Nutrition Advisor\": \"You provide evidence-based advice on nutrition and healthy eating habits.\",\n",
166
+ "}\n",
167
+ "\n",
168
+ "# Define some agentic workflows for Tab 2\n",
169
+ "agentic_workflows = {\n",
170
+ " \"Blog Post Generator\": \"This agent is designed to help generate a blog post based on user input.\",\n",
171
+ " \"Document Summarizer\": \"This agent summarizes long documents by extracting key points.\",\n",
172
+ " \"Task Manager\": \"This agent helps you organize tasks and provides step-by-step guidance.\"\n",
173
+ "}\n",
174
+ "\n",
175
+ "# Chatbot logic for custom instructions or pre-written templates\n",
176
+ "def chatbot_response(system_instructions, user_query):\n",
177
+ " if \"friendly\" in system_instructions.lower():\n",
178
+ " return f\"Friendly Chatbot says: Hi there! 😊 How can I assist you today?\"\n",
179
+ " elif \"technical\" in system_instructions.lower():\n",
180
+ " return f\"Technical Assistant says: Sure! Here's some information on Python: {user_query}\"\n",
181
+ " elif \"nutrition\" in system_instructions.lower():\n",
182
+ " return f\"Nutrition Advisor says: Here's some advice about healthy eating: {user_query}\"\n",
183
+ " else:\n",
184
+ " return f\"Custom Chatbot says: {user_query}\"\n",
185
+ "\n",
186
+ "# Chatbot conversation function\n",
187
+ "def chatbot_conversation(system_instructions, chat_history, user_query):\n",
188
+ " response = chatbot_response(system_instructions, user_query)\n",
189
+ " chat_history.append((user_query, response))\n",
190
+ " return chat_history, \"\"\n",
191
+ "\n",
192
+ "# Chatbot conversation for predefined agentic workflows\n",
193
+ "def agentic_chatbot_conversation(workflow_instructions, chat_history, user_query):\n",
194
+ " response = f\"Agent Workflow ({workflow_instructions}) says: {user_query}\"\n",
195
+ " chat_history.append((user_query, response))\n",
196
+ " return chat_history, \"\"\n",
197
+ "\n",
198
+ "# Function to update the interface when a selection is made from the dropdown (Tab 1)\n",
199
+ "def update_interface(template_name, custom_instructions):\n",
200
+ " if template_name == \"Custom Instructions\":\n",
201
+ " return gr.update(visible=True), gr.update(visible=False)\n",
202
+ " else:\n",
203
+ " template_content = templates.get(template_name, \"\")\n",
204
+ " return gr.update(visible=False), gr.update(visible=True, value=template_content)\n",
205
+ "\n",
206
+ "# Build the Gradio interface with Tabs\n",
207
+ "with gr.Blocks() as demo:\n",
208
+ " \n",
209
+ " # Add Tabs\n",
210
+ " with gr.Tabs():\n",
211
+ " \n",
212
+ " # Tab 1: Custom Instructions or Pre-Written Templates\n",
213
+ " with gr.Tab(\"Custom Instructions Chatbot\"):\n",
214
+ " gr.Markdown(\"# **SRF Innovation Labs - AI Chatbot Use Case Explorer**\")\n",
215
+ " gr.Markdown(\"\"\"\n",
216
+ " This tool allows you to experiment with different system prompts, \n",
217
+ " giving you control over how the chatbot behaves. You can either use pre-defined templates or write your own custom instructions.\n",
218
+ " \"\"\")\n",
219
+ "\n",
220
+ " # Section to select system instructions from dropdown\n",
221
+ " gr.Markdown(\"## **Chatbot Setup**\")\n",
222
+ " template_name = gr.Dropdown(choices=[\"Custom Instructions\"] + list(templates.keys()), label=\"Choose Instructions\", value=\"Friendly Chatbot\")\n",
223
+ " custom_instructions = gr.Textbox(label=\"Custom Instructions\", visible=False, placeholder=\"Write your own instructions here...\")\n",
224
+ " template_display = gr.Textbox(label=\"Template Content\", interactive=False, visible=True)\n",
225
+ "\n",
226
+ " # Chatbot interface\n",
227
+ " gr.Markdown(\"## **Chatbot Interaction**\")\n",
228
+ " chatbot = gr.Chatbot(label=\"Chatbot Conversation\")\n",
229
+ " user_query = gr.Textbox(label=\"Your Query\", placeholder=\"Ask a question or say something to the chatbot...\")\n",
230
+ " submit_button = gr.Button(\"Send\")\n",
231
+ "\n",
232
+ " # Update logic for Tab 1\n",
233
+ " template_name.change(fn=update_interface, inputs=[template_name, custom_instructions], outputs=[custom_instructions, template_display])\n",
234
+ " submit_button.click(fn=chatbot_conversation, inputs=[custom_instructions if template_name == \"Custom Instructions\" else template_display, chatbot, user_query], outputs=[chatbot, user_query])\n",
235
+ "\n",
236
+ " # Tab 2: Predefined Agentic Workflows\n",
237
+ " with gr.Tab(\"Agentic Workflow Chatbots\"):\n",
238
+ " gr.Markdown(\"# **Agentic Workflow Explorer**\")\n",
239
+ " gr.Markdown(\"\"\"\n",
240
+ " This tab allows you to experiment with different agentic workflows that are predefined. \n",
241
+ " Each workflow executes a specific task, such as generating blog posts, summarizing documents, or managing tasks.\n",
242
+ " \"\"\")\n",
243
+ "\n",
244
+ " # Dropdown for selecting agentic workflows\n",
245
+ " workflow_name = gr.Dropdown(choices=list(agentic_workflows.keys()), label=\"Choose Agent Workflow\", value=\"Blog Post Generator\")\n",
246
+ " workflow_display = gr.Textbox(label=\"Workflow Description\", interactive=False, visible=True)\n",
247
+ " workflow_chatbot = gr.Chatbot(label=\"Agent Workflow Conversation\")\n",
248
+ " workflow_user_query = gr.Textbox(label=\"Your Query\", placeholder=\"Ask the agent to perform a task...\")\n",
249
+ " workflow_submit_button = gr.Button(\"Send\")\n",
250
+ "\n",
251
+ " # Chatbot interaction for agentic workflows\n",
252
+ " workflow_submit_button.click(fn=agentic_chatbot_conversation, inputs=[workflow_name, workflow_chatbot, workflow_user_query], outputs=[workflow_chatbot, workflow_user_query])\n",
253
+ "\n",
254
+ "# Launch the app\n",
255
+ "demo.launch()\n"
256
+ ]
257
+ },
258
+ {
259
+ "cell_type": "code",
260
+ "execution_count": null,
261
+ "metadata": {},
262
+ "outputs": [],
263
+ "source": []
264
+ }
265
+ ],
266
+ "metadata": {
267
+ "kernelspec": {
268
+ "display_name": "srf_chatbot_v2",
269
+ "language": "python",
270
+ "name": "srf_chatbot_v2"
271
+ },
272
+ "language_info": {
273
+ "codemirror_mode": {
274
+ "name": "ipython",
275
+ "version": 3
276
+ },
277
+ "file_extension": ".py",
278
+ "mimetype": "text/x-python",
279
+ "name": "python",
280
+ "nbconvert_exporter": "python",
281
+ "pygments_lexer": "ipython3",
282
+ "version": "3.11.9"
283
+ }
284
+ },
285
+ "nbformat": 4,
286
+ "nbformat_minor": 2
287
+ }
notebooks/03 Experimentation Chatbot.ipynb CHANGED
@@ -2,7 +2,7 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 65,
6
  "metadata": {},
7
  "outputs": [
8
  {
@@ -51,7 +51,7 @@
51
  },
52
  {
53
  "cell_type": "code",
54
- "execution_count": 64,
55
  "metadata": {},
56
  "outputs": [],
57
  "source": [
@@ -93,20 +93,15 @@
93
  },
94
  {
95
  "cell_type": "code",
96
- "execution_count": 37,
97
  "metadata": {},
98
  "outputs": [],
99
  "source": [
100
- "# class ChatbotState(TypedDict):\n",
101
- "# # Messages have the type \"list\". The `add_messages` function defines how this state key should be updated\n",
102
- "# # (in this case, it appends messages to the list, rather than overwriting them)\n",
103
- "# messages: Annotated[list, add_messages]\n",
104
- "\n",
105
  "\n",
106
  "class SRFChatbot:\n",
107
  " def __init__(\n",
108
  " self,\n",
109
- " chatbot_instructions: str,\n",
110
  " model: str = 'gpt-4o-mini',\n",
111
  " temperature: float = 0,\n",
112
  " ):\n",
@@ -121,8 +116,18 @@
121
  " # Get the configurable\n",
122
  " self.config = self.get_configurable()\n",
123
  " \n",
 
 
 
 
 
 
 
 
 
124
  "\n",
125
  " def get_configurable(self):\n",
 
126
  " self.thread_id = str(uuid.uuid4())\n",
127
  " return {\"configurable\": {\"thread_id\": self.thread_id}}\n",
128
  " \n",
@@ -164,104 +169,202 @@
164
  },
165
  {
166
  "cell_type": "code",
167
- "execution_count": 59,
168
  "metadata": {},
169
  "outputs": [],
170
  "source": [
171
- "chatbot_instructions = sp.system_prompt_templates['Open-Ended Bot']\n",
172
- "chatbot = SRFChatbot(chatbot_instructions=chatbot_instructions)\n"
173
  ]
174
  },
175
  {
176
  "cell_type": "code",
177
- "execution_count": 61,
178
  "metadata": {},
179
  "outputs": [],
180
  "source": [
181
- "query = \"I am having a lot of trouble sleeping. What can I do?\"\n",
182
  "results = chatbot.graph.invoke({\"messages\": [HumanMessage(content=query)]}, chatbot.config)"
183
  ]
184
  },
185
  {
186
  "cell_type": "code",
187
- "execution_count": 62,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  "metadata": {},
189
  "outputs": [
190
  {
191
  "data": {
192
  "text/plain": [
193
- "[HumanMessage(content='I am having a lot of trouble sleeping. What can I do?', additional_kwargs={}, response_metadata={}, id='49aec330-967f-48ec-a14c-3e2f351281b1'),\n",
194
- " AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_9mRC9uFfiJ3E7F1wmYuR7fSS', 'function': {'arguments': '{\"query\":\"trouble sleeping\"}', 'name': 'vector_search'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 249, 'total_tokens': 265, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_e9627b5346', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-868473e1-e6e9-49be-9c87-973a9c9289dd-0', tool_calls=[{'name': 'vector_search', 'args': {'query': 'trouble sleeping'}, 'id': 'call_9mRC9uFfiJ3E7F1wmYuR7fSS', 'type': 'tool_call'}], usage_metadata={'input_tokens': 249, 'output_tokens': 16, 'total_tokens': 265}),\n",
195
- " ToolMessage(content=\"[Document(metadata={'chapter_name': 'The Nervous System Connects You to the World and to God', 'split_id_sequential': 606, 'split_id_uuid': '21278b52-b4c0-4c0a-8355-a31448c7ce72', 'publication_name': 'Journey to Self-Realization', '_id': '0a69ff6f-1d13-451c-815a-6db330a19d6e', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Sleep is an unconscious way of turning off life energy from the nerves. You therefore get some rest during slumber, but you do not have the conscious experience of bliss that the superconscious state produces. When you awaken from sleep, you are just the same as you were before sleep. But if you can cross the subconscious realm into the superconscious land of light, you will have the most wonderful experiences, and these produce lasting spiritual changes in the consciousness. The more you can remain in that interiorized state of bliss in meditation, the more you will feel that joy with you all the time, even in the midst of activities.'), Document(metadata={'chapter_number': 12, 'split_id_sequential': 215, 'split_id_uuid': 'fcfcaed4-65da-41c8-a5e7-6e68a5773829', 'chapter_name': 'Chapter 12: Years In My Master’S Hermitage', 'publication_name': 'Autobiography of a Yogi', '_id': '0a4aeeaa-eb45-4f4b-b0af-716b68ac70ed', '_collection_name': 'openai_large_chunks_1500char'}, page_content='As midnight approached, my guru might fall into a doze with the naturalness of a child. There was no fuss about bedding. He often lay down, without even a pillow, on a narrow davenport which was the background for his customary tiger-skin seat. A night-long philosophical discussion was not rare; any disciple could summon it by intensity of interest. I felt no tiredness then, no desire for sleep; Master’s living words were sufficient. “Oh, it is dawn! Let us walk by the Ganges.” So ended many of my periods of nocturnal edification. My early months with Sri Yukteswar culminated in a useful lesson: “How to Outwit a Mosquito.” At home my family always used protective curtains at night. I was dismayed to discover that in the Serampore hermitage this prudent custom was honoured in the breach. Yet the insects were in full residence; I was bitten from head to foot. My guru took pity on me. “Buy yourself a curtain, and also one for me.” He laughed and added, “If you buy only one, for yourself, all mosquitoes will concentrate on me!” I was more than thankful to comply. On every night that I spent in Serampore, my guru would ask me to arrange the bedtime curtains. One night, when a cloud of mosquitoes surrounded us, Master failed to issue his usual instructions. I listened nervously to the anticipatory hum of the insects. Getting into bed, I threw a propitiatory prayer in their general direction. A half hour later, I coughed pretentiously to attract my guru’s attention.'), Document(metadata={'publication_name': 'The Second Coming of Christ', 'split_id_uuid': 'dfffff39-bce8-4cc5-9a8a-383dc14db69a', 'chapter_number': 14, 'chapter_name': 'Discourse 14 - The Ascension Of Man—Lifting Up The Serpent In The Wilderness', 'split_id_sequential': 497, '_id': '73103f5f-8745-4eb5-8b27-7560a7395531', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Why does man feel joy in sleep? Because when he is in the stage of deep, dreamless sleep, unconscious of the body, physical limitations are forgotten and the mind momentarily taps a higher consciousness. The yogi knows the scientific art of withdrawing consciously from his sensory nerves, so that no outer disturbance of sight, sound, touch, taste, or smell can gain entry into the inner sanctum of his peace-saturated meditation. Soldiers posted for days on the front lines are able to fall asleep despite the constant roar of battle, because of the body’s mechanism of unconsciously withdrawing the energy from the ears and other sensory organs. The yogi reasons that this can be done consciously. By knowledge and practice of the definite laws and scientific techniques of concentration, yogis switch off the senses at will—going beyond subconscious slumber into blissful superconscious interiorization. Though the soul is given periods of freedom from body consciousness at regular intervals in its existence—for a few hours each night, and for a longer respite between physical incarnations during the sleep of death—the unenlightened man inevitably finds that his unfulfilled earthly yearnings stir him once again to the consciousness of the body.'), Document(metadata={'split_id_sequential': 471, 'publication_name': 'The Second Coming of Christ', 'split_id_uuid': '4052d4dc-3f3d-4134-9724-1a3ce5b29178', 'chapter_number': 13, 'chapter_name': 'Discourse 13 - The Second Birth Of Man In Spirit', '_id': 'cf225e5e-6892-41e5-984d-612275968193', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Man remains firmly convinced that he is essentially a body, even though he daily receives proof to the contrary. Every night in sleep, “the little death,” he discards his identification with the physical form and is reborn as invisible consciousness. Why is it that man is compelled to sleep? Because sleep is a reminder of what is beyond the state of sleep—the state of the soul.13 Mortal existence could not be borne without at least subconscious contact with the soul, which is provided by sleep. At nighttime man dumps the body into the subconscious and becomes an angel; in the daytime he becomes once more a devil, divorced from Spirit by the desires and sensations of the body. By Kriya Yoga meditation he can be a god in the daytime, like Christ and the Great Ones. He goes beyond the subconscious to the superconscious, and dissolves the consciousness of the body in the ecstasy of God. One who can do this is born again. He knows his soul as a waft of the invisible wind of Spirit—soaring free in the unbounded heavens, entrapped no longer in a whirling dust devil traipsing heedlessly over the toilsome tracks of matter. This earth is a habitat of trouble and suffering, but the kingdom of God that is behind this material plane is an abode of freedom and bliss. The soul of the awakening man has followed a hard-earned way—many incarnations of upward evolution—in order to arrive at the human state and the possibility to reclaim his lost divinity.'), Document(metadata={'chapter_name': 'Examine Yourself to See What Makes You Nervous', 'publication_name': 'Journey to Self-Realization', 'split_id_sequential': 160, 'split_id_uuid': '0900b6ab-2a48-48db-a66b-2ca0e80f9c70', '_id': 'de7f20d2-d3ac-45b6-8588-1a0b568e2ec9', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Other cars were speeding past us on the steep, winding grade. I thought they were hurrying to get to the mountaintop in time to see the sunrise. To my great amazement, when we arrived we were the only ones outside to enjoy the view. All the others were in the restaurant drinking coffee and eating doughnuts. Imagine! They rushed to the top and then rushed back, just for the thrill of being able to say when they got home that they had been there, and had coffee and doughnuts on Pikes Peak. That is what nervousness does. We should take time to enjoy things—the beauties of God’s creation, the many blessings of life—but avoid undue excitement, restlessness, and sudden emotions, which burn up the nervous system. Talking too much, including the habit of engaging in long conversations on the telephone, creates nervousness. Habitual twitching—such as drumming the fingers or moving the toes—burns energy in the nerves. Another cause of nervousness, though you may not be aware of it, is the noise of the radio or television going on for hours at a time. All sounds cause the nerves to react.1 A study conducted in the police department in Chicago showed that if human beings were not subjected to the bombardment of the sounds of modern living, which are especially harsh in cities, they could live years longer. Learn to enjoy silence; don’t listen to the radio or television for hours on end, or have them blaring mindlessly in the background all the time.')]\", name='vector_search', id='cec3278a-776b-4f4c-a7df-680bc132d50f', tool_call_id='call_9mRC9uFfiJ3E7F1wmYuR7fSS'),\n",
196
- " AIMessage(content=\"If you're having trouble sleeping, here are some insights from the teachings of Paramhansa Yogananda that may help:\\n\\n1. **Understanding Sleep**: Sleep is described as an unconscious way of turning off life energy from the nerves. While you get some rest during sleep, it does not provide the conscious experience of bliss that meditation can offer. By practicing meditation and striving to reach a superconscious state, you can experience lasting spiritual changes and a deeper sense of joy that can accompany you even during your waking hours.\\n\\n2. **Conscious Withdrawal**: Yogananda explains that the yogi learns to consciously withdraw from sensory nerves, allowing for a peaceful state of meditation. This practice can help you manage disturbances that might affect your sleep. By training yourself to switch off the senses at will, you can go beyond mere subconscious slumber into a blissful state of interiorization.\\n\\n3. **The Nature of Sleep**: Sleep serves as a reminder of the soul's existence beyond the physical body. It allows for a temporary escape from physical limitations. Engaging in practices like Kriya Yoga meditation can help you connect with your soul and experience a sense of freedom and bliss, even during the day.\\n\\n4. **Managing Nervousness**: Nervousness can significantly impact your ability to sleep. Yogananda advises avoiding undue excitement, restlessness, and sudden emotions, as these can burn up the nervous system. Creating a peaceful environment, minimizing noise, and enjoying silence can help calm your nerves and improve your sleep quality.\\n\\n5. **Meditation Practice**: Incorporating meditation into your daily routine can help you achieve a state of calmness and bliss, which may alleviate sleep troubles. The more you can interiorize and experience that bliss during meditation, the more it can positively affect your overall well-being, including your sleep.\\n\\nConsider integrating these practices into your life to help improve your sleep quality.\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 384, 'prompt_tokens': 2208, 'total_tokens': 2592, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_1bb46167f9', 'finish_reason': 'stop', 'logprobs': None}, id='run-6e2e6206-fe5a-4ade-8688-d89532b26c60-0', usage_metadata={'input_tokens': 2208, 'output_tokens': 384, 'total_tokens': 2592})]"
197
  ]
198
  },
199
- "execution_count": 62,
200
  "metadata": {},
201
  "output_type": "execute_result"
202
  }
203
  ],
204
  "source": [
205
- "chatbot.graph.get_state(chatbot.config).values['messages']"
 
206
  ]
207
  },
208
  {
209
  "cell_type": "code",
210
- "execution_count": 63,
 
 
 
 
 
 
 
211
  "metadata": {},
212
  "outputs": [
213
  {
214
  "name": "stdout",
215
  "output_type": "stream",
216
  "text": [
217
- "If you're having trouble sleeping, here are some insights from the teachings of Paramhansa Yogananda that may help:\n",
218
- "\n",
219
- "1. **Understanding Sleep**: Sleep is described as an unconscious way of turning off life energy from the nerves. While you get some rest during sleep, it does not provide the conscious experience of bliss that meditation can offer. By practicing meditation and striving to reach a superconscious state, you can experience lasting spiritual changes and a deeper sense of joy that can accompany you even during your waking hours.\n",
220
- "\n",
221
- "2. **Conscious Withdrawal**: Yogananda explains that the yogi learns to consciously withdraw from sensory nerves, allowing for a peaceful state of meditation. This practice can help you manage disturbances that might affect your sleep. By training yourself to switch off the senses at will, you can go beyond mere subconscious slumber into a blissful state of interiorization.\n",
222
- "\n",
223
- "3. **The Nature of Sleep**: Sleep serves as a reminder of the soul's existence beyond the physical body. It allows for a temporary escape from physical limitations. Engaging in practices like Kriya Yoga meditation can help you connect with your soul and experience a sense of freedom and bliss, even during the day.\n",
224
- "\n",
225
- "4. **Managing Nervousness**: Nervousness can significantly impact your ability to sleep. Yogananda advises avoiding undue excitement, restlessness, and sudden emotions, as these can burn up the nervous system. Creating a peaceful environment, minimizing noise, and enjoying silence can help calm your nerves and improve your sleep quality.\n",
226
  "\n",
227
- "5. **Meditation Practice**: Incorporating meditation into your daily routine can help you achieve a state of calmness and bliss, which may alleviate sleep troubles. The more you can interiorize and experience that bliss during meditation, the more it can positively affect your overall well-being, including your sleep.\n",
228
- "\n",
229
- "Consider integrating these practices into your life to help improve your sleep quality.\n"
230
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  }
232
  ],
233
  "source": [
234
- "print(results['messages'][-1].content)"
235
- ]
236
- },
237
- {
238
- "cell_type": "code",
239
- "execution_count": null,
240
- "metadata": {},
241
- "outputs": [],
242
- "source": [
243
- "\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  ]
245
  },
246
  {
247
  "cell_type": "code",
248
- "execution_count": 66,
249
  "metadata": {},
250
  "outputs": [
251
  {
252
  "name": "stdout",
253
  "output_type": "stream",
254
  "text": [
255
- "Running on local URL: http://127.0.0.1:7866\n",
256
- "Running on public URL: https://94b754ba708e7402d2.gradio.live\n",
257
  "\n",
258
- "This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)\n"
259
  ]
260
  },
261
  {
262
  "data": {
263
  "text/html": [
264
- "<div><iframe src=\"https://94b754ba708e7402d2.gradio.live\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
265
  ],
266
  "text/plain": [
267
  "<IPython.core.display.HTML object>"
@@ -274,46 +377,143 @@
274
  "data": {
275
  "text/plain": []
276
  },
277
- "execution_count": 66,
278
  "metadata": {},
279
  "output_type": "execute_result"
280
  }
281
  ],
282
  "source": [
283
- "def respond(message, history):\n",
284
- " # Format the history and new message into the expected structure\n",
285
- " formatted_messages = []\n",
286
- " for human, ai in history:\n",
287
- " formatted_messages.append(HumanMessage(content=human))\n",
288
- " if ai: # AI might not have responded yet\n",
289
- " formatted_messages.append(AIMessage(content=ai))\n",
290
- " \n",
291
- " # Add the new message\n",
292
- " formatted_messages.append(HumanMessage(content=message))\n",
293
- " \n",
294
  " # Invoke the graph with properly formatted input\n",
295
- " result = chatbot.graph.invoke({\"messages\": formatted_messages}, chatbot.config)\n",
296
  " \n",
297
  " # Extract the assistant's response\n",
298
  " response = result[\"messages\"][-1].content\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  " \n",
300
- " return response\n",
 
 
 
 
 
 
 
 
 
 
 
 
301
  "\n",
302
- "# Create and launch the Gradio interface\n",
303
- "gradio = gr.ChatInterface(respond)\n",
304
- "gradio.launch(share=True)"
305
  ]
306
  },
307
  {
308
  "cell_type": "code",
309
- "execution_count": 74,
310
  "metadata": {},
311
  "outputs": [
312
  {
313
  "name": "stdout",
314
  "output_type": "stream",
315
  "text": [
316
- "Running on local URL: http://127.0.0.1:7869\n",
317
  "\n",
318
  "To create a public link, set `share=True` in `launch()`.\n"
319
  ]
@@ -321,7 +521,7 @@
321
  {
322
  "data": {
323
  "text/html": [
324
- "<div><iframe src=\"http://127.0.0.1:7869/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
325
  ],
326
  "text/plain": [
327
  "<IPython.core.display.HTML object>"
@@ -334,118 +534,135 @@
334
  "data": {
335
  "text/plain": []
336
  },
337
- "execution_count": 74,
338
  "metadata": {},
339
  "output_type": "execute_result"
340
- },
341
- {
342
- "name": "stderr",
343
- "output_type": "stream",
344
- "text": [
345
- "Traceback (most recent call last):\n",
346
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/gradio/queueing.py\", line 536, in process_events\n",
347
- " response = await route_utils.call_process_api(\n",
348
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
349
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/gradio/route_utils.py\", line 322, in call_process_api\n",
350
- " output = await app.get_blocks().process_api(\n",
351
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
352
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/gradio/blocks.py\", line 1935, in process_api\n",
353
- " result = await self.call_function(\n",
354
- " ^^^^^^^^^^^^^^^^^^^^^^^^^\n",
355
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/gradio/blocks.py\", line 1520, in call_function\n",
356
- " prediction = await anyio.to_thread.run_sync( # type: ignore\n",
357
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
358
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/anyio/to_thread.py\", line 56, in run_sync\n",
359
- " return await get_async_backend().run_sync_in_worker_thread(\n",
360
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
361
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/anyio/_backends/_asyncio.py\", line 2405, in run_sync_in_worker_thread\n",
362
- " return await future\n",
363
- " ^^^^^^^^^^^^\n",
364
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/anyio/_backends/_asyncio.py\", line 914, in run\n",
365
- " result = context.run(func, *args)\n",
366
- " ^^^^^^^^^^^^^^^^^^^^^^^^\n",
367
- " File \"/Users/nadaa/.local/share/virtualenvs/srf_chatbot_v2-9vTIDuJW/lib/python3.11/site-packages/gradio/utils.py\", line 826, in wrapper\n",
368
- " response = f(*args, **kwargs)\n",
369
- " ^^^^^^^^^^^^^^^^^^\n",
370
- " File \"/var/folders/wm/nll4dzqx2_n5zxq0y2h84cs40000gn/T/ipykernel_49088/3264473872.py\", line 24, in chatbot_conversation\n",
371
- " result = respond(user_query, history)\n",
372
- " ^^^^^^^\n",
373
- "NameError: name 'history' is not defined\n"
374
- ]
375
  }
376
  ],
377
  "source": [
378
  "import gradio as gr\n",
 
 
 
379
  "\n",
380
- "# Get the prompt templates\n",
381
- "prompt_templates = sp.system_prompt_templates\n",
 
 
 
 
 
 
382
  "\n",
383
- "# Global variable to hold the current SRFChatbot instance\n",
384
- "chatbot = SRFChatbot(chatbot_instructions=prompt_templates['Open-Ended Bot'])\n",
385
  "\n",
386
- "def initialize_chatbot(prompt_name):\n",
387
- " selected_prompt = prompt_templates[prompt_name]\n",
388
- " chatbot = SRFChatbot(chatbot_instructions=selected_prompt)\n",
389
- " return selected_prompt, [] # Return the prompt text and reset the chat history\n",
390
  "\n",
391
- "def chatbot_conversation(chat_history, user_query):\n",
392
- " global chatbot\n",
393
- " if chatbot is None:\n",
394
- " # Initialize with default prompt if not already initialized\n",
395
- " default_prompt = list(prompt_templates.keys())[0]\n",
396
- " chatbot = SRFChatbot(chatbot_instructions=prompt_templates[default_prompt])\n",
397
- " \n",
398
- " \n",
399
- " # Process the conversation\n",
400
- " result = respond(user_query, history)\n",
401
- " \n",
402
- " # Extract the bot's response\n",
403
- " bot_response = result[\"messages\"][-1].content\n",
404
- " \n",
405
- " # Update the chat history\n",
406
- " chat_history.append((user_query, bot_response))\n",
407
- " \n",
408
- " return chat_history, \"\"\n",
409
  "\n",
410
- "# Gradio interface\n",
411
- "with gr.Blocks() as demo:\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  " gr.Markdown(\"# SRF Chatbot\")\n",
413
  " \n",
414
- " with gr.Row():\n",
415
- " with gr.Column(scale=4):\n",
416
- " chatbot_output = gr.Chatbot()\n",
417
- " user_input = gr.Textbox(placeholder=\"Type your message here...\")\n",
 
418
  " submit_button = gr.Button(\"Submit\")\n",
419
  " \n",
420
- " with gr.Column(scale=1):\n",
 
421
  " system_prompt_dropdown = gr.Dropdown(\n",
422
- " choices=list(prompt_templates.keys()),\n",
423
- " label=\"Select System Prompt\",\n",
424
- " value=list(prompt_templates.keys())[0]\n",
 
425
  " )\n",
 
426
  " system_prompt_display = gr.Textbox(\n",
427
- " value=prompt_templates[list(prompt_templates.keys())[0]],\n",
428
- " label=\"Current System Prompt\",\n",
429
  " lines=5,\n",
430
  " interactive=False\n",
431
  " )\n",
 
 
 
 
 
 
 
 
 
 
 
 
432
  " \n",
 
433
  " system_prompt_dropdown.change(\n",
434
- " fn=initialize_chatbot,\n",
435
  " inputs=[system_prompt_dropdown],\n",
436
  " outputs=[system_prompt_display]\n",
437
  " )\n",
438
  " \n",
 
439
  " submit_button.click(\n",
440
- " fn=chatbot_conversation,\n",
441
- " inputs=[chatbot_output, user_input],\n",
442
- " outputs=[chatbot_output]\n",
443
  " )\n",
444
  "\n",
445
- "# Initialize the chatbot with the default prompt\n",
446
- "initialize_chatbot(list(prompt_templates.keys())[0])\n",
447
- "\n",
448
- "demo.launch()"
449
  ]
450
  },
451
  {
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 30,
6
  "metadata": {},
7
  "outputs": [
8
  {
 
51
  },
52
  {
53
  "cell_type": "code",
54
+ "execution_count": 31,
55
  "metadata": {},
56
  "outputs": [],
57
  "source": [
 
93
  },
94
  {
95
  "cell_type": "code",
96
+ "execution_count": 32,
97
  "metadata": {},
98
  "outputs": [],
99
  "source": [
 
 
 
 
 
100
  "\n",
101
  "class SRFChatbot:\n",
102
  " def __init__(\n",
103
  " self,\n",
104
+ " chatbot_instructions: str = sp.system_prompt_templates['Open-Ended Bot'],\n",
105
  " model: str = 'gpt-4o-mini',\n",
106
  " temperature: float = 0,\n",
107
  " ):\n",
 
116
  " # Get the configurable\n",
117
  " self.config = self.get_configurable()\n",
118
  " \n",
119
+ " def reset_system_prompt(self, chatbot_instructions_dropdown: str):\n",
120
+ " # Get chatbot instructions\n",
121
+ " chatbot_instructions = sp.system_prompt_templates[chatbot_instructions_dropdown]\n",
122
+ " # Reset the system prompt\n",
123
+ " self.system_message = SystemMessage(content=chatbot_instructions)\n",
124
+ " # Reset the configurable\n",
125
+ " self.config = self.get_configurable()\n",
126
+ "\n",
127
+ " return chatbot_instructions\n",
128
  "\n",
129
  " def get_configurable(self):\n",
130
+ " # This thread id is used to keep track of the chatbot's conversation\n",
131
  " self.thread_id = str(uuid.uuid4())\n",
132
  " return {\"configurable\": {\"thread_id\": self.thread_id}}\n",
133
  " \n",
 
169
  },
170
  {
171
  "cell_type": "code",
172
+ "execution_count": 33,
173
  "metadata": {},
174
  "outputs": [],
175
  "source": [
176
+ "chatbot = SRFChatbot()\n"
 
177
  ]
178
  },
179
  {
180
  "cell_type": "code",
181
+ "execution_count": 15,
182
  "metadata": {},
183
  "outputs": [],
184
  "source": [
185
+ "query = \"Tell me more about reducing nervousness to improve sleep\"\n",
186
  "results = chatbot.graph.invoke({\"messages\": [HumanMessage(content=query)]}, chatbot.config)"
187
  ]
188
  },
189
  {
190
  "cell_type": "code",
191
+ "execution_count": 16,
192
+ "metadata": {},
193
+ "outputs": [
194
+ {
195
+ "name": "stdout",
196
+ "output_type": "stream",
197
+ "text": [
198
+ "To reduce nervousness and improve sleep, it is essential to recognize that much of our nervousness stems from our own reactions and emotional states. Paramhansa Yogananda emphasizes that restlessness and emotional excitement can overload the nervous system, leading to fatigue and anxiety. Engaging in deep meditation can help calm the nerves, as it allows the body to rest and rejuvenate. Additionally, dietary choices play a significant role; consuming calming foods such as whole grains, fruits, and avoiding stimulants like caffeine and alcohol can support a healthier nervous system. Practicing silence and reducing exposure to noise can also alleviate nervousness, creating a more peaceful environment conducive to sleep.\n",
199
+ "\n",
200
+ "**Quotes:**\n",
201
+ "1. \"You always blame other things for making you nervous, but never accuse yourself. Yet it is you who make yourself nervous; ninety-nine percent is your own fault.\" - *Journey to Self-Realization, Probing the Core of Nervousness*\n",
202
+ "2. \"When you stop overloading the nervous system, as when you are in deep sleep or a state of calmness in meditation, you are not nervous at all.\" - *Journey to Self-Realization, Probing the Core of Nervousness*\n",
203
+ "3. \"Learn to enjoy silence; don’t listen to the radio or television for hours on end, or have them blaring mindlessly in the background all the time.\" - *Journey to Self-Realization, Examine Yourself to See What Makes You Nervous*\n",
204
+ "4. \"The greatest healing of nervousness takes place when we attune our lives to God.\" - *Journey to Self-Realization, Attunement With God: Greatest Cure for Nervousness*\n",
205
+ "\n",
206
+ "**Recommended Reading:**\n",
207
+ "- *Journey to Self-Realization* by Paramhansa Yogananda\n",
208
+ "\n",
209
+ "**Follow-up Questions:**\n",
210
+ "1. What specific techniques can I use in meditation to calm my nerves?\n",
211
+ "2. Are there particular foods or drinks that are especially beneficial for reducing nervousness?\n",
212
+ "3. How can I create a more peaceful environment at home to improve my sleep?\n"
213
+ ]
214
+ }
215
+ ],
216
+ "source": [
217
+ "print(results['messages'][-1].content)"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": 17,
223
  "metadata": {},
224
  "outputs": [
225
  {
226
  "data": {
227
  "text/plain": [
228
+ "[HumanMessage(content='Tell me more about reducing nervousness to improve sleep', additional_kwargs={}, response_metadata={}, id='c1d3f9ba-0e06-4a6a-b38c-3dcd3be78bbf'),\n",
229
+ " AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_fjyQpF0pjUQZ8gobl2SAozXV', 'function': {'arguments': '{\"query\":\"reducing nervousness improve sleep\"}', 'name': 'vector_search'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 433, 'total_tokens': 452, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_1bb46167f9', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4a39fe1a-6413-4ba3-8aa3-290dc31a27bb-0', tool_calls=[{'name': 'vector_search', 'args': {'query': 'reducing nervousness improve sleep'}, 'id': 'call_fjyQpF0pjUQZ8gobl2SAozXV', 'type': 'tool_call'}], usage_metadata={'input_tokens': 433, 'output_tokens': 19, 'total_tokens': 452}),\n",
230
+ " ToolMessage(content=\"[Document(metadata={'chapter_name': 'Probing the Core of Nervousness', 'split_id_sequential': 418, 'split_id_uuid': '5ca2777d-c2a0-4e32-96b7-e43ed71c3aa2', 'publication_name': 'Journey to Self-Realization', '_id': '2151431e-7e07-44b6-8f33-7c8e277993c8', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Probing the Core of Nervousness Self-Realization Fellowship Temple, San Diego, California, June 15, 1947 Everyone has at times been nervous, more or less, without knowing why. I may shake this piece of cloth and say it is nervous, but what is making the cloth move? When I cease moving my hand, the cloth lies limp. You always blame other things for making you nervous, but never accuse yourself. Yet it is you who make yourself nervous; ninety-nine percent is your own fault. Restlessness, emotional excitement, concentrates too much energy in the nerves so that they begin to wear out. After years and years, the adverse effects of that nervousness begin to show. The nerves are very tough—God made them so, because they have to last a lifetime—but it is necessary to give them proper care. When you stop overloading the nervous system, as when you are in deep sleep or a state of calmness in meditation, you are not nervous at all. In meditative ecstasy the nerves become highly rested and rejuvenated.'), Document(metadata={'split_id_sequential': 526, 'publication_name': 'Journey to Self-Realization', 'split_id_uuid': '2cecd1d8-68bf-4831-a6d2-de6028ff5fc5', 'chapter_name': 'The Best Diet for the Nerves', '_id': 'ff7b43a1-b42d-4983-8472-6eaeed695f4b', '_collection_name': 'openai_large_chunks_1500char'}, page_content='A yogic drink that is very good for the nervous system is made by adding crushed rock candy and fresh lime juice to a glass of water. It should be thoroughly mixed and evenly blended so that the taste is equally sweet and sour. I have recommended this to many people with excellent results. Another beneficial practice when you are very nervous is to take a cold bath. I once told this to a newspaperman. He said, “Well, if I did that every time I was nervous, I would have to carry a bathtub with me all the time!” I said, “Not necessary. Take a large piece of ice and rub it all over the body, especially over all the openings of the body. With this yoga technique, you will find that your nerves will become much calmer.”'), Document(metadata={'split_id_sequential': 525, 'publication_name': 'Journey to Self-Realization', 'chapter_name': 'The Best Diet for the Nerves', 'split_id_uuid': '5b366387-d311-486a-bc74-0559cb45d041', '_id': 'e2a33e74-64d8-47f4-9edd-41eebe277585', '_collection_name': 'openai_large_chunks_1500char'}, page_content='The Best Diet for the Nerves Even foods, which also are material condensations of astral rays of life, have effects that are correlated to their colour. Various kinds of natural white foods are good for the nervous system; they benefit the white matter of the brain. Berries are good for the gray matter of the brain—that is, blueberries or blackberries (which are really purple). Most fruits are gold in colour (or variants of gold, such as red and orange). As gold is the colour of the creative vibratory energy in matter, such fruits help the muscles, the blood, and the tissues. Goat’s milk, unbleached almonds, and raisins are very good for the nervous system. But all forms of meat of higher animals, especially beef and pork, are harmful to the nervous system; they are hyperstimulating and cause aggressiveness. Avoid too much starch, especially foods made from refined flour. Eat whole grains, cottage cheese, and plenty of fruits, fruit juices, and fresh vegetables—these are important. Needless to say, alcoholic beverages and drugs destroy the nervous system; stay away from them. A yogic drink that is very good for the nervous system is made by adding crushed rock candy and fresh lime juice to a glass of water. It should be thoroughly mixed and evenly blended so that the taste is equally sweet and sour. I have recommended this to many people with excellent results. Another beneficial practice when you are very nervous is to take a cold bath. I once told this to a newspaperman.'), Document(metadata={'chapter_name': 'Examine Yourself to See What Makes You Nervous', 'publication_name': 'Journey to Self-Realization', 'split_id_sequential': 160, 'split_id_uuid': '0900b6ab-2a48-48db-a66b-2ca0e80f9c70', '_id': 'de7f20d2-d3ac-45b6-8588-1a0b568e2ec9', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Other cars were speeding past us on the steep, winding grade. I thought they were hurrying to get to the mountaintop in time to see the sunrise. To my great amazement, when we arrived we were the only ones outside to enjoy the view. All the others were in the restaurant drinking coffee and eating doughnuts. Imagine! They rushed to the top and then rushed back, just for the thrill of being able to say when they got home that they had been there, and had coffee and doughnuts on Pikes Peak. That is what nervousness does. We should take time to enjoy things—the beauties of God’s creation, the many blessings of life—but avoid undue excitement, restlessness, and sudden emotions, which burn up the nervous system. Talking too much, including the habit of engaging in long conversations on the telephone, creates nervousness. Habitual twitching—such as drumming the fingers or moving the toes—burns energy in the nerves. Another cause of nervousness, though you may not be aware of it, is the noise of the radio or television going on for hours at a time. All sounds cause the nerves to react.1 A study conducted in the police department in Chicago showed that if human beings were not subjected to the bombardment of the sounds of modern living, which are especially harsh in cities, they could live years longer. Learn to enjoy silence; don’t listen to the radio or television for hours on end, or have them blaring mindlessly in the background all the time.'), Document(metadata={'chapter_name': 'Attunement With God: Greatest Cure for Nervousness', 'split_id_sequential': 33, 'split_id_uuid': '28716ee9-dae2-46e5-80e6-f53bffa190c1', 'publication_name': 'Journey to Self-Realization', '_id': 'b079c905-181b-42ef-8c5f-849c0ba81f9b', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Attunement With God: Greatest Cure for Nervousness Remember that the greatest healing of nervousness takes place when we attune our lives to God. The highest commandments given to man are to love God with all your heart, and with all your soul, and with all your mind, and with all your strength; and secondly, to love your neighbour as yourself.13 If you follow these, everything will come in its own way, and in the right way. It is not enough just to be a strict moralist—stones and goats do not break moral laws; still, they do not know God. But when you love God deeply enough, even if you are the greatest of sinners, you will be transformed and redeemed. The great saint Mirabai14 said, “To find the Divine One, the only indispensable is love.” That truth touched me deeply. All the prophets observe these two foremost commandments. Loving God with all your heart means to love Him with the love that you feel for the person who is dearest to you—with the love of the mother or father for the child, or the lover for the beloved. Give that kind of unconditional love to God. Loving God with all your soul means you can truly love Him when through deep meditation you know yourself as a soul, a child of God, made in His image. Loving God with all your mind means that when you are praying, your whole attention is on Him, not distracted by restless thoughts. In meditation, think only of God; don’t let the mind wander to everything else but God.')]\", name='vector_search', id='34f93038-5940-4a3b-bfd2-7f595ee69775', tool_call_id='call_fjyQpF0pjUQZ8gobl2SAozXV'),\n",
231
+ " AIMessage(content='To reduce nervousness and improve sleep, it is essential to recognize that much of our nervousness stems from our own reactions and emotional states. Paramhansa Yogananda emphasizes that restlessness and emotional excitement can overload the nervous system, leading to fatigue and anxiety. Engaging in deep meditation can help calm the nerves, as it allows the body to rest and rejuvenate. Additionally, dietary choices play a significant role; consuming calming foods such as whole grains, fruits, and avoiding stimulants like caffeine and alcohol can support a healthier nervous system. Practicing silence and reducing exposure to noise can also alleviate nervousness, creating a more peaceful environment conducive to sleep.\\n\\n**Quotes:**\\n1. \"You always blame other things for making you nervous, but never accuse yourself. Yet it is you who make yourself nervous; ninety-nine percent is your own fault.\" - *Journey to Self-Realization, Probing the Core of Nervousness*\\n2. \"When you stop overloading the nervous system, as when you are in deep sleep or a state of calmness in meditation, you are not nervous at all.\" - *Journey to Self-Realization, Probing the Core of Nervousness*\\n3. \"Learn to enjoy silence; don’t listen to the radio or television for hours on end, or have them blaring mindlessly in the background all the time.\" - *Journey to Self-Realization, Examine Yourself to See What Makes You Nervous*\\n4. \"The greatest healing of nervousness takes place when we attune our lives to God.\" - *Journey to Self-Realization, Attunement With God: Greatest Cure for Nervousness*\\n\\n**Recommended Reading:**\\n- *Journey to Self-Realization* by Paramhansa Yogananda\\n\\n**Follow-up Questions:**\\n1. What specific techniques can I use in meditation to calm my nerves?\\n2. Are there particular foods or drinks that are especially beneficial for reducing nervousness?\\n3. How can I create a more peaceful environment at home to improve my sleep?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 416, 'prompt_tokens': 2347, 'total_tokens': 2763, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_1bb46167f9', 'finish_reason': 'stop', 'logprobs': None}, id='run-0814edcd-020f-4ae0-bab2-b696f9948fec-0', usage_metadata={'input_tokens': 2347, 'output_tokens': 416, 'total_tokens': 2763})]"
232
  ]
233
  },
234
+ "execution_count": 17,
235
  "metadata": {},
236
  "output_type": "execute_result"
237
  }
238
  ],
239
  "source": [
240
+ "\n",
241
+ "chatbot.graph.get_state(chatbot.config)[0]['messages']"
242
  ]
243
  },
244
  {
245
  "cell_type": "code",
246
+ "execution_count": 20,
247
+ "metadata": {},
248
+ "outputs": [],
249
+ "source": []
250
+ },
251
+ {
252
+ "cell_type": "code",
253
+ "execution_count": 35,
254
  "metadata": {},
255
  "outputs": [
256
  {
257
  "name": "stdout",
258
  "output_type": "stream",
259
  "text": [
260
+ "Running on local URL: http://127.0.0.1:7875\n",
 
 
 
 
 
 
 
 
261
  "\n",
262
+ "To create a public link, set `share=True` in `launch()`.\n"
 
 
263
  ]
264
+ },
265
+ {
266
+ "data": {
267
+ "text/html": [
268
+ "<div><iframe src=\"http://127.0.0.1:7875/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
269
+ ],
270
+ "text/plain": [
271
+ "<IPython.core.display.HTML object>"
272
+ ]
273
+ },
274
+ "metadata": {},
275
+ "output_type": "display_data"
276
+ },
277
+ {
278
+ "data": {
279
+ "text/plain": []
280
+ },
281
+ "execution_count": 35,
282
+ "metadata": {},
283
+ "output_type": "execute_result"
284
  }
285
  ],
286
  "source": [
287
+ "\n",
288
+ "def respond(query, history):\n",
289
+ "\n",
290
+ " formatted_query = [HumanMessage(content=query)]\n",
291
+ " # Invoke the graph with properly formatted input\n",
292
+ " result = chatbot.graph.invoke({\"messages\": formatted_query}, chatbot.config)\n",
293
+ " \n",
294
+ " # Extract the assistant's response\n",
295
+ " response = result[\"messages\"][-1].content\n",
296
+ "\n",
297
+ " history.append((query, response))\n",
298
+ "\n",
299
+ " \n",
300
+ " return history\n",
301
+ "\n",
302
+ "chatbot = SRFChatbot()\n",
303
+ "\n",
304
+ "# Gradio interface with responsive layout\n",
305
+ "with gr.Blocks(css=\"\"\"\n",
306
+ " @media (max-width: 600px) {\n",
307
+ " .gr-row { flex-direction: column !important; }\n",
308
+ " .gr-column { width: 100% !important; }\n",
309
+ " }\n",
310
+ "\"\"\") as demo:\n",
311
+ " gr.Markdown(\"# SRF Chatbot\")\n",
312
+ " \n",
313
+ " with gr.Row(elem_classes=\"gr-row\"):\n",
314
+ " with gr.Column(scale=4, elem_classes=\"gr-column\"):\n",
315
+ " chatbot_output = gr.Chatbot()\n",
316
+ " user_input = gr.Textbox(placeholder=\"Type your question here...\")\n",
317
+ " submit_button = gr.Button(\"Submit\")\n",
318
+ " \n",
319
+ " with gr.Column(scale=1, elem_classes=\"gr-column\"):\n",
320
+ " system_prompt_dropdown = gr.Dropdown(\n",
321
+ " choices=list(sp.system_prompt_templates.keys()),\n",
322
+ " label=\"Select Chatbot Instructions\",\n",
323
+ " value=list(sp.system_prompt_templates.keys())[0]\n",
324
+ " )\n",
325
+ " system_prompt_display = gr.Textbox(\n",
326
+ " value=sp.system_prompt_templates[list(sp.system_prompt_templates.keys())[0]],\n",
327
+ " label=\"Current Chatbot Instructions\",\n",
328
+ " lines=5,\n",
329
+ " interactive=False\n",
330
+ " )\n",
331
+ " \n",
332
+ " # Update system prompt display when a new prompt is selected\n",
333
+ " system_prompt_dropdown.change(\n",
334
+ " fn=chatbot.reset_system_prompt,\n",
335
+ " inputs=[system_prompt_dropdown],\n",
336
+ " outputs=[system_prompt_display]\n",
337
+ " )\n",
338
+ " \n",
339
+ " # Submit button logic to handle chatbot conversation\n",
340
+ " submit_button.click(\n",
341
+ " fn=respond,\n",
342
+ " inputs=[user_input, chatbot_output],\n",
343
+ " outputs=[chatbot_output]\n",
344
+ " )\n",
345
+ "\n",
346
+ "\n",
347
+ "demo.launch()\n"
348
  ]
349
  },
350
  {
351
  "cell_type": "code",
352
+ "execution_count": 43,
353
  "metadata": {},
354
  "outputs": [
355
  {
356
  "name": "stdout",
357
  "output_type": "stream",
358
  "text": [
359
+ "Running on local URL: http://127.0.0.1:7883\n",
 
360
  "\n",
361
+ "To create a public link, set `share=True` in `launch()`.\n"
362
  ]
363
  },
364
  {
365
  "data": {
366
  "text/html": [
367
+ "<div><iframe src=\"http://127.0.0.1:7883/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
368
  ],
369
  "text/plain": [
370
  "<IPython.core.display.HTML object>"
 
377
  "data": {
378
  "text/plain": []
379
  },
380
+ "execution_count": 43,
381
  "metadata": {},
382
  "output_type": "execute_result"
383
  }
384
  ],
385
  "source": [
386
+ "import gradio as gr\n",
387
+ "\n",
388
+ "# Define the respond function\n",
389
+ "def respond(query, history):\n",
390
+ " formatted_query = [HumanMessage(content=query)]\n",
 
 
 
 
 
 
391
  " # Invoke the graph with properly formatted input\n",
392
+ " result = chatbot.graph.invoke({\"messages\": formatted_query}, chatbot.config)\n",
393
  " \n",
394
  " # Extract the assistant's response\n",
395
  " response = result[\"messages\"][-1].content\n",
396
+ "\n",
397
+ " history.append((query, response))\n",
398
+ "\n",
399
+ " return history, \"\"\n",
400
+ "\n",
401
+ "# Initialize chatbot\n",
402
+ "chatbot = SRFChatbot()\n",
403
+ "\n",
404
+ "# Gradio interface with black and grey color scheme\n",
405
+ "with gr.Blocks(css=\"\"\"\n",
406
+ " .gradio-container {\n",
407
+ " background-color: #F0F0F0; \n",
408
+ " font-family: 'Arial', sans-serif;\n",
409
+ " }\n",
410
+ " h1, h2, p {\n",
411
+ " color: black;\n",
412
+ " }\n",
413
+ " h1 {\n",
414
+ " font-size: 32px;\n",
415
+ " text-align: left;\n",
416
+ " }\n",
417
+ " h2 {\n",
418
+ " font-size: 24px;\n",
419
+ " }\n",
420
+ " p {\n",
421
+ " font-size: 18px;\n",
422
+ " margin-bottom: 15px;\n",
423
+ " }\n",
424
+ " .gr-button {\n",
425
+ " background-color: #333333; \n",
426
+ " color: white;\n",
427
+ " font-size: 18px;\n",
428
+ " padding: 10px;\n",
429
+ " }\n",
430
+ " .gr-textbox textarea {\n",
431
+ " font-size: 18px;\n",
432
+ " color: black;\n",
433
+ " }\n",
434
+ " .gr-dropdown {\n",
435
+ " font-size: 18px;\n",
436
+ " color: black;\n",
437
+ " }\n",
438
+ " .source-box {\n",
439
+ " background-color: #D0D0D0; \n",
440
+ " padding: 10px; \n",
441
+ " border-radius: 8px; \n",
442
+ " margin-top: 20px;\n",
443
+ " color: black;\n",
444
+ " }\n",
445
+ " @media (max-width: 600px) {\n",
446
+ " .gr-row { flex-direction: column !important; }\n",
447
+ " .gr-column { width: 100% !important; }\n",
448
+ " }\n",
449
+ "\"\"\") as demo:\n",
450
+ " \n",
451
+ " # Title\n",
452
+ " gr.Markdown(\"# SRF Chatbot\")\n",
453
+ " \n",
454
+ " with gr.Row(elem_classes=\"gr-row\"):\n",
455
+ " with gr.Column(scale=4, elem_classes=\"gr-column\"):\n",
456
+ " # Chatbot interface\n",
457
+ " chatbot_output = gr.Chatbot()\n",
458
+ " user_input = gr.Textbox(placeholder=\"Type your question here...\", label=\"Your Question\")\n",
459
+ " submit_button = gr.Button(\"Submit\")\n",
460
+ " \n",
461
+ " with gr.Column(scale=1, elem_classes=\"gr-column\"):\n",
462
+ " # Dropdown to select system prompts\n",
463
+ " system_prompt_dropdown = gr.Dropdown(\n",
464
+ " choices=list(sp.system_prompt_templates.keys()),\n",
465
+ " label=\"Select Chatbot Instructions\",\n",
466
+ " value=list(sp.system_prompt_templates.keys())[0],\n",
467
+ " elem_classes=\"gr-dropdown\"\n",
468
+ " )\n",
469
+ " # Display the selected system prompt\n",
470
+ " system_prompt_display = gr.Textbox(\n",
471
+ " value=sp.system_prompt_templates[list(sp.system_prompt_templates.keys())[0]],\n",
472
+ " label=\"Current Chatbot Instructions\",\n",
473
+ " lines=5,\n",
474
+ " interactive=False\n",
475
+ " )\n",
476
+ " \n",
477
+ " # Sources box\n",
478
+ " gr.Markdown(\"\"\"\n",
479
+ " <div class=\"source-box\">\n",
480
+ " <strong>Available sources:</strong>\n",
481
+ " <ul>\n",
482
+ " <li>Journey to Self-Realization</li>\n",
483
+ " <li>The Second Coming of Christ</li>\n",
484
+ " <li>Autobiography of a Yogi</li>\n",
485
+ " </ul>\n",
486
+ " </div>\n",
487
+ " \"\"\")\n",
488
  " \n",
489
+ " # Update system prompt display when a new prompt is selected\n",
490
+ " system_prompt_dropdown.change(\n",
491
+ " fn=chatbot.reset_system_prompt,\n",
492
+ " inputs=[system_prompt_dropdown],\n",
493
+ " outputs=[system_prompt_display]\n",
494
+ " )\n",
495
+ " \n",
496
+ " # Submit button logic to handle chatbot conversation\n",
497
+ " submit_button.click(\n",
498
+ " fn=respond,\n",
499
+ " inputs=[user_input, chatbot_output],\n",
500
+ " outputs=[chatbot_output, user_input]\n",
501
+ " )\n",
502
  "\n",
503
+ "# Launch the interface\n",
504
+ "demo.launch()\n"
 
505
  ]
506
  },
507
  {
508
  "cell_type": "code",
509
+ "execution_count": 44,
510
  "metadata": {},
511
  "outputs": [
512
  {
513
  "name": "stdout",
514
  "output_type": "stream",
515
  "text": [
516
+ "Running on local URL: http://127.0.0.1:7885\n",
517
  "\n",
518
  "To create a public link, set `share=True` in `launch()`.\n"
519
  ]
 
521
  {
522
  "data": {
523
  "text/html": [
524
+ "<div><iframe src=\"http://127.0.0.1:7885/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
525
  ],
526
  "text/plain": [
527
  "<IPython.core.display.HTML object>"
 
534
  "data": {
535
  "text/plain": []
536
  },
537
+ "execution_count": 44,
538
  "metadata": {},
539
  "output_type": "execute_result"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  }
541
  ],
542
  "source": [
543
  "import gradio as gr\n",
544
+ "import src.srf_bot as sb\n",
545
+ "import prompts.system_prompts as sp\n",
546
+ "from langchain_core.messages import HumanMessage \n",
547
  "\n",
548
+ "# Define the respond function\n",
549
+ "def respond(query, history):\n",
550
+ " formatted_query = [HumanMessage(content=query)]\n",
551
+ " # Invoke the graph with properly formatted input\n",
552
+ " result = chatbot.graph.invoke({\"messages\": formatted_query}, chatbot.config)\n",
553
+ " \n",
554
+ " # Extract the assistant's response\n",
555
+ " response = result[\"messages\"][-1].content\n",
556
  "\n",
557
+ " history.append((query, response))\n",
 
558
  "\n",
559
+ " return history, \"\"\n",
 
 
 
560
  "\n",
561
+ "# Initialize chatbot\n",
562
+ "chatbot = sb.SRFChatbot()\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  "\n",
564
+ "# Gradio interface with black and grey color scheme\n",
565
+ "with gr.Blocks(css=\"\"\"\n",
566
+ " .gradio-container {\n",
567
+ " background-color: #F0F0F0; \n",
568
+ " font-family: 'Arial', sans-serif;\n",
569
+ " }\n",
570
+ " h1, h2, p {\n",
571
+ " color: black;\n",
572
+ " }\n",
573
+ " h1 {\n",
574
+ " font-size: 32px;\n",
575
+ " text-align: left;\n",
576
+ " }\n",
577
+ " h2 {\n",
578
+ " font-size: 24px;\n",
579
+ " }\n",
580
+ " p {\n",
581
+ " font-size: 18px;\n",
582
+ " margin-bottom: 15px;\n",
583
+ " }\n",
584
+ " .gr-button {\n",
585
+ " background-color: #333333; \n",
586
+ " color: white;\n",
587
+ " font-size: 18px;\n",
588
+ " padding: 10px;\n",
589
+ " }\n",
590
+ " .gr-textbox textarea {\n",
591
+ " font-size: 18px;\n",
592
+ " color: black;\n",
593
+ " }\n",
594
+ " .gr-dropdown {\n",
595
+ " font-size: 18px;\n",
596
+ " color: black;\n",
597
+ " }\n",
598
+ " .source-box {\n",
599
+ " background-color: white; \n",
600
+ " padding: 10px; \n",
601
+ " border-radius: 8px; \n",
602
+ " margin-top: 20px;\n",
603
+ " color: black;\n",
604
+ " border: 1px solid #D0D0D0;\n",
605
+ " }\n",
606
+ " @media (max-width: 600px) {\n",
607
+ " .gr-row { flex-direction: column !important; }\n",
608
+ " .gr-column { width: 100% !important; }\n",
609
+ " }\n",
610
+ "\"\"\") as demo:\n",
611
+ " \n",
612
+ " # Title\n",
613
  " gr.Markdown(\"# SRF Chatbot\")\n",
614
  " \n",
615
+ " with gr.Row(elem_classes=\"gr-row\"):\n",
616
+ " with gr.Column(scale=4, elem_classes=\"gr-column\"):\n",
617
+ " # Chatbot interface\n",
618
+ " chatbot_output = gr.Chatbot(height=600) # Increased height for longer chat interface\n",
619
+ " user_input = gr.Textbox(placeholder=\"Type your question here...\", label=\"Your Question\")\n",
620
  " submit_button = gr.Button(\"Submit\")\n",
621
  " \n",
622
+ " with gr.Column(scale=1, elem_classes=\"gr-column\"):\n",
623
+ " # Dropdown to select system prompts\n",
624
  " system_prompt_dropdown = gr.Dropdown(\n",
625
+ " choices=list(sp.system_prompt_templates.keys()),\n",
626
+ " label=\"Select Chatbot Instructions\",\n",
627
+ " value=list(sp.system_prompt_templates.keys())[0],\n",
628
+ " elem_classes=\"gr-dropdown\"\n",
629
  " )\n",
630
+ " # Display the selected system prompt\n",
631
  " system_prompt_display = gr.Textbox(\n",
632
+ " value=sp.system_prompt_templates[list(sp.system_prompt_templates.keys())[0]],\n",
633
+ " label=\"Current Chatbot Instructions\",\n",
634
  " lines=5,\n",
635
  " interactive=False\n",
636
  " )\n",
637
+ " \n",
638
+ " # Sources box (Now white, matching the other boxes)\n",
639
+ " gr.Markdown(\"\"\"\n",
640
+ " <div class=\"source-box\">\n",
641
+ " <strong>Available sources:</strong>\n",
642
+ " <ul>\n",
643
+ " <li>Journey to Self-Realization</li>\n",
644
+ " <li>The Second Coming of Christ</li>\n",
645
+ " <li>Autobiography of a Yogi</li>\n",
646
+ " </ul>\n",
647
+ " </div>\n",
648
+ " \"\"\")\n",
649
  " \n",
650
+ " # Update system prompt display when a new prompt is selected\n",
651
  " system_prompt_dropdown.change(\n",
652
+ " fn=chatbot.reset_system_prompt,\n",
653
  " inputs=[system_prompt_dropdown],\n",
654
  " outputs=[system_prompt_display]\n",
655
  " )\n",
656
  " \n",
657
+ " # Submit button logic to handle chatbot conversation\n",
658
  " submit_button.click(\n",
659
+ " fn=respond,\n",
660
+ " inputs=[user_input, chatbot_output],\n",
661
+ " outputs=[chatbot_output, user_input]\n",
662
  " )\n",
663
  "\n",
664
+ "# Launch the interface\n",
665
+ "demo.launch()\n"
 
 
666
  ]
667
  },
668
  {
notebooks/04 Return Passages.ipynb ADDED
File without changes
notebooks/05 Scratch.ipynb ADDED
File without changes
prompts/system_prompts.py CHANGED
@@ -3,58 +3,48 @@
3
 
4
  # System prompt options for the chatbot
5
  system_prompt_templates = {
6
- "Open-Ended Bot": '''You are a helpful assistant for people that want to query the teachings of Paramhansa Yogananda
7
- and the Self-Realization Fellowship. Look up the vector database provided for relevant
8
- passages to answer queries. Only use the context provided. Do not use any other sources.''',
9
 
10
- "Question-Answer Bot with Quotes": """You are a helpful assistant for people that want to query the teachings of
11
- Paramhansa Yogananda and the Self-Realization Fellowship to find answers to their questions.
12
- You will only answer questions that are related to the teachings based on the provided context.
13
- You have a vector database of the teachings of Paramhansa Yogananda and the Self-Realization Fellowship
14
- that you can search for information to answer the user's question.
15
- Provide compassionate and insightful responses that are grounded only in the context provided.
16
- Instructions:
17
- - Ask follow-up questions if needed to clarify the question
18
- - Query the vector database multiple times if the user query contains a question or questions that span multiple topics
19
- Output Format
20
- - The answer should be one paragraph and only be derived from the context provided
21
- - Provide a list of quotes verbatim from the retrieved passages with source and chapter name
22
- - Provide a list of recommended reading based on the retrieved passages
23
- - Provide up to three suggestions for followup questions
24
- - If the provided context does not contain the answer, please say so and ask the user to clarify their question.
25
- """,
26
 
27
- "Quote Finder": '''You are a helpful assistant for people that want to find quotes from the teachings of
28
- Paramhansa Yogananda and the Self-Realization Fellowship related to a give topic or question.
29
- In some cases, the user may describe a life problem or scenario. In you should break up the user query into
30
- multiple search queries. You have a vector database of the teachings of Paramhansa Yoganand and the Self-Realization
31
- Fellowship that can search for passages that you can use to pull out relevant quotes.
32
- Only extract quotes from the passages in the provided context. Ensure that the quotes are verbatim.
33
- Here are further instructions:
34
- - Ask follow-up questions if needed to clarify the question or topic
35
- - Query the vector database multiple times if the user query contains spans multiple topics
36
- - Include the source and chapter name for each quote you provide.
37
- - Provide a list of recommended reading
38
- - Provide up to three suggestions for followup quote searches
39
- - Do not paraphrase the quotes into an answer. Return the quotes directly.''',
40
 
41
  "Passage Finder": '''You are a helpful assistant that finds passages from the teachings of Paramhansa Yogananda and
42
- the Self-Realization Fellowship that are related to a given topic or question. If the user query
43
- is not related to the teachings, tell the user that you are not able to answer that question.''',
 
44
 
45
  "Subtopic Finder and Deep Dive": '''You are a helpful assistant that generates subtopics for a given topic or question from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship
46
- and allows users to do a deep dive into those subtopics.
47
- Retrieve at least 20 passages from the vector database for the given topic and then list out sub-topics that emerge from the retrieved passages.
48
- For each sub-topic, provide a concise summary of the sub-topic and a list of recommended readings
49
- from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship.''',
50
 
51
  "In Depth Topic Summary": '''You are a helpful assistant that summarizes topics from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship.
52
- Provide a detailed summary of the topic and a list of recommended readings from the teachings of
53
- Paramhansa Yogananda and the Self-Realization Fellowship. Your summaries should only use information from the provided context.
54
- Do not include information outside of the context provided. The summaries should be comprehensive and provide a deep understanding of the topic.
55
- The summaries should be in a paragraph format. At the end of the summary provide supporting quotes and resources.
56
- Make multiple queries to the vector database to retrieve information to answer the user's question if needed.
57
- Also ask follow-up questions to clarify the user's question if needed.''',
58
 
59
  }
60
 
 
3
 
4
  # System prompt options for the chatbot
5
  system_prompt_templates = {
6
+ "Open-Ended Bot": '''You are a helpful assistant for people that want to query the teachings of Paramhansa Yogananda and the Self-Realization Fellowship. Look up the vector database provided for relevantpassages to answer queries. Only use the context provided. Do not use any other sources.''',
 
 
7
 
8
+ "Question-Answer Bot with Quotes": """You are a helpful assistant that can query the teachings of Paramhansa Yogananda and the Self-Realization Fellowship from a vector database.
9
+ You will only answer questions based on the provided context.
10
+ Instructions:
11
+ - Ask follow-up questions if needed to clarify the question
12
+ - Query the vector database multiple times if the user query contains a question or questions that span multiple topics
13
+ Output Format
14
+ - The answer should be one paragraph and only be derived from the context provided
15
+ - Provide a list of quotes verbatim from the retrieved passages with source and chapter name
16
+ - Provide a list of recommended reading based on the retrieved passages
17
+ - Provide up to three suggestions for followup questions
18
+ - If the provided context does not contain the answer, please say so and ask the user to clarify their question.""",
 
 
 
 
 
19
 
20
+ "Quote Finder": '''You are a helpful assistant that can query a vector database for the teachings of
21
+ Paramhansa Yogananda and the Self-Realization Fellowship related to a give topic or question.
22
+ In some cases, the user may describe a life problem or scenario. In you should break up the user query into
23
+ multiple search queries. Only extract quotes from the passages in the provided context. Ensure that the quotes are verbatim.
24
+ Here are further instructions:
25
+ - Ask follow-up questions if needed to clarify the question or topic
26
+ - Query the vector database multiple times if the user query contains spans multiple topics
27
+ - Include the source and chapter name for each quote you provide.
28
+ - Provide a list of recommended reading
29
+ - Provide up to three suggestions for followup quote searches
30
+ - Do not paraphrase the quotes into an answer. Return the quotes directly.''',
 
 
31
 
32
  "Passage Finder": '''You are a helpful assistant that finds passages from the teachings of Paramhansa Yogananda and
33
+ the Self-Realization Fellowship that are related to a given topic or question from a vector database. Output
34
+ the full passages provided in the context. Organize them by relevance to the user query. Bold quotes that
35
+ are particularly insightful or relevant to the user query.''',
36
 
37
  "Subtopic Finder and Deep Dive": '''You are a helpful assistant that generates subtopics for a given topic or question from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship
38
+ and allows users to do a deep dive into those subtopics. Retrieve at least 20 passages from the vector database for the given topic and then list out sub-topics that emerge from the retrieved passages.
39
+ For each sub-topic, provide a concise summary of the sub-topic and a list of recommended readings from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship.''',
 
 
40
 
41
  "In Depth Topic Summary": '''You are a helpful assistant that summarizes topics from the teachings of Paramhansa Yogananda and the Self-Realization Fellowship.
42
+ Provide a detailed summary of the topic and a list of recommended readings from the teachings of
43
+ Paramhansa Yogananda and the Self-Realization Fellowship. Your summaries should only use information from the provided context.
44
+ Do not include information outside of the context provided. The summaries should be comprehensive and provide a deep understanding of the topic.
45
+ The summaries should be in a paragraph format. At the end of the summary provide supporting quotes and resources.
46
+ Make multiple queries to the vector database to retrieve information to answer the user's question if needed.
47
+ Also ask follow-up questions to clarify the user's question if needed.''',
48
 
49
  }
50
 
src/srf_bot.py CHANGED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ import uuid
4
+ from dotenv import load_dotenv
5
+ from typing import Annotated, List, Tuple
6
+ from typing_extensions import TypedDict
7
+ from langchain.tools import tool, BaseTool
8
+ from langchain.schema import Document
9
+ from langgraph.graph import StateGraph, START, END, MessagesState
10
+ from langgraph.graph.message import add_messages
11
+ from langgraph.prebuilt import ToolNode, tools_condition
12
+ from langgraph.checkpoint.memory import MemorySaver
13
+ from langchain_openai import ChatOpenAI
14
+ from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate
15
+ # from langchain.schema import SystemMessage, HumanMessage, AIMessage, ToolMessage
16
+ from langchain_core.messages import HumanMessage, AIMessage, ToolMessage, SystemMessage
17
+ from langchain.retrievers.multi_query import MultiQueryRetriever
18
+ import json
19
+ sys.path.append(os.path.abspath('..'))
20
+
21
+
22
+ import src.utils.qdrant_manager as qm
23
+ import prompts.system_prompts as sp
24
+
25
+ load_dotenv('/Users/nadaa/Documents/code/py_innovations/srf_chatbot_v2/.env')
26
+
27
+
28
+ class ToolManager:
29
+ def __init__(self, collection_name="openai_large_chunks_1500char"):
30
+ self.tools = []
31
+ self.qdrant = qm.QdrantManager(collection_name=collection_name)
32
+ self.vectorstore = self.qdrant.get_vectorstore()
33
+ self.add_tools()
34
+
35
+ def get_tools(self):
36
+ return self.tools
37
+
38
+ def add_tools(self):
39
+ @tool
40
+ def vector_search(query: str, k: int = 5) -> list[Document]:
41
+ """Useful for simple queries. This tool will search a vector database for passages from the teachings of Paramhansa Yogananda and other publications from the Self Realization Fellowship (SRF).
42
+ The user has the option to specify the number of passages they want the search to return, otherwise the number of passages will be set to the default value."""
43
+ retriever = self.vectorstore.as_retriever(search_kwargs={"k": k})
44
+ documents = retriever.invoke(query)
45
+ return documents
46
+
47
+ @tool
48
+ def multiple_query_vector_search(query: str, k: int = 5) -> list[Document]:
49
+ """Useful when the user's query is vague, complex, or involves multiple concepts.
50
+ This tool will write multiple versions of the user's query and search the vector database for relevant passages.
51
+ Use this tool when the user asks for an in depth answer to their question."""
52
+
53
+ llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.5)
54
+ retriever_from_llm = MultiQueryRetriever.from_llm(retriever=self.vectorstore.as_retriever(), llm=llm)
55
+ documents = retriever_from_llm.invoke(query)
56
+ return documents
57
+
58
+ self.tools.append(vector_search)
59
+ self.tools.append(multiple_query_vector_search)
60
+
61
+ class BasicToolNode:
62
+ """A node that runs the tools requested in the last AIMessage."""
63
+
64
+ def __init__(self, tools: list) -> None:
65
+ self.tools_by_name = {tool.name: tool for tool in tools}
66
+
67
+ def __call__(self, inputs: dict):
68
+ if messages := inputs.get("messages", []):
69
+ message = messages[-1]
70
+ else:
71
+ raise ValueError("No message found in input")
72
+ outputs = []
73
+ documents = []
74
+ for tool_call in message.tool_calls:
75
+ tool_result = self.tools_by_name[tool_call["name"]].invoke(
76
+ tool_call["args"]
77
+ )
78
+ outputs.append(
79
+ ToolMessage(
80
+ content=str(tool_result),
81
+ name=tool_call["name"],
82
+ tool_call_id=tool_call["id"],
83
+ )
84
+ )
85
+ documents += tool_result
86
+
87
+ return {"messages": outputs, "documents": documents}
88
+
89
+ class AgentState(TypedDict):
90
+
91
+ messages: Annotated[list, add_messages]
92
+ documents: list[Document]
93
+ system_message: list[SystemMessage]
94
+ system_message_dropdown: list[str]
95
+
96
+ class SRFChatbot:
97
+ def __init__(
98
+ self,
99
+ chatbot_instructions_dropdown: str = 'Open-Ended Bot',
100
+ model: str = 'gpt-4o-mini',
101
+ temperature: float = 0,
102
+ ):
103
+ # Initialize the LLM and the system message
104
+ ## THIS SHOULD BE REFACTORED AS THERE IS REPEITITION OF THE CODE IN RESET SYSTEM PROMPT TOO
105
+ self.chatbot_instructions_dropdown = chatbot_instructions_dropdown
106
+ self.chatbot_instructions = sp.system_prompt_templates[self.chatbot_instructions_dropdown]
107
+ self.system_message = SystemMessage(content=self.chatbot_instructions)
108
+
109
+ self.llm = ChatOpenAI(model=model, temperature=temperature)
110
+ self.tools = ToolManager().get_tools()
111
+ self.llm_with_tools = self.llm.bind_tools(self.tools)
112
+
113
+ # Build the graph
114
+ self.graph = self.build_graph()
115
+ # Get the configurable
116
+ self.config = self.get_configurable()
117
+
118
+ def reset_system_prompt(self, chatbot_instructions_dropdown: str):
119
+ # Update the dropdown
120
+ self.chatbot_instructions_dropdown = chatbot_instructions_dropdown
121
+ # Get chatbot instructions
122
+ self.chatbot_instructions = sp.system_prompt_templates[self.chatbot_instructions_dropdown]
123
+ # Reset the system prompt
124
+ self.system_message = SystemMessage(content=self.chatbot_instructions)
125
+ # Reset the configurable
126
+ self.config = self.get_configurable()
127
+ return self.chatbot_instructions
128
+
129
+ def get_configurable(self):
130
+ # This thread id is used to keep track of the chatbot's conversation
131
+ self.thread_id = str(uuid.uuid4())
132
+ return {"configurable": {"thread_id": self.thread_id}}
133
+
134
+ def get_system_message_dropdown(self):
135
+ return self.graph.get_state(config=self.config).values['system_message_dropdown']
136
+
137
+ # Add the system message onto the llm
138
+ ## THIS SHOULD BE REFACTORED SO THAT THE STATE ALWAYS HAS THE DEFINITIVE SYSTEM MESSAGE THAT SHOULD BE IN USE
139
+ def chatbot(self, state: AgentState):
140
+ messages = [self.system_message] + state["messages"]
141
+ return {"messages": [self.llm_with_tools.invoke(messages)], "system_message": self.system_message, "system_message_dropdown": self.chatbot_instructions_dropdown}
142
+
143
+ def build_graph(self):
144
+ # Add chatbot state
145
+ graph_builder = StateGraph(AgentState)
146
+
147
+ # Add nodes
148
+ tool_node = BasicToolNode(tools=self.tools)
149
+ # tool_node = ToolNode(self.tools)
150
+ graph_builder.add_node("tools", tool_node)
151
+ graph_builder.add_node("chatbot", self.chatbot)
152
+
153
+ # Add a conditional edge wherein the chatbot can decide whether or not to go to the tools
154
+ graph_builder.add_conditional_edges(
155
+ "chatbot",
156
+ tools_condition,
157
+ )
158
+
159
+ # Add fixed edges
160
+ graph_builder.add_edge(START, "chatbot")
161
+ graph_builder.add_edge("tools", "chatbot")
162
+
163
+ # Instantiate the memory saver
164
+ memory = MemorySaver()
165
+
166
+ # Compile the graph
167
+ return graph_builder.compile(checkpointer=memory)
168
+
169
+
170
+
171
+
172
+