code: # https://blog.streamlit.io/build-a-chatbot-with-custom-data-sources-powered-by-llamaindex/
  import os
  import streamlit as st
  
  from llama_index.core import ServiceContext, Document, SimpleDirectoryReader, VectorStoreIndex, Settings
  from llama_index.llms.ollama import Ollama
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
  
  OLLAMA_HOST = os.getenv('OLLAMA_HOST', 'localhost')
  print(f"Connecting to ollama server {OLLAMA_HOST}")
  
  # connect to ollama service running on OpenShift
  my_llm = Ollama(model="zephyr", base_url="http://"+OLLAMA_HOST+":11434")
  
  system_prompt = \
      "You are Linuxbot, an expert on Linux and Linus Torvalds and your job is to answer questions about these two topics." \
      "Assume that all questions are related to Linus Torvalds or Linux." \
      "Keep your answers to a few sentences and based on context – do not hallucinate facts." \
      "Always try to cite your source document."
  
  st.title("Linuxbot 🐧🤖")
  st.subheader("Everything you want to know about Linux or Linus")
  
  if "messages" not in st.session_state.keys(): # Initialize the chat message history
      st.session_state.messages = [
          {"role": "assistant", "content": "Ask me a question about Linus or Linux"}
      ]
  
  @st.cache_resource(show_spinner=False)
  def load_data(_llm):
      with st.spinner(text="Loading and indexing the document data – might take 1-2 minutes."):
          reader = SimpleDirectoryReader(input_dir="./docs", recursive=True)
          docs = reader.load_data()
          
          # ServiceContext is deprected ...
          # Also see https://docs.llamaindex.ai/en/stable/examples/embeddings/huggingface.html
          Settings.llm = my_llm
          Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
          index = VectorStoreIndex.from_documents(docs)
  
          return index
  
  
  index = load_data(my_llm)
  
  chat_engine = index.as_chat_engine(
      chat_mode="context", verbose=True, system_prompt=system_prompt
  )
  
  if prompt := st.chat_input("Ask me a question about Linus or Linux"): 
      st.session_state.messages.append({"role": "user", "content": prompt})
  
  # Display previous chat messages
  for message in st.session_state.messages:
      with st.chat_message(message["role"]):
          st.write(message["content"])
  
  # Generate a new response if last message is not from assistant
  if st.session_state.messages[-1]["role"] != "assistant":
      with st.chat_message("assistant"):
          with st.spinner("Querying..."):
              streaming_response = chat_engine.stream_chat(prompt)
              placeholder = st.empty()
              full_response = ''
              for token in streaming_response.response_gen:
                  full_response += token
                  placeholder.markdown(full_response)
              placeholder.markdown(full_response)
              message = {"role": "assistant", "content": full_response}
              st.session_state.messages.append(message) # Add response to message history
  
apis: llama_index.embeddings.huggingface.HuggingFaceEmbedding llama_index.core.VectorStoreIndex.from_documents llama_index.llms.ollama.Ollama llama_index.core.SimpleDirectoryReader
extract_api: [((357, 394), 'os.getenv', 'os.getenv', (['"""OLLAMA_HOST"""', '"""localhost"""'], {}), "('OLLAMA_HOST', 'localhost')\n", (366, 394), False, 'import os\n'), ((506, 573), 'llama_index.llms.ollama.Ollama', 'Ollama', ([], {'model': '"""zephyr"""', 'base_url': "('http://' + OLLAMA_HOST + ':11434')"}), "(model='zephyr', base_url='http://' + OLLAMA_HOST + ':11434')\n", (512, 573), False, 'from llama_index.llms.ollama import Ollama\n'), ((929, 952), 'streamlit.title', 'st.title', (['"""Linuxbot 🐧🤖"""'], {}), "('Linuxbot 🐧🤖')\n", (937, 952), True, 'import streamlit as st\n'), ((953, 1017), 'streamlit.subheader', 'st.subheader', (['"""Everything you want to know about Linux or Linus"""'], {}), "('Everything you want to know about Linux or Linus')\n", (965, 1017), True, 'import streamlit as st\n'), ((1228, 1265), 'streamlit.cache_resource', 'st.cache_resource', ([], {'show_spinner': '(False)'}), '(show_spinner=False)\n', (1245, 1265), True, 'import streamlit as st\n'), ((1040, 1063), 'streamlit.session_state.keys', 'st.session_state.keys', ([], {}), '()\n', (1061, 1063), True, 'import streamlit as st\n'), ((1977, 2032), 'streamlit.chat_input', 'st.chat_input', (['"""Ask me a question about Linus or Linux"""'], {}), "('Ask me a question about Linus or Linux')\n", (1990, 2032), True, 'import streamlit as st\n'), ((2039, 2108), 'streamlit.session_state.messages.append', 'st.session_state.messages.append', (["{'role': 'user', 'content': prompt}"], {}), "({'role': 'user', 'content': prompt})\n", (2071, 2108), True, 'import streamlit as st\n'), ((1296, 1384), 'streamlit.spinner', 'st.spinner', ([], {'text': '"""Loading and indexing the document data – might take 1-2 minutes."""'}), "(text=\n    'Loading and indexing the document data – might take 1-2 minutes.')\n", (1306, 1384), True, 'import streamlit as st\n'), ((1398, 1455), 'llama_index.core.SimpleDirectoryReader', 'SimpleDirectoryReader', ([], {'input_dir': '"""./docs"""', 'recursive': '(True)'}), "(input_dir='./docs', recursive=True)\n", (1419, 1455), False, 'from llama_index.core import ServiceContext, Document, SimpleDirectoryReader, VectorStoreIndex, Settings\n'), ((1695, 1752), 'llama_index.embeddings.huggingface.HuggingFaceEmbedding', 'HuggingFaceEmbedding', ([], {'model_name': '"""BAAI/bge-small-en-v1.5"""'}), "(model_name='BAAI/bge-small-en-v1.5')\n", (1715, 1752), False, 'from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n'), ((1769, 1806), 'llama_index.core.VectorStoreIndex.from_documents', 'VectorStoreIndex.from_documents', (['docs'], {}), '(docs)\n', (1800, 1806), False, 'from llama_index.core import ServiceContext, Document, SimpleDirectoryReader, VectorStoreIndex, Settings\n'), ((2194, 2226), 'streamlit.chat_message', 'st.chat_message', (["message['role']"], {}), "(message['role'])\n", (2209, 2226), True, 'import streamlit as st\n'), ((2236, 2264), 'streamlit.write', 'st.write', (["message['content']"], {}), "(message['content'])\n", (2244, 2264), True, 'import streamlit as st\n'), ((2396, 2424), 'streamlit.chat_message', 'st.chat_message', (['"""assistant"""'], {}), "('assistant')\n", (2411, 2424), True, 'import streamlit as st\n'), ((2439, 2464), 'streamlit.spinner', 'st.spinner', (['"""Querying..."""'], {}), "('Querying...')\n", (2449, 2464), True, 'import streamlit as st\n'), ((2557, 2567), 'streamlit.empty', 'st.empty', ([], {}), '()\n', (2565, 2567), True, 'import streamlit as st\n'), ((2878, 2919), 'streamlit.session_state.messages.append', 'st.session_state.messages.append', (['message'], {}), '(message)\n', (2910, 2919), True, 'import streamlit as st\n')]