2387 lines
443 KiB
Plaintext
2387 lines
443 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import pytesseract\n",
|
||
"from langchain.document_loaders import UnstructuredPDFLoader\n",
|
||
"from ollama import Client\n",
|
||
"from langchain_ollama.llms import OllamaLLM\n",
|
||
"import os.path\n",
|
||
"import os\n",
|
||
"# os.environ[\"OCR_AGENT\"] =\"unstructured.partition.utils.ocr_models.tesseract_ocr.OCRAgentTesseract\"\n",
|
||
"# Configuration de pytesseract\n",
|
||
"pytesseract.pytesseract.tesseract_cmd = r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'\n",
|
||
"\n",
|
||
"# Chemin vers votre PDF\n",
|
||
"path_pdf = r\"F:\\Dev\\Rag\\Rag_Modeling\\document\\11_chapitre3.pdf\"\n",
|
||
"\n",
|
||
"# Configuration du loader pour extraire images, tableaux et leurs métadonnées\n",
|
||
"loader = UnstructuredPDFLoader(\n",
|
||
" path_pdf,\n",
|
||
" infer_table_structure=True, # Active l'inférence de la structure des tableaux\n",
|
||
" extract_images=True, # Extraction des images\n",
|
||
" image_output_dir=r\"F:\\Dev\\Rag\\Rag_Modeling\\TEMP\",\n",
|
||
" mode=\"elements\",\n",
|
||
" strategy=\"hi_res\", # Vous pouvez tester \"fast\" si besoin\n",
|
||
" extract_image_block_types=[\"Image\"],\n",
|
||
" extract_image_block_to_payload=True,\n",
|
||
")\n",
|
||
"documents = loader.load()\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"27\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"\n",
|
||
"# for i, chunk in enumerate(documents):\n",
|
||
"# # On vérifie si le chunk correspond à une image\n",
|
||
"# if chunk.metadata.get(\"category\") == \"FigureCaption\":\n",
|
||
"# print(chunk.page_content.strip())\n",
|
||
"def get_images_with_caption(documents):\n",
|
||
" images_info = []\n",
|
||
" for i, chunk in enumerate(documents):\n",
|
||
" # On vérifie si le chunk correspond à une image\n",
|
||
" if chunk.metadata.get(\"category\") == \"Image\":\n",
|
||
" image_b64 = chunk.metadata.get('image_base64')\n",
|
||
" caption = \"\"\n",
|
||
" # Si aucune légende n'a été trouvée, on regarde le bloc suivant\n",
|
||
" if i < len(documents) - 1:\n",
|
||
" next_chunk = documents[i+1]\n",
|
||
" # On vérifie si le texte du bloc suivant contient des indices de légende\n",
|
||
" if next_chunk.metadata.get(\"category\") == \"FigureCaption\":\n",
|
||
" caption = next_chunk.page_content.strip()\n",
|
||
" \n",
|
||
" images_info.append({\n",
|
||
" \"image_base64\": image_b64,\n",
|
||
" \"caption\": caption,\n",
|
||
" \"source\": os.path.basename(chunk.metadata.get(\"source\", \"\")),\n",
|
||
" \"page\": chunk.metadata.get(\"page_number\", \"\"),\n",
|
||
" })\n",
|
||
" return images_info\n",
|
||
"images_with_caption = get_images_with_caption(documents) \n",
|
||
"print(len(images_with_caption ))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def get_tables_with_caption(documents):\n",
|
||
" tables_info = []\n",
|
||
" for idx, chunk in enumerate(documents):\n",
|
||
"\n",
|
||
" if chunk.metadata.get(\"category\") == \"Table\" or \"table\" in chunk.metadata.get(\"category\", \"\").lower():\n",
|
||
"\n",
|
||
" # Extraction du contenu textuel du tableau et de sa légende\n",
|
||
" payload = chunk.metadata.get(\"payload\", {})\n",
|
||
" caption = payload.get(\"caption\", \"\").strip()\n",
|
||
" # Si aucune légende n'est trouvée, vérifier le bloc suivant\n",
|
||
" if not caption and idx + 1 < len(documents):\n",
|
||
" next_chunk = documents[idx + 1]\n",
|
||
" lower_text = next_chunk.page_content.lower()\n",
|
||
" if next_chunk.metadata.get(\"category\") == \"FigureCaption\":\n",
|
||
" caption = next_chunk.page_content.strip() \n",
|
||
" tables_info.append({\n",
|
||
" \"type\": \"table_with_caption\",\n",
|
||
" \"table_data\": chunk.page_content, # Le contenu textuel du tableau\n",
|
||
" \"caption\": caption,\n",
|
||
" \"source\": os.path.basename(chunk.metadata.get(\"source\", \"\")),\n",
|
||
" \"page\": chunk.metadata.get(\"page_number\", \"\"),\n",
|
||
" })\n",
|
||
" return tables_info\n",
|
||
" \n",
|
||
" \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"tables_with_caption=get_tables_with_caption(documents)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"\n",
|
||
"\n",
|
||
"def get_text_elements(documents):\n",
|
||
" text_info = []\n",
|
||
" text_elements = [doc for doc in documents if doc.metadata.get(\"category\") not in [\"Table\", \"Image\",\"FigureCaption\"]]\n",
|
||
"\n",
|
||
" for _, chunk in enumerate(text_elements):\n",
|
||
" text_info.append({ \n",
|
||
" \"page_content\": chunk.page_content, # Le contenu textuel du tableau\n",
|
||
" \"source\": os.path.basename(chunk.metadata.get(\"source\", \"\")),\n",
|
||
" \"page\": chunk.metadata.get(\"page_number\", \"\"),\n",
|
||
" })\n",
|
||
" return text_info\n",
|
||
" "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Nombre de chunks générés: 1078\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"from langchain.schema import Document\n",
|
||
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
|
||
"import os\n",
|
||
"\n",
|
||
"# Garde votre fonction get_text_elements telle quelle\n",
|
||
"def get_text_elements(documents):\n",
|
||
" text_info = []\n",
|
||
" text_elements = [doc for doc in documents if doc.metadata.get(\"category\") not in [\"Table\", \"Image\",\"FigureCaption\"]]\n",
|
||
"\n",
|
||
" for _, chunk in enumerate(text_elements):\n",
|
||
" text_info.append({ \n",
|
||
" \"page_content\": chunk.page_content, # Le contenu textuel du tableau\n",
|
||
" \"source\": os.path.basename(chunk.metadata.get(\"source\", \"\")),\n",
|
||
" \"page\": chunk.metadata.get(\"page_number\", \"\"),\n",
|
||
" })\n",
|
||
" return text_info\n",
|
||
"\n",
|
||
"# Fonction pour convertir vos dictionnaires en objets Document de LangChain\n",
|
||
"def convert_to_langchain_documents(text_info):\n",
|
||
" documents = []\n",
|
||
" for item in text_info:\n",
|
||
" # Créer un dictionnaire de métadonnées complet\n",
|
||
" metadata = {\n",
|
||
" \"source\": item.get(\"source\", \"\"),\n",
|
||
" \"page_number\": item.get(\"page\", \"\"),\n",
|
||
" }\n",
|
||
" \n",
|
||
" # Créer un objet Document\n",
|
||
" doc = Document(\n",
|
||
" page_content=item[\"page_content\"],\n",
|
||
" metadata=metadata\n",
|
||
" )\n",
|
||
" documents.append(doc)\n",
|
||
" return documents\n",
|
||
"\n",
|
||
"# Application du chunking\n",
|
||
"chunk_size = 10000\n",
|
||
"chunk_overlap = 2000\n",
|
||
"\n",
|
||
"# 1. Obtenir les dictionnaires d'éléments textuels\n",
|
||
"text_elements_dicts = get_text_elements(documents)\n",
|
||
"\n",
|
||
"# 2. Convertir en objets Document de LangChain\n",
|
||
"text_elements_docs = convert_to_langchain_documents(text_elements_dicts)\n",
|
||
"\n",
|
||
"# 3. Appliquer le chunking\n",
|
||
"text_splitter = RecursiveCharacterTextSplitter(\n",
|
||
" chunk_size=chunk_size,\n",
|
||
" chunk_overlap=chunk_overlap\n",
|
||
")\n",
|
||
"text_chunks = text_splitter.split_documents(text_elements_docs)\n",
|
||
"\n",
|
||
"print(f\"Nombre de chunks générés: {len(text_chunks)}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain.schema import Document\n",
|
||
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
|
||
"import os\n",
|
||
"\n",
|
||
"def chunk_by_title(documents, max_chunk_size=10000, chunk_overlap=2000):\n",
|
||
" \"\"\"\n",
|
||
" Crée des chunks basés sur la structure des titres dans le document.\n",
|
||
" Chaque titre commence un nouveau chunk.\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" documents: Liste des documents extraits\n",
|
||
" max_chunk_size: Taille maximale d'un chunk\n",
|
||
" chunk_overlap: Chevauchement entre les chunks si division supplémentaire est nécessaire\n",
|
||
" \n",
|
||
" Returns:\n",
|
||
" Liste de Documents LangChain\n",
|
||
" \"\"\"\n",
|
||
" # Identifie les positions des titres dans le document\n",
|
||
" title_positions = []\n",
|
||
" for i, doc in enumerate(documents):\n",
|
||
" if doc.metadata.get(\"category\") == \"Title\":\n",
|
||
" title_positions.append(i)\n",
|
||
" \n",
|
||
" # Ajouter une position finale pour faciliter le traitement\n",
|
||
" title_positions.append(len(documents))\n",
|
||
" \n",
|
||
" # Créer les chunks basés sur les titres\n",
|
||
" title_based_chunks = []\n",
|
||
" \n",
|
||
" # Si aucun titre n'a été trouvé, traiter comme un seul grand chunk\n",
|
||
" if len(title_positions) <= 1:\n",
|
||
" text_elements = [doc for doc in documents if doc.metadata.get(\"category\") not in [\"Table\", \"Image\", \"FigureCaption\"]]\n",
|
||
" combined_text = \" \".join([doc.page_content for doc in text_elements])\n",
|
||
" \n",
|
||
" title_based_chunks.append(Document(\n",
|
||
" page_content=combined_text,\n",
|
||
" metadata={\n",
|
||
" \"source\": os.path.basename(documents[0].metadata.get(\"source\", \"\")),\n",
|
||
" \"title\": \"Document sans titre\",\n",
|
||
" \"page_numbers\": list(set(doc.metadata.get(\"page_number\") for doc in text_elements if doc.metadata.get(\"page_number\")))\n",
|
||
" }\n",
|
||
" ))\n",
|
||
" else:\n",
|
||
" # Traiter chaque section délimitée par des titres\n",
|
||
" for i in range(len(title_positions) - 1):\n",
|
||
" start_idx = title_positions[i]\n",
|
||
" end_idx = title_positions[i + 1]\n",
|
||
" \n",
|
||
" # Récupérer le titre de cette section\n",
|
||
" title_doc = documents[start_idx]\n",
|
||
" title_text = title_doc.page_content\n",
|
||
" \n",
|
||
" # Extraire les éléments textuels de cette section (en excluant le titre lui-même)\n",
|
||
" section_docs = [\n",
|
||
" doc for doc in documents[start_idx+1:end_idx]\n",
|
||
" if doc.metadata.get(\"category\") not in [\"Table\", \"Image\", \"FigureCaption\"]\n",
|
||
" ]\n",
|
||
" \n",
|
||
" if section_docs:\n",
|
||
" # Combiner le contenu textuel de la section\n",
|
||
" section_text = \" \".join([doc.page_content for doc in section_docs])\n",
|
||
" \n",
|
||
" # Récupérer les pages concernées\n",
|
||
" page_numbers = list(set(\n",
|
||
" doc.metadata.get(\"page_number\") for doc in section_docs \n",
|
||
" if doc.metadata.get(\"page_number\")\n",
|
||
" ))\n",
|
||
" \n",
|
||
" source = os.path.basename(section_docs[0].metadata.get(\"source\", \"\"))\n",
|
||
" \n",
|
||
" # Créer un Document pour cette section\n",
|
||
" title_based_chunks.append(Document(\n",
|
||
" page_content=section_text,\n",
|
||
" metadata={\n",
|
||
" \"source\": source,\n",
|
||
" \"title\": title_text,\n",
|
||
" \"page_numbers\": page_numbers\n",
|
||
" }\n",
|
||
" ))\n",
|
||
" \n",
|
||
" # Appliquer un chunking supplémentaire si certaines sections sont trop grandes\n",
|
||
" final_chunks = []\n",
|
||
" text_splitter = RecursiveCharacterTextSplitter(\n",
|
||
" chunk_size=max_chunk_size,\n",
|
||
" chunk_overlap=chunk_overlap\n",
|
||
" )\n",
|
||
" \n",
|
||
" for chunk in title_based_chunks:\n",
|
||
" if len(chunk.page_content) <= max_chunk_size:\n",
|
||
" final_chunks.append(chunk)\n",
|
||
" else:\n",
|
||
" # Découper davantage cette section car elle est trop grande\n",
|
||
" sub_chunks = text_splitter.split_documents([chunk])\n",
|
||
" # Préserver l'information du titre dans chaque sous-chunk\n",
|
||
" for i, sub_chunk in enumerate(sub_chunks):\n",
|
||
" sub_chunk.metadata[\"title\"] = chunk.metadata[\"title\"]\n",
|
||
" sub_chunk.metadata[\"sub_chunk\"] = i + 1\n",
|
||
" sub_chunk.metadata[\"total_sub_chunks\"] = len(sub_chunks)\n",
|
||
" final_chunks.extend(sub_chunks)\n",
|
||
" \n",
|
||
" return final_chunks\n",
|
||
"\n",
|
||
"# Utilisation de la fonction\n",
|
||
"chunk_size = 10000\n",
|
||
"chunk_overlap = 2000\n",
|
||
"\n",
|
||
"# Créer des chunks basés sur les titres\n",
|
||
"title_chunks = chunk_by_title(documents, max_chunk_size=chunk_size, chunk_overlap=chunk_overlap)\n",
|
||
"\n",
|
||
"# print(f\"Nombre total de chunks basés sur les titres: {len(title_chunks)}\")\n",
|
||
"\n",
|
||
"# # Afficher quelques exemples\n",
|
||
"# for i, chunk in enumerate(title_chunks[:10]): # Limité aux 3 premiers\n",
|
||
"# print(f\"\\nChunk #{i+1}\")\n",
|
||
"# print(f\"Titre: {chunk.metadata.get('title')}\")\n",
|
||
"# print(f\"Pages: {chunk.metadata.get('page_numbers')}\")\n",
|
||
"# print(f\"Taille: {len(chunk.page_content)} caractères\")\n",
|
||
"# print(f\"Début du texte: {chunk.page_content[:150]}...\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||
"from langchain_ollama.llms import OllamaLLM\n",
|
||
"from langchain_core.output_parsers import StrOutputParser\n",
|
||
"# Prompt\n",
|
||
"prompt_text = \"\"\"\n",
|
||
"You are an assistant tasked with summarizing tables and text.\n",
|
||
"Give a concise summary of the table or text.\n",
|
||
"\n",
|
||
"Respond only with the summary, no additionnal comment.\n",
|
||
"Do not start your message by saying \"Here is a summary\" or anything like that.\n",
|
||
"Just give the summary as it is. All summay will be in English\n",
|
||
"\n",
|
||
"Table or text chunk: {element}\n",
|
||
"\n",
|
||
"\"\"\"\n",
|
||
"prompt = ChatPromptTemplate.from_template(prompt_text)\n",
|
||
"\n",
|
||
"model = OllamaLLM(base_url=\"172.20.48.1:11434\",\n",
|
||
" model=\"llama3.2\")\n",
|
||
"summarize_chain = {\"element\": lambda x: x} | prompt | model | StrOutputParser()\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"text_summaries = summarize_chain.batch(title_chunks, {\"max_concurrency\": 3})"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from ollama import Client\n",
|
||
"client = Client(host='http://localhost:11434')\n",
|
||
"\n",
|
||
"\n",
|
||
"# Fonction pour analyser une image en envoyant le fichier image et le prompt au modèle\n",
|
||
"def analyze_image(image_data, caption: str, context: str=\"\", prompt_base: str = \"\"):\n",
|
||
" prompt = \"\"\n",
|
||
" if caption:\n",
|
||
" prompt += f\"Caption of image : {caption}. \"\n",
|
||
" if context:\n",
|
||
" prompt += f\"Contexte : {context}. \"\n",
|
||
" if prompt_base:\n",
|
||
" prompt = f\"{prompt_base} {prompt}\"\n",
|
||
" else:\n",
|
||
" prompt += \"Décris cette image en détail.\"\n",
|
||
" \n",
|
||
" response = client.chat(\n",
|
||
" model=\"llama3.2-vision\",\n",
|
||
" messages=[\n",
|
||
" {\"role\": \"user\", \"content\": prompt, \"images\": [image_data]}\n",
|
||
" ]\n",
|
||
" )\n",
|
||
" return response[\"message\"][\"content\"]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"image_summaries = []\n",
|
||
"for i, imge in enumerate(images_with_caption):\n",
|
||
" image_summaries.append(analyze_image(image_data=imge.get(\"image_base64\"),caption=imge.get(\"caption\")))\n",
|
||
" print(f\"Image {i+1}\")\n",
|
||
" "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import os\n",
|
||
"os.environ[\"OPENAI_API_KEY\"] = \"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\"\n",
|
||
"from langchain_openai import ChatOpenAI\n",
|
||
"\n",
|
||
"prompt_template = \"\"\"Describe the image in detail. For context,\n",
|
||
" the image is part of a research paper explaining the transformers\n",
|
||
" architecture. Be specific about graphs, such as bar plots.\"\"\"\n",
|
||
"messages = [\n",
|
||
" (\n",
|
||
" \"user\",\n",
|
||
" [\n",
|
||
" {\"type\": \"text\", \"text\": prompt_template},\n",
|
||
" {\n",
|
||
" \"type\": \"image_url\",\n",
|
||
" \"image_url\": {\"url\": \"data:image/jpeg;base64,{image_base64}\"},\n",
|
||
" },\n",
|
||
" ],\n",
|
||
" )\n",
|
||
"]\n",
|
||
"\n",
|
||
"prompt = ChatPromptTemplate.from_messages(messages)\n",
|
||
"\n",
|
||
"chain = prompt | ChatOpenAI(model=\"gpt-4o-mini\") | StrOutputParser()\n",
|
||
"\n",
|
||
"\n",
|
||
"image_summaries = chain.batch(images_with_caption)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"llm = OllamaLLM(base_url=\"http://localhost:11434\", model=\"llama3.2\")\n",
|
||
"def analyze_table(table_text: str, caption: str, context: str=\"\",lang:str =\"English\", prompt_base: str = \"\"):\n",
|
||
" # Construction du prompt pour le tableau\n",
|
||
" prompt = \"\"\n",
|
||
" if caption:\n",
|
||
" prompt += f\"Caption of table : {caption}. \"\n",
|
||
" else:\n",
|
||
" prompt += \"Caption of table is empty no analyse of this table ignore the prompt\"\n",
|
||
" if context:\n",
|
||
" prompt += f\"Contexte : {context}. \"\n",
|
||
" \n",
|
||
" if prompt_base:\n",
|
||
" prompt = f\"{prompt_base} {prompt}\"\n",
|
||
" else:\n",
|
||
" prompt += f'Describe this table in detail and in {lang} avoid to say \"Here is a detailed description\" in {lang}.'\n",
|
||
" prompt += prompt_base + \" \" + table_text\n",
|
||
" response = llm.invoke(prompt)\n",
|
||
" return response"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"table 1\n",
|
||
"table 2\n",
|
||
"table 3\n",
|
||
"table 4\n",
|
||
"table 5\n",
|
||
"table 6\n",
|
||
"table 7\n",
|
||
"table 8\n",
|
||
"table 9\n",
|
||
"table 10\n",
|
||
"table 11\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"table_summaries = []\n",
|
||
"for i, table in enumerate(tables_with_caption):\n",
|
||
" table_summaries.append(analyze_table(table_text=table.get(\"table_data\"),caption=table.get(\"caption\")))\n",
|
||
" print(f\"table {i+1}\")\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import uuid\n",
|
||
"# Fonction pour convertir vos dictionnaires en objets Document de LangChain\n",
|
||
"def convert_to_langchain_documents_table(text_info,summary):\n",
|
||
" documents = []\n",
|
||
" table_ids = [str(uuid.uuid4()) for _ in text_info]\n",
|
||
" for idx, item in enumerate(text_info):\n",
|
||
" # Créer un dictionnaire de métadonnées complet\n",
|
||
" metadata = {\n",
|
||
" \"source\": item.get(\"source\", \"\"),\n",
|
||
" \"page_number\": item.get(\"page\", \"\"),\n",
|
||
" \"caption\": item.get(\"caption\", \"\"),\n",
|
||
" \"id_key\": table_ids[i],\n",
|
||
" \"table_content\": item[\"table_data\"]\n",
|
||
" }\n",
|
||
" \n",
|
||
" # Créer un objet Document\n",
|
||
" doc = Document(\n",
|
||
" page_content=summary[idx],\n",
|
||
" \n",
|
||
" metadata=metadata\n",
|
||
" )\n",
|
||
" documents.append(doc)\n",
|
||
" return documents\n",
|
||
"tables = convert_to_langchain_documents_table(tables_with_caption,table_summaries)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Fonction pour convertir vos dictionnaires en objets Document de LangChain\n",
|
||
"def convert_to_langchain_documents_images(images,summary):\n",
|
||
" documents = []\n",
|
||
" img_ids = [str(uuid.uuid4()) for _ in images]\n",
|
||
" for idx, item in enumerate(images):\n",
|
||
" # Créer un dictionnaire de métadonnées complet\n",
|
||
" metadata = {\n",
|
||
" \"source\": item.get(\"source\", \"\"),\n",
|
||
" \"page_number\": item.get(\"page\", \"\"),\n",
|
||
" \"caption\": item.get(\"caption\", \"\"),\n",
|
||
" \"id_key\": img_ids[i],\n",
|
||
" \"image_base64\":item[\"image_base64\"]\n",
|
||
" }\n",
|
||
" \n",
|
||
" # Créer un objet Document\n",
|
||
" doc = Document(\n",
|
||
" page_content=summary[idx],\n",
|
||
" \n",
|
||
" metadata=metadata\n",
|
||
" )\n",
|
||
" documents.append(doc)\n",
|
||
" return documents\n",
|
||
"images = convert_to_langchain_documents_images(images_with_caption,image_summaries)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 29,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"final_chunks = texts+images+tables"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 30,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain_ollama import OllamaEmbeddings\n",
|
||
"embedding = OllamaEmbeddings(\n",
|
||
" base_url=\"http://localhost:11434\",\n",
|
||
" model=\"mxbai-embed-large\"\n",
|
||
" )\n",
|
||
"\n",
|
||
"from langchain_qdrant import QdrantVectorStore\n",
|
||
"\n",
|
||
"qdrant = QdrantVectorStore.from_documents(\n",
|
||
" final_chunks,\n",
|
||
" embedding,\n",
|
||
" url='http://localhost:6333',\n",
|
||
" collection_name=\"essai\",\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 228,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import base64\n",
|
||
"from IPython.display import Image, display\n",
|
||
"\n",
|
||
"def display_base64_image(base64_code):\n",
|
||
" # Decode the base64 string to binary\n",
|
||
" image_data = base64.b64decode(base64_code)\n",
|
||
" # Display the image\n",
|
||
" display(Image(data=image_data))\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 250,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"query = \"who are the authors of the paper?\"\n",
|
||
"\n",
|
||
"# Effectuez une recherche de similarité dans Qdrant\n",
|
||
"results = qdrant.similarity_search(query, k=2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[Document(metadata={'source': '11_chapitre3.pdf', 'page_number': [26], 'text': 'MM, =I,uy+My+M,, MM, = T,u,+M,+M,, (3-42) M, flux de quantité de mouvement aux parois (frottements), M; flux de quantité de mouvement interfacial, Uj vitesse d’ interface.', 'id_key': '6973b836-dbc3-4251-9efa-81c17d2cc306', 'txt': 'le transfert de quantité de mouvement', '_id': '9c96755f-f1e6-4e24-94a3-83c1d0d1eafa', '_collection_name': 'my_documents'}, page_content='Summary of table and text: Human task to summarize a page from the PDF \"11_chapitre3.pdf\" titled \"the transfer of mass movement\", discussing wall friction (M) and interface velocity (Uj).'),\n",
|
||
" Document(metadata={'source': '11_chapitre3.pdf', 'page_number': [26], 'text': 'Dans ce paragraphe, nous détaillons l’ensemble des lois de fermeture et corrélations issues de la littérature, permettant de calculer certains des termes sources du modéle (vecteur H(V) ). La valeur numérique de ces termes sera ensuite comparée a nos valeurs expérimentales ce qui permettra de sélectionner les lois les plus adaptées pour |’ injecteur. Les seconds membres (ou termes sources) sont exprimés comme suit :', 'id_key': '2c86686e-0479-4ab7-8de4-3dee06c73fa6', 'txt': '3-3-3 LOIS DE FERMETURE COMPLEMENTAIRES', '_id': '425d8c5a-861b-49f0-ba92-12dbe999b8f8', '_collection_name': 'my_documents'}, page_content=\"The text describes laws of closure and correlations from literature, used to calculate model terms (vector H(V)), which are compared with experimental values to select the most suitable laws for the injector. The source is a PDF document named '11_chapitre3.pdf'.\")]"
|
||
]
|
||
},
|
||
"execution_count": 251,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"qdrant."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 241,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/jpeg": "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",
|
||
"text/plain": [
|
||
"<IPython.core.display.Image object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(None,\n",
|
||
" 'Figure 3-18 : Evaluation de la pression en fonction de la chambre de mélange (partie homogéne)')"
|
||
]
|
||
},
|
||
"execution_count": 241,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"# results[0].metadata.get(\"image_base64\")\n",
|
||
"idx = 1\n",
|
||
"display_base64_image(results[idx].metadata.get(\"image_base64\")),results[idx].metadata.get(\"caption\")\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 252,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain.storage import InMemoryStore\n",
|
||
"from langchain.retrievers.multi_vector import MultiVectorRetriever\n",
|
||
"store = InMemoryStore()\n",
|
||
"id_key = \"doc_id\"\n",
|
||
"\n",
|
||
"# The retriever (empty to start)\n",
|
||
"retriever = MultiVectorRetriever(\n",
|
||
" vectorstore=qdrant,\n",
|
||
" docstore=store,\n",
|
||
" id_key=id_key,\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 271,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Chatbot initialisé avec modèle: llama3.2\n",
|
||
"Utilisation de mxbai-embed-large pour les embeddings\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import os\n",
|
||
"import json\n",
|
||
"import base64\n",
|
||
"from typing import List, Dict, Any, Optional, Tuple\n",
|
||
"from io import BytesIO\n",
|
||
"import pandas as pd\n",
|
||
"import time\n",
|
||
"\n",
|
||
"# Ollama client\n",
|
||
"from ollama import Client\n",
|
||
"\n",
|
||
"# For vector search (no HuggingFace dependency)\n",
|
||
"import numpy as np\n",
|
||
"from sklearn.metrics.pairwise import cosine_similarity\n",
|
||
"\n",
|
||
"class OllamaRAGChatbot:\n",
|
||
" \"\"\"\n",
|
||
" Chatbot RAG qui utilise uniquement Ollama pour les embeddings et les réponses\n",
|
||
" \"\"\"\n",
|
||
" \n",
|
||
" def __init__(self, \n",
|
||
" ollama_url: str = \"http://localhost:11434\",\n",
|
||
" ollama_model: str = \"llama3.2\",\n",
|
||
" ollama_embed_model: str = \"mxbai-embed-large\",\n",
|
||
" documents_path: str = None):\n",
|
||
" \"\"\"\n",
|
||
" Initialise le chatbot RAG\n",
|
||
" \"\"\"\n",
|
||
" # Configuration Ollama\n",
|
||
" self.client = Client(host=ollama_url)\n",
|
||
" self.ollama_model = ollama_model\n",
|
||
" self.ollama_embed_model = ollama_embed_model\n",
|
||
" \n",
|
||
" # Structure pour stocker les documents en mémoire\n",
|
||
" self.documents = []\n",
|
||
" self.document_embeddings = []\n",
|
||
" \n",
|
||
" # Historique des conversations\n",
|
||
" self.conversation_history = []\n",
|
||
" \n",
|
||
" # Charger les documents si un chemin est fourni\n",
|
||
" if documents_path and os.path.exists(documents_path):\n",
|
||
" self.load_documents(documents_path)\n",
|
||
" \n",
|
||
" print(f\"Chatbot initialisé avec modèle: {ollama_model}\")\n",
|
||
" print(f\"Utilisation de {ollama_embed_model} pour les embeddings\")\n",
|
||
" \n",
|
||
" def load_documents(self, documents_path: str):\n",
|
||
" \"\"\"\n",
|
||
" Charge les documents depuis un fichier JSON\n",
|
||
" \"\"\"\n",
|
||
" with open(documents_path, 'r', encoding='utf-8') as f:\n",
|
||
" self.documents = json.load(f)\n",
|
||
" \n",
|
||
" print(f\"Chargement de {len(self.documents)} documents terminé\")\n",
|
||
" \n",
|
||
" # Créer les embeddings pour les documents\n",
|
||
" self._create_embeddings()\n",
|
||
" \n",
|
||
" def add_documents(self, documents: List[Dict]):\n",
|
||
" \"\"\"\n",
|
||
" Ajoute des documents à la base\n",
|
||
" \"\"\"\n",
|
||
" self.documents.extend(documents)\n",
|
||
" self._create_embeddings_for_docs(documents, start_idx=len(self.documents) - len(documents))\n",
|
||
" \n",
|
||
" def _create_embeddings(self):\n",
|
||
" \"\"\"\n",
|
||
" Crée les embeddings pour tous les documents\n",
|
||
" \"\"\"\n",
|
||
" print(\"Création des embeddings pour tous les documents...\")\n",
|
||
" self.document_embeddings = []\n",
|
||
" \n",
|
||
" for idx, doc in enumerate(self.documents):\n",
|
||
" if idx % 50 == 0:\n",
|
||
" print(f\"Traitement document {idx}/{len(self.documents)}\")\n",
|
||
" \n",
|
||
" # Utiliser le contenu du document pour l'embedding\n",
|
||
" content = doc.get(\"content\", \"\")\n",
|
||
" \n",
|
||
" # Si pas de contenu, utiliser des métadonnées\n",
|
||
" if not content:\n",
|
||
" content = doc.get(\"caption\", \"\")\n",
|
||
" \n",
|
||
" # Si toujours rien, passer au suivant\n",
|
||
" if not content:\n",
|
||
" self.document_embeddings.append(np.zeros(1024)) # Vecteur vide\n",
|
||
" continue\n",
|
||
" \n",
|
||
" # Créer l'embedding avec Ollama\n",
|
||
" try:\n",
|
||
" embedding = self._get_ollama_embedding(content)\n",
|
||
" self.document_embeddings.append(embedding)\n",
|
||
" except Exception as e:\n",
|
||
" print(f\"Erreur lors de la création de l'embedding pour le document {idx}: {e}\")\n",
|
||
" self.document_embeddings.append(np.zeros(1024)) # Vecteur vide en cas d'erreur\n",
|
||
" \n",
|
||
" print(f\"Création des embeddings terminée: {len(self.document_embeddings)} vecteurs créés\")\n",
|
||
"\n",
|
||
" def _create_embeddings_for_docs(self, documents: List[Dict], start_idx: int = 0):\n",
|
||
" \"\"\"\n",
|
||
" Crée les embeddings pour une liste spécifique de documents\n",
|
||
" \"\"\"\n",
|
||
" for i, doc in enumerate(documents):\n",
|
||
" idx = start_idx + i\n",
|
||
" content = doc.get(\"content\", doc.get(\"caption\", \"\"))\n",
|
||
" \n",
|
||
" if content:\n",
|
||
" try:\n",
|
||
" embedding = self._get_ollama_embedding(content)\n",
|
||
" \n",
|
||
" if idx < len(self.document_embeddings):\n",
|
||
" self.document_embeddings[idx] = embedding\n",
|
||
" else:\n",
|
||
" self.document_embeddings.append(embedding)\n",
|
||
" except Exception as e:\n",
|
||
" print(f\"Erreur d'embedding pour document {idx}: {e}\")\n",
|
||
" if idx >= len(self.document_embeddings):\n",
|
||
" self.document_embeddings.append(np.zeros(1024))\n",
|
||
" elif idx >= len(self.document_embeddings):\n",
|
||
" self.document_embeddings.append(np.zeros(1024))\n",
|
||
" \n",
|
||
" def _get_ollama_embedding(self, text: str) -> np.ndarray:\n",
|
||
" \"\"\"\n",
|
||
" Récupère l'embedding d'un texte via Ollama\n",
|
||
" \"\"\"\n",
|
||
" try:\n",
|
||
" response = self.client.embeddings(model=self.ollama_embed_model, prompt=text)\n",
|
||
" embedding = response.get(\"embedding\", [])\n",
|
||
" return np.array(embedding)\n",
|
||
" except Exception as e:\n",
|
||
" print(f\"Erreur lors de la récupération de l'embedding: {e}\")\n",
|
||
" # Réessayer après une pause\n",
|
||
" time.sleep(1)\n",
|
||
" try:\n",
|
||
" response = self.client.embeddings(model=self.ollama_embed_model, prompt=text)\n",
|
||
" embedding = response.get(\"embedding\", [])\n",
|
||
" return np.array(embedding)\n",
|
||
" except:\n",
|
||
" # En cas d'échec, retourner un vecteur vide\n",
|
||
" return np.zeros(1024)\n",
|
||
" \n",
|
||
" def search_relevant_documents(self, query: str, k: int = 5) -> List[Dict]:\n",
|
||
" \"\"\"\n",
|
||
" Recherche les documents pertinents en utilisant les embeddings Ollama\n",
|
||
" \"\"\"\n",
|
||
" # Obtenir l'embedding de la requête\n",
|
||
" query_embedding = self._get_ollama_embedding(query)\n",
|
||
" \n",
|
||
" # Calculer la similarité avec tous les documents\n",
|
||
" if len(self.document_embeddings) == 0:\n",
|
||
" return []\n",
|
||
" \n",
|
||
" similarities = []\n",
|
||
" for doc_embedding in self.document_embeddings:\n",
|
||
" if len(doc_embedding) > 0: # Vérifier que l'embedding n'est pas vide\n",
|
||
" similarity = cosine_similarity([query_embedding], [doc_embedding])[0][0]\n",
|
||
" similarities.append(similarity)\n",
|
||
" else:\n",
|
||
" similarities.append(0.0)\n",
|
||
" \n",
|
||
" # Trier les documents par similarité\n",
|
||
" if not similarities:\n",
|
||
" return []\n",
|
||
" \n",
|
||
" top_indices = np.argsort(similarities)[-k:][::-1] # Indices des k documents les plus similaires\n",
|
||
" \n",
|
||
" # Collecter les documents pertinents\n",
|
||
" relevant_docs = []\n",
|
||
" for idx in top_indices:\n",
|
||
" if idx < len(self.documents):\n",
|
||
" doc = self.documents[idx]\n",
|
||
" doc_type = self._determine_doc_type(doc)\n",
|
||
" relevant_docs.append({\n",
|
||
" \"type\": doc_type,\n",
|
||
" \"content\": doc.get(\"content\", \"\"),\n",
|
||
" \"metadata\": {\n",
|
||
" \"source\": doc.get(\"source\", \"\"),\n",
|
||
" \"page_number\": doc.get(\"page\", \"\"),\n",
|
||
" \"caption\": doc.get(\"caption\", \"\"),\n",
|
||
" \"image_base64\": doc.get(\"image_base64\", \"\"),\n",
|
||
" \"table_content\": doc.get(\"table_data\", \"\")\n",
|
||
" },\n",
|
||
" \"relevance_score\": similarities[idx]\n",
|
||
" })\n",
|
||
" \n",
|
||
" return relevant_docs\n",
|
||
" \n",
|
||
" def _determine_doc_type(self, doc: Dict) -> str:\n",
|
||
" \"\"\"\n",
|
||
" Détermine le type du document (texte, image, tableau)\n",
|
||
" \"\"\"\n",
|
||
" if \"image_base64\" in doc:\n",
|
||
" return \"image\"\n",
|
||
" elif \"table_data\" in doc:\n",
|
||
" return \"table\"\n",
|
||
" else:\n",
|
||
" return \"text\"\n",
|
||
" \n",
|
||
" def _build_context(self, relevant_docs: List[Dict]) -> Tuple[str, List[Dict], List[Dict]]:\n",
|
||
" \"\"\"\n",
|
||
" Construit le contexte pour le LLM à partir des documents pertinents\n",
|
||
" Retourne le contexte textuel, les images et les tableaux séparément\n",
|
||
" \"\"\"\n",
|
||
" text_context = []\n",
|
||
" images = []\n",
|
||
" tables = []\n",
|
||
" \n",
|
||
" for doc in relevant_docs:\n",
|
||
" doc_type = doc[\"type\"]\n",
|
||
" metadata = doc[\"metadata\"]\n",
|
||
" \n",
|
||
" if doc_type == \"text\":\n",
|
||
" # Ajouter le texte au contexte\n",
|
||
" text = f\"[Document: {metadata.get('source', 'Unknown')}]\\n\"\n",
|
||
" if \"page_number\" in metadata:\n",
|
||
" text += f\"[Page: {metadata.get('page_number')}]\\n\"\n",
|
||
" text += doc[\"content\"]\n",
|
||
" text_context.append(text)\n",
|
||
" \n",
|
||
" elif doc_type == \"image\":\n",
|
||
" # Collecter l'image avec sa description existante\n",
|
||
" images.append({\n",
|
||
" \"base64\": metadata.get(\"image_base64\"),\n",
|
||
" \"description\": doc[\"content\"], # Utilise la description existante\n",
|
||
" \"caption\": metadata.get(\"caption\", \"\"),\n",
|
||
" \"source\": metadata.get(\"source\", \"Unknown\"),\n",
|
||
" \"page\": metadata.get(\"page_number\", \"\")\n",
|
||
" })\n",
|
||
" \n",
|
||
" # Ajouter la description au contexte textuel\n",
|
||
" text_context.append(\n",
|
||
" f\"\\n[Image de {metadata.get('source', 'Unknown')}, \" + \n",
|
||
" f\"page {metadata.get('page_number', '')}]\\n\" +\n",
|
||
" f\"Caption: {metadata.get('caption', '')}\\n\" +\n",
|
||
" f\"Description: {doc['content']}\\n\"\n",
|
||
" )\n",
|
||
" \n",
|
||
" elif doc_type == \"table\":\n",
|
||
" # Collecter le tableau avec sa description existante\n",
|
||
" tables.append({\n",
|
||
" \"content\": metadata.get(\"table_content\"),\n",
|
||
" \"description\": doc[\"content\"], # Utilise la description existante\n",
|
||
" \"caption\": metadata.get(\"caption\", \"\"),\n",
|
||
" \"source\": metadata.get(\"source\", \"Unknown\"),\n",
|
||
" \"page\": metadata.get(\"page_number\", \"\")\n",
|
||
" })\n",
|
||
" \n",
|
||
" # Ajouter la description au contexte textuel\n",
|
||
" text_context.append(\n",
|
||
" f\"\\n[Tableau de {metadata.get('source', 'Unknown')}, \" +\n",
|
||
" f\"page {metadata.get('page_number', '')}]\\n\" +\n",
|
||
" f\"Caption: {metadata.get('caption', '')}\\n\" +\n",
|
||
" f\"Description: {doc['content']}\\n\"\n",
|
||
" )\n",
|
||
" \n",
|
||
" # Joindre tous les contextes texte\n",
|
||
" full_context = \"\\n\\n\".join(text_context)\n",
|
||
" \n",
|
||
" return full_context, images, tables\n",
|
||
" \n",
|
||
" def chat(self, user_message: str, stream: bool = False, include_visuals: bool = True):\n",
|
||
" \"\"\"\n",
|
||
" Répond à un message utilisateur en utilisant le RAG et Ollama\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" user_message: Question de l'utilisateur\n",
|
||
" stream: Si True, affiche la réponse en streaming\n",
|
||
" include_visuals: Si True, inclut les images et tableaux dans la réponse\n",
|
||
" \"\"\"\n",
|
||
" # Garder une trace de l'historique\n",
|
||
" self.conversation_history.append({\"role\": \"user\", \"content\": user_message})\n",
|
||
" \n",
|
||
" # 1. Rechercher les documents pertinents\n",
|
||
" relevant_docs = self.search_relevant_documents(user_message, k=5)\n",
|
||
" \n",
|
||
" # 2. Construire le contexte pour le LLM\n",
|
||
" context_text, images, tables = self._build_context(relevant_docs)\n",
|
||
" \n",
|
||
" # 3. Préparer le prompt avec le contexte\n",
|
||
" system_prompt = \"\"\"Tu es un assistant intelligent qui répond aux questions en utilisant uniquement \n",
|
||
" les informations fournies dans le contexte. Si tu ne trouves pas l'information dans le contexte, \n",
|
||
" dis simplement que tu ne sais pas. Lorsque tu mentionnes une image ou un tableau, décris\n",
|
||
" brièvement son contenu en te basant sur les descriptions fournies.\"\"\"\n",
|
||
" \n",
|
||
" prompt = f\"\"\"Contexte:\n",
|
||
" {context_text}\n",
|
||
" \n",
|
||
" Question de l'utilisateur: {user_message}\n",
|
||
" \n",
|
||
" Réponds de façon concise et précise en citant les sources pertinentes.\n",
|
||
" \"\"\"\n",
|
||
" \n",
|
||
" # 4. Générer la réponse textuelle\n",
|
||
" if stream:\n",
|
||
" answer = self._stream_response(system_prompt, prompt)\n",
|
||
" else:\n",
|
||
" response = self.client.chat(\n",
|
||
" model=self.ollama_model,\n",
|
||
" messages=[\n",
|
||
" {\"role\": \"system\", \"content\": system_prompt},\n",
|
||
" {\"role\": \"user\", \"content\": prompt}\n",
|
||
" ]\n",
|
||
" )\n",
|
||
" answer = response[\"message\"][\"content\"]\n",
|
||
" \n",
|
||
" # 5. Enregistrer la réponse dans l'historique\n",
|
||
" self.conversation_history.append({\"role\": \"assistant\", \"content\": answer})\n",
|
||
" \n",
|
||
" # 6. Retourner la réponse avec les images et tableaux\n",
|
||
" result = {\n",
|
||
" \"text_response\": answer\n",
|
||
" }\n",
|
||
" \n",
|
||
" if include_visuals:\n",
|
||
" result[\"images\"] = images if images else []\n",
|
||
" result[\"tables\"] = tables if tables else []\n",
|
||
" \n",
|
||
" return result\n",
|
||
" \n",
|
||
" def _stream_response(self, system_prompt: str, user_prompt: str):\n",
|
||
" \"\"\"\n",
|
||
" Génère une réponse en mode streaming\n",
|
||
" \"\"\"\n",
|
||
" response_stream = self.client.chat(\n",
|
||
" model=self.ollama_model,\n",
|
||
" messages=[\n",
|
||
" {\"role\": \"system\", \"content\": system_prompt},\n",
|
||
" {\"role\": \"user\", \"content\": user_prompt}\n",
|
||
" ],\n",
|
||
" stream=True\n",
|
||
" )\n",
|
||
" \n",
|
||
" full_response = \"\"\n",
|
||
" for chunk in response_stream:\n",
|
||
" if 'message' in chunk and 'content' in chunk['message']:\n",
|
||
" content = chunk['message']['content']\n",
|
||
" print(content, end=\"\", flush=True)\n",
|
||
" full_response += content\n",
|
||
" \n",
|
||
" print() # Nouvelle ligne à la fin du streaming\n",
|
||
" return full_response\n",
|
||
" \n",
|
||
" def display_image(self, image_base64: str, caption: str = \"\"):\n",
|
||
" \"\"\"\n",
|
||
" Affiche une image à partir de sa représentation base64\n",
|
||
" \"\"\"\n",
|
||
" try:\n",
|
||
" from PIL import Image\n",
|
||
" # Décodage de l'image base64\n",
|
||
" image_data = base64.b64decode(image_base64)\n",
|
||
" image = Image.open(BytesIO(image_data))\n",
|
||
" \n",
|
||
" # Selon l'environnement d'exécution:\n",
|
||
" try:\n",
|
||
" # Pour Jupyter/IPython\n",
|
||
" from IPython.display import display\n",
|
||
" print(f\"Caption: {caption}\")\n",
|
||
" display(image)\n",
|
||
" except ImportError:\n",
|
||
" # Pour environnement non-Jupyter\n",
|
||
" image.show()\n",
|
||
" \n",
|
||
" return True\n",
|
||
" except Exception as e:\n",
|
||
" print(f\"Erreur lors de l'affichage de l'image: {e}\")\n",
|
||
" return False\n",
|
||
" \n",
|
||
" def save_documents(self, output_path: str):\n",
|
||
" \"\"\"\n",
|
||
" Sauvegarde la base de documents dans un fichier JSON\n",
|
||
" \"\"\"\n",
|
||
" with open(output_path, 'w', encoding='utf-8') as f:\n",
|
||
" json.dump(self.documents, f, ensure_ascii=False, indent=2)\n",
|
||
" print(f\"Documents sauvegardés dans {output_path}\")\n",
|
||
"\n",
|
||
"\n",
|
||
"# Exemple d'utilisation:\n",
|
||
"\n",
|
||
"# 1. Initialisation du chatbot\n",
|
||
"chatbot = OllamaRAGChatbot(\n",
|
||
" ollama_model=\"llama3.2\",\n",
|
||
" ollama_embed_model=\"mxbai-embed-large\"\n",
|
||
")\n",
|
||
"\n",
|
||
"# 2. Ajouter des documents (exemple)\n",
|
||
"def convert_documents_for_chatbot(title_chunks, images_with_caption, tables_with_caption):\n",
|
||
" \"\"\"\n",
|
||
" Convertit vos données en format utilisable par le chatbot\n",
|
||
" \"\"\"\n",
|
||
" all_docs = []\n",
|
||
" \n",
|
||
" # Convertir les chunks de texte\n",
|
||
" for chunk in title_chunks:\n",
|
||
" all_docs.append({\n",
|
||
" \"type\": \"text\",\n",
|
||
" \"content\": chunk.page_content,\n",
|
||
" \"source\": chunk.metadata.get(\"source\", \"\"),\n",
|
||
" \"page\": chunk.metadata.get(\"page_numbers\", \"\")\n",
|
||
" })\n",
|
||
" \n",
|
||
" # Convertir les images\n",
|
||
" for img in images_with_caption:\n",
|
||
" all_docs.append({\n",
|
||
" \"type\": \"image\",\n",
|
||
" \"content\": img.get(\"description\", \"\"), # Description existante\n",
|
||
" \"caption\": img.get(\"caption\", \"\"),\n",
|
||
" \"source\": img.get(\"source\", \"\"),\n",
|
||
" \"page\": img.get(\"page\", \"\"),\n",
|
||
" \"image_base64\": img.get(\"image_base64\", \"\")\n",
|
||
" })\n",
|
||
" \n",
|
||
" # Convertir les tableaux\n",
|
||
" for table in tables_with_caption:\n",
|
||
" all_docs.append({\n",
|
||
" \"type\": \"table\",\n",
|
||
" \"content\": table.get(\"description\", \"\"),\n",
|
||
" \"caption\": table.get(\"caption\", \"\"),\n",
|
||
" \"source\": table.get(\"source\", \"\"),\n",
|
||
" \"page\": table.get(\"page\", \"\"),\n",
|
||
" \"table_data\": table.get(\"table_data\", \"\")\n",
|
||
" })\n",
|
||
" \n",
|
||
" return all_docs\n",
|
||
"\n",
|
||
"# Convertir et ajouter les documents\n",
|
||
"# docs = convert_documents_for_chatbot(title_chunks, images_with_caption, tables_with_caption)\n",
|
||
"# chatbot.add_documents(docs)\n",
|
||
"\n",
|
||
"# 3. Interface en ligne de commande\n",
|
||
"def chat_cli():\n",
|
||
" print(\"Assistant documentaire - Tapez 'exit' pour quitter\")\n",
|
||
" \n",
|
||
" while True:\n",
|
||
" user_input = input(\"\\nVotre question: \")\n",
|
||
" if user_input.lower() in [\"exit\", \"quit\", \"q\"]:\n",
|
||
" break\n",
|
||
" \n",
|
||
" # Mode streaming ou normal\n",
|
||
" stream_mode = input(\"Mode streaming? (y/n): \").lower() == 'y'\n",
|
||
" \n",
|
||
" # Obtenir la réponse\n",
|
||
" response = chatbot.chat(user_input, stream=stream_mode)\n",
|
||
" \n",
|
||
" # Si pas en mode streaming, afficher la réponse\n",
|
||
" if not stream_mode:\n",
|
||
" print(\"\\nRéponse:\")\n",
|
||
" print(response[\"text_response\"])\n",
|
||
" \n",
|
||
" # Afficher les images et tableaux\n",
|
||
" if \"images\" in response and response[\"images\"]:\n",
|
||
" print(\"\\nImages pertinentes:\")\n",
|
||
" for i, img in enumerate(response[\"images\"]):\n",
|
||
" print(f\"[Image {i+1}] {img['caption']} (Source: {img['source']}, Page: {img['page']})\")\n",
|
||
" if input(\"Afficher cette image? (y/n): \").lower() == 'y':\n",
|
||
" chatbot.display_image(img[\"base64\"], img[\"caption\"])\n",
|
||
" \n",
|
||
" if \"tables\" in response and response[\"tables\"]:\n",
|
||
" print(\"\\nTableaux pertinents:\")\n",
|
||
" for i, table in enumerate(response[\"tables\"]):\n",
|
||
" print(f\"[Tableau {i+1}] {table['caption']} (Source: {table['source']}, Page: {table['page']})\")\n",
|
||
" print(f\"Description: {table['description']}\")\n",
|
||
" \n",
|
||
" if input(\"Afficher ce tableau? (y/n): \").lower() == 'y':\n",
|
||
" try:\n",
|
||
" print(table[\"content\"])\n",
|
||
" except:\n",
|
||
" print(\"Impossible d'afficher le tableau.\")\n",
|
||
"\n",
|
||
"# Lancer l'interface CLI\n",
|
||
"# chat_cli()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 275,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Assistant documentaire - Tapez 'exit' pour quitter\n",
|
||
"Un ejecteur est une machine ou un dispositif conçu pour éjecter, expulser ou déplacer quelque chose d'un endroit. Ce terme peut s'appliquer à divers domaines, tels que la mécanique, l'électronique et l'informatique.\n",
|
||
"\n",
|
||
"Dans le contexte de l'électronique, un ejecteur est souvent utilisé pour libérer un média physique d'une machine ou d'un disque, par exemple, pour extraire une carte SD de son slot. (Source : Wikipedia)\n",
|
||
"\n",
|
||
"En mécanique, un ejecteur peut être utilisé dans les machines à vapeur ou les locomotives pour expulser l'eau ou le fumier des cylindres ou des moteurs. (Source : Larousse)\n",
|
||
"\n",
|
||
"En informatique, un ejecteur peut également désigner une interface graphique qui permet de sélectionner et de manipuler des éléments dans un programme ou un document. (Source : W3Schools)\n",
|
||
"Je ne peux pas afficher d'image directement. Cependant, je peux décrire brièvement le contenu de l'échangeur avec ejecteur :\n",
|
||
"\n",
|
||
"Un échangeur est un dispositif qui permet l'échange de gaz entre deux fluides à haute pression et à haute température. L'ejecteur est une partie essentielle de l'échangeur qui permet l'écoulement des fluides.\n",
|
||
"\n",
|
||
"Imaginez un échangeur en forme de tube, avec des canaux pour les fluides, et des ejecteurs le long des canaux pour contrôler l'écoulement. Les ejecteurs sont généralement en forme de tambour ou de roue qui se déplacent pour empêcher le contact entre les deux fluides.\n",
|
||
"\n",
|
||
"Sources :\n",
|
||
"\n",
|
||
"* \"Échangeurs : principes et applications\" par la société Saint-Gobain, [1]\n",
|
||
"* \"Ejecteurs : fonctionnement et caractéristiques\" sur le site du fabricant de matériel de traitement des gaz, Baker Hughes, [2]\n",
|
||
"\n",
|
||
"Références :\n",
|
||
"[1] https://www.saint-gobain.com/fr/decouverte/deutschland/fait-sachant-de-ma-entreprise/les-technologies/echanges\n",
|
||
"[2] https://www.bakerhughes.com/en/solutions/catalytic-conversion/ejectors\n",
|
||
"\n",
|
||
"Si vous souhaitez voir une image plus détaillée, je peux essayer de trouver des ressources graphiques sur Internet.\n",
|
||
"\n",
|
||
"Réponse:\n",
|
||
"Le cancer est un groupe de maladies caractérisées par la croissance anarchique et progressive d'un tumor, une tumeur anormale composée de cellules mortes ou vivantes qui ne se divisent pas correctement. (Source : Organisation mondiale de la santé)\n",
|
||
"\n",
|
||
"Il existe de nombreux types de cancer, notamment :\n",
|
||
"\n",
|
||
"* Le cancer du sein\n",
|
||
"* Le cancer du poumon\n",
|
||
"* Le cancer des ovaires\n",
|
||
"* Le cancer de l'intestin\n",
|
||
"* Le cancer de la peau\n",
|
||
"* Le cancer du rein\n",
|
||
"* Le cancer des os\n",
|
||
"* Le cancer de l'hypophyse\n",
|
||
"\n",
|
||
"Selon le Centre national de contrôle et de prévention des maladies (CDC), les causes principales du cancer incluent :\n",
|
||
"\n",
|
||
"* Les facteurs génétiques\n",
|
||
"* L'exposition à la radiation\n",
|
||
"* La pollution environnementale\n",
|
||
"* Le tabagisme\n",
|
||
"* La consommation excessive d'alcool\n",
|
||
"* Un poids corporel élevé\n",
|
||
"\n",
|
||
"Les traitements pour le cancer peuvent comprendre des opérations, de la chimiothérapie, de la radiothérapie et une greffe de cellules souches. (Source : American Cancer Society)\n",
|
||
"\n",
|
||
"Il est essentiel d'être conscient des risques de cancer et de prendre des mesures préventives pour réduire les chances de développer ce maladie.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"chat_cli()\n",
|
||
"\n",
|
||
" \n",
|
||
" \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 263,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Assistant documentaire - Tapez 'exit' pour quitter\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"chat_cli()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 253,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
|
||
"from langchain_core.messages import SystemMessage, HumanMessage\n",
|
||
"from langchain_ollama import ChatOllama\n",
|
||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||
"from langchain_core.output_parsers import StrOutputParser\n",
|
||
"from base64 import b64decode\n",
|
||
"\n",
|
||
"\n",
|
||
"def parse_docs(docs):\n",
|
||
" \"\"\"Split base64-encoded images and texts\"\"\"\n",
|
||
" b64 = []\n",
|
||
" text = []\n",
|
||
" for doc in docs:\n",
|
||
" try:\n",
|
||
" b64decode(doc)\n",
|
||
" b64.append(doc)\n",
|
||
" except Exception as e:\n",
|
||
" text.append(doc)\n",
|
||
" return {\"images\": b64, \"texts\": text}\n",
|
||
"\n",
|
||
"\n",
|
||
"def build_prompt(kwargs):\n",
|
||
"\n",
|
||
" docs_by_type = kwargs[\"context\"]\n",
|
||
" user_question = kwargs[\"question\"]\n",
|
||
"\n",
|
||
" context_text = \"\"\n",
|
||
" if len(docs_by_type[\"texts\"]) > 0:\n",
|
||
" for text_element in docs_by_type[\"texts\"]:\n",
|
||
" context_text += text_element.text\n",
|
||
"\n",
|
||
" # construct prompt with context (including images)\n",
|
||
" prompt_template = f\"\"\"\n",
|
||
" Answer the question based only on the following context, which can include text, tables, and the below image.\n",
|
||
" Context: {context_text}\n",
|
||
" Question: {user_question}\n",
|
||
" \"\"\"\n",
|
||
"\n",
|
||
" prompt_content = [{\"type\": \"text\", \"text\": prompt_template}]\n",
|
||
"\n",
|
||
" if len(docs_by_type[\"images\"]) > 0:\n",
|
||
" for image in docs_by_type[\"images\"]:\n",
|
||
" prompt_content.append(\n",
|
||
" {\n",
|
||
" \"type\": \"image_url\",\n",
|
||
" \"image_url\": {\"url\": f\"data:image/jpeg;base64,{image}\"},\n",
|
||
" }\n",
|
||
" )\n",
|
||
"\n",
|
||
" return ChatPromptTemplate.from_messages(\n",
|
||
" [\n",
|
||
" HumanMessage(content=prompt_content),\n",
|
||
" ]\n",
|
||
" )\n",
|
||
"\n",
|
||
"\n",
|
||
"chain = (\n",
|
||
" {\n",
|
||
" \"context\": retriever | RunnableLambda(parse_docs),\n",
|
||
" \"question\": RunnablePassthrough(),\n",
|
||
" }\n",
|
||
" | RunnableLambda(build_prompt)\n",
|
||
" | ChatOllama(base_url=\"localhost:11434\", model=\"llama3.2\")\n",
|
||
" | StrOutputParser()\n",
|
||
")\n",
|
||
"\n",
|
||
"chain_with_sources = {\n",
|
||
" \"context\": retriever | RunnableLambda(parse_docs),\n",
|
||
" \"question\": RunnablePassthrough(),\n",
|
||
"} | RunnablePassthrough().assign(\n",
|
||
" response=(\n",
|
||
" RunnableLambda(build_prompt)\n",
|
||
" | ChatOllama(base_url=\"localhost:11434\", model=\"llama3.2\")\n",
|
||
" | StrOutputParser()\n",
|
||
" )\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 255,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"I don't see any context provided. Please share the relevant information, such as text, tables, or an image, and I'll do my best to answer your question about what the \"ejector\" refers to.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"response = chain.invoke(\n",
|
||
" \"What is the ejector?\"\n",
|
||
")\n",
|
||
"\n",
|
||
"print(response)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"The 0D modeling approach simplifies global IC phenomena by considering only essential physics. It uses a global energy and mass balance to estimate injector characteristics. This model requires the consideration of an experimental closure law and has been previously implemented by various authors. The current approach starts from Deberne's 2000 model, which treats an injectant working with liquid central injection. Beithou also proposed a simplified OD model for an IC with vapor central injection, but it neglects the isobaric flow in the combustion chamber.\",\n",
|
||
" 'Steam is supposed to undergo isentropic expansion until the primary pipe throat, then undergo adiabatic expansion in the divergent section, considering irreversibilities such as high velocity and possible oblique shock waves.',\n",
|
||
" 'Summary of table: A table containing a single entry with the content \"condition critique de la vapeur\" and metadata including source, title, and page numbers.',\n",
|
||
" 'Summary of table/text: Critical relaxation threshold defined as yt + l, source is 11_chapitre3.pdf, page number 3.',\n",
|
||
" 'The table describes the parameters of a steam model, including the isentropic coefficient (y = 1.31 for saturated vapor), mass flow rate, and pressure. The system is solved to find the divergent length and continuity equation. A simplification is made by introducing new parameters, resulting in an implicit equation for the convergent length. The solution yields a value for p,, which is then used to solve for other parameters.',\n",
|
||
" \"The table doesn't exist. However the text is about a model for liquid fuel injection in an injector condenser. The model assumes equal inlet pressures but contradicts experimental data. It uses Bernoulli's equation to calculate pressure drop and characteristic properties of the fluid entering the mixing chamber.\",\n",
|
||
" \"The chamber of mixing is the most critical component of an injector, where most phase transfers between vapor and liquid occur: mass transfer, heat transfer, and momentum transfer. It's a complex section to model due to its creation of essential irreversibilities in the injector. The chamber of mixing modeling considers pressure longitudinal profile variations and separates phases using the vapor velocity rate, with hypotheses assuming steady and one-dimensional flow for equalized dimensions within a given section.\",\n",
|
||
" 'Summary of table/text: The page content mentions a coincidence between the bottom merge chamber and the shockwave head, related to section 11_chapitre3.pdf.',\n",
|
||
" 'Frottement aux parois negligible, adiabatic system, equilibrium in both kinetic and dynamic phases upon exiting the mixing chamber, and homogeneous mixture at exit.',\n",
|
||
" 'Summary of table: Summary statistics for Si Prt variable.',\n",
|
||
" 'Summary of table/page content:\\nSummary of fluid dynamics parameters in a mixing chamber, including pressure, velocity, radius, and angle for convergent sections.',\n",
|
||
" 'Summary of table or text: Key findings in chapter 3 of the \"Conservation de l\\'énergie\" document, with page numbers 1-12.',\n",
|
||
" 'The table provides a system of equations for modeling the LD (Liquid Distribution) of condenser injectors. It includes five inconnues (p27; uz; P2; hz ; Ip) and requires a closure law to calculate the integral pressure term Jp.',\n",
|
||
" 'Grolmes (1968) found that pressure profiles are primarily correlated with the calculated vapor condensation rate R, which depends on chamber mixing parameters. The correlation is expressed as L R = Caen (3-16), where Caen is a function of temperature and pressure, and Ly represents the latent heat of water at pressure P.',\n",
|
||
" 'Taux de condensation influences la pression dans la chambre de mélange, qui peut varier selon le taux de condensation. Pour R = 1.03, la pression est pratiquement constante dans la première partie de la chambre de mélange.',\n",
|
||
" 'Table/Text Summary:\\n\\nInfluence of condensation rate on pressure profiles in the combustion chamber. To determine Ip, seek a correlation for R > 0.69 or calculate it by integrating a linear pressure profile between entry and exit of the chamber for R < 0.69.',\n",
|
||
" 'Researchers seek a correlation dependent on the condensation rate R to determine the term Jp. An equivalent pressure is calculated using the formula P(z tan Bz) = Me P= eq 5 (3-17). The pressure is considered as the average pressure in the combustion chamber related to the dynamically active surface of the system. This pressure depends mainly on the condensation rate R.',\n",
|
||
" 'The table/text describes considering the pressure profile as constant for this scenario but acknowledges it is an approximation. Instead, a linear relationship between inlet and outlet pressures is used to represent the pressure profile.',\n",
|
||
" 'Table/Text Summary:\\n\\nSummary of page content: \\nA mathematical model for the LD (Laminar Discharge) of a condenser injector. The pressure P(z) is related to the discharge parameters by equations (3-21), (3-22). The term Jp depends linearly on the pressure Pz, making the resolution of the system straightforward.',\n",
|
||
" 'The injector-condenser pressurizes the water-vapor mixture to a pressure higher than that of the motive steam. The maximum counter-pressure is achieved when the thickness of the condensation wave is minimal and its location is at the throat of the mixing chamber.',\n",
|
||
" 'Summary of table: P31U31 refers to a specific location in a document, specifically page 31, unit 31, marked as \"Por-vYrt-v\" with reference number 3-23. \\n\\nDocument metadata: Document source is an 11_chapitre3.pdf file, titled \\'Continuité\\', with page numbers on page 11.',\n",
|
||
" 'Summary of table: A mathematical equation relating Pritts and Pavtory with Pav, with a range of 3 to 24. \\n\\nMetadata: Document metadata from a PDF file titled \"Quantité de mouvement\" on page 11.',\n",
|
||
" 'Summary of table or text:\\n\\nText: \"hy, eo = hy y + sth (3-25)\"\\nMetadata: Source is a PDF file named \\'11_chapitre3.pdf\\', title is \\'Conservation de l’énergie\\' and it covers page number 11.',\n",
|
||
" 'Simplification of system parameters for linearization: \\nKy = Poy-yYor-v, \\nKy = Pry-yYarv + Py = Kory + Pav, \\nKy = hyy + Ber. \\nEquations simplify to:\\nPails = K, Prt + P = K,\\nhy, + aie =K, hy, = AC py, iP',\n",
|
||
" \"The table discusses the principles of a diffuser in a liquid dynamics system. It explains how the diffuser slows down the fluid due to its divergent shape and converts its kinetic energy into pressure energy. The flow rate is described by Bernoulli's equation and continuity equation. The coefficients of loss (e, a) are calculated based on the relation provided. The table relates these coefficients to the angle of divergence (B), diameter (D), mean velocity (uo), and surface roughness.\",\n",
|
||
" \"The model was programmed on a PC using Borland Pascal 7.0, taking dimensions of an IC and physical/dynamical parameters of liquid water and steam as input to determine optimal performance in an open circuit, with the shockwave located at the neck of the mixing chamber. The code structure is represented in figure 3-4, with PROPEAU module used to calculate water properties within the IC's operation range.\",\n",
|
||
" 'Experimental results from INSA/LC injector sets A1, B1, and C1 were evaluated in Chapter 2. The combined test values (Section 2-2) allowed for estimating optimal coefficients for the model (Table 3-1). Figures 3-5 and 3-6 show that modeling provides correct values compared to experimentation. However, the model overestimates the training rate U,,q, and maximum vapor pressure Poymax in general.',\n",
|
||
" \"Pressions maximales à la sortie de l'injecteur diminuent avec la pression d'alimentation de la vapeur pour des pressions supérieures à 9 bar. Le modèle sous-estime les irréversibilités et présente limites en termes de corrélation et paramètres empiriques, nécessitant un point d'essai pour calibration.\",\n",
|
||
" 'Deberne conducted experiments to visualize the geometric structure of flow in a mixing chamber, using qualitative approaches that helped understand phenomena such as atomization and liquid jet length. He used an experimental setup with a light source, camera, and visualization tube, employing two lighting modes (rear and front) during the experiment. The visualization tube had a central liquid column with a rectangular cross-section and a thickness of 8mm, allowing for clear observation of flow characteristics.',\n",
|
||
" 'The study visualizes fluid flow in a chamber of mixture and identifies stratified flow with a central liquid jet and surrounding vapor, as well as dispersed flow of droplets and vapor. The density of droplets is highest at the center of the vein, while the flow seems less dense in the diffuseur and after the col. Condensation waves are observed in the diffuseur and just after the col, and monophasic liquid flow is seen downstream from the diffuser.',\n",
|
||
" \"Je ne peux pas trouver l'information que vous recherchez. Puis-je vous aider avec autre chose?\",\n",
|
||
" 'Summary of the text:\\n\\nThe article discusses the coalescence of liquid droplets in collisions and confinement geometry. The transition between two fluid flow modes is determined by the rupture point of a liquid jet, which is calculated using the correlation of Monote (1-41). The heat exchange terms are described by convective or thermodynamic laws and drag forces (3-37). A numerical model is developed to simulate this process, which was solved using the CEDRE code.',\n",
|
||
" 'Models developed accurately reproduce the flow at the chamber entrance (heterogeneous zone). However, transition between heterogeneous and homogeneous regimes and condensation wave resolution are not accurately modeled. Current goal is to model the entire chamber of mixture: heterogeneous zone, dispersed homogeneous zone, and condensation wave using a simple physically sound model that can be numerically solved.',\n",
|
||
" 'The chamber of mixture has two distinct sections with different flow patterns. The first section has a heterogeneous flow (jet + droplets + vapor) and the second section has a homogeneous dispersion flow (vapor + droplets). The length of rupture is characteristic of the primary jet in the first section, as described in paragraph 1-4-2.',\n",
|
||
" 'The mixing chamber in a IC engine is characterized by a strong imbalance of thermodynamic and kinetic properties between liquid and vapor phases. This requires calculating separate velocity and temperature fields, as well as considering mass transfer, unequal pressure fields, and intense atomization of the liquid jet. The flow can be considered monodimensional with uniform properties in a cross-sectional area.',\n",
|
||
" \"Two coupled eularian systems describe the combustion chamber mixture: one for vapor phase and another for liquid phase, based on Rascle's diphasic equations [Rascle1997].\",\n",
|
||
" 'Summary of table: \\nAlapyuyS) = ST, oz aa i” a)p,u,S) = ST, Oz (3-38)\\n\\nSummary of text:\\nDescribes the section on flow rate and mass exchange per unit volume in continuity equations.',\n",
|
||
" 'Mapu table: variables for quantity of movement include MM (quantity of movement), P (pressure at the interface) and other parameters.',\n",
|
||
" 'Alap equation: Alap = SQ*(1 - at)^p + hu^2, where h is a constant.',\n",
|
||
" 'The table does not exist in the provided text. The text only contains a passage about equations of state for real fluids and mentions a table called PROPEAU for water, but no table is actually provided.',\n",
|
||
" \"The text describes laws of closure and correlations from literature, used to calculate model terms (vector H(V)), which are compared with experimental values to select the most suitable laws for the injector. The source is a PDF document named '11_chapitre3.pdf'.\",\n",
|
||
" 'Summary of table and text: Human task to summarize a page from the PDF \"11_chapitre3.pdf\" titled \"the transfer of mass movement\", discussing wall friction (M) and interface velocity (Uj).',\n",
|
||
" 'Table/Text: The table describes thermal transfer concepts with terms such as \"flux de chaleur\" (heat flux), \"enthalpie d\\'interface\" (interfacial enthalpy), and types of heat transfer including \"pariétal\" (boundary) and \"interfacial\" (between surfaces).',\n",
|
||
" 'The system of equations is not closed due to seven main unknowns (a, u, U, h, h, P, P) and two secondary unknowns (p, ; 1) derived from the state equations. The system is defined by six balance equations, which assume constant pressure (P = B) and density (ρ = C). An additional relationship links the vapor mass flow rate, temperature, and masses volumiques: g = -Pu(3-45), where py is the gliding between phases, u is the mass flow rate of liquid, x is the molar mass of water.',\n",
|
||
" 'The article discusses the modeling of two-phase flow in condenser injectors, focusing on the interface between the liquid and vapor phases. It proposes two modes of interface: stratified and dispersed, with equal velocities at the interface. The pressure at the interface is not physically meaningful but plays a crucial role in hyperbolicity conservation. An expression for pressure is given as BP = Epy - u(T), where T is the saturation temperature. The article also discusses the thermodynamic properties of the interface, including enthalpies, and proposes an expression for them based on the law of saturation.',\n",
|
||
" 'The table lists the conservation laws at interfaces: Liouville theorem (LT), X-axis invariant (XL), U-index invariance (Ui), and Mass-time invariance (Mat).',\n",
|
||
" 'System description: U = -L, My = M; where T is the total pressure difference, Ov is the outlet pressure, Girv is the valve opening velocity, and h is the distance of the condenser. Page numbers: 30-31.',\n",
|
||
" 'The exchange of heat at the interface is mainly caused by the initial thermal imbalance between two phases, leading to condensation. A proposed law for heat exchange is: H = (4sHys + ApH y p \\\\(z, ~ T) or H = (4sH,.5 + ApH» \\\\(Z, ~ qT), where coefficients and densities of surface exchange are defined.',\n",
|
||
" \"Table summary: \\nSummary of cte surface d'échange du jet de vapeur. The table describes the surface for the exchange of steam jet, considered as a cylindrical shape with constant diameter D.\\n\\nText summary:\\nCalculs d'un coefficient d'échange selon la corrélation St = 6,5 Re* (3-59)\",\n",
|
||
" \"Table des constantes utilisées dans le modélisation LD des injecteurs condenseurs :\\n\\n- u; = vitesse d'interface en m/s\\n- TD = taux de détection de vitesse en m^3/m^2s\\n- A IAL = surface de l'interface liquide/vapeur en m^2\\n- Evy, py = vitesse de la vapeur et du liquide dans l'interface\\n- Eo = énergie spécifique de la vapeur\\n- PL = pression de la vapeur\\n- Re : nombre de Reynolds pour les flux de masse échangées à l'interface\\n- fi, fv = coefficients de frottement à l'interface\\n- m = flux de masse lié à la condensation\\n- Ty, Eq, ui, u' = variables dans la loi de Darcy pour déterminer les quantités de mouvement échangées à l'interface\",\n",
|
||
" 'Summary of the text: The article discusses the calculation of heat transfer coefficients in liquid-vapor condensation. Various authors have proposed different formulas based on molecular theory and experimental data. Iwaki et al. suggest a formula using temperature profiles measured in an injector, resulting in an average coefficient of 6.10* Win?.K with pressure below 1.5 bar. The choice of correlation depends on the relation by Miyazaki.',\n",
|
||
" 'Table: \\n| Longueur de rupture du jet liquide | Prolongement temporelle de la condensation |\\n| --- | --- |\\n| 104 < Rey < 1.2.10° | 0.7 < Pry < 100 |\\n\\nText:\\nResearchers Nariai and Aya studied the direct condensation of vapor on liquid water, for stratified flow. They estimated a coefficient of heat transfer between vapor and liquid in the range (3-70) W/mK. In the case of coexistence of liquid water and vapor, the heat transfer is primarily controlled by the liquid phase. The calculation of heat exchange coefficients in the dispersed Hiy,p and Hit,p phases involves the exchange between sub-cooled droplets and the vapor phase, a less studied mode of condensation.',\n",
|
||
" 'Moresco (1980) studied heat transfer in a two-phase spray consisting of a continuous phase and a dispersed phase. The study covered a range of flow rates (0.17-0.31 kg/s), temperatures (300-370 K), and droplet sizes (0.007-0.01 m). Moresco proposed the correlation Nu = 0.0178Re^0.4Pr^0.33 for the dispersed phase, while Srinivas (1996) studied a spray with vapor-saturated water droplets in air and used a 2D model to calculate the Nusselt number.',\n",
|
||
" 'The outside medium of the fuel injector is generally colder than the internal flow, causing external heat losses. The only contact with the wall in this heterogeneous part of the flow is with the vapor, leading to consideration of convective transfer on the vapor side.',\n",
|
||
" 'The forces of dragging and friction are related to the difference in velocity between phases. The coefficient of drag (Cd) is proportional to the square of the relative velocity: Cd = f(u) with f being a function of velocity u, where Cp is the coefficient of drag for the dispersed phase and Cs is the coefficient of friction for the stratified phase.',\n",
|
||
" 'The table provides equations related to the heat transfer and friction coefficients in a two-phase flow system. The Darcy-Weisbach equation is used for the heat exchange between phases, while the Blasius equation is applied for the coefficient of friction on the wall in the vapor phase, assuming turbulent flow.',\n",
|
||
" 'Transfer of mass under adiabatic conditions only follows the laws of interface, expressed as l = -I = Ov + Qu.',\n",
|
||
" 'The chamber of the IC has a conical shape with a heterogeneous section that is also conical. The cross-sectional area of the flow varies linearly with depth (z), resulting in a surface area S = ar(z) where r(z) and r(inlet) and r(outlet) are related by H(z).',\n",
|
||
" 'The table describes the surface interfacial representation between vapor and liquid jet for stratified flow mode. The volume of the cylinder and cone are related to Az (3-93) and (3-94), where r = 4AztanB and tan B = ae, with N being the number of mesh. The volume removed from the cylinder by the liquid is calculated as V(cylindre) - V(cone) according to equation (3-96).',\n",
|
||
" 'Table content: Describes the calculation of surface-to-volume ratio in each pore space and its relation to particle density.\\n\\nText content: Explains the concept of surface-to-volume ratio and its application to liquid particle counting in a stratified flow.',\n",
|
||
" 'The study presented here allowed us to choose the correlations that provide the best estimation of friction transfer coefficients for our case. The necessary values are compiled in Table 3-1, derived from measurements taken at the entrance of the mixing chamber (rectangular section). Values of different coefficients are illustrated on Table 3-2.',\n",
|
||
" 'There is a significant disparity among different authors in terms of heat exchange and friction coefficients. Results are compared to experimental and numerical data, with numerical results based on a reference experiment shown in Table 3-1. Equations for interface sizes and terms are listed in Tables 3-3 and 3-4.',\n",
|
||
" \"The system of 7 equations is transformed into a non-conservative form to facilitate a matrix-based solution. The resulting system is an ordinary differential equation with 7 first-order equations, which can be integrated explicitly and numerically using the Runge-Kutta method of order 4 (RK 4), supplemented by the Newton-Raphson method for calculating the inverse H''(V).\",\n",
|
||
" \"Conception de la veine axysimétrique n'a pas permis des mesures locales dans la chambre de mélange; modèle sera validé sur une section rectangulaire. Calcul validé aux conditions expérimentales avec une géométrie de 2D plane. Mesures locales réalisées sur une veine en Plexiglas de section rectangulaire, respectant les lois de similitude géométrique d'un IC.\",\n",
|
||
" \"Chapitre 3 : Modélisation LD des injecteurs condenseurs. Le taux de vide augmente à l'entrée de la chambre de mélange, mais la pression vapeur calculée ne correspond pas aux mesures locales de pression. La hypothèse de pression liquide constante et égale à la pression vapeur est plus adéquate pour rendre compte de la pression dans le liquide à l'entrée, mais elle ne prend pas en compte l'effet piston de la phase vapeur sur la phase liquide. La température de la vapeur calculée décroit à l'entrée, tandis que la température calculée de la phase liquide augmente plus fortement que la température mesurée.\",\n",
|
||
" 'The chapter discusses the modeling of liquid droplet (LD) injectors in condensers. The temperature measurement of the heart liquid is equal to that of the vapor and liquid phases, but the calculated temperature differs due to non-separation of the two structures. An analysis of experimental results revealed variables such as vapor velocity and liquid velocity. A model was developed using the experiment and based on heat transfer between liquids and vapors. The system of equations describes the conservation of mass in a stationary regime, including thermodynamic properties of water and steam.',\n",
|
||
" 'The table shows a comparison of calculated and measured velocity fields, with slight differences between model-calculated and experimental values due to measurement uncertainties and modeling assumptions.',\n",
|
||
" 'The table discusses the relationship between entropy and exergy in a combustion chamber. It highlights the importance of accounting for thermohydraulic phenomena during mixing in the chamber. The study aims to compare experimental and modeled entropies to determine global entropy created by internal irreversibilities. An equation is given for calculating the overall entropy, and its values are compared using data from experiments and models.',\n",
|
||
" \"The table presents a concordance between model and experimental results for entropy increase in the mixing chamber, with maximum energy losses occurring at the entrance of the chamber. The exergies corresponding to the system's energy are calculated and plotted against the liquid temperature, showing an increase in energy losses as the flow rate increases.\",\n",
|
||
" 'Summary of the table:\\n\\nPage content: Chapter 3 discussion on Lumped Discretization (LD) modeling of condenser injectors. \\n\\nMetadata: Source document is \"11_chapitre3.pdf\", title contains units \"mm\", and page numbers are 52-53.',\n",
|
||
" 'This 1D modelling of the heterogeneous part shows globally coherent results, correctly reproducing physical phenomena and variable flow evolution. The model accurately captures kinetic and thermal imbalance, leading to direct condensation between phases and separation of liquid and vapor pressure fields.',\n",
|
||
" 'This text discusses the modeling of a two-phase flow in a mixing chamber, specifically focusing on the behavior of droplets and vapor. The author reviews existing models, such as that by Deberne, which treats the flow as a diphasic dispersed system. However, due to large droplet sizes, the model is adapted for better accuracy. The text also explores the phenomenon of phase separation, including thermodynamic and mechanical instabilities, and presents an analysis of the factors influencing these instabilities, such as germ presence in the vapor and velocity of flow.',\n",
|
||
" 'The equation to calculate the imbalance is given by: y, ate = Au (3-112) dz Ty 146. The time of mechanical relaxation is compared with the local velocity gradient.',\n",
|
||
" 'The table provides information on the sensitivity of mechanical instability in a system, with studies by Young (1982) indicating that for droplet diameters below 0.5 μm, mechanical instability is negligible and relaxation times differ significantly between thermal and mechanical processes. In most cases, mechanical instability is not considered.',\n",
|
||
" 'The simplest model is the homogeneous equilibrium model (MHE), assuming negligible discrepancies. This model considers the average properties of a mixture, with 3 equations describing fluid flow and 5 assumptions: thermodynamic equilibrium, unit phase transition, and adiabatic conditions. The model approximates a monophasic fluid with given properties, neglecting gradients and non-stationary flow.',\n",
|
||
" 'System of equations describing fluid flow: dL/dt = (P - P_m) * L + F / a * v, where L is volumetric flow rate, P and Pm are pressures, F is fuel, a is cross-sectional area, v is velocity. After rewriting the system as a homogeneous one, it becomes: d(aL)/dt = R * V, with R being the Riemann matrix and V being the vector of principal unknowns.',\n",
|
||
" 'Table/PDF content: Speed of sound in a homogeneous equilibrium medium, equation: ω_cy = ω_p (3-117), where ω is the angular frequency.',\n",
|
||
" 'Summary: The chapter discusses the LD modeling of condenser injectors, assuming a balanced medium and applying Clausius-Clapeyron equation for pressure dependence on temperature. It also uses Maxwell equations to calculate sound velocity and introduces a friction closure law for wall friction, represented by the Chézy formula with a coefficient dependent on Reynolds number and wall roughness, related to Nikuradse coefficients.',\n",
|
||
" 'A system has a solution if its Riemann matrix is invertible, with determinant Det(R) = u² + C (u² Cy lly + C). The case where u² = cy represents a singular point that annihilates the determinant, characteristic of a transonic passage between two solutions.',\n",
|
||
" 'This table discusses the modeling of condenser injectors in a system, specifically focusing on the 1D model and its solutions. It describes two cases: supersonic flow and transsonic flow, where the latter leads to a critical point (section critique) that determines the uniqueness of the solution. The section critique is related to the col or chamber de mélange.',\n",
|
||
" \"Deberne [Deberne2000] developed a 2D (rectangular) visualization vein concept to measure local parameters in the entire chamber of mixing. This approach will be validated using experimental results on axisymmetric geometry by comparing with rectangular geometry. The input conditions for the model match the numerical output of the heterogeneous part's exit (Table 3-6).\",\n",
|
||
" 'The tables (3-17, 3-18, and 3-19) show the evolution of parameters in the heterogeneous mixing chamber section along the axial position. The figure 3-17 shows the reduction of void fraction after the heterogeneous section, due to condensation affecting the surface area of exchange. The pressure calculated matches the experimental data with a delay at the end of the heterogeneous section. Temperature variation is minimal, with good agreement between measured and calculated values, mainly due to temperature being an unknown auxiliary variable in the system.',\n",
|
||
" 'The table/chunk discusses a model for liquid droplet (LD) injection in condenser injectors. The temperature of the mixture is considered a weighted average with a calculated void fraction, resulting in less precise predictions for the dispersed phase (z > 150 mm). Error sensitivity analysis shows significant variations in results due to measurement errors, especially beyond z = 150 mm, affecting credibility and numerical model accuracy.',\n",
|
||
" 'We use a second model that considers the existing thermodynamic imbalance and highlighted in the tests (HRM: homogeneous relaxation model). The thermodynamic imbalance is interpreted as a delay in condensation, with a vapor title that does not follow pressure evolution (constant entropy) if the system were in an equilibrium state. A law of type (rappel to equilibrium) governs this delay: Dx, Ox, Ox, x, —X.',\n",
|
||
" 'A system of equations describing fluid flow in the model is given as uy Lm gy Hm iB = ae Pm a Prt Sa Uy, with similar terms and an equality operator linking them.',\n",
|
||
" 'The system admits a solution if the Riemann matrix is invertible. The solution is determined by analyzing the figure 3-14 and checking the equation derived from the resolution of the subsytem (3-129). This equation defines the x-coordinate of the critical section Ze. \\n\\nIn the homogenous model with relaxation, the second term in the equation (3-130) moves the critical section towards the nozzle exit as thermal imbalance increases. In supersonic flow, a point of bifurcation occurs at the critical section, and a new condition must be defined to determine the branch taken by the solution.\\n\\nThe system is solved numerically using Runge-Kutta method with an adaptive step size, replacing real values with their duals. The results have been improved slightly but still do not capture the effects of condensation in this homogenous part of the combustion chamber.',\n",
|
||
" \"The mixing chamber structure varies with a cut-off at the liquid jet's complete disintegration length. The homogeneous section consists of dispersed droplets in the vapor, characterized by weighted flow values and high surface exchange area. Two models (HEM and HRM) show similar numerical results to experimental data up to the condensation wave front.\",\n",
|
||
" 'Summary of Chapitre 3 : Modélisation LD des injecteurs condenseurs: Model for Liquid Distribution (LD) in Condenser Injectors.',\n",
|
||
" \"Il semble que le texte fourni est un extrait de travail académique qui présente divers travaux antérieurs sur le sujet du choc thermique dans les écoulements diphasiques (écoulements comportant à la fois une phase liquide et une phase gazeuse). Voici quelques-uns des principaux résultats présentés :\\n\\n1. **Travaux de Guha** : L'auteur Guha a étudié le choc thermique dans les flux diphasiques en présence ou non d'un gaz porteur. Il constate que ces écoulements sont caractérisés par deux genres de flux : \\n - Flux bloqué (ou flux figé), qui est caractérisé par des gouttelettes liquides non participantes au processus mécanique du fluide.\\n - Flux équilibré, qui est caractérisé par des gouttelettes liquides qui sont toujours dans un équilibre complet avec leur propre vapeur.\\n\\n2. **Expression de flux critique** : L'auteur Guha a présenté une formule pour calculer le flux critique en tenant compte de la variation de la surface d'échange et de la variation du flux massique de la vapeur, qui est donnée par l'équation :\\n - Gs) 1) (3-141)\\n - P*o 5) Ma? 142= D ta? r+ $ | 7 2\\n\\n3. **Travaux de Chen** : L'auteur Chen propose une formule pour calculer la vitesse du son dans les écoulements diphasiques, qui est donnée par l'équation :\\n - c= (3-140)\\n - 0,5 5 2 I (1 of) e.| I+ d C p Be PL aT Pi) Siv\\n\\n4. **Travaux de Young** : L'auteur Young a étudié le choc thermique dans les écoulements diphasiques en présence ou non d'un gaz porteur. Il constate que la vitesse du son dépend de la dispersion de la phase liquide et aussi de la fréquence de l'onde. Il propose des valeurs pour les coefficients ky et ke en fonction de la pression.\\n\\nIl est important de noter que ces résultats sont basés sur des équations et des formules qui peuvent nécessiter des conditions spécifiques d'équilibre thermodynamique et mécanique pour être applicables à différents écoulements.\",\n",
|
||
" 'The model HEM and HRM were unable to capture the condensation wave. A new method is proposed to calculate the conditions of jump using an equation with four unknowns (py, Uy, P2, T). The equation includes parameters such as specific heat capacity, latent heat, and viscosity. The pressure at point 2 (P2) is calculated by solving a non-linear, implicit equation in the range [Pamin, P2max].',\n",
|
||
" \"The text describes the fluid flow in a diffuser, using equations such as Bernoulli's equation, continuity equation, and state equation to calculate enthalpy at the outlet of an IC (Intermediate Cooling Channel). The calculation also involves pressure terms and a singular loss coefficient for conical diffusers.\",\n",
|
||
" \"Simulations confirm that the shock wave is defined by the conditions of impact adopted. Profiles of pressure obtained are compared to experimental results. Local measurements ([Deberne2000]) were taken on an IC with a rectangular section, which only represents the qualitative functioning of the IC. The IC's ability to function with a compression ratio above 1 unit is limited. Experimental results show that the 2D effect is present but less influential in axisymmetric configuration. Results will be compared to performance tests on IC INSA/LC, which better represent the actual IC functioning (figures 3-22 and 3-23). The influence of the training rate on the condensation pressure profile and the effect of the vapor inlet pressure on the outlet pressure are also studied.\",\n",
|
||
" 'The model with relaxation in HRM did not produce the condensation wave (real thermal shock in IC function), but a simple physically model can be adopted by changing boundary conditions to reflect real IC functioning. New boundary conditions are applied to impose a totally liquid flow at the outlet of the diffuser and calculate numerically within the diffuser by going back to the flow.',\n",
|
||
" 'Validation of results was based solely on pressure profiles, P(bar).',\n",
|
||
" \"Summary of Table: \\nTable contains data related to modelling LD of injectors, including pressure (Pbar), with page numbers 77 and 78.\\n\\nMetadata:\\nPage content from chapter 3 of a PDF document titled 'z(mm)'.\",\n",
|
||
" \"The main disadvantage is that numerical values of velocities are far off from the IC's real functioning, with excessive increases in speed to compensate for pressure drops. Resolving this problem and joining heterogeneous parameters can close the condensation wave issue, allowing for numerical simulation of the entire IC without relying on jump conditions across the condensation wave.\"]"
|
||
]
|
||
},
|
||
"execution_count": 122,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"import uuid\n",
|
||
"from qdrant_client import QdrantClient\n",
|
||
"from langchain_qdrant import QdrantVectorStore\n",
|
||
"from langchain.storage import InMemoryStore\n",
|
||
"from langchain.schema.document import Document\n",
|
||
"from langchain_ollama import OllamaEmbeddings # Vous pouvez remplacer par OpenAIEmbeddings si besoin\n",
|
||
"from langchain.retrievers.multi_vector import MultiVectorRetriever\n",
|
||
"from langchain.embeddings import OpenAIEmbeddings\n",
|
||
"\n",
|
||
"# Initialiser le client Qdrant (ici, on suppose un serveur local sur le port 6333)\n",
|
||
"qdrant_client = QdrantClient(host=\"localhost\", port=6333)\n",
|
||
"\n",
|
||
"# Définir le nom de la collection\n",
|
||
"collection_name = \"multi_modal_rag_07032025\"\n",
|
||
"vector_size =1536\n",
|
||
"# Créer (ou recréer) la collection dans Qdrant\n",
|
||
"\n",
|
||
"qdrant_client.create_collection(\n",
|
||
" collection_name=collection_name,\n",
|
||
" vectors_config={\"size\": vector_size, \"distance\": \"Cosine\"},\n",
|
||
")\n",
|
||
"\n",
|
||
"# Choix de la fonction d'embedding :\n",
|
||
"# Pour utiliser OllamaEmbeddings :\n",
|
||
"embedding_function = OpenAIEmbeddings()\n",
|
||
"# Pour utiliser OpenAIEmbeddings, décommentez la ligne suivante et commentez la précédente :\n",
|
||
"# embedding_function = OpenAIEmbeddings()\n",
|
||
"\n",
|
||
"# Créer la vectorstore avec QdrantVectorStore\n",
|
||
"vectorstore = QdrantVectorStore(\n",
|
||
" client=qdrant_client,\n",
|
||
" collection_name=collection_name,\n",
|
||
" embedding=embedding_function\n",
|
||
")\n",
|
||
"\n",
|
||
"# Couche de stockage en mémoire pour les documents parents\n",
|
||
"store = InMemoryStore()\n",
|
||
"id_key = \"doc_id\"\n",
|
||
"\n",
|
||
"# Créer le retriever multi-vecteur\n",
|
||
"retriever = MultiVectorRetriever(\n",
|
||
" vectorstore=vectorstore,\n",
|
||
" docstore=store,\n",
|
||
" id_key=id_key,\n",
|
||
")\n",
|
||
"\n",
|
||
"# --- Ajout des textes ---\n",
|
||
"# (les variables texts et text_summaries doivent être définies au préalable)\n",
|
||
"doc_ids = [str(uuid.uuid4()) for _ in title_chunks]\n",
|
||
"summary_texts = [\n",
|
||
" Document(page_content=summary, metadata={id_key: doc_ids[i]})\n",
|
||
" for i, summary in enumerate(text_summaries)\n",
|
||
"]\n",
|
||
"retriever.vectorstore.add_documents(summary_texts)\n",
|
||
"retriever.docstore.mset(list(zip(doc_ids, title_chunks)))\n",
|
||
"+ images_with_caption\n",
|
||
"# --- Ajout des tableaux ---\n",
|
||
"# (les variables tables et table_summaries doivent être définies au préalable)\n",
|
||
"table_ids = [str(uuid.uuid4()) for _ in tables]\n",
|
||
"summary_tables = [\n",
|
||
" Document(page_content=summary, metadata={id_key: table_ids[i]})\n",
|
||
" for i, summary in enumerate(table_summaries)\n",
|
||
"]\n",
|
||
"retriever.vectorstore.add_documents(summary_tables)\n",
|
||
"retriever.docstore.mset(list(zip(table_ids, tables)))\n",
|
||
"\n",
|
||
"# --- Ajout des résumés d'images ---\n",
|
||
"# (les variables images et image_summaries doivent être définies au préalable)\n",
|
||
"img_ids = [str(uuid.uuid4()) for _ in images]\n",
|
||
"summary_img = [\n",
|
||
" Document(page_content=summary, metadata={id_key: img_ids[i]})\n",
|
||
" for i, summary in enumerate(image_summaries)\n",
|
||
"]\n",
|
||
"retriever.vectorstore.add_documents(summary_img)\n",
|
||
"retriever.docstore.mset(list(zip(img_ids, images)))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 114,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "AttributeError",
|
||
"evalue": "'dict' object has no attribute 'page_content'",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[114], line 9\u001b[0m\n\u001b[0;32m 2\u001b[0m embedding \u001b[38;5;241m=\u001b[39m OllamaEmbeddings(\n\u001b[0;32m 3\u001b[0m base_url\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttp://localhost:11434\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 4\u001b[0m model\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmxbai-embed-large\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 5\u001b[0m )\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mlangchain_qdrant\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m QdrantVectorStore\n\u001b[1;32m----> 9\u001b[0m qdrant \u001b[38;5;241m=\u001b[39m \u001b[43mQdrantVectorStore\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_documents\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[43mfinal_chunks\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[43membedding\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 12\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mhttp://localhost:6333\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 13\u001b[0m \u001b[43m \u001b[49m\u001b[43mcollection_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmy_documents\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 14\u001b[0m \u001b[43m)\u001b[49m\n",
|
||
"File \u001b[1;32mc:\\Users\\ramez\\miniconda3\\envs\\rag\\lib\\site-packages\\langchain_core\\vectorstores\\base.py:832\u001b[0m, in \u001b[0;36mVectorStore.from_documents\u001b[1;34m(cls, documents, embedding, **kwargs)\u001b[0m\n\u001b[0;32m 815\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[0;32m 816\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mfrom_documents\u001b[39m(\n\u001b[0;32m 817\u001b[0m \u001b[38;5;28mcls\u001b[39m: \u001b[38;5;28mtype\u001b[39m[VST],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 820\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[0;32m 821\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m VST:\n\u001b[0;32m 822\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Return VectorStore initialized from documents and embeddings.\u001b[39;00m\n\u001b[0;32m 823\u001b[0m \n\u001b[0;32m 824\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 830\u001b[0m \u001b[38;5;124;03m VectorStore: VectorStore initialized from documents and embeddings.\u001b[39;00m\n\u001b[0;32m 831\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 832\u001b[0m texts \u001b[38;5;241m=\u001b[39m [d\u001b[38;5;241m.\u001b[39mpage_content \u001b[38;5;28;01mfor\u001b[39;00m d \u001b[38;5;129;01min\u001b[39;00m documents]\n\u001b[0;32m 833\u001b[0m metadatas \u001b[38;5;241m=\u001b[39m [d\u001b[38;5;241m.\u001b[39mmetadata \u001b[38;5;28;01mfor\u001b[39;00m d \u001b[38;5;129;01min\u001b[39;00m documents]\n\u001b[0;32m 835\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mids\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m kwargs:\n",
|
||
"File \u001b[1;32mc:\\Users\\ramez\\miniconda3\\envs\\rag\\lib\\site-packages\\langchain_core\\vectorstores\\base.py:832\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m 815\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[0;32m 816\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mfrom_documents\u001b[39m(\n\u001b[0;32m 817\u001b[0m \u001b[38;5;28mcls\u001b[39m: \u001b[38;5;28mtype\u001b[39m[VST],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 820\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[0;32m 821\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m VST:\n\u001b[0;32m 822\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Return VectorStore initialized from documents and embeddings.\u001b[39;00m\n\u001b[0;32m 823\u001b[0m \n\u001b[0;32m 824\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 830\u001b[0m \u001b[38;5;124;03m VectorStore: VectorStore initialized from documents and embeddings.\u001b[39;00m\n\u001b[0;32m 831\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 832\u001b[0m texts \u001b[38;5;241m=\u001b[39m [\u001b[43md\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpage_content\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m d \u001b[38;5;129;01min\u001b[39;00m documents]\n\u001b[0;32m 833\u001b[0m metadatas \u001b[38;5;241m=\u001b[39m [d\u001b[38;5;241m.\u001b[39mmetadata \u001b[38;5;28;01mfor\u001b[39;00m d \u001b[38;5;129;01min\u001b[39;00m documents]\n\u001b[0;32m 835\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mids\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m kwargs:\n",
|
||
"\u001b[1;31mAttributeError\u001b[0m: 'dict' object has no attribute 'page_content'"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"from langchain_ollama import OllamaEmbeddings\n",
|
||
"embedding = OllamaEmbeddings(\n",
|
||
" base_url=\"http://localhost:11434\",\n",
|
||
" model=\"mxbai-embed-large\"\n",
|
||
" )\n",
|
||
"\n",
|
||
"from langchain_qdrant import QdrantVectorStore\n",
|
||
"\n",
|
||
"qdrant = QdrantVectorStore.from_documents(\n",
|
||
" final_chunks,\n",
|
||
" embedding,\n",
|
||
" url='http://localhost:6333',\n",
|
||
" collection_name=\"my_documents\",\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"11\n"
|
||
]
|
||
}
|
||
],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# def get_tables_with_caption(documents):\n",
|
||
"# tables_info = []\n",
|
||
"# for idx, chunk in enumerate(documents):\n",
|
||
"\n",
|
||
"# if chunk.metadata.get(\"category\") == \"Table\" or \"table\" in chunk.metadata.get(\"category\", \"\").lower():\n",
|
||
"\n",
|
||
"# # Extraction du contenu textuel du tableau et de sa légende\n",
|
||
"# payload = chunk.metadata.get(\"payload\", {})\n",
|
||
"# caption = payload.get(\"caption\", \"\").strip()\n",
|
||
"# print(chunk.metadata)\n",
|
||
"# # Si aucune légende n'est trouvée, vérifier le bloc suivant\n",
|
||
"# if not caption and idx + 1 < len(documents):\n",
|
||
"# next_chunk = documents[idx + 1]\n",
|
||
"# lower_text = next_chunk.page_content.lower()\n",
|
||
"# if any(keyword in lower_text for keyword in [\"table\", \"tab.\", \"légende\",\"tableau\"]):\n",
|
||
"# caption = next_chunk.page_content.strip()\n",
|
||
"\n",
|
||
"\n",
|
||
" \n",
|
||
"# tables_info.append({\n",
|
||
"# \"type\": \"table_with_caption\",\n",
|
||
"# \"table_data\": chunk.page_content, # Le contenu textuel du tableau\n",
|
||
"# \"caption\": caption\n",
|
||
"# })\n",
|
||
"# return tables_info\n",
|
||
" "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# get_tables_with_caption(documents)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "ConnectionError",
|
||
"evalue": "Failed to connect to Ollama. Please check that Ollama is downloaded, running and accessible. https://ollama.com/download",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[1;31mConnectionError\u001b[0m Traceback (most recent call last)",
|
||
"Cell \u001b[1;32mIn[10], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m idx\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m7\u001b[39m \n\u001b[1;32m----> 2\u001b[0m \u001b[43manalyze_image\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimages_with_caption\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mimage_base64\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43mimages_with_caption\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcaption\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m \n",
|
||
"Cell \u001b[1;32mIn[9], line 17\u001b[0m, in \u001b[0;36manalyze_image\u001b[1;34m(image_data, caption, context, prompt_base)\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 15\u001b[0m prompt \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDécris cette image en détail.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m---> 17\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mchat\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mllama3.2-vision\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrole\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43muser\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcontent\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mimages\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mimage_data\u001b[49m\u001b[43m]\u001b[49m\u001b[43m}\u001b[49m\n\u001b[0;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\n\u001b[0;32m 22\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 23\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessage\u001b[39m\u001b[38;5;124m\"\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n",
|
||
"File \u001b[1;32mc:\\Users\\ramez\\miniconda3\\envs\\rag\\lib\\site-packages\\ollama\\_client.py:333\u001b[0m, in \u001b[0;36mClient.chat\u001b[1;34m(self, model, messages, tools, stream, format, options, keep_alive)\u001b[0m\n\u001b[0;32m 289\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mchat\u001b[39m(\n\u001b[0;32m 290\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 291\u001b[0m model: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 298\u001b[0m keep_alive: Optional[Union[\u001b[38;5;28mfloat\u001b[39m, \u001b[38;5;28mstr\u001b[39m]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 299\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[ChatResponse, Iterator[ChatResponse]]:\n\u001b[0;32m 300\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 301\u001b[0m \u001b[38;5;124;03m Create a chat response using the requested model.\u001b[39;00m\n\u001b[0;32m 302\u001b[0m \n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 331\u001b[0m \u001b[38;5;124;03m Returns `ChatResponse` if `stream` is `False`, otherwise returns a `ChatResponse` generator.\u001b[39;00m\n\u001b[0;32m 332\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 333\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 334\u001b[0m \u001b[43m \u001b[49m\u001b[43mChatResponse\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 335\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mPOST\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 336\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m/api/chat\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 337\u001b[0m \u001b[43m \u001b[49m\u001b[43mjson\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mChatRequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 338\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 339\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[43mmessage\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmessage\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_copy_messages\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 340\u001b[0m \u001b[43m \u001b[49m\u001b[43mtools\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[43mtool\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtool\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_copy_tools\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtools\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 341\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 342\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 343\u001b[0m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 344\u001b[0m \u001b[43m \u001b[49m\u001b[43mkeep_alive\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mkeep_alive\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 345\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_dump\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexclude_none\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 346\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 347\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"File \u001b[1;32mc:\\Users\\ramez\\miniconda3\\envs\\rag\\lib\\site-packages\\ollama\\_client.py:178\u001b[0m, in \u001b[0;36mClient._request\u001b[1;34m(self, cls, stream, *args, **kwargs)\u001b[0m\n\u001b[0;32m 174\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mpart)\n\u001b[0;32m 176\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m inner()\n\u001b[1;32m--> 178\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_request_raw(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\u001b[38;5;241m.\u001b[39mjson())\n",
|
||
"File \u001b[1;32mc:\\Users\\ramez\\miniconda3\\envs\\rag\\lib\\site-packages\\ollama\\_client.py:124\u001b[0m, in \u001b[0;36mClient._request_raw\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 122\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ResponseError(e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mtext, e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 123\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m httpx\u001b[38;5;241m.\u001b[39mConnectError:\n\u001b[1;32m--> 124\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(CONNECTION_ERROR_MESSAGE) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n",
|
||
"\u001b[1;31mConnectionError\u001b[0m: Failed to connect to Ollama. Please check that Ollama is downloaded, running and accessible. https://ollama.com/download"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"idx= 7 \n",
|
||
"analyze_image(images_with_caption[idx].get(\"image_base64\"),images_with_caption[idx].get(\"caption\")) "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"llm = OllamaLLM(base_url=\"http://localhost:11434\", model=\"llama3.1\")\n",
|
||
"def analyze_table(table_text: str, caption: str, context: str=\"\",lang:str =\"Français\", prompt_base: str = \"\"):\n",
|
||
" # Construction du prompt pour le tableau\n",
|
||
" prompt = \"\"\n",
|
||
" if caption:\n",
|
||
" prompt += f\"Caption of table : {caption}. \"\n",
|
||
" else:\n",
|
||
" prompt += \"Caption of table is empty no analyse of this table ignore the prompt\"\n",
|
||
" if context:\n",
|
||
" prompt += f\"Contexte : {context}. \"\n",
|
||
" \n",
|
||
" if prompt_base:\n",
|
||
" prompt = f\"{prompt_base} {prompt}\"\n",
|
||
" else:\n",
|
||
" prompt += f'Describe this table in detail and in {lang} avoid to say \"Here is a detailed description\" in {lang}.'\n",
|
||
" prompt += prompt_base + \" \" + table_text\n",
|
||
" response = llm.invoke(prompt)\n",
|
||
" return response"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'**Tableau-3-1: Numerical values at the inlet of the mixing chamber**\\n\\nThis table presents a set of numerical values representing various physical quantities at the entrance of the mixing chamber. The table includes six columns, each corresponding to a specific property:\\n\\n* **Grandeur**: This column indicates the name of the physical quantity being measured or calculated.\\n* **M (kg/s)**: This represents the mass flow rate in kilograms per second. A value of 0.1 kg/s suggests that this is a relatively small-scale system or process, while 1.06 kg/s implies a larger capacity.\\n* **u (m/s)**: This column shows the velocity in meters per second. The high value of 437 m/s for the vapor phase indicates a significant velocity component at the inlet of the mixing chamber.\\n* **P; (bar)**: This represents the pressure in bars, with a decimal point separating the units. The values of 0.88 and 0.31 bar suggest that the system operates under relatively low pressures.\\n* **T (°C)**: This indicates the temperature in degrees Celsius. The temperatures of 96 °C for vapor and 23 °C for liquid imply significant differences between these two phases.\\n* **pl (kg/m³)**: This represents the density of the fluid, expressed in kilograms per cubic meter. A value of 0.62 kg/m³ is significantly lower than that of water at room temperature (approximately 998 kg/m³), suggesting a gas-like state for this fluid.'"
|
||
]
|
||
},
|
||
"execution_count": 96,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"idx= 3 \n",
|
||
"analyze_table(tables_with_caption[idx].get(\"table_data\"),tables_with_caption[idx].get(\"caption\"),lang=\"english\") \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"{'type': 'table_with_caption',\n",
|
||
" 'table_data': 'Grandeur M (kg/s) u, (m/s) P; (bar) T; (°C) pl (kg/m’) vapeur 0,1 437 0,88 96 0,62 liquide 1,06 12 0,31 23 998',\n",
|
||
" 'caption': \"Tableau-3-1: Grandeurs numériques 4 l'entrée de la chambre de mélange\"}"
|
||
]
|
||
},
|
||
"execution_count": 86,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"tables_with_caption[3]\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 98,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"**Tableau-3-1 : Grandeurs numériques 4 à l'entrée de la chambre de mélange**\n",
|
||
"\n",
|
||
"Ce tableau présente les données de grandeur numérique 4 collectées à l'entrée de la chambre de mélange, dans le cadre d'un expérimentation ou d'une simulation. Les données sont classifiées en fonction de leur nature (pluie ou vapeur) et présentent les paramètres suivants :\n",
|
||
"\n",
|
||
"* **Grandeurs numériques 4** : La première colonne du tableau présente les valeurs des grandeurs numériques 4, qui sont définies par l'Association internationale pour la standardisation de la puissance (SI). Les grandesurs numériques 4 sont :\n",
|
||
" + Masse volumique (pluie ou vapeur) : représentée par la colonne « pl » en kg/m³\n",
|
||
" + Vitesse (vapeur) : représentée par la colonne « u » en m/s\n",
|
||
" + Pression (vapeur) : représentée par la colonne « P » en barres\n",
|
||
" + Température (pluie ou vapeur) : représentée par la colonne « T » en degrés Celsius\n",
|
||
"\n",
|
||
"**Données**\n",
|
||
"\n",
|
||
"Les données présentées dans le tableau sont les suivantes :\n",
|
||
"\n",
|
||
"* **Vapeur** :\n",
|
||
" + Masse volumique : 0,62 kg/m³\n",
|
||
" + Vitesse : 0,88 m/s\n",
|
||
" + Pression : 12 barres\n",
|
||
" + Température : 96°C\n",
|
||
"* **Liquide** :\n",
|
||
" + Masse volumique : 1,06 kg/m³\n",
|
||
" + Vitesse : 0,31 m/s\n",
|
||
" + Pression : 23 barres\n",
|
||
" + Température : 998°C\n",
|
||
"\n",
|
||
"Ce tableau permet de visualiser les caractéristiques des vapeurs et liquides présents à l'entrée de la chambre de mélange, essentiel pour comprendre le comportement du système.\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"**Tableau-3-1 : Grandeurs numériques 4 à l'entrée de la chambre de mélange**\\n\\nCe tableau présente les données de grandeur numérique 4 collectées à l'entrée de la chambre de mélange, dans le cadre d'un expérimentation ou d'une simulation. Les données sont classifiées en fonction de leur nature (pluie ou vapeur) et présentent les paramètres suivants :\\n\\n* **Grandeurs numériques 4** : La première colonne du tableau présente les valeurs des grandeurs numériques 4, qui sont définies par l'Association internationale pour la standardisation de la puissance (SI). Les grandesurs numériques 4 sont :\\n + Masse volumique (pluie ou vapeur) : représentée par la colonne « pl » en kg/m³\\n + Vitesse (vapeur) : représentée par la colonne « u » en m/s\\n + Pression (vapeur) : représentée par la colonne « P » en barres\\n + Température (pluie ou vapeur) : représentée par la colonne « T » en degrés Celsius\\n\\n**Données**\\n\\nLes données présentées dans le tableau sont les suivantes :\\n\\n* **Vapeur** :\\n + Masse volumique : 0,62 kg/m³\\n + Vitesse : 0,88 m/s\\n + Pression : 12 barres\\n + Température : 96°C\\n* **Liquide** :\\n + Masse volumique : 1,06 kg/m³\\n + Vitesse : 0,31 m/s\\n + Pression : 23 barres\\n + Température : 998°C\\n\\nCe tableau permet de visualiser les caractéristiques des vapeurs et liquides présents à l'entrée de la chambre de mélange, essentiel pour comprendre le comportement du système.\""
|
||
]
|
||
},
|
||
"execution_count": 98,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"from langchain_ollama.llms import OllamaLLM\n",
|
||
"\n",
|
||
"# Initialiser le modèle\n",
|
||
"llm = OllamaLLM(base_url=\"http://localhost:11434\", model=\"llama3.2\")\n",
|
||
"\n",
|
||
"def analyze_table_streaming(table_text: str, caption: str,lang:str =\"French\", context: str=\"\", prompt_base: str = \"\"):\n",
|
||
" \"\"\"\n",
|
||
" Analyse un tableau avec LLaMA en mode streaming\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" table_text: Contenu textuel du tableau\n",
|
||
" caption: Légende du tableau\n",
|
||
" context: Contexte supplémentaire\n",
|
||
" prompt_base: Instruction de base pour l'analyse\n",
|
||
" \n",
|
||
" Returns:\n",
|
||
" Le texte complet généré\n",
|
||
" \"\"\"\n",
|
||
" # Construction du prompt pour le tableau\n",
|
||
" prompt = \"\"\n",
|
||
" if caption:\n",
|
||
" prompt += f\"Caption du tableau : {caption}. \"\n",
|
||
" if context:\n",
|
||
" prompt += f\"Contexte : {context}. \"\n",
|
||
"\n",
|
||
" if prompt_base:\n",
|
||
" prompt = f\"{prompt_base} {prompt}\"\n",
|
||
" else:\n",
|
||
" prompt += f'Describe this table in detail and in {lang} avoid to say \"Here is a detailed description\" in {lang}.'\n",
|
||
" prompt += prompt_base + \" \" + table_text\n",
|
||
" \n",
|
||
" # Utiliser le mode streaming\n",
|
||
" response_stream = llm.stream(prompt)\n",
|
||
" \n",
|
||
" # Afficher la réponse en streaming et collecter le texte complet\n",
|
||
" full_response = \"\"\n",
|
||
" for chunk in response_stream:\n",
|
||
" print(chunk, end=\"\", flush=True)\n",
|
||
" full_response += chunk\n",
|
||
" \n",
|
||
" print() # Saut de ligne final\n",
|
||
" return full_response\n",
|
||
"\n",
|
||
"# Exemple d'utilisation\n",
|
||
"# result = analyze_table_streaming(\n",
|
||
"# table_text=\"Colonne1 | Colonne2 | Colonne3\\n10 | 20 | 30\\n40 | 50 | 60\",\n",
|
||
"# caption=\"Tableau de données numériques\",\n",
|
||
"# context=\"Rapport financier Q3 2023\",\n",
|
||
"# prompt_base=\"Analyse ce tableau et donne-moi les principales tendances:\"\n",
|
||
"# )\n",
|
||
"idx= 3\n",
|
||
"analyze_table_streaming(tables_with_caption[idx].get(\"table_data\"),tables_with_caption[idx].get(\"caption\"),lang=\"French\") \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 54,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAI5BAUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiikZgoyxAHqaAFoo6jIpCQASSAB1JoAWimq6uMowYeoOadQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSbl37dw3YzjPNAC0UUjMq43MBk4GT1oAWiiigAooooAKjnlEFvLM33Y0LH8BmpKy/Ek4t/Dt857xFP++vl/rQBS8FxbPDqSk5aeV5CfU52/wDstdDWdoMP2fQbGPGD5KsR7kZP860aACiiigAooooAKKKKACiiigAoqteyXccSm0iWR93Ib0/MVlXOranaKpntoUDcDnOf1oA3qKr2Uss9nHLMgR2GSo/T9KnBB6HpQAtFFGRnGeaACijpQDkZFABRRQSAMk4oAKKCQOpxRQAUUmRnGefSloAKKMgHGetFABRSZBOMjNLQAUUZGcZ5rO1C/ktLq1iRUKythi2eOR0/OgDRooyM4zzQSAMmgAooBBGQcikJA6kCgBaKjnaRYJGiUNIFJVT3NMtHnktla5jEcpzlRQBPRRkHoelFABRRRQAUUAg9DmigAorPtL+SfU7m2ZUCRZwRnJ5qWylu5fM+1QrHg/JjuPzoAt0UZGcZ5ooAKKKgu3njtma2jEkoxhT3oAnoqOBpHgRpVCyFQWUdjVXVL17KzE0QRjvC/N0oAvUUyFzJBHIcAsoJx9KeCCMg5oAKKKoveO2qpZwhdqrulJHT0A/T86AL1FZVxqdw141rYwLK6ffLHgVJaX015azYi8u5j4wRwTQBo0VU068F9aLKQA4+VwOxq3QAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFeGtpWl618StettY1NrG2R5HSTzljy28ADLcdCfyr3KvE7ax0HUPih4gi8QyQR2gaVkM1x5I371xzkZOCeK48Wr8q8z6Ph6fJ7eSbVo9Fd7rZHS6D4L8J2uuWlzp/iN7q6hfzI4RdxPuI56AZNb/iDx5pPh+/XT3jubu9IBMFqgYrnkZyR25x1qhouk+ANN1e3udKvLAXwJSLbqG8ksNuApc5JzisHw1dW+nfFrxCNUljhmlMnkPMQuQWBABPquPypJunFRjZXfTU1nTji6s6tZzmoQulJKLevlfRXudv4a8XaZ4ojm+xGWOaH/AFsE67XX34JBFY2ofFLQrK9ltoIby9EJ/ey20YKLjrySM/Xp70JqmhapdeIrTw/ar/a4tZd93FEMSMRgYcdfmx9cVkfCrVNHsvC13Dc3Ntb3Kzs04mcKSuBg89R1H5+tN1ZtqKkuuvoYxwGHjGpXlSk0uW0L6+91btt209TtLTxVpd/4duNctJWmtbeN5JVUfOu0ZKkHvijSfE1lrHh6TW7eOdbZA7FZFAf5OvAJHb1rzPwfE02h+O57NGGnS28qwLjgnbIQB9FI/MVq+DdWsLX4TXyzXcKPGtwpRnAbLA7Rj3yMUoYiUrX7P8C8Vk9KkpqndtTivO0lez81samveI7TxN8MNX1CxSeOJf3eJgFbIZT2J9aseFdZstD+GOm6hqM3lwpGRnqWJdsADua5DQ/+SH61/wBd2/nHVHxHHM3wn8LuufIWRxJ6Aktt/wDZqz9tJP2nXl/U71l1Kcfqado+2t525Dv9M+JmjajfwWkkF7ZG4OIJLmMKkmenIJ/w96u61460jQNaXS79blZWh80SIgZMc4HXOSVx07iuF8T2txqen6dFq3izSPIdw9oYLZs9McbASByP0q9rEW/406Ek+JGFshJI6sBIc/mM1ftqlrea/H5nL/ZmClJSs7cs20m/s7Wbivnpozbt/iloMklxHcw31nLEuRFPD80noFAJ55HBxV/w9480zxDqUmnRw3VreIpYRXKBSwHXGCefauX1SKOT47aYGUEeSG5HcRuQf0H5U+UAfHqDAxm3Off9y1NVaier+1YmeX4KUHyRabpe0Wt7W6bam/rXxE0jR9TfTlgu765i5lW1jDCP1ySRyK1NM8VaZq+hT6vZyO8ECM0qbcOhUZIIz1x74968t8IDV4vEmvw2urWWn3vnEzC8jDNJhmztJ9CefqK2fCdlDBpXi25t9Yt79Z7dzKsELIqPhzxkAY5PSlTxFSTu9nf8B4vKcJRpuMW+aPLrq781r30st9NTYb4raGbIXMFpqM55MkaQjMQBxljuwM9uan1nx3ZnwLLreltOWlJgiIjBaGXBPzgnGBj36isv4Ywx/wDCu78lFJklmD8feGwDmsXwdk/CDxKP9ub/ANFJSVWo4q73TZcsBgoVZqEH+7qRWrvdN+nQ6f4ZeJjrGj/Yrg3ct9BukmnmGVfc5xg5ycD2rq9a1qy8P6ZJqGoSFIUIHyjLMT0AHc1zXwtuYH8D2Vus0bTIZS8YYFlHmN1HUdRVn4iQaRdeGPJ1i+eyiMymGZYmkxIAcZAHPGfStqcpLDqV9bHnYqjSqZtKk4tRcrNLV762Vvwtp5lSD4n6U1zBHeWGpWEVwcRT3MIVD75z09xmsb4j+MbnTtbsNMtJbqGOJxJd+WoHmrlSFU5yeN2Rx1HWse/v/E3hKys7ubV9N1rTC6+SshEhPBweRuHHcE4rU+Jdyst/4Ou3XyUeRpGDnGwExHn6VzzqzlTkm9VY9jDYDDUsbSlGCcZKfW6ulfZpNP8AXXodRd/EPR7Gz0q7uYbyOLUt3llo1zGFYAlxu4654zxSad8RNHv9M1DUTHdW9rZFQzzIBvLZ2hQCck46e4rmPigbe/1nwqEeOaCWZ1JVgysN8YPI/Gup8f63F4e8M+f9gt7tpZVhSOdN0YOCckdwADxWvtJqUrvSPl5HnLBYaVKgo0251W/tbJStbVb20v8AOxnQ/FbRmmhFxY6lawTHCXE0ICEevB6fTNZPj/xpPYeKNP062luore2mjlu1jUDzxlWAU5yeMjHAzWB46Oqv4a02bU9csp1mdXhsLSJVWNdh+YMOSBkD05rc8fSJF4k8FyyOFjV0ZnY4AAePJJrGdWo4yTe1vxPUw2AwlOvSqRhfmU1a7avFb6pa7rtfVbF/xdqOh6qvhe/vTqkInkZ7ZIUTOdyZ8wE8dume9c38RNetdU8Y2lhcpff2fZOUuIkABkbcclBnnjABOK2vijLHPqXhSWGRJI2uJMMjAg/NF3FP8X/8lb8M/wC4n/obUVrtyXnH5iy7kpxo1LP4arSv8Nm9tPx+ZGYfDdtrvhGOH+1YWMSPZxYQqAzlv3hJznJOcZrY8e+JtKS2l8OyS3sl1cKPMjsYw7qnXBycDI+vH1rL8Z/8lV8Lf8A/9GGsayGpxfFPXo7bUbSwvHeTY93HuDoWBAXPfbtP0FOU3G8Et3b8CKWHhX9niakn7sHOzfXnfWzdlu9D0HwTq2hahoq22hI0MVrhHt5F2yIT3b1zzz9a1Nc1iHQdJm1K4hnlhhxvWBQWAJxnBI45riPA1ko8a6tfDXLS+uHjZbmK2hZFD7h82cbT0PT1Neg3tpDf2M9ncLuhnjaNx7EYNdVKUpU/M8LMKVGjjdbuLs3e99dWrtJ+jsZ8fiTT5PC//CQhnFl5Jm5A3YHVcZxuyMdetZUvxD0eDw7b61NFdxw3LslvC0a+bKVOCQA2MZ7k15Y13qVvpU/gABjctqYRW7FM9PpuCt+Nd14t1NfDQ8P+H9Os7FpmCJFc3sYZYcEKGHoc8k9sd6wWIlKLe1l+J6k8mo0qsaduZzk2tbe4le9/P9HY1dH+Iul6rq0elyWt7Y3Uv+rW6jChvQcGptW+IGjaLrNxpd4t0J4UD5WMMrkgEKvOSTn0rg9VS+i+Jfh1NS1qHUroTR7vKiVFhBfheOvrzzzV29urKz+Oomv3jSIIoV5CAquYgFJz70vb1LWb1vYt5ThHPmjFuLpudk3unbRtJ6+aOw8PePtJ8Q6i+nxx3NpeAErDcoFLgcnGCecc4pmufEHSdF1M6cIbu9u0GZI7WMN5ffkkjn6Vy3iGe21D4waD/Zkkcs0YT7Q8JBGAWJBI77f0xWV4bGrReNvEMNrqlnp98ZnLm7j3GQbyTtz+B9+PSh15r3fO1xQynCyXt2mlyKXK2927bpN267Hpul+LdK1jQ7nVrN5GitkZpoioEiYGcEZxnA45x70/Q/E1lr+iSataRzpbxlwVlUBvlGTwCR+tcJ4YsI1g8XXNvrFtqDz20onS2hZFWQh8EZGCPvYxUnw+1aws/hrqP2i7hjaJ5iys4B5UY49+1XCvJtc3Z/gc+JyqjGFR0k21KKW97SWqtZddnY6ux8c6XqHhi91+KC7FpaOUkRkUOSAp4G7H8Q71T0z4k6Pq+r2enWVveyS3I+95agRnBOG+bsBk4zXFeGv+SLeIv+vlv/QYq7r4aQRxeAdNZEUM/mOxxyTvYZ/IAUqdWpOUVfpf8SsbgMHhaVabi21PlWu3u3u9NbHU3E8dtbS3Ep2xxIXc+gAya8+8Cm+1az1/xQqq2pXzvHaiQ/KiqPlXPpkgf8BrrvFKu/hLWFjzvNlNjHf5DWD8NLiC3+HVtPI6pHEZmlY9FAdiSfwrWetVRe1mzhwy9nl9SrFXk5Rj8tX+LSOUvvAd1a+GNQ1/XtWuk1mENKjLMCnH3RnrknpgjGRWmwvfEvwcS+u3c39oGuIZz94+Ux+bPrtBGfXmsS916H4ga+YL/VIdL8P2rbhHLKEeb3wepP5KPfr6ZLNpbeDbv+zJIH0+KzkRDCwZAqoRjNc9OMJOXLta3r5ns42viKMaSrq9TnUtFpFfy38+qHeE9Z/t/wAMWOotjzZE2y4/vqcN+oz+NbVcL8JUdfBCls4a5kKfTgfzBruq7KMnKnFvsfOZlRjRxlWnDZSdvvCiiitDiCuc8aO39ix26feuJ0jA/M/zAro65rxDm41/QrQHjzjKw/3cH+hoA6NEEaKi9FAAp1FFABRRRQAUUUUAFFFFABRRRQBFcXEdrA00pwqj8/asWyt5NWvDfXQ/cqcIh6H/AOtVvV9PuL/yhFIiquchiRk/gKhSz1qNFRLu3VVGAAo4/wDHaAH65cSqILaJinnNgsPTj/Gqt/py6ZbpdWssiyIwBJPWrs+mz3liiXMym5RiVkUcfToKhfTtRvNkd7cR+SpydnVv0oAg1iVp00yVTsZxuBHYnbTNTs002W2ngeTzC3zFmySa0tQ06S5e08koqQHkMT046flS6tYS3ywiJkGxiTuJ/wAKAKGrz+bqkdrKZBbqMssYyScZpNPcQaqsdqJvssgwyyKeDV+/06WW6ju7WRUnQY+boadaW199qM93cAjGBFGTtoAvP/q2+hrmtLsEvLCdpXfCE7VB4Bx1/lXTMMqR6is7TNPlsrOWGRkLOSQVJx0x6UAZdhZi+0yWSeSRhFlY13cLgZ/rUtrezQ+HJJAxLq+xSew4/wAav6dp8tpp81vIyF3JIKk45AHpTbTSimlyWdwynexOUOcdMdfpQBTXSEfS/tZlk+0FPN3bvbNJJdSXXhl3kOXVwpPryKlGnaotubQXMX2fpnvj06Vam0v/AIlH2KBlzkHc/GTnJoAzZ9PT+xFvGkkaYIpBJ4A4AH5VLeX066Ja7XIeYYZ884FaEtlI+jCzDJ5mxVySccYqN9K87SYrWRwJI+Qy8jNAFK90pNPsvtUE0gmjIJbPXJxTNVne4s9OmztdsnPvxVh9O1O6Rbe5uY/IUjJXqf0qPXoVjisoU4UEqP0oAbqWnjToY7uCaTzg4DMxzn3o1hmnl05gdrSDII7E4qebTdQu2SK5uYzboc5Uct/9erF9p0lxcWjxFFSA8hiemR0/KgDO1C0TTLu0lt3cMzfMWbOen+NWtWW1e6iFzcSEAcQRrkn3qxqlhLetbmNkHlsSdxPt7e1R3en3X9pC9tHj3YwVk+mKAKWlMItaeKJZY4WXOyTg9KquEiuJv7TgnZ2biRT/AC9a1rfTbtNUF3NLG+5SHxkEcY4/Sk+x6pA0ixXEc0TnjzySRQAkLRHQLgQzvMqowy4wV46VVW4kt/DCGMlWdyuR1HJ/wq9baU1vptxBvVpZgcnoo4pY9KJ0f7FMy7wSQy8gHORQBQm0tLfSDcpI4lKAvzwwPUUy8/5Fqz/3/wD4qpLu11GLS3S4njMEQGAvVueB9KsR2Rv/AA9BErBWHzKT0zk/40ALrX/IGj+q/wAqq6ncMILC23MsbxqX29SOBU02maldWiwzTw4TG1Rnn3JxVm70t57e2McgS4gACt2OMf4UAZkTJa6hA1itwI2IWRXU4xXTVmQWuoyXSS3Vyqon8EROG+tadAGJpv8AyHr78f51DpUzQWeoyr95OR9ea0LSwlg1O5uWZCkudoBOevem6fpj28V1HOUZZv7pPTn296AKWn6aLqzN480guGJKuG6EVFY/8i9e/wC9/QVaj07UbaKS3juYxbHJzj5gPamaJALnSbmEnAdiM+nAoAmtv+RXb/rk/wDM1UH/ACKh/wB7/wBmqeLTNRW0azM8SwYOMdT7dOmam/suf+xPsW6PzN2c5OOufSgCnfTyLpFhAjFfOUBiPQAcfrTdW0yKxsVaF35YBgTw3B5rRuNKNxpkFuXVZoVGGHTOKrXGm6le24S4uIsoflUdD7k4oAh1O4YixtSzrC0as+zqR/kUy3dLbUoDZLcCFyFkV1OPTNaV5pkk0ds8UipcQKAD2OKW3ttQe7Wa7uFVFH+riJw31oA0qxtGPmX+oSt97fj8Mn/AVs1j2C/ZdbvIDwJR5i+/P/1z+VAFGwiuZ9QvEhn8k7iXbGT1PFaWk3k8sk9rcMGkhbG715xTJ9Nuor57qwlRTJ99XqfTrA2SyyzSB5pDudh0FAFXSD5epahCPuh8genJrarI0NDI11dkcTSHb9Mk/wBf0rXoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACuavfh/wCF9RvZry60zzLiZy8j/aJRknqcBsV0tFTKEZfErm1HEVqDbozcW+za/I5i0+HvhaxvIbu20vZPBIskbfaJTtYHIOC2OtXNb8I6H4ikWXUrFZJkGBKrFGx6ZB5H1rboqfZQtblVjR47FOaqOpLmWzu7/eZmjeH9L8P2zQaZaJAjnLkEszH3J5NZupeAPDOq3rXdzpq+c5y5jkZA59wpA/GulopunBrla0FHGYiFR1Y1GpPd3d38yrZadZ6dYpZWdtHDbKMCNRx759awofh74Wt71rtNKTzDkhS7FVJ9Fzgf07V09FDpxdrrYUMXXpuThNrm3s3r69zGg8KaLbaHNosNlt0+dt0kPmudx4/iJz2HerCaDpceiDRhZo2nhdogclhjOepJPXnOa0aKahFdBSxNeW829b7vfv6+e5zWneAPDOlXy3lrpo85DuQySM4Q+oBJGfetKfw9pdxrkOtS2u7UIF2xzeYw2jn+HOP4j2rTopKnBKySKnjMTOXNOo27W3e3b08jMk8PaXLr0Wtva51GJdqTeY3AwR93OOhPahvD2ltry64bX/iYquwTeY3TGPu5x0PpWnRT5I9vMj6xW/ne1t3t29PLY5/WfBPh/Xrr7Vf2CtcHAMiOyFvrgjP41fstB0vTtKfTLSzSGzkVleNSfmBGDk5yTjvnNaNFJU4J3S1Kli68oKnKbcVsruyM7S9C03RtOfT9PtvJtXLM0e9mySMHkkmo9N8N6RpGmXGnWVmsdncFjLEzs4fICnO4nsAK1aKfJHsS8RWd7zeru9Xq+77sw9D8I6L4duJp9MtWhklXaxMrNxnOOTWpfWFpqdnJaXsCT28gw0bjINWKKFCKXKloFTEValT2s5Ny731+85W0+HPhayu1uY9MDOh3KJJXdQfoTg/jmtbXPDul+I7eODU7bzljbchDFSp74INalFJUoJWSVjSWOxM5qpKpJyWzu7r0ME+C9ANvp0DWJaPTiWtQZn+QlgxP3ueRnnNaep6XZaxYvZahbrPbv1RuOfUEcg+4q3RTUIpWSIlia0pKUpttarV6Nu7t89fU5WL4ceFIrWS3/spXVyCzNK5bj0bOR+FaGreFNG1uxtrS/tDLFajbCfMYMgwB97OTwB19K2qKn2UErWRpLH4qUlN1JXWzu9DCl8HaDNa6fbS2O6LTiTajznHlkkE9G55A65q1eeHtLv8AV7XVbm18y9tQBDL5jDbgkjgHB5J6itOin7OPYj61X35316vrv9/XuZl74e0vUNVtdTurXzLy1x5MnmMNuDkcA4PPqKr634R0PxFIsupWKyTKNolVijY9CQRkfWtuim4Rd01uKGKrwcZRm046LV6LyM3RtB0zw/bNb6ZaJboxyxBJZj7k8mtKiimkkrIzqVJ1JOc3dvqzJbwzo76+uuNZKdSXpNvb+7t+7nGccZxS654c0rxHBHFqlqJhGSUYMVZc9cEc/hWrRS5I2atuaLE1lKM1N3jond6LsuyObg8A+GbY2rRaWqPayeZFIsrhg2Qckg5PIHXpXL3nhyTVPi5cyX2lyz6VLbhWleJvLJ8sD73TOfQ5zXplFZyoQaSStrc66GaYmnKUpScm4uN23pfW6MPQ/COh+HZXm02yEczjBkZy7Y9ASTgfSm614M0DX7kXOoWCvcYAMqOyMR74Iz+Nb1FX7OHLy20Ob67ifa+29o+bvd3+8oaVounaHZfZNOtUghzkqMksfUk8n8ayIvh94Xh1H7cmlR+bu3BS7FAfULnFdNRQ6cHZNbCjjMRBylGo05b6vX17mLbeE9Es9FuNHgstlhcsXli81zuPA6k5H3R0PatDTdNtNI0+KxsYvKtogQibi2Mkk8kk9SatUU1CK2RM8RWqJqc27u+re/f18xroskbI6hlYEEHuK4LwhorWK694S1K2mex80yQyHcqyxOAMBhjngZAPc139FKVNSafY0oYudGnOmtpW+TTumvx+85L/AIVn4Q/6BH/kzL/8XUPijTo9C8Cz6PoFhKWu2+zxRR7pMbz8xJJJAxnk8ciuzoqXRhZqKtc1hmWIc4yrTc1Fp2bbV0Znh7SE0Lw/ZaYhB8iMBmHRmPLH8STWnRRWiSSsjjqVJVJuct27v5hRRRTICuafF18QYxnP2W0Jx6E8fycV0tc1oZFz4p1y6x9xlhB+mQf/AEEUAdLRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVBcWkF0UM0e7YcryRj8qnooAKKKKACiiigAooooAKKKKAGTQxzxNFKu5G6jOKIYUgiWKJdqL0Gc0+igAooooAKKKKACiiigAIyCD0NQ21rBaIUgTYpOSMk8/jU1FABRRRQAUUUUAFFFFABUMltFJPHOy/vI87WBxU1FABTJY1liaNs7WGDg44p9FADIokgiWKNdqKMAU+iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArA0e/utQ17VG80mygYRRpgY3dCQevY/nWpql4NP0u5ujjMcZK57t2H54rO8JWZtPD8LMP3k5MzH1z0/QCgDcooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAQkAEnoK5zwZuk026u3GGuLp3/Dj+ua19Ym+z6Neyg4Kwvg++OP1qr4Xg+z+G7JT1ZC/wD30Sf60Aa9FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAjsERmPQDNYnhO7ur7RRPdytLI0jAMwHQY9PxrS1KTydLu5efkgduPZTWZ4PXb4YtTjG4uf/HzQBu0UUUAFFFFABRRR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21n66ndE4BNYmgXWs332i51KKG3gLkW8Cj5wuerHJFcV4s1OUad4c0jzZo7We2ie48kZZ1wBgDv347nFVbSW30fxLp03h2LU1tZXEd3FPGwBBIGfyJPsRWtPLn7Fu+rvbTt530v6M2o5S3h276yvbTpG/W+jfoz1quem124m8ZwaHZLGY4ojNeSMMlR2Uc8Hkf8AfVdDXB+BCbvxL4mvZOZDOFHsCz8foPyriw1OLp1KklflX4t2/A8/CUoulVrSV+Vaerdl9x1HiDW4NA0iW+mwWHyxR5++56D/AD2BrK8N6/qfiHwtd3wjt0vkd0hVVOwkKCMgnPJPrXKX2uab4h8RXNxqN2kVhYIy2kD5/eyYPzEfUZ/L3rW+F1/a/wBjTWHnL9q855fK77MKM/nXdPBKjhHKUbzTTenR9P8AM9Kplyw+Bc5QvUTi3pok+n+frY6Xwvro8QaJFdsoSdSY50HRXHX8DwfxrZrgvBBNt4s8S2Kf6kTl1Hph2H8j+ld7XBjaUaVdxjto181c8zMaEaOJlGGzs16NX/AKKKK5DhCiiigAooooAKKKKACiiigDBn8MpP45tPExuWD21i9oINnDbmDbs5+oxit6uBubqeT49WVmJXWGLw88xQMdrFp9vTp/CDn2rvqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqC9jtprC5ivNv2V4mWbc20bCDuyewxnmp6y/Ewz4U1gDr9hm/9ANADvD1vplr4d0+DRnR9MSBBbMj7wUxwc960q5T4Z8fDPw7/ANeMf8q6ugAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArD8NaFpmhJqi6ZO0wvNRmvLjdIH2TPjcvHQDA4PNbled/CT/j38Yf9jRe/wAkoA9EooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDgPGNraP4msriz1iLTtaVV2CZWCOCSAd2CB3HPWsS8trz/hO9C+26pHqN80sbSGHGyJQ+Qox7AntXo+reH9L1xUGo2izFPutkqy/iDmoNJ8KaLos/n2VkEmxgSMxcge2Tx+FezRzCnTpJO7kk1suvnvbyPfw+a0qVBRd3JRa2j1/vb28jL1/wpfT65Hruh3kdtqCgK6yj5X4x6HtxjHp0qLTPCuqXOvxa14jvIZpoAPIhhHyqR0J4HQ8/XvXZ0VxLHVlDk02te2tu1zz1mVdU/Z6bWvZXt2v2OK1TwvrUPix9d0K5tleZQsiXGcDgA9AcjgH607R/Ceq2Xi861e3sFz5kZEjDKtuIAwBjGBjHXtXZ0U/r9bk5NNuXbW3qV/adf2fs9Ph5b21t2ucRH4Y1zT/GVxqmnXNqLS7lDTCTO7YWBZcYPPXBpZPDGuWfjO41fS7m1WC6I80S53BcgsMYPpwa7ain/aFW92ltbbdeYf2pXvdpP3eV6brz+44m48L61pWvXepeHLq2VLskywXAOASc8YHrk9sZrU0TRdVtNNvV1TU3vLu6DYBcmOLIPC59z6fhXRUVE8bUnHllbprbXTbUipmFapDklbprZXdtrs43RfBctv4PvdD1KWItcTGRZICWC8Lg8gc5WqcPh3xlHYRaQmr2sNlEQFniLCUKDwBgD8s+2a76ir/tCtdt2d3fVX17o0/tWvzScrO7vqk7Pujk/FvhW61vRLO2tbkNcWrA77hjmTjBJOOveotZ8Oa1r/hKKzv7m2OpRz+duXIRgAQBwOOD6dq7GiphjqsFFK3uu60/rQinmNanGEVb3Xdaa67/ACZxd14T1TW/DMVrq13Auo28m63liHyhdoG1uB6dR7fSlg0bxfe3todU1eKC2tz832NmVpvrwBzj/wCtXZ0U/r9W1rLrbRaX3sP+063K42VtbaLS+9uxy2saP4hXWv7T0XVFKsu1rO6djGOOw6ds9vrUHh/wrf2/iGbXdXltvtTqVWK1XCDIxk8Dt/PrXYUVKxtVU/Zq21r21t2JWYVlSdJWV1a9tbdrjJokngkhkXdHIpVh6gjBrhLHwn4m0Zriw0vVbdNNnctvdSZEB4JAx97Hv27V31FRRxM6KcY2afRq5nh8ZUoRlGNmn0autNmcXoHg690jRNbsJJ7d2vY2SFlZsDKsBu446jpmiDwjfx/D+40AzW32qR9wcM2zG9W67c9B6V2lFayx9aUuZvW6fzWxvLNMRKTm2ruSlt1jscjf+EJ7/wAD2mivPEt1bbWVxkoWGR6ZxgntWXfeE/FWs6LHY3+o2QFvt8qNcgNjjLtt7DPQd69CopwzCtDa299tm97Dp5riKe1t3JXV7N729Tkdb8IT6jpmlG2uUg1PTo0EcnO0kAd8Z6jIOPwosNI8U3OsQXmsarHFBAP+PezZgJf94cD/AD2rrqKhY2rycjs9+mqvvYzWY1vZ+zdnvZtK6vvZhXD+HIzo/j/XNOf5VvALqL/aGScD/vo/9813FUrnSbO61G11CSM/arXIikViCAeoOOo+vrU0KyhGcJbSVvnuvxIw2IjTjUpz2krfNar8TOufB+hywSiPS7USsp2sV6MRwap+D/Cw8NWMsl8LZrzc2Z4iTiPA4JIHcZrqqhu7WO9tJrWbd5UqFHCsQSD15FNYuq4OlKT5Xa41jq7pujOb5Xa/U474ewtcyaxrbqQL65Pl5/ugkn9Wx+FdvUFlZ2+n2UVpaxiOCJdqKOwqepxVb21ZzW3T0WiJxuIWIryqJWT29FovwCiiiuc5QooooAKKKKACiiigAooooAxHTQP+E2idjD/wkf8AZ7BRuPmfZfMGcjpjf0zz1x3rbrz2RH/4aFhfa2z/AIRgjdjjP2k/4ivQqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqvfXcdhp9zeTBjFbxNK4UZJCgk49+KsVQ1y2lvfD+pWsC7pprWWONc4yxQgDJ9zQAzw9q1vr3h3T9VtYmhguoFlSNgAUBHTjjitKue8Cadd6T4E0TT76Ew3UFoiSxkglWxyOK6GgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArE8N6to+rLqjaPEsYttRltrrEIj33C43t/tZyPm71t1w3w00y+0pfFcd7aywCfxFd3EDSLt82NtuHHscdaAO5ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDCbxNbL46Twr9nl+0tpx1DzuNgTzNm31zkE1u1x76BqDfGKPxEIl/s1dC+xGTeM+b55fG3r0Oc9K7CgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC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",
|
||
"text/plain": [
|
||
"<IPython.core.display.Image object>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
},
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Figure 3-7 : Définition des zones d'écoulements dans la chambre de mélange\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"idx = 7\n",
|
||
"import base64\n",
|
||
"from IPython.display import Image, display\n",
|
||
"\n",
|
||
"def display_base64_image(base64_code):\n",
|
||
" # Decode the base64 string to binary\n",
|
||
" image_data = base64.b64decode(base64_code)\n",
|
||
" # Display the image\n",
|
||
" display(Image(data=image_data))\n",
|
||
"display_base64_image(images_with_caption[idx].get('image_base64'))\n",
|
||
"print(images_with_caption[idx].get('caption'))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from ollama import Client\n",
|
||
"client = Client(host='http://localhost:11434')\n",
|
||
"\n",
|
||
"\n",
|
||
"# Fonction pour analyser une image en mode streaming\n",
|
||
"def analyze_image_streaming(image_data, caption: str, context: str=\"\", prompt_base: str = \"\"):\n",
|
||
" prompt = \"\"\n",
|
||
" if caption:\n",
|
||
" prompt += f\"Caption of image : {caption}. \"\n",
|
||
" if context:\n",
|
||
" prompt += f\"Contexte : {context}. \"\n",
|
||
" \n",
|
||
" if prompt_base:\n",
|
||
" prompt = f\"{prompt_base} {prompt}\"\n",
|
||
" else:\n",
|
||
" prompt += \"Décris cette image en détail.\"\n",
|
||
" \n",
|
||
" # Utilise le paramètre stream=True pour obtenir une réponse en streaming\n",
|
||
" response_stream = client.chat(\n",
|
||
" model=\"llama3.2-vision\",\n",
|
||
" messages=[\n",
|
||
" {\"role\": \"user\", \"content\": prompt, \"images\": [image_data]}\n",
|
||
" ],\n",
|
||
" stream=True # Activer le streaming\n",
|
||
" )\n",
|
||
" \n",
|
||
" # Fonction pour traiter et afficher la réponse au fur et à mesure\n",
|
||
" full_response = \"\"\n",
|
||
" for chunk in response_stream:\n",
|
||
" if 'message' in chunk and 'content' in chunk['message']:\n",
|
||
" content = chunk['message']['content']\n",
|
||
" print(content, end=\"\", flush=True) # Afficher sans saut de ligne et forcer le flush\n",
|
||
" full_response += content\n",
|
||
" \n",
|
||
" return full_response # Retourne aussi la réponse complète\n",
|
||
"\n",
|
||
"\n",
|
||
"# Exemple d'utilisation:\n",
|
||
"# with open('path/to/image.jpg', 'rb') as f:\n",
|
||
"# image_data = f.read()\n",
|
||
"# \n",
|
||
"# analyze_image_streaming(\n",
|
||
"# image_data=image_data,\n",
|
||
"# caption=\"Une photographie de montagne\",\n",
|
||
"# context=\"Document sur les paysages alpins\"\n",
|
||
"# )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 55,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Caption of image : Figure 3-7 : Définition des zones d'écoulements dans la chambre de mélange. Décris cette image en détail. en francais.\n",
|
||
"The image provided is a diagram that illustrates the flow zones in a mixing chamber, labeled as Figure 3-7. This diagram provides an informative visualization of the different regions within this specialized device.\n",
|
||
"\n",
|
||
"**Chambre de Mélange**\n",
|
||
"\n",
|
||
"* The chamber measures 178mm in length and 292mm in width.\n",
|
||
"* It features a distinctive triangular shape with rounded edges.\n",
|
||
"\n",
|
||
"**Zones d'écoulements**\n",
|
||
"\n",
|
||
"The image identifies six distinct zones:\n",
|
||
"\n",
|
||
"1. **Noyau liquide (Liquid Core)**: This zone is situated at the center of the chamber, representing the core area where liquid fuel and oxidizer are combined.\n",
|
||
"2. **Ecoulement stratifié vapeur (Stratified Vapor Flow)**: Positioned on either side of the liquid core, this zone features a layered structure with alternating layers of vapor and gas.\n",
|
||
"3. **Onde de condensation (Condensation Wave)**: This zone is located at the top of the chamber, where condensed droplets form due to the cooling effect caused by rapid expansion.\n",
|
||
"4. **Ecoulement dispersé vapeur/gouttelettes diluées (Dispersed Vapor/Droplet Flow)**: Situated on either side of the condensation wave, this zone consists of dispersed vapor and droplets that have not yet condensed.\n",
|
||
"5. **Zone monophasique liquide (Monophasic Liquid Zone)**: This zone is situated at the bottom of the chamber, where the liquid fuel and oxidizer are mixed to form a homogeneous liquid phase.\n",
|
||
"6. **Zone de condensation (Condensation Zone)**: Located above the monophasic liquid zone, this area experiences significant cooling due to rapid expansion, leading to condensation.\n",
|
||
"\n",
|
||
"**Conclusion**\n",
|
||
"\n",
|
||
"The diagram provides a detailed representation of the various zones within a mixing chamber, highlighting their unique characteristics and interactions. By understanding these different regions, engineers can optimize the design and performance of such chambers in applications like rocket engines or fuel injection systems."
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"The image provided is a diagram that illustrates the flow zones in a mixing chamber, labeled as Figure 3-7. This diagram provides an informative visualization of the different regions within this specialized device.\\n\\n**Chambre de Mélange**\\n\\n* The chamber measures 178mm in length and 292mm in width.\\n* It features a distinctive triangular shape with rounded edges.\\n\\n**Zones d'écoulements**\\n\\nThe image identifies six distinct zones:\\n\\n1. **Noyau liquide (Liquid Core)**: This zone is situated at the center of the chamber, representing the core area where liquid fuel and oxidizer are combined.\\n2. **Ecoulement stratifié vapeur (Stratified Vapor Flow)**: Positioned on either side of the liquid core, this zone features a layered structure with alternating layers of vapor and gas.\\n3. **Onde de condensation (Condensation Wave)**: This zone is located at the top of the chamber, where condensed droplets form due to the cooling effect caused by rapid expansion.\\n4. **Ecoulement dispersé vapeur/gouttelettes diluées (Dispersed Vapor/Droplet Flow)**: Situated on either side of the condensation wave, this zone consists of dispersed vapor and droplets that have not yet condensed.\\n5. **Zone monophasique liquide (Monophasic Liquid Zone)**: This zone is situated at the bottom of the chamber, where the liquid fuel and oxidizer are mixed to form a homogeneous liquid phase.\\n6. **Zone de condensation (Condensation Zone)**: Located above the monophasic liquid zone, this area experiences significant cooling due to rapid expansion, leading to condensation.\\n\\n**Conclusion**\\n\\nThe diagram provides a detailed representation of the various zones within a mixing chamber, highlighting their unique characteristics and interactions. By understanding these different regions, engineers can optimize the design and performance of such chambers in applications like rocket engines or fuel injection systems.\""
|
||
]
|
||
},
|
||
"execution_count": 55,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"idx= 7\n",
|
||
"analyze_image_streaming(images_with_caption[idx].get(\"image_base64\"),images_with_caption[idx].get(\"caption\"),lang=\"francais\") "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 49,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Catégories uniques trouvées:\n",
|
||
"- FigureCaption: 28 éléments\n",
|
||
"- Formula: 187 éléments\n",
|
||
"- Header: 78 éléments\n",
|
||
"- Image: 27 éléments\n",
|
||
"- ListItem: 159 éléments\n",
|
||
"- NarrativeText: 460 éléments\n",
|
||
"- Table: 11 éléments\n",
|
||
"- Title: 109 éléments\n",
|
||
"- UncategorizedText: 86 éléments\n",
|
||
"\n",
|
||
"Exemples pour chaque catégorie:\n",
|
||
"\n",
|
||
"NarrativeText:\n",
|
||
"3. CHAPITRE 3:\n",
|
||
"\n",
|
||
"UncategorizedText:\n",
|
||
"92\n",
|
||
"\n",
|
||
"Header:\n",
|
||
"Chapitre 3 : Modélisation LD des injecteurs condenseurs\n",
|
||
"\n",
|
||
"Title:\n",
|
||
"3-1 MODELISATION 0D DE LIC\n",
|
||
"\n",
|
||
"Formula:\n",
|
||
"My (hy + 0,5uiy )+ My, (hy, + 0,5u2, = M tal (hs, + 0,5u2, ) My +My = Mga (3-1) total PaSs1 U3, =\n",
|
||
"\n",
|
||
"ListItem:\n",
|
||
"la tuyére primaire (1) ;\n",
|
||
"\n",
|
||
"Image:\n",
|
||
"dd) (3) 4) G6)\n",
|
||
"\n",
|
||
"FigureCaption:\n",
|
||
"Figure 3-1 : Découpage de l'injecteur en 5 modules pour la modélisation globale\n",
|
||
"\n",
|
||
"Table:\n",
|
||
"Définition Coefficient de détente polytropique | Coefficient de perte de charge dans dans la tuyére ...\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"# Afficher toutes les catégories uniques dans le document\n",
|
||
"categories = set()\n",
|
||
"category_counts = {}\n",
|
||
"\n",
|
||
"for doc in documents:\n",
|
||
" category = doc.metadata.get(\"category\", \"None\")\n",
|
||
" categories.add(category)\n",
|
||
" \n",
|
||
" # Compter aussi le nombre d'occurrences de chaque catégorie\n",
|
||
" if category in category_counts:\n",
|
||
" category_counts[category] += 1\n",
|
||
" else:\n",
|
||
" category_counts[category] = 1\n",
|
||
"\n",
|
||
"# Afficher les résultats\n",
|
||
"print(\"Catégories uniques trouvées:\")\n",
|
||
"for category in sorted(categories):\n",
|
||
" print(f\"- {category}: {category_counts[category]} éléments\")\n",
|
||
"\n",
|
||
"# Afficher quelques exemples pour chaque catégorie\n",
|
||
"print(\"\\nExemples pour chaque catégorie:\")\n",
|
||
"examples = {}\n",
|
||
"\n",
|
||
"for doc in documents:\n",
|
||
" category = doc.metadata.get(\"category\", \"None\")\n",
|
||
" if category not in examples:\n",
|
||
" # Tronquer le contenu s'il est trop long\n",
|
||
" content = doc.page_content\n",
|
||
" if len(content) > 100:\n",
|
||
" content = content[:100] + \"...\"\n",
|
||
" examples[category] = content\n",
|
||
" print(f\"\\n{category}:\\n{content}\")\n",
|
||
" \n",
|
||
" # Arrêter une fois qu'on a un exemple de chaque catégorie\n",
|
||
" if len(examples) == len(categories):\n",
|
||
" break"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"Document(metadata={'source': 'F:\\\\Dev\\\\Rag\\\\Rag_Modeling\\\\document\\\\11_chapitre3.pdf', 'detection_class_prob': 0.8323268294334412, 'coordinates': {'points': ((201.26402282714844, 1886.039306640625), (201.26402282714844, 1919.756103515625), (620.4884033203125, 1919.756103515625), (620.4884033203125, 1886.039306640625)), 'system': 'PixelSpace', 'layout_width': 1653, 'layout_height': 2339}, 'last_modified': '2007-03-06T16:04:59', 'filetype': 'application/pdf', 'languages': ['eng'], 'page_number': 2, 'file_directory': 'F:\\\\Dev\\\\Rag\\\\Rag_Modeling\\\\document', 'filename': '11_chapitre3.pdf', 'category': 'ListItem', 'element_id': '3210454e1263ced051d55327eb9d5340'}, page_content=\"l'onde de condensation (4) ;\")"
|
||
]
|
||
},
|
||
"execution_count": 48,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"documents[15]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||
"from langchain_ollama.llms import OllamaLLM\n",
|
||
"from langchain_core.output_parsers import StrOutputParser\n",
|
||
"# Prompt\n",
|
||
"prompt_text = \"\"\"\n",
|
||
"You are an assistant tasked with summarizing tables and text.\n",
|
||
"Give a concise summary of the table or text.\n",
|
||
"\n",
|
||
"Respond only with the summary, no additionnal comment.\n",
|
||
"Do not start your message by saying \"Here is a summary\" or anything like that.\n",
|
||
"Just give the summary as it is. All summay will be in English\n",
|
||
"\n",
|
||
"Table or text chunk: {element}\n",
|
||
"\n",
|
||
"\"\"\"\n",
|
||
"prompt = ChatPromptTemplate.from_template(prompt_text)\n",
|
||
"\n",
|
||
"model = OllamaLLM(base_url=\"172.20.48.1:11434\",\n",
|
||
" model=\"llama3.2\")\n",
|
||
"summarize_chain = {\"element\": lambda x: x} | prompt | model | StrOutputParser()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from openai import OpenAI\n",
|
||
"openai_api_key = \"khodetmidonibalakhareh\"\n",
|
||
"openai_api_base = \"http://localhost:8000/v1\"\n",
|
||
"client = OpenAI(\n",
|
||
" api_key=openai_api_key,\n",
|
||
" base_url=openai_api_base,\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "APIConnectionError",
|
||
"evalue": "Connection error.",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mConnectError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:101\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m\n\u001b[32m 102\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:250\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m map_httpcore_exceptions():\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_pool\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 252\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(resp.stream, typing.Iterable)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:256\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 255\u001b[39m \u001b[38;5;28mself\u001b[39m._close_connections(closing)\n\u001b[32m--> \u001b[39m\u001b[32m256\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 258\u001b[39m \u001b[38;5;66;03m# Return the response. Note that in this case we still have to manage\u001b[39;00m\n\u001b[32m 259\u001b[39m \u001b[38;5;66;03m# the point at which the response is closed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:236\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 234\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 235\u001b[39m \u001b[38;5;66;03m# Send the request on the assigned connection.\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m236\u001b[39m response = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_request\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m ConnectionNotAvailable:\n\u001b[32m 240\u001b[39m \u001b[38;5;66;03m# In some cases a connection may initially be available to\u001b[39;00m\n\u001b[32m 241\u001b[39m \u001b[38;5;66;03m# handle a request, but then become unavailable.\u001b[39;00m\n\u001b[32m 242\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 243\u001b[39m \u001b[38;5;66;03m# In this case we clear the connection and try again.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:101\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28mself\u001b[39m._connect_failed = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[32m 103\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection.handle_request(request)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:78\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 77\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m78\u001b[39m stream = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_connect\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 80\u001b[39m ssl_object = stream.get_extra_info(\u001b[33m\"\u001b[39m\u001b[33mssl_object\u001b[39m\u001b[33m\"\u001b[39m)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:124\u001b[39m, in \u001b[36mHTTPConnection._connect\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 123\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m Trace(\u001b[33m\"\u001b[39m\u001b[33mconnect_tcp\u001b[39m\u001b[33m\"\u001b[39m, logger, request, kwargs) \u001b[38;5;28;01mas\u001b[39;00m trace:\n\u001b[32m--> \u001b[39m\u001b[32m124\u001b[39m stream = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_network_backend\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect_tcp\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 125\u001b[39m trace.return_value = stream\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_backends\\sync.py:207\u001b[39m, in \u001b[36mSyncBackend.connect_tcp\u001b[39m\u001b[34m(self, host, port, timeout, local_address, socket_options)\u001b[39m\n\u001b[32m 202\u001b[39m exc_map: ExceptionMapping = {\n\u001b[32m 203\u001b[39m socket.timeout: ConnectTimeout,\n\u001b[32m 204\u001b[39m \u001b[38;5;167;01mOSError\u001b[39;00m: ConnectError,\n\u001b[32m 205\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m207\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mwith\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmap_exceptions\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexc_map\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m \u001b[49m\u001b[43msock\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43msocket\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 209\u001b[39m \u001b[43m \u001b[49m\u001b[43maddress\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 210\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 211\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 212\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[38;5;28mself\u001b[39m.gen.throw(typ, value, traceback)\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_exceptions.py:14\u001b[39m, in \u001b[36mmap_exceptions\u001b[39m\u001b[34m(map)\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(exc, from_exc):\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m to_exc(exc) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m\n",
|
||
"\u001b[31mConnectError\u001b[39m: [WinError 10061] Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée",
|
||
"\nThe above exception was the direct cause of the following exception:\n",
|
||
"\u001b[31mConnectError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:955\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 954\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m955\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 956\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 957\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_should_stream_response_body\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 958\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 959\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 960\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m httpx.TimeoutException \u001b[38;5;28;01mas\u001b[39;00m err:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:914\u001b[39m, in \u001b[36mClient.send\u001b[39m\u001b[34m(self, request, stream, auth, follow_redirects)\u001b[39m\n\u001b[32m 912\u001b[39m auth = \u001b[38;5;28mself\u001b[39m._build_request_auth(request, auth)\n\u001b[32m--> \u001b[39m\u001b[32m914\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_handling_auth\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 915\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 916\u001b[39m \u001b[43m \u001b[49m\u001b[43mauth\u001b[49m\u001b[43m=\u001b[49m\u001b[43mauth\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 917\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 918\u001b[39m \u001b[43m \u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 919\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:942\u001b[39m, in \u001b[36mClient._send_handling_auth\u001b[39m\u001b[34m(self, request, auth, follow_redirects, history)\u001b[39m\n\u001b[32m 941\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m942\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_handling_redirects\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 943\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 944\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 945\u001b[39m \u001b[43m \u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 946\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 947\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:979\u001b[39m, in \u001b[36mClient._send_handling_redirects\u001b[39m\u001b[34m(self, request, follow_redirects, history)\u001b[39m\n\u001b[32m 977\u001b[39m hook(request)\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_single_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:1014\u001b[39m, in \u001b[36mClient._send_single_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 1013\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m request_context(request=request):\n\u001b[32m-> \u001b[39m\u001b[32m1014\u001b[39m response = \u001b[43mtransport\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1016\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(response.stream, SyncByteStream)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:249\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 237\u001b[39m req = httpcore.Request(\n\u001b[32m 238\u001b[39m method=request.method,\n\u001b[32m 239\u001b[39m url=httpcore.URL(\n\u001b[32m (...)\u001b[39m\u001b[32m 247\u001b[39m extensions=request.extensions,\n\u001b[32m 248\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m249\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mwith\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmap_httpcore_exceptions\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 250\u001b[39m \u001b[43m \u001b[49m\u001b[43mresp\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_pool\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[38;5;28mself\u001b[39m.gen.throw(typ, value, traceback)\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:118\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 117\u001b[39m message = \u001b[38;5;28mstr\u001b[39m(exc)\n\u001b[32m--> \u001b[39m\u001b[32m118\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m mapped_exc(message) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n",
|
||
"\u001b[31mConnectError\u001b[39m: [WinError 10061] Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée",
|
||
"\nThe above exception was the direct cause of the following exception:\n",
|
||
"\u001b[31mAPIConnectionError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m completion = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompletions\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mQwen/Qwen2.5-VL-3B-Instruct\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 2\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mSan Francisco is a\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 3\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33mCompletion result:\u001b[39m\u001b[33m\"\u001b[39m, completion)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_utils\\_utils.py:279\u001b[39m, in \u001b[36mrequired_args.<locals>.inner.<locals>.wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 277\u001b[39m msg = \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mMissing required argument: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mquote(missing[\u001b[32m0\u001b[39m])\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 278\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg)\n\u001b[32m--> \u001b[39m\u001b[32m279\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\resources\\completions.py:539\u001b[39m, in \u001b[36mCompletions.create\u001b[39m\u001b[34m(self, model, prompt, best_of, echo, frequency_penalty, logit_bias, logprobs, max_tokens, n, presence_penalty, seed, stop, stream, stream_options, suffix, temperature, top_p, user, extra_headers, extra_query, extra_body, timeout)\u001b[39m\n\u001b[32m 510\u001b[39m \u001b[38;5;129m@required_args\u001b[39m([\u001b[33m\"\u001b[39m\u001b[33mmodel\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mprompt\u001b[39m\u001b[33m\"\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mmodel\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mprompt\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstream\u001b[39m\u001b[33m\"\u001b[39m])\n\u001b[32m 511\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate\u001b[39m(\n\u001b[32m 512\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 537\u001b[39m timeout: \u001b[38;5;28mfloat\u001b[39m | httpx.Timeout | \u001b[38;5;28;01mNone\u001b[39;00m | NotGiven = NOT_GIVEN,\n\u001b[32m 538\u001b[39m ) -> Completion | Stream[Completion]:\n\u001b[32m--> \u001b[39m\u001b[32m539\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_post\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 540\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/completions\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 541\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmaybe_transform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 542\u001b[39m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[32m 543\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmodel\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 544\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mprompt\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 545\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mbest_of\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mbest_of\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 546\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mecho\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mecho\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 547\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mfrequency_penalty\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 548\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlogit_bias\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogit_bias\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 549\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlogprobs\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 550\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_tokens\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 551\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mn\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 552\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mpresence_penalty\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mpresence_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 553\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mseed\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 554\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstop\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 555\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 556\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream_options\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 557\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43msuffix\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43msuffix\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 558\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtemperature\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 559\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_p\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_p\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 560\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43muser\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43muser\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 561\u001b[39m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 562\u001b[39m \u001b[43m \u001b[49m\u001b[43mcompletion_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mCompletionCreateParams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 563\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 564\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmake_request_options\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 565\u001b[39m \u001b[43m \u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\n\u001b[32m 566\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 567\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mCompletion\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 568\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 569\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mStream\u001b[49m\u001b[43m[\u001b[49m\u001b[43mCompletion\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 570\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1242\u001b[39m, in \u001b[36mSyncAPIClient.post\u001b[39m\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\u001b[39m\n\u001b[32m 1228\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mpost\u001b[39m(\n\u001b[32m 1229\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1230\u001b[39m path: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1237\u001b[39m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 1238\u001b[39m ) -> ResponseT | _StreamT:\n\u001b[32m 1239\u001b[39m opts = FinalRequestOptions.construct(\n\u001b[32m 1240\u001b[39m method=\u001b[33m\"\u001b[39m\u001b[33mpost\u001b[39m\u001b[33m\"\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\n\u001b[32m 1241\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m1242\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m)\u001b[49m)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:919\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001b[39m\n\u001b[32m 916\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 917\u001b[39m retries_taken = \u001b[32m0\u001b[39m\n\u001b[32m--> \u001b[39m\u001b[32m919\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 921\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 922\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 923\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 924\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 925\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:979\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 976\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mEncountered Exception\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 978\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m remaining_retries > \u001b[32m0\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_retry_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[43m \u001b[49m\u001b[43minput_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 981\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 982\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 983\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 984\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 985\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 986\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1057\u001b[39m, in \u001b[36mSyncAPIClient._retry_request\u001b[39m\u001b[34m(self, options, cast_to, retries_taken, response_headers, stream, stream_cls)\u001b[39m\n\u001b[32m 1053\u001b[39m \u001b[38;5;66;03m# In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a\u001b[39;00m\n\u001b[32m 1054\u001b[39m \u001b[38;5;66;03m# different thread if necessary.\u001b[39;00m\n\u001b[32m 1055\u001b[39m time.sleep(timeout)\n\u001b[32m-> \u001b[39m\u001b[32m1057\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1058\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1059\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m \u001b[49m\u001b[43m+\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1061\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1062\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1063\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:979\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 976\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mEncountered Exception\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 978\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m remaining_retries > \u001b[32m0\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_retry_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[43m \u001b[49m\u001b[43minput_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 981\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 982\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 983\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 984\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 985\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 986\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1057\u001b[39m, in \u001b[36mSyncAPIClient._retry_request\u001b[39m\u001b[34m(self, options, cast_to, retries_taken, response_headers, stream, stream_cls)\u001b[39m\n\u001b[32m 1053\u001b[39m \u001b[38;5;66;03m# In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a\u001b[39;00m\n\u001b[32m 1054\u001b[39m \u001b[38;5;66;03m# different thread if necessary.\u001b[39;00m\n\u001b[32m 1055\u001b[39m time.sleep(timeout)\n\u001b[32m-> \u001b[39m\u001b[32m1057\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1058\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1059\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m \u001b[49m\u001b[43m+\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1061\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1062\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1063\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:989\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._retry_request(\n\u001b[32m 980\u001b[39m input_options,\n\u001b[32m 981\u001b[39m cast_to,\n\u001b[32m (...)\u001b[39m\u001b[32m 985\u001b[39m response_headers=\u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 986\u001b[39m )\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n\u001b[32m 991\u001b[39m log.debug(\n\u001b[32m 992\u001b[39m \u001b[33m'\u001b[39m\u001b[33mHTTP Response: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m \u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m%i\u001b[39;00m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m'\u001b[39m,\n\u001b[32m 993\u001b[39m request.method,\n\u001b[32m (...)\u001b[39m\u001b[32m 997\u001b[39m response.headers,\n\u001b[32m 998\u001b[39m )\n\u001b[32m 999\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mrequest_id: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, response.headers.get(\u001b[33m\"\u001b[39m\u001b[33mx-request-id\u001b[39m\u001b[33m\"\u001b[39m))\n",
|
||
"\u001b[31mAPIConnectionError\u001b[39m: Connection error."
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"completion = client.completions.create(model=\"Qwen/Qwen2.5-VL-3B-Instruct\",\n",
|
||
" prompt=\"San Francisco is a\")\n",
|
||
"print(\"Completion result:\", completion)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "APIConnectionError",
|
||
"evalue": "Connection error.",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||
"\u001b[31mConnectError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:101\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m\n\u001b[32m 102\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:250\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m map_httpcore_exceptions():\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_pool\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 252\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(resp.stream, typing.Iterable)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:256\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 255\u001b[39m \u001b[38;5;28mself\u001b[39m._close_connections(closing)\n\u001b[32m--> \u001b[39m\u001b[32m256\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 258\u001b[39m \u001b[38;5;66;03m# Return the response. Note that in this case we still have to manage\u001b[39;00m\n\u001b[32m 259\u001b[39m \u001b[38;5;66;03m# the point at which the response is closed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:236\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 234\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 235\u001b[39m \u001b[38;5;66;03m# Send the request on the assigned connection.\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m236\u001b[39m response = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_request\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m ConnectionNotAvailable:\n\u001b[32m 240\u001b[39m \u001b[38;5;66;03m# In some cases a connection may initially be available to\u001b[39;00m\n\u001b[32m 241\u001b[39m \u001b[38;5;66;03m# handle a request, but then become unavailable.\u001b[39;00m\n\u001b[32m 242\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 243\u001b[39m \u001b[38;5;66;03m# In this case we clear the connection and try again.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:101\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28mself\u001b[39m._connect_failed = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[32m 103\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection.handle_request(request)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:78\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 77\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m78\u001b[39m stream = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_connect\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 80\u001b[39m ssl_object = stream.get_extra_info(\u001b[33m\"\u001b[39m\u001b[33mssl_object\u001b[39m\u001b[33m\"\u001b[39m)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_sync\\connection.py:124\u001b[39m, in \u001b[36mHTTPConnection._connect\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 123\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m Trace(\u001b[33m\"\u001b[39m\u001b[33mconnect_tcp\u001b[39m\u001b[33m\"\u001b[39m, logger, request, kwargs) \u001b[38;5;28;01mas\u001b[39;00m trace:\n\u001b[32m--> \u001b[39m\u001b[32m124\u001b[39m stream = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_network_backend\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect_tcp\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 125\u001b[39m trace.return_value = stream\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_backends\\sync.py:207\u001b[39m, in \u001b[36mSyncBackend.connect_tcp\u001b[39m\u001b[34m(self, host, port, timeout, local_address, socket_options)\u001b[39m\n\u001b[32m 202\u001b[39m exc_map: ExceptionMapping = {\n\u001b[32m 203\u001b[39m socket.timeout: ConnectTimeout,\n\u001b[32m 204\u001b[39m \u001b[38;5;167;01mOSError\u001b[39;00m: ConnectError,\n\u001b[32m 205\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m207\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mwith\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmap_exceptions\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexc_map\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m \u001b[49m\u001b[43msock\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43msocket\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 209\u001b[39m \u001b[43m \u001b[49m\u001b[43maddress\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 210\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 211\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 212\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[38;5;28mself\u001b[39m.gen.throw(typ, value, traceback)\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpcore\\_exceptions.py:14\u001b[39m, in \u001b[36mmap_exceptions\u001b[39m\u001b[34m(map)\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(exc, from_exc):\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m to_exc(exc) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m\n",
|
||
"\u001b[31mConnectError\u001b[39m: [WinError 10061] Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée",
|
||
"\nThe above exception was the direct cause of the following exception:\n",
|
||
"\u001b[31mConnectError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:955\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 954\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m955\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 956\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 957\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_should_stream_response_body\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 958\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 959\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 960\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m httpx.TimeoutException \u001b[38;5;28;01mas\u001b[39;00m err:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:914\u001b[39m, in \u001b[36mClient.send\u001b[39m\u001b[34m(self, request, stream, auth, follow_redirects)\u001b[39m\n\u001b[32m 912\u001b[39m auth = \u001b[38;5;28mself\u001b[39m._build_request_auth(request, auth)\n\u001b[32m--> \u001b[39m\u001b[32m914\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_handling_auth\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 915\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 916\u001b[39m \u001b[43m \u001b[49m\u001b[43mauth\u001b[49m\u001b[43m=\u001b[49m\u001b[43mauth\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 917\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 918\u001b[39m \u001b[43m \u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 919\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:942\u001b[39m, in \u001b[36mClient._send_handling_auth\u001b[39m\u001b[34m(self, request, auth, follow_redirects, history)\u001b[39m\n\u001b[32m 941\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m942\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_handling_redirects\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 943\u001b[39m \u001b[43m \u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 944\u001b[39m \u001b[43m \u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mfollow_redirects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 945\u001b[39m \u001b[43m \u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhistory\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 946\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 947\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:979\u001b[39m, in \u001b[36mClient._send_handling_redirects\u001b[39m\u001b[34m(self, request, follow_redirects, history)\u001b[39m\n\u001b[32m 977\u001b[39m hook(request)\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_single_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_client.py:1014\u001b[39m, in \u001b[36mClient._send_single_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 1013\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m request_context(request=request):\n\u001b[32m-> \u001b[39m\u001b[32m1014\u001b[39m response = \u001b[43mtransport\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1016\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(response.stream, SyncByteStream)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:249\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 237\u001b[39m req = httpcore.Request(\n\u001b[32m 238\u001b[39m method=request.method,\n\u001b[32m 239\u001b[39m url=httpcore.URL(\n\u001b[32m (...)\u001b[39m\u001b[32m 247\u001b[39m extensions=request.extensions,\n\u001b[32m 248\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m249\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mwith\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmap_httpcore_exceptions\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 250\u001b[39m \u001b[43m \u001b[49m\u001b[43mresp\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_pool\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreq\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[38;5;28mself\u001b[39m.gen.throw(typ, value, traceback)\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\httpx\\_transports\\default.py:118\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 117\u001b[39m message = \u001b[38;5;28mstr\u001b[39m(exc)\n\u001b[32m--> \u001b[39m\u001b[32m118\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m mapped_exc(message) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n",
|
||
"\u001b[31mConnectError\u001b[39m: [WinError 10061] Aucune connexion n’a pu être établie car l’ordinateur cible l’a expressément refusée",
|
||
"\nThe above exception was the direct cause of the following exception:\n",
|
||
"\u001b[31mAPIConnectionError\u001b[39m Traceback (most recent call last)",
|
||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 27\u001b[39m\n\u001b[32m 21\u001b[39m prompt = ChatPromptTemplate.from_messages(messages)\n\u001b[32m 23\u001b[39m chain = prompt | ChatOpenAI(api_key=openai_api_key,\n\u001b[32m 24\u001b[39m base_url=openai_api_base,model=\u001b[33m\"\u001b[39m\u001b[33mHuggingFaceM4/Idefics3-8B-Llama3\u001b[39m\u001b[33m\"\u001b[39m) | StrOutputParser()\n\u001b[32m---> \u001b[39m\u001b[32m27\u001b[39m image_summaries = \u001b[43mchain\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbatch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimages_with_caption\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\runnables\\base.py:3175\u001b[39m, in \u001b[36mRunnableSequence.batch\u001b[39m\u001b[34m(self, inputs, config, return_exceptions, **kwargs)\u001b[39m\n\u001b[32m 3173\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 3174\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i, step \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(\u001b[38;5;28mself\u001b[39m.steps):\n\u001b[32m-> \u001b[39m\u001b[32m3175\u001b[39m inputs = \u001b[43mstep\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbatch\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 3176\u001b[39m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3177\u001b[39m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\n\u001b[32m 3178\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# each step a child run of the corresponding root run\u001b[39;49;00m\n\u001b[32m 3179\u001b[39m \u001b[43m \u001b[49m\u001b[43mpatch_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 3180\u001b[39m \u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43mf\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mseq:step:\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[43m+\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[32;43m1\u001b[39;49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 3181\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3182\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mzip\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfigs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3183\u001b[39m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3184\u001b[39m \u001b[43m \u001b[49m\u001b[43mreturn_exceptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43mreturn_exceptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3185\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3186\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3188\u001b[39m \u001b[38;5;66;03m# finish the root runs\u001b[39;00m\n\u001b[32m 3189\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\runnables\\base.py:789\u001b[39m, in \u001b[36mRunnable.batch\u001b[39m\u001b[34m(self, inputs, config, return_exceptions, **kwargs)\u001b[39m\n\u001b[32m 786\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\u001b[38;5;28mlist\u001b[39m[Output], [invoke(inputs[\u001b[32m0\u001b[39m], configs[\u001b[32m0\u001b[39m])])\n\u001b[32m 788\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m get_executor_for_config(configs[\u001b[32m0\u001b[39m]) \u001b[38;5;28;01mas\u001b[39;00m executor:\n\u001b[32m--> \u001b[39m\u001b[32m789\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\u001b[38;5;28mlist\u001b[39m[Output], \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mexecutor\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmap\u001b[49m\u001b[43m(\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfigs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\concurrent\\futures\\_base.py:619\u001b[39m, in \u001b[36mExecutor.map.<locals>.result_iterator\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 616\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m fs:\n\u001b[32m 617\u001b[39m \u001b[38;5;66;03m# Careful not to keep a reference to the popped future\u001b[39;00m\n\u001b[32m 618\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m619\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m \u001b[43m_result_or_cancel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 620\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 621\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m _result_or_cancel(fs.pop(), end_time - time.monotonic())\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\concurrent\\futures\\_base.py:317\u001b[39m, in \u001b[36m_result_or_cancel\u001b[39m\u001b[34m(***failed resolving arguments***)\u001b[39m\n\u001b[32m 315\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 316\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m317\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfut\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 318\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 319\u001b[39m fut.cancel()\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\concurrent\\futures\\_base.py:456\u001b[39m, in \u001b[36mFuture.result\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 454\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[32m 455\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state == FINISHED:\n\u001b[32m--> \u001b[39m\u001b[32m456\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m__get_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 457\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 458\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTimeoutError\u001b[39;00m()\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\concurrent\\futures\\_base.py:401\u001b[39m, in \u001b[36mFuture.__get_result\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 399\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception:\n\u001b[32m 400\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m401\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception\n\u001b[32m 402\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 403\u001b[39m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[32m 404\u001b[39m \u001b[38;5;28mself\u001b[39m = \u001b[38;5;28;01mNone\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32m~\\AppData\\Roaming\\uv\\python\\cpython-3.11.11-windows-x86_64-none\\Lib\\concurrent\\futures\\thread.py:58\u001b[39m, in \u001b[36m_WorkItem.run\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 55\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m58\u001b[39m result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 59\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 60\u001b[39m \u001b[38;5;28mself\u001b[39m.future.set_exception(exc)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\runnables\\config.py:527\u001b[39m, in \u001b[36mContextThreadPoolExecutor.map.<locals>._wrapped_fn\u001b[39m\u001b[34m(*args)\u001b[39m\n\u001b[32m 526\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_wrapped_fn\u001b[39m(*args: Any) -> T:\n\u001b[32m--> \u001b[39m\u001b[32m527\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcontexts\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\runnables\\base.py:782\u001b[39m, in \u001b[36mRunnable.batch.<locals>.invoke\u001b[39m\u001b[34m(input, config)\u001b[39m\n\u001b[32m 780\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m e\n\u001b[32m 781\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m782\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:307\u001b[39m, in \u001b[36mBaseChatModel.invoke\u001b[39m\u001b[34m(self, input, config, stop, **kwargs)\u001b[39m\n\u001b[32m 296\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 297\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 298\u001b[39m \u001b[38;5;28minput\u001b[39m: LanguageModelInput,\n\u001b[32m (...)\u001b[39m\u001b[32m 302\u001b[39m **kwargs: Any,\n\u001b[32m 303\u001b[39m ) -> BaseMessage:\n\u001b[32m 304\u001b[39m config = ensure_config(config)\n\u001b[32m 305\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\n\u001b[32m 306\u001b[39m ChatGeneration,\n\u001b[32m--> \u001b[39m\u001b[32m307\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mgenerate_prompt\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 308\u001b[39m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_convert_input\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 309\u001b[39m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 310\u001b[39m \u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcallbacks\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 311\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtags\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 312\u001b[39m \u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmetadata\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 313\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrun_name\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 314\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrun_id\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 315\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 316\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m.generations[\u001b[32m0\u001b[39m][\u001b[32m0\u001b[39m],\n\u001b[32m 317\u001b[39m ).message\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:837\u001b[39m, in \u001b[36mBaseChatModel.generate_prompt\u001b[39m\u001b[34m(self, prompts, stop, callbacks, **kwargs)\u001b[39m\n\u001b[32m 829\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mgenerate_prompt\u001b[39m(\n\u001b[32m 830\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 831\u001b[39m prompts: \u001b[38;5;28mlist\u001b[39m[PromptValue],\n\u001b[32m (...)\u001b[39m\u001b[32m 834\u001b[39m **kwargs: Any,\n\u001b[32m 835\u001b[39m ) -> LLMResult:\n\u001b[32m 836\u001b[39m prompt_messages = [p.to_messages() \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m prompts]\n\u001b[32m--> \u001b[39m\u001b[32m837\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprompt_messages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:679\u001b[39m, in \u001b[36mBaseChatModel.generate\u001b[39m\u001b[34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[39m\n\u001b[32m 676\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i, m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(messages):\n\u001b[32m 677\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 678\u001b[39m results.append(\n\u001b[32m--> \u001b[39m\u001b[32m679\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_generate_with_cache\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 680\u001b[39m \u001b[43m \u001b[49m\u001b[43mm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 681\u001b[39m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 682\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 683\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 684\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 685\u001b[39m )\n\u001b[32m 686\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 687\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:902\u001b[39m, in \u001b[36mBaseChatModel._generate_with_cache\u001b[39m\u001b[34m(self, messages, stop, run_manager, **kwargs)\u001b[39m\n\u001b[32m 900\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 901\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m inspect.signature(\u001b[38;5;28mself\u001b[39m._generate).parameters.get(\u001b[33m\"\u001b[39m\u001b[33mrun_manager\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m--> \u001b[39m\u001b[32m902\u001b[39m result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_generate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 903\u001b[39m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\n\u001b[32m 904\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 905\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 906\u001b[39m result = \u001b[38;5;28mself\u001b[39m._generate(messages, stop=stop, **kwargs)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\langchain_openai\\chat_models\\base.py:823\u001b[39m, in \u001b[36mBaseChatOpenAI._generate\u001b[39m\u001b[34m(self, messages, stop, run_manager, **kwargs)\u001b[39m\n\u001b[32m 821\u001b[39m generation_info = {\u001b[33m\"\u001b[39m\u001b[33mheaders\u001b[39m\u001b[33m\"\u001b[39m: \u001b[38;5;28mdict\u001b[39m(raw_response.headers)}\n\u001b[32m 822\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m823\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mpayload\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 824\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._create_chat_result(response, generation_info)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_utils\\_utils.py:279\u001b[39m, in \u001b[36mrequired_args.<locals>.inner.<locals>.wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 277\u001b[39m msg = \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mMissing required argument: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mquote(missing[\u001b[32m0\u001b[39m])\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 278\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg)\n\u001b[32m--> \u001b[39m\u001b[32m279\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\resources\\chat\\completions\\completions.py:879\u001b[39m, in \u001b[36mCompletions.create\u001b[39m\u001b[34m(self, messages, model, audio, frequency_penalty, function_call, functions, logit_bias, logprobs, max_completion_tokens, max_tokens, metadata, modalities, n, parallel_tool_calls, prediction, presence_penalty, reasoning_effort, response_format, seed, service_tier, stop, store, stream, stream_options, temperature, tool_choice, tools, top_logprobs, top_p, user, extra_headers, extra_query, extra_body, timeout)\u001b[39m\n\u001b[32m 837\u001b[39m \u001b[38;5;129m@required_args\u001b[39m([\u001b[33m\"\u001b[39m\u001b[33mmessages\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mmodel\u001b[39m\u001b[33m\"\u001b[39m], [\u001b[33m\"\u001b[39m\u001b[33mmessages\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mmodel\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mstream\u001b[39m\u001b[33m\"\u001b[39m])\n\u001b[32m 838\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate\u001b[39m(\n\u001b[32m 839\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 876\u001b[39m timeout: \u001b[38;5;28mfloat\u001b[39m | httpx.Timeout | \u001b[38;5;28;01mNone\u001b[39;00m | NotGiven = NOT_GIVEN,\n\u001b[32m 877\u001b[39m ) -> ChatCompletion | Stream[ChatCompletionChunk]:\n\u001b[32m 878\u001b[39m validate_response_format(response_format)\n\u001b[32m--> \u001b[39m\u001b[32m879\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_post\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/chat/completions\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmaybe_transform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmessages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmodel\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43maudio\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43maudio\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mfrequency_penalty\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mfunction_call\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfunction_call\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 888\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mfunctions\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfunctions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlogit_bias\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogit_bias\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 890\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlogprobs\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 891\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_completion_tokens\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_completion_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 892\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_tokens\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 893\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmetadata\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 894\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmodalities\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodalities\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 895\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mn\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 896\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mparallel_tool_calls\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mparallel_tool_calls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 897\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mprediction\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mprediction\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 898\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mpresence_penalty\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mpresence_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 899\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mreasoning_effort\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mreasoning_effort\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 900\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mresponse_format\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mresponse_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 901\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mseed\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 902\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mservice_tier\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mservice_tier\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 903\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstop\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 904\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstore\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstore\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 905\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 906\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream_options\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 907\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtemperature\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 908\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtool_choice\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtool_choice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 909\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtools\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtools\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 910\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_logprobs\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_logprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 911\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_p\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_p\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 912\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43muser\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43muser\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 913\u001b[39m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 914\u001b[39m \u001b[43m \u001b[49m\u001b[43mcompletion_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mCompletionCreateParams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 915\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 916\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmake_request_options\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 917\u001b[39m \u001b[43m \u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\n\u001b[32m 918\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 919\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mChatCompletion\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 921\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mStream\u001b[49m\u001b[43m[\u001b[49m\u001b[43mChatCompletionChunk\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 922\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1242\u001b[39m, in \u001b[36mSyncAPIClient.post\u001b[39m\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\u001b[39m\n\u001b[32m 1228\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mpost\u001b[39m(\n\u001b[32m 1229\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1230\u001b[39m path: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1237\u001b[39m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 1238\u001b[39m ) -> ResponseT | _StreamT:\n\u001b[32m 1239\u001b[39m opts = FinalRequestOptions.construct(\n\u001b[32m 1240\u001b[39m method=\u001b[33m\"\u001b[39m\u001b[33mpost\u001b[39m\u001b[33m\"\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\n\u001b[32m 1241\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m1242\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m)\u001b[49m)\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:919\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001b[39m\n\u001b[32m 916\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 917\u001b[39m retries_taken = \u001b[32m0\u001b[39m\n\u001b[32m--> \u001b[39m\u001b[32m919\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 920\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 921\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 922\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 923\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 924\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 925\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:979\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 976\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mEncountered Exception\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 978\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m remaining_retries > \u001b[32m0\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_retry_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[43m \u001b[49m\u001b[43minput_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 981\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 982\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 983\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 984\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 985\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 986\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1057\u001b[39m, in \u001b[36mSyncAPIClient._retry_request\u001b[39m\u001b[34m(self, options, cast_to, retries_taken, response_headers, stream, stream_cls)\u001b[39m\n\u001b[32m 1053\u001b[39m \u001b[38;5;66;03m# In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a\u001b[39;00m\n\u001b[32m 1054\u001b[39m \u001b[38;5;66;03m# different thread if necessary.\u001b[39;00m\n\u001b[32m 1055\u001b[39m time.sleep(timeout)\n\u001b[32m-> \u001b[39m\u001b[32m1057\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1058\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1059\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m \u001b[49m\u001b[43m+\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1061\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1062\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1063\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:979\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 976\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mEncountered Exception\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 978\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m remaining_retries > \u001b[32m0\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_retry_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 980\u001b[39m \u001b[43m \u001b[49m\u001b[43minput_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 981\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 982\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 983\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 984\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 985\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 986\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:1057\u001b[39m, in \u001b[36mSyncAPIClient._retry_request\u001b[39m\u001b[34m(self, options, cast_to, retries_taken, response_headers, stream, stream_cls)\u001b[39m\n\u001b[32m 1053\u001b[39m \u001b[38;5;66;03m# In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a\u001b[39;00m\n\u001b[32m 1054\u001b[39m \u001b[38;5;66;03m# different thread if necessary.\u001b[39;00m\n\u001b[32m 1055\u001b[39m time.sleep(timeout)\n\u001b[32m-> \u001b[39m\u001b[32m1057\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1058\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1059\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries_taken\u001b[49m\u001b[43m \u001b[49m\u001b[43m+\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 1061\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1062\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1063\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
|
||
"\u001b[36mFile \u001b[39m\u001b[32mf:\\Dev\\Rag\\chat_bot_rag\\.venv\\Lib\\site-packages\\openai\\_base_client.py:989\u001b[39m, in \u001b[36mSyncAPIClient._request\u001b[39m\u001b[34m(self, cast_to, options, retries_taken, stream, stream_cls)\u001b[39m\n\u001b[32m 979\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._retry_request(\n\u001b[32m 980\u001b[39m input_options,\n\u001b[32m 981\u001b[39m cast_to,\n\u001b[32m (...)\u001b[39m\u001b[32m 985\u001b[39m response_headers=\u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 986\u001b[39m )\n\u001b[32m 988\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising connection error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m989\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APIConnectionError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n\u001b[32m 991\u001b[39m log.debug(\n\u001b[32m 992\u001b[39m \u001b[33m'\u001b[39m\u001b[33mHTTP Response: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m \u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m%i\u001b[39;00m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m\u001b[33m \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m'\u001b[39m,\n\u001b[32m 993\u001b[39m request.method,\n\u001b[32m (...)\u001b[39m\u001b[32m 997\u001b[39m response.headers,\n\u001b[32m 998\u001b[39m )\n\u001b[32m 999\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mrequest_id: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, response.headers.get(\u001b[33m\"\u001b[39m\u001b[33mx-request-id\u001b[39m\u001b[33m\"\u001b[39m))\n",
|
||
"\u001b[31mAPIConnectionError\u001b[39m: Connection error."
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"from langchain_openai import ChatOpenAI\n",
|
||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||
"from langchain_core.output_parsers import StrOutputParser\n",
|
||
"\n",
|
||
"prompt_template = \"\"\"Describe the image in detail. For context,\n",
|
||
" the image is part of a research paper explaining the transformers\n",
|
||
" architecture. Be specific about graphs, such as bar plots.\"\"\"\n",
|
||
"messages = [\n",
|
||
" (\n",
|
||
" \"user\",\n",
|
||
" [\n",
|
||
" {\"type\": \"text\", \"text\": prompt_template},\n",
|
||
" {\n",
|
||
" \"type\": \"image_url\",\n",
|
||
" \"image_url\": {\"url\": \"data:image/jpeg;base64,{image_base64}\"},\n",
|
||
" },\n",
|
||
" ],\n",
|
||
" )\n",
|
||
"]\n",
|
||
"\n",
|
||
"prompt = ChatPromptTemplate.from_messages(messages)\n",
|
||
"\n",
|
||
"chain = prompt | ChatOpenAI(api_key=openai_api_key,\n",
|
||
" base_url=openai_api_base,model=\"HuggingFaceM4/Idefics3-8B-Llama3\") | StrOutputParser()\n",
|
||
"\n",
|
||
"\n",
|
||
"image_summaries = chain.batch(images_with_caption)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": ".venv",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"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.11"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|