File size: 55,434 Bytes
0436f2c
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
dfbf21d
 
 
0436f2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
 
 
 
dfbf21d
0436f2c
 
 
 
 
 
dfbf21d
 
 
0436f2c
dfbf21d
0436f2c
dfbf21d
0436f2c
dfbf21d
0436f2c
dfbf21d
0436f2c
dfbf21d
 
 
 
0436f2c
dfbf21d
 
 
 
0436f2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfbf21d
0436f2c
dfbf21d
0436f2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "srf-chatbot\n",
      "The autoreload extension is already loaded. To reload it, use:\n",
      "  %reload_ext autoreload\n"
     ]
    }
   ],
   "source": [
    "from dotenv import load_dotenv\n",
    "from typing import Annotated\n",
    "from typing_extensions import TypedDict\n",
    "from langchain.tools import tool\n",
    "from langchain.schema import Document\n",
    "from langgraph.graph import StateGraph, START, END\n",
    "from langgraph.graph.message import add_messages\n",
    "from langgraph.prebuilt import ToolNode, tools_condition\n",
    "from langgraph.checkpoint.memory import MemorySaver\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate\n",
    "from langchain.schema import SystemMessage, HumanMessage, AIMessage\n",
    "\n",
    "from IPython.display import Image, display\n",
    "import sys\n",
    "import os\n",
    "\n",
    "load_dotenv('/Users/nadaa/Documents/code/langgraph_learning/.env')\n",
    "print(os.environ['LANGCHAIN_PROJECT'])\n",
    "\n",
    "sys.path.append(os.path.abspath('..'))\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "import src.utils.qdrant_manager as qm\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Build a Basic Chatbot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class State(TypedDict):\n",
    "    # Messages have the type \"list\". The `add_messages` function\n",
    "    # in the annotation defines how this state key should be updated\n",
    "    # (in this case, it appends messages to the list, rather than overwriting them)\n",
    "    messages: Annotated[list, add_messages]\n",
    "\n",
    "graph_builder = StateGraph(State)\n",
    "\n",
    "llm = ChatOpenAI(model='gpt-4o-mini', temperature=0.5)\n",
    "\n",
    "def chatbot(state: State):\n",
    "    return {\"messages\": [llm.invoke(state[\"messages\"])]}\n",
    "\n",
    "# Creating a name for the node and specifying the function.\n",
    "# The messages that hte chatbot function returns will be added to the state\n",
    "graph_builder.add_node(\"chatbot\", chatbot)\n",
    "# Add a starting point\n",
    "graph_builder.add_edge(START, \"chatbot\")\n",
    "# Add an ending point\n",
    "graph_builder.add_edge(\"chatbot\", END)\n",
    "# Compile the graph\n",
    "graph = graph_builder.compile()\n",
    "\n",
    "try:\n",
    "    display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "except Exception:\n",
    "    # This requires some extra dependencies and is optional\n",
    "    pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Goodbye!\n"
     ]
    }
   ],
   "source": [
    "# Use streaming\n",
    "while True:\n",
    "    user_input = input(\"User: \")\n",
    "    if user_input.lower() in [\"quit\", \"exit\", \"q\"]:\n",
    "        print(\"Goodbye!\")\n",
    "        break\n",
    "    for event in graph.stream({\"messages\": (\"user\", user_input)}):\n",
    "        for value in event.values():\n",
    "            print(\"Assistant:\", value[\"messages\"][-1].content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'messages': [HumanMessage(content='tell me a joke', additional_kwargs={}, response_metadata={}, id='489e1ce6-64eb-4033-af63-f1479d2cb9f8'),\n",
       "  AIMessage(content='Why did the scarecrow win an award?\\n\\nBecause he was outstanding in his field!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 11, 'total_tokens': 28, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_483d39d857', 'finish_reason': 'stop', 'logprobs': None}, id='run-29a969e4-b3db-4a7f-ad58-263c2b3be67e-0', usage_metadata={'input_tokens': 11, 'output_tokens': 17, 'total_tokens': 28})]}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Note that when using invoke you must pass a dictionary where the key is  messages and the value is a list of dictionaries with the messages and includes role and content\n",
    "graph.invoke({'messages':[{'role': 'user', 'content': 'tell me a joke' }]})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chatbot with Vector Look-Up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/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",
      "  self.qdrant = Qdrant(\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "chatbot_instructions = \"\"\"You are a helpful assistant for people that want to query and research the teachings of \n",
    "Paramhansa Yogananda and the Self-Realization Fellowship. You will only answer questions that are related to the teachings.\n",
    "Provide compassionate and insightful responses that are grounded only in the context provided. \n",
    "Instructions:\n",
    "- Ask follow-up questions if needed to clarify the question\n",
    "- Query the vector database multiple times if the user query contains a question or questions that span multiple topics\n",
    "- Include direct quotes whenever possible. \n",
    "- Provide a list of recommended reading when you output your answer\n",
    "- Provide up to three suggestions for followup questions\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "# Create the system message\n",
    "system_message = SystemMessage(content=chatbot_instructions)\n",
    "\n",
    "# Modify the LLM initialization\n",
    "llm = ChatOpenAI(model='gpt-4o-mini', temperature=0.5)\n",
    "\n",
    "memory = MemorySaver()\n",
    "# Setup the state\n",
    "class State(TypedDict):\n",
    "    # Messages have the type \"list\". The `add_messages` function\n",
    "    # in the annotation defines how this state key should be updated\n",
    "    # (in this case, it appends messages to the list, rather than overwriting them)\n",
    "    messages: Annotated[list, add_messages]\n",
    "\n",
    "graph_builder = StateGraph(State)\n",
    "\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0.5)\n",
    "\n",
    "\n",
    "# Get vectorstore from qdrant\n",
    "qdrant = qm.QdrantManager(collection_name=\"openai_large_chunks_1500char\")\n",
    "vectorstore = qdrant.get_vectorstore()\n",
    "\n",
    "# Create my vector search tool\n",
    "@tool\n",
    "def vector_search(query: str, k: int = 5) -> list[Document]:\n",
    "    \"\"\"Search a vector database for passages from the teachings of Paramhansa Yogananda and other publications from the Self Realization Fellowship (SRF).\n",
    "    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.\"\"\"\n",
    "    retriever = vectorstore.as_retriever(search_kwargs={\"k\": k})\n",
    "    documents = retriever.invoke(query)\n",
    "    return documents\n",
    "\n",
    "# Create a list of tools and bind them to the LLM\n",
    "tools=[vector_search]\n",
    "llm_with_tools = llm.bind_tools(tools)\n",
    "\n",
    "# Add the system message onto the llm\n",
    "def chatbot(state: State):\n",
    "    messages = [system_message] + state[\"messages\"]\n",
    "    return {\"messages\": [llm_with_tools.invoke(messages)]}\n",
    "\n",
    "# Create and add a tool node\n",
    "tool_node = ToolNode(tools)\n",
    "graph_builder.add_node(\"tools\", tool_node)\n",
    "graph_builder.add_node(\"chatbot\", chatbot)\n",
    "\n",
    "# Add a conditional edge wherein the chatbot can decide whether or not to go to the tools\n",
    "graph_builder.add_conditional_edges(\n",
    "    \"chatbot\",\n",
    "    tools_condition,\n",
    ")\n",
    "\n",
    "# Any time a tool is called, we return to the chatbot to decide the next step\n",
    "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
    "graph_builder.add_edge(START, \"chatbot\")\n",
    "\n",
    "# Recompile the graph with the new structure\n",
    "graph = graph_builder.compile(checkpointer=memory)\n",
    "\n",
    "# Visualize the updated graph\n",
    "try:\n",
    "    display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "except Exception:\n",
    "    # This requires some extra dependencies and is optional\n",
    "    pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Assistant: \n",
      "Assistant: [Document(metadata={'split_id_uuid': 'e0d78426-d586-464d-ab83-fa1b4c6d74f1', 'split_id_sequential': 282, 'chapter_name': 'Intuition Develops Through Meditation', 'publication_name': 'Journey to Self-Realization', '_id': '40595e45-e286-43da-adad-fb54de68b614', '_collection_name': 'openai_large_chunks_1500char'}, page_content='A joy and peace will strike your heart. When that comes, you know that you are communing with God. If you make the effort, you shall contact that Power. Give yourself that opportunity. You cannot succeed unless you try. If you spend your life in constant excitement, you will never know true happiness. Live simply and take life more easily. Happiness lies in giving yourself time to think and to introspect. Be alone once in a while, and remain more in silence. If the radio is going all the time, or other stimuli are constantly bombarding the senses, it truly affects the nerves and creates nervousness. And don’t think so much about reforming others; reform yourself first. The greatest field of victory is your own home. If you are an angel at home, you can be an angel everywhere. The sweetness of your voice, the peace of your behaviour, is needed in your own household more than anywhere else.'), Document(metadata={'split_id_sequential': 716, 'publication_name': 'Journey to Self-Realization', 'chapter_name': 'Use Tact; Persons Are Not Unfeeling Stones', 'split_id_uuid': '7b8ee071-2240-4db1-b967-4b3f47bc9933', '_id': '667c9cc7-6f35-4c9f-b8b0-e9b2c6e99fab', '_collection_name': 'openai_large_chunks_1500char'}, page_content='Find your peace by meditating regularly and deeply, and you will be surprised to see how your relationships with others improve. Also develop your power of usefulness. That is love. Think about that. Learn to be serviceful to others—useful with positive thoughts; useful with your speech; useful with constructive suggestions. But do not give advice where it is not wanted; if your suggestions are unwelcome, have the control to remain silent. And when sometimes you do good to others and then can no longer help them in a material way, if they become inimical because they continue to expect from you, never mind; go on doing what is right. Do the best you can and forget it.'), Document(metadata={'split_id_sequential': 75, 'publication_name': 'Journey to Self-Realization', 'split_id_uuid': '1b706451-f27f-4466-8b44-f1fb17c80a69', 'chapter_name': 'Be a Conqueror of Hearts', '_id': '6714c2d3-f32a-42e6-bcf3-49f24cfb3d40', '_collection_name': 'openai_large_chunks_1500char'}, page_content='That is a lesson given to strengthen us, to bring out our hidden powers. But instead, the contradiction of desires causes anger. When desires are thwarted and we are caught in the paroxysm of anger, the mind becomes befogged and we forget our position and lose our discrimination; and when we act without discrimination, errors and unhappiness follow.2 If you never get angry at life’s reverses, or at their human instigators, you can see your way more clearly through whatever is going on around you. That is why your peace is to be guarded above everything else. If you can retain your inner peace, therein lies your supreme victory. No matter how you are situated in life, never feel justified in losing your peace. When that is gone and you cannot think clearly, you have lost the battle. If you never lose your peace, you will find you are always victorious, no matter what the outcome of your problems. That is the way to conquer life. You have nothing to fear. If you have to be afraid at all, be afraid only of yourself. But if you do everything with sincerity and love in your heart, you do not have to fear anybody or anything. As you find your soul-reservoir of peace, less and less controversy will be able to afflict your life. One who loves God lives in the soul, his true Self. He does everything for God, nothing for himself. He loves everybody, because he sees the world as the Lord’s cosmic show.'), Document(metadata={'split_id_uuid': '9f26c821-5e3c-4746-806a-54edd5df5a3a', 'publication_name': 'Journey to Self-Realization', 'chapter_name': 'Use Tact; Persons Are Not Unfeeling Stones', 'split_id_sequential': 715, '_id': 'e066e97f-21a6-446d-be4d-e28f9ca4d20f', '_collection_name': 'openai_large_chunks_1500char'}, page_content='After doing so, I said, “Now, I am not going to shut you out of my classes. But you must promise me that you will not talk against anyone during the class series. Do not think of yourselves as teachers. As long as there is prideful desire to teach, you are not qualified to teach. First you yourself must live it. If you do that, others will follow your example.” And do you know that hour after hour they attended the classes and didn’t once disturb anyone. They were the meekest of students. You see, I got along with them all right because I did not get angry. I used tact to bring them to the sudden realization of their mental weaknesses. But getting along with others cannot be done only by tact. It also requires example, calmness, evenness of mind, sincerity, joy, doing everything in an honourable way; not clinging to pride and egotism; and not governing your actions by what everybody else does, but doing those things that please God. Find your peace by meditating regularly and deeply, and you will be surprised to see how your relationships with others improve. Also develop your power of usefulness. That is love. Think about that. Learn to be serviceful to others—useful with positive thoughts; useful with your speech; useful with constructive suggestions. But do not give advice where it is not wanted; if your suggestions are unwelcome, have the control to remain silent.'), Document(metadata={'chapter_number': 61, 'publication_name': 'The Second Coming of Christ', 'split_id_sequential': 2217, 'split_id_uuid': '7e3cc238-62a7-4ad4-8da2-f26f25e2da99', 'chapter_name': 'Discourse 61 - “The Kingdom Of God Is Within You”', '_id': 'e9c475cd-898c-4368-b502-4bf783a88d9a', '_collection_name': 'openai_large_chunks_1500char'}, page_content='The yogi begins with proper deep breathing, inhaling and tensing the whole body, exhaling and relaxing, several times. With each exhalation all muscular tension and motion should be cast away, until a state of bodily stillness is attained. Then, by concentration techniques, restless motion is removed from the mind. In perfect stillness of body and mind, the yogi enjoys the ineffable peace of the presence of the soul. In the body, life is templed; in the mind, light is templed; in the soul, peace is templed. The deeper one goes into the soul the more that peace is felt; that is superconsciousness. When by deeper meditation the devotee expands that awareness of peace and feels his consciousness spreading with it over the universe, that all beings and all creation are swallowed up in that peace, then he is entering into Cosmic Consciousness. He feels that peace everywhere—in the flowers, in every human being, in the atmosphere. He beholds the earth and all worlds floating like bubbles in that ocean of peace.14 The inner peace first experienced by the devotee in meditation is his own soul; the vaster peace he feels by going deeper is God. The devotee who experiences unity with everything has established God in the temple of his infinite inner perception. In the temple of silence, in the temple of peace, I will meet Thee, I will touch Thee, I will love Thee, And coax Thee to my altar of peace.')]\n",
      "Assistant: To cultivate a greater sense of peace in your life, Paramhansa Yogananda's teachings emphasize several key practices and attitudes:\n",
      "\n",
      "1. **Meditation**: Regular and deep meditation is fundamental. Yogananda teaches that \"Find your peace by meditating regularly and deeply, and you will be surprised to see how your relationships with others improve.\" Meditation helps quiet the mind and connect with a deeper state of peace.\n",
      "\n",
      "2. **Simplicity and Introspection**: Living simply and allowing time for introspection can lead to happiness. Yogananda advises, \"Happiness lies in giving yourself time to think and to introspect.\" This means taking moments of solitude to reflect and connect with your inner self.\n",
      "\n",
      "3. **Guarding Your Peace**: It's crucial to maintain your inner peace, regardless of external circumstances. Yogananda states, \"If you never lose your peace, you will find you are always victorious, no matter what the outcome of your problems.\" This involves not allowing anger or frustration to derail your calmness.\n",
      "\n",
      "4. **Service to Others**: Engaging in acts of kindness and being useful to others fosters love and peace. Yogananda suggests, \"Learn to be serviceful to others—useful with positive thoughts; useful with your speech; useful with constructive suggestions.\" \n",
      "\n",
      "5. **Breath and Stillness**: Practicing proper deep breathing and achieving bodily stillness can enhance your sense of peace. Yogananda describes, \"In perfect stillness of body and mind, the yogi enjoys the ineffable peace of the presence of the soul.\"\n",
      "\n",
      "Incorporating these practices into your daily routine can help you cultivate a more peaceful state of being.\n",
      "\n",
      "### Recommended Reading:\n",
      "- **\"Journey to Self-Realization\"** by Paramhansa Yogananda\n",
      "- **\"The Second Coming of Christ\"** by Paramhansa Yogananda\n",
      "\n",
      "### Follow-Up Questions:\n",
      "1. What specific challenges do you face that disrupt your peace?\n",
      "2. Have you tried meditation before, and if so, what was your experience?\n",
      "3. Are there particular areas in your life where you feel you could be more serviceful to others?\n",
      "Goodbye!\n"
     ]
    }
   ],
   "source": [
    "# Use streaming\n",
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "\n",
    "while True:\n",
    "    user_input = input(\"User: \")\n",
    "    if user_input.lower() in [\"quit\", \"exit\", \"q\"]:\n",
    "        print(\"Goodbye!\")\n",
    "        break\n",
    "    for event in graph.stream({\"messages\": (\"user\", user_input)}, config):\n",
    "        for value in event.values():\n",
    "            print(\"Assistant:\", value[\"messages\"][-1].content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "result = graph.invoke({\"messages\":[{\"role\": \"user\", \"content\": \"Search the vector database on the importance of a true guru, return the full passages returned from the vector search verbatim and bold the most important quotes\"}]}, config)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Here are the full passages from the teachings of Paramhansa Yogananda regarding the importance of a true guru, with key quotes emphasized:\n",
      "\n",
      "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",
      "\n",
      "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",
      "\n",
      "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",
      "\n",
      "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",
      "\n",
      "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",
      "\n",
      "### Recommended Reading:\n",
      "- \"The Second Coming of Christ\" by Paramhansa Yogananda\n",
      "- \"Autobiography of a Yogi\" by Paramhansa Yogananda\n",
      "- \"The Yoga of Jesus\" by Paramhansa Yogananda\n",
      "\n",
      "### Follow-Up Questions:\n",
      "1. What qualities should one look for in a true guru?\n",
      "2. How can a disciple cultivate a deeper connection with their guru?\n",
      "3. Can the teachings of a guru be accessed without physical presence?\n"
     ]
    }
   ],
   "source": [
    "print(result['messages'][-1].content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "result = graph.invoke({\"messages\":[{\"role\": \"user\", \"content\": \"Summarize in a nice paragraph format what yogananda says about introspection. At the end of the summary provide supporting quotes and resources.\"}]}, config)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Paramhansa Yogananda emphasizes the significance of introspection as a crucial practice for spiritual development and self-awareness. He describes introspection as a \"wonderful mirror\" that allows individuals to evaluate their thoughts and actions, promoting moral and spiritual growth. By reflecting on oneself, particularly in the light of a guru's wisdom, one can gain deeper insights and clarity. Yogananda advocates for accepting criticism as a sign of spiritual strength, encouraging individuals to learn from feedback and continuously strive for improvement. He also highlights the importance of deep thinking, asserting that concentrated reflection can lead to profound understanding and peace. Ultimately, Yogananda underscores personal responsibility, urging individuals to prioritize self-correction over the tendency to criticize others. This holistic approach to introspection is seen as essential on the path to self-realization and divine connection.\n",
      "\n",
      "### Supporting Quotes:\n",
      "- **\"Introspection is a wonderful mirror in which to judge oneself.\"**\n",
      "- **\"Even more accurate than that mirror is one’s reflection in the mirror of a wise man’s mind.\"**\n",
      "- **\"To be able humbly to stand the barbs of criticism, just or unjust, and to make continuous effort to improve one’s attitudes and behavior when criticism is justified, will make one a saint.\"**\n",
      "- **\"Without deep thinking, concentration of the mind, one will never find the way to God.\"**\n",
      "\n",
      "### Recommended Resources:\n",
      "- **\"The Second Coming of Christ\"** by Paramhansa Yogananda\n",
      "- **\"Journey to Self-Realization\"** by Paramhansa Yogananda\n"
     ]
    }
   ],
   "source": [
    "print(result['messages'][-1].content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "result = graph.invoke({\"messages\":[{\"role\": \"user\", \"content\": \"Find 20 passages on introspection and identify the subtopics that emerge.\"}]}, config)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Here are 20 passages on introspection from the teachings of Paramhansa Yogananda, along with the subtopics that emerge from these reflections:\n",
      "\n",
      "1. **Introspection as Self-Judgment**: Yogananda describes introspection as a \"wonderful mirror\" for self-assessment, emphasizing the importance of judging oneself rather than others.\n",
      "\n",
      "2. **Guidance from a Guru**: He highlights the value of seeing oneself through the lens of a wise guru, stating that their insights can lead to spiritual transformation.\n",
      "\n",
      "3. **Strength in Criticism**: Yogananda notes that the ability to accept criticism is a sign of spiritual strength and encourages individuals to use criticism as a tool for self-improvement.\n",
      "\n",
      "4. **Deep Thinking**: He advocates for deep thinking as a means to cultivate introspection, suggesting that it allows individuals to dive deeper into their thoughts and gain clarity and peace.\n",
      "\n",
      "5. **Personal Responsibility**: Yogananda emphasizes the importance of personal responsibility in self-correction, urging individuals to focus on their own flaws rather than criticizing others.\n",
      "\n",
      "6. **Inner Peace**: He warns against the negative effects of harboring critical thoughts about others, suggesting that such negativity disrupts one's inner peace.\n",
      "\n",
      "7. **The Role of Intuition**: Yogananda connects introspection to the development of intuition, stating that a calm mind allows for greater intuitive understanding and insight.\n",
      "\n",
      "8. **Meditation and Introspection**: He stresses that meditation is essential for developing introspection, as it helps clear the mind and facilitates deeper self-examination.\n",
      "\n",
      "9. **The Nature of Truth**: Yogananda discusses the need for honest self-scrutiny, suggesting that true understanding of one's nature requires confronting uncomfortable truths.\n",
      "\n",
      "10. **Avoiding Hypocrisy**: He warns against the dangers of hypocrisy, advocating for sincere self-reflection rather than the superficial acknowledgment of faults.\n",
      "\n",
      "11. **Self-Enquiry**: Yogananda encourages self-enquiry as a means to uncover deeper truths about oneself, promoting questions like \"Who am I?\" and \"What is my purpose?\"\n",
      "\n",
      "12. **The Importance of Silence**: He suggests that spending time in silence is crucial for introspection, allowing individuals to connect with their inner selves.\n",
      "\n",
      "13. **Judgment vs. Observation**: Yogananda differentiates between judgment and observation, advocating for a neutral perspective that focuses on understanding rather than criticizing.\n",
      "\n",
      "14. **Transformation through Introspection**: He believes that introspection leads to personal transformation, enabling individuals to align more closely with their true selves.\n",
      "\n",
      "15. **The Dangers of External Validation**: Yogananda cautions against seeking validation from others, emphasizing that true worth comes from self-knowledge and inner peace.\n",
      "\n",
      "16. **The Impact of Environment**: He notes that one's environment can influence thoughts and feelings, highlighting the importance of cultivating a positive inner space.\n",
      "\n",
      "17. **Self-Reflection as a Path to God**: Yogananda teaches that introspection can lead to a deeper communion with God, as it opens the heart and mind to divine truths.\n",
      "\n",
      "18. **The Connection between Introspection and Faith**: He connects introspection to the development of faith, suggesting that understanding oneself leads to a stronger connection with the divine.\n",
      "\n",
      "19. **Ego and Self-Analysis**: Yogananda discusses the role of ego in hindering true self-analysis, urging individuals to confront and transcend their egos.\n",
      "\n",
      "20. **The Journey of Self-Discovery**: He frames introspection as an ongoing journey of self-discovery, encouraging individuals to continually seek deeper understanding of themselves and their relationship with God.\n",
      "\n",
      "### Subtopics Identified:\n",
      "- Self-Judgment and Self-Assessment\n",
      "- Guidance and Influence of a Guru\n",
      "- Strength and Growth through Criticism\n",
      "- Deep Thinking and Concentration\n",
      "- Personal Responsibility in Self-Correction\n",
      "- Inner Peace and Mental Clarity\n",
      "- Development of Intuition\n",
      "- The Role of Meditation in Introspection\n",
      "- Honest Self-Enquiry and Truth-Seeking\n",
      "- Avoiding Hypocrisy and Sincerity\n",
      "- The Importance of Silence for Reflection\n",
      "- Observation vs. Judgment\n",
      "- Transformation through Self-Reflection\n",
      "- The Impact of External Validation\n",
      "- The Influence of Environment on Thoughts\n",
      "- Introspection as a Path to God\n",
      "- Connection between Introspection and Faith\n",
      "- Ego and Self-Analysis\n",
      "- Ongoing Journey of Self-Discovery\n",
      "\n",
      "These passages and subtopics provide a comprehensive view of Yogananda's teachings on introspection, highlighting its significance in the spiritual journey. If you have further questions or need more insights, feel free to ask!\n"
     ]
    }
   ],
   "source": [
    "print(result['messages'][-1].content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running on local URL:  http://127.0.0.1:7861\n",
      "Running on public URL: https://5c55504e6a49d443ab.gradio.live\n",
      "\n",
      "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"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div><iframe src=\"https://5c55504e6a49d443ab.gradio.live\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import gradio as gr\n",
    "from langgraph.graph import StateGraph, END\n",
    "from langchain_openai import ChatOpenAI\n",
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "\n",
    "# Define the chatbot function\n",
    "# def chatbot(state):\n",
    "#     llm = ChatOpenAI()\n",
    "#     return {\"messages\": state[\"messages\"] + [llm.invoke(state[\"messages\"])]}\n",
    "\n",
    "# # Create the graph\n",
    "# graph = StateGraph()\n",
    "\n",
    "# # Add the chatbot node\n",
    "# graph.add_node(\"chatbot\", chatbot)\n",
    "\n",
    "# # Define the edges\n",
    "# graph.add_edge(graph.START, \"chatbot\")\n",
    "# graph.add_edge(\"chatbot\", graph.END)\n",
    "\n",
    "# # Compile the graph\n",
    "# chain = graph.compile()\n",
    "\n",
    "# Define the Gradio interface\n",
    "def respond(message, history):\n",
    "    # Format the history and new message into the expected structure\n",
    "    formatted_messages = []\n",
    "    for human, ai in history:\n",
    "        formatted_messages.append(HumanMessage(content=human))\n",
    "        if ai:  # AI might not have responded yet\n",
    "            formatted_messages.append(AIMessage(content=ai))\n",
    "    \n",
    "    # Add the new message\n",
    "    formatted_messages.append(HumanMessage(content=message))\n",
    "    \n",
    "    # Invoke the graph with properly formatted input\n",
    "    result = graph.invoke({\"messages\": formatted_messages}, config)\n",
    "    \n",
    "    # Extract the assistant's response\n",
    "    response = result[\"messages\"][-1].content\n",
    "    \n",
    "    return response\n",
    "\n",
    "# Create and launch the Gradio interface\n",
    "gradio = gr.ChatInterface(respond)\n",
    "gradio.launch(share=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "srf_chatbot_v2",
   "language": "python",
   "name": "srf_chatbot_v2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}