import json
from llama_index.core.service_context_elements.llm_predictor import LLMPredictor
from llama_index.core.utilities.sql_wrapper import SQLDatabase
from llama_index.core.response_synthesizers import get_response_synthesizer
from llama_index.embeddings.langchain import LangchainEmbedding
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SimilarityPostprocessor
from llama_index.core.prompts import PromptTemplate
from llama_index.core.chat_engine import CondensePlusContextChatEngine, ContextChatEngine
from llama_index.core.indices.struct_store.sql_query import NLSQLTableQueryEngine
from llama_index.core.schema import ImageDocument
from llama_index.core.base.llms.types import ChatMessage
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.postprocessor.colbert_rerank import ColbertRerank
from llama_index.core.tools import ToolMetadata
from llama_index.core.selectors import LLMSingleSelector

from langchain.agents import initialize_agent
import ollama
from sqlalchemy import create_engine
from app.llms.tools.dalle import DalleImage
from app.llms.tools.describeimage import DescribeImage
from app.llms.tools.instantid import InstantID
from app.llms.tools.stablediffusion import StableDiffusionImage
from app.model import Model

from app.models import LLMModel, ProjectModel, QuestionModel, ChatModel
from app.project import Project
from app.tools import getLLMClass
from app.vectordb import vector_init
from modules.embeddings import EMBEDDINGS
from app.database import dbc
from sqlalchemy.orm import Session
from langchain_community.chat_models import ChatOpenAI

from transformers import pipeline


class Brain:
    def __init__(self):
        self.llmCache = {}
        self.embeddingCache = {}
        self.defaultCensorship = "This question is outside of my scope. Didn't find any related data."
        self.defaultNegative = "I'm sorry, I don't know the answer to that."
        self.defaultSystem = ""
        self.loopFailsafe = 0

    def memoryModelsInfo(self):
        models = []
        for llmr, mr in self.llmCache.items():
            if mr.privacy == "private":
                models.append(llmr)
        return models

    def getLLM(self, llmName, db: Session, **kwargs):      
        llm = None
      
        if llmName in self.llmCache:
            llm = self.llmCache[llmName]
        else:
            llm = self.loadLLM(llmName, db)
        
        if llm.props.class_name == "Ollama":
            model_name = json.loads(llm.props.options).get("model")
            try:
                ollama.show(model_name)
            except Exception as e:
              if e.status_code == 404:
                  print("Model not found, pulling " + model_name + " from Ollama")
                  ollama.pull(model_name)
              else:
                  raise e
        
        return llm
    
    def loadLLM(self, llmName, db: Session):
        llm_db = dbc.get_llm_by_name(db, llmName)

        if llm_db is not None:
            llmm = LLMModel.model_validate(llm_db)

            llm = getLLMClass(llmm.class_name)(**json.loads(llmm.options))

            if llmName in self.llmCache:
                del self.llmCache[llmName]
            self.llmCache[llmName] = Model(llmName, llmm, llm)
            return self.llmCache[llmName]
        else:
            return None

    def getEmbedding(self, embeddingModel):
        if embeddingModel in self.embeddingCache:
            return self.embeddingCache[embeddingModel]
        else:
            if embeddingModel in EMBEDDINGS:
                embedding_class, embedding_args, privacy, description = EMBEDDINGS[embeddingModel]
                model = LangchainEmbedding(embedding_class(**embedding_args))
                self.embeddingCache[embeddingModel] = model
                return model
            else:
                raise Exception("Invalid Embedding type.")
              
    def findProject(self, name, db):
        p = dbc.get_project_by_name(db, name)
        if p is None:
            return None
        proj = ProjectModel.model_validate(p)
        if proj is not None:
            project = Project()
            project.model = proj
            if project.model.type == "rag":
                project.db = vector_init(self, project)
            return project

    def entryChat(self, projectName: str, chatModel: ChatModel, db: Session):
        project = self.findProject(projectName, db)

        model = self.getLLM(project.model.llm, db)
        chat = project.loadChat(chatModel)

        threshold = chatModel.score or project.model.score or 0.2
        k = chatModel.k or project.model.k or 1

        sysTemplate = project.model.system or self.defaultSystem
        
        if project.model.colbert_rerank or project.model.llm_rerank:
            final_k = k * 2
        else:
            final_k = k

        retriever = VectorIndexRetriever(
            index=project.db,
            similarity_top_k=final_k,
        )

        postprocessors = []

        if project.model.colbert_rerank:
            postprocessors.append(ColbertRerank(
                top_n=k,
                model="colbert-ir/colbertv2.0",
                tokenizer="colbert-ir/colbertv2.0",
                keep_retrieval_score=True,
            ))

        if project.model.llm_rerank:
            postprocessors.append(LLMRerank(
                choice_batch_size=k,
                top_n=k,
                llm=model.llm,
            ))
            
        postprocessors.append(SimilarityPostprocessor(similarity_cutoff=threshold))

        chat_engine = ContextChatEngine.from_defaults(
            retriever=retriever,
            system_prompt=sysTemplate,
            memory=chat.history,
            node_postprocessors=postprocessors,
        )
        chat_engine._llm = model.llm

        try:
            if chatModel.stream:
                response = chat_engine.stream_chat(chatModel.question)
            else:
                response = chat_engine.chat(chatModel.question)

            output_nodes = []
            for node in response.source_nodes:
                output_nodes.append(
                    {"source": node.metadata["source"], "keywords": node.metadata["keywords"], "score": node.score, "id": node.node_id, "text": node.text})

            output = {
                "id": chat.id,
                "question": chatModel.question,
                "sources": output_nodes,
                "type": "chat"
            }

            if chatModel.stream:
                if hasattr(response, "response_gen"): 
                    for text in response.response_gen:
                        yield "data: " + text + "\n\n"
                    yield "data: " + json.dumps(output) + "\n"
                    yield "event: close\n\n"
                else:
                    yield "data: " + self.defaultCensorship + "\n\n"
                    yield "data: " + json.dumps(output) + "\n"
                    yield "event: close\n\n"
            else:  
                if len(response.source_nodes) == 0:
                    output["answer"] = project.model.censorship or self.defaultCensorship
                else:
                    output["answer"] = response.response

                yield output
        except Exception as e:              
            if chatModel.stream:
                yield "data: Inference failed\n"
                yield "event: error\n\n"
            raise e


    def entryQuestion(self, projectName: str, questionModel: QuestionModel, db: Session):
        project = self.findProject(projectName, db)

        model = self.getLLM(project.model.llm, db)

        sysTemplate = questionModel.system or project.model.system or self.defaultSystem

        k = questionModel.k or project.model.k or 2
        threshold = questionModel.score or project.model.score or 0.2

        if questionModel.colbert_rerank or questionModel.llm_rerank or project.model.colbert_rerank or project.model.llm_rerank:
            final_k = k * 2
        else:
            final_k = k

        retriever = VectorIndexRetriever(
            index=project.db,
            similarity_top_k=final_k,
        )

        qa_prompt_tmpl = (
            "Context information is below.\n"
            "---------------------\n"
            "{context_str}\n"
            "---------------------\n"
            "Given the context information and not prior knowledge, "
            "answer the query.\n"
            "Query: {query_str}\n"
            "Answer: "
        )

        qa_prompt = PromptTemplate(qa_prompt_tmpl)

        llm_predictor = LLMPredictor(llm=model.llm, system_prompt=sysTemplate)

        response_synthesizer = get_response_synthesizer(llm=llm_predictor, text_qa_template=qa_prompt, streaming=questionModel.stream)

        postprocessors = []

        if questionModel.colbert_rerank or project.model.colbert_rerank:
            postprocessors.append(ColbertRerank(
                top_n=k,
                model="colbert-ir/colbertv2.0",
                tokenizer="colbert-ir/colbertv2.0",
                keep_retrieval_score=True,
            ))

        if questionModel.llm_rerank or project.model.llm_rerank:
            postprocessors.append(LLMRerank(
                choice_batch_size=k,
                top_n=k,
                llm=model.llm,
            ))
            
        postprocessors.append(SimilarityPostprocessor(similarity_cutoff=threshold))

        query_engine = RetrieverQueryEngine(
            retriever=retriever,
            response_synthesizer=response_synthesizer,
            node_postprocessors=postprocessors
        )

        try:
            response = query_engine.query(questionModel.question)

            output_nodes = []
            if hasattr(response, "source_nodes"): 
                for node in response.source_nodes:
                    output_nodes.append(
                        {"source": node.metadata["source"], "keywords": node.metadata["keywords"], "score": node.score, "id": node.node_id, "text": node.text})
                    
            output = {
                "question": questionModel.question,
                "sources": output_nodes,
                "type": "question"
            }

            if questionModel.stream:
                if hasattr(response, "response_gen"): 
                    for text in response.response_gen:
                        yield "data: " + text + "\n\n"
                    yield "data: " + json.dumps(output) + "\n"
                    yield "event: close\n\n"
                else :
                    yield "data: " + self.defaultCensorship + "\n\n"
                    yield "data: " + json.dumps(output) + "\n"
                    yield "event: close\n\n"
            else:
                if len(response.source_nodes) == 0:
                    output["answer"] = project.model.censorship or self.defaultCensorship
                else:
                    output["answer"] = response.response

                yield output
        except Exception as e:
            if questionModel.stream:
                yield "data: Inference failed\n"
                yield "event: error\n\n"
            raise e

    def entryVision(self, projectName, visionInput, isprivate, db: Session):
        image = None
        output = ""

        project = self.findProject(projectName, db)
        if project is None:
            raise Exception("Project not found")

        tools = [
            DalleImage(),
            StableDiffusionImage(),
            DescribeImage(),
            InstantID(),
        ]

        if isprivate:
            tools.pop(0)

        llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

        agent = initialize_agent(
            tools, llm, agent="zero-shot-react-description", verbose=True)
        
        outputAgent = agent.run(visionInput.question, tags=[visionInput])

        if isinstance(outputAgent, str):
            output = outputAgent
        else:
            if outputAgent["type"] == "describeimage":
                model = self.getLLM(project.model.llm, db)

                try:
                    response = model.llm.complete(prompt=visionInput.question, image_documents=[ImageDocument(image=visionInput.image)])
                except Exception as e:
                    raise e
                
                output = response.text
                image = visionInput.image
            else:
                output = outputAgent["prompt"]
                image = outputAgent["image"]
                
        outputf = {
            "question": visionInput.question,
            "answer": output,
            "image": image,
            "sources": [],
            "type": "vision"
        }

        return outputf

    def inference(self, projectName, inferenceModel, db: Session):
        project = self.findProject(projectName, db)
        if project is None:
            raise Exception("Project not found")

        model = self.getLLM(project.model.llm, db)

        sysTemplate = inferenceModel.system or project.model.system or self.defaultSystem
        model.llm.system_prompt = sysTemplate

        #model.llm.system = sysTemplate
        #resp = model.llm.complete(inferenceModel.question)
        messages = [
            ChatMessage(
                role="system", content=sysTemplate
            ),
            ChatMessage(role="user", content=inferenceModel.question),
        ]

        try:
            if(inferenceModel.stream):
                respgen = model.llm.stream_chat(messages)
                for text in respgen:
                    yield "data: " + text.delta + "\n\n"
                yield "event: close\n\n"
            else:
                resp = model.llm.chat(messages)
                output = {
                    "question": inferenceModel.question,
                    "answer": resp.message.content.strip(),
                    "type": "inference"
                }
                yield output
        except Exception as e:              
            if inferenceModel.stream:
                yield "data: Inference failed\n"
                yield "event: error\n\n"
            raise e

    def ragSQL(self, projectName, questionModel, db: Session):
        project = self.findProject(projectName, db)
        if project is None:
            raise Exception("Project not found")

        model = self.getLLM(project.model.llm, db)

        engine = create_engine(project.model.connection)

        sql_database = SQLDatabase(engine)

        tables = None
        if hasattr(questionModel, 'tables') and questionModel.tables is not None:
            tables = questionModel.tables
        elif project.model.tables:
            tables = [table.strip() for table in project.model.tables.split(',')]

        query_engine = NLSQLTableQueryEngine(
            llm=model.llm,
            sql_database=sql_database,
            tables=tables,
        )

        question = (project.model.system or self.defaultSystem) + "\n Question: " + questionModel.question

        try:
            response = query_engine.query(question)
        except Exception as e:
            raise e

        output = {
            "question": questionModel.question,
            "answer": response.response,
            "sources": [response.metadata['sql_query']],
            "type": "questionsql"
        }

        return output
      
      
    def router(self, projectName, questionModel, db: Session):
        choices = []
        
        project = self.findProject(projectName, db)
        if project is None:
            raise Exception("Project not found")
          
        for entrance in project.model.entrances:
            choices.append(ToolMetadata(description=entrance.description, name=entrance.name))
        

        selector = LLMSingleSelector.from_defaults()
        selector_result = selector.select(
            choices, query=questionModel.question
        )
        
        projectNameDest = project.model.entrances[selector_result.selections[0].index].destination
        return projectNameDest
      
    def classify(self, input):
        classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")

        sequence_to_classify = input.sequence
        candidate_labels = input.labels
        return classifier(sequence_to_classify, candidate_labels, multi_label=True)
langchain.agents.initialize_agent langchain_community.chat_models.ChatOpenAI
[((3043, 3075), 'app.database.dbc.get_llm_by_name', 'dbc.get_llm_by_name', (['db', 'llmName'], {}), '(db, llmName)\n', (3062, 3075), False, 'from app.database import dbc\n'), ((4079, 4112), 'app.database.dbc.get_project_by_name', 'dbc.get_project_by_name', (['db', 'name'], {}), '(db, name)\n', (4102, 4112), False, 'from app.database import dbc\n'), ((4174, 4204), 'app.models.ProjectModel.model_validate', 'ProjectModel.model_validate', (['p'], {}), '(p)\n', (4201, 4204), False, 'from app.models import LLMModel, ProjectModel, QuestionModel, ChatModel\n'), ((4998, 5062), 'llama_index.core.retrievers.VectorIndexRetriever', 'VectorIndexRetriever', ([], {'index': 'project.db', 'similarity_top_k': 'final_k'}), '(index=project.db, similarity_top_k=final_k)\n', (5018, 5062), False, 'from llama_index.core.retrievers import VectorIndexRetriever\n'), ((5712, 5853), 'llama_index.core.chat_engine.ContextChatEngine.from_defaults', 'ContextChatEngine.from_defaults', ([], {'retriever': 'retriever', 'system_prompt': 'sysTemplate', 'memory': 'chat.history', 'node_postprocessors': 'postprocessors'}), '(retriever=retriever, system_prompt=\n    sysTemplate, memory=chat.history, node_postprocessors=postprocessors)\n', (5743, 5853), False, 'from llama_index.core.chat_engine import CondensePlusContextChatEngine, ContextChatEngine\n'), ((8196, 8260), 'llama_index.core.retrievers.VectorIndexRetriever', 'VectorIndexRetriever', ([], {'index': 'project.db', 'similarity_top_k': 'final_k'}), '(index=project.db, similarity_top_k=final_k)\n', (8216, 8260), False, 'from llama_index.core.retrievers import VectorIndexRetriever\n'), ((8669, 8699), 'llama_index.core.prompts.PromptTemplate', 'PromptTemplate', (['qa_prompt_tmpl'], {}), '(qa_prompt_tmpl)\n', (8683, 8699), False, 'from llama_index.core.prompts import PromptTemplate\n'), ((8725, 8779), 'llama_index.core.service_context_elements.llm_predictor.LLMPredictor', 'LLMPredictor', ([], {'llm': 'model.llm', 'system_prompt': 'sysTemplate'}), '(llm=model.llm, system_prompt=sysTemplate)\n', (8737, 8779), False, 'from llama_index.core.service_context_elements.llm_predictor import LLMPredictor\n'), ((8812, 8919), 'llama_index.core.response_synthesizers.get_response_synthesizer', 'get_response_synthesizer', ([], {'llm': 'llm_predictor', 'text_qa_template': 'qa_prompt', 'streaming': 'questionModel.stream'}), '(llm=llm_predictor, text_qa_template=qa_prompt,\n    streaming=questionModel.stream)\n', (8836, 8919), False, 'from llama_index.core.response_synthesizers import get_response_synthesizer\n'), ((9591, 9716), 'llama_index.core.query_engine.RetrieverQueryEngine', 'RetrieverQueryEngine', ([], {'retriever': 'retriever', 'response_synthesizer': 'response_synthesizer', 'node_postprocessors': 'postprocessors'}), '(retriever=retriever, response_synthesizer=\n    response_synthesizer, node_postprocessors=postprocessors)\n', (9611, 9716), False, 'from llama_index.core.query_engine import RetrieverQueryEngine\n'), ((11773, 11821), 'langchain_community.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model': '"""gpt-3.5-turbo"""', 'temperature': '(0)'}), "(model='gpt-3.5-turbo', temperature=0)\n", (11783, 11821), False, 'from langchain_community.chat_models import ChatOpenAI\n'), ((11839, 11918), 'langchain.agents.initialize_agent', 'initialize_agent', (['tools', 'llm'], {'agent': '"""zero-shot-react-description"""', 'verbose': '(True)'}), "(tools, llm, agent='zero-shot-react-description', verbose=True)\n", (11855, 11918), False, 'from langchain.agents import initialize_agent\n'), ((14562, 14601), 'sqlalchemy.create_engine', 'create_engine', (['project.model.connection'], {}), '(project.model.connection)\n', (14575, 14601), False, 'from sqlalchemy import create_engine\n'), ((14626, 14645), 'llama_index.core.utilities.sql_wrapper.SQLDatabase', 'SQLDatabase', (['engine'], {}), '(engine)\n', (14637, 14645), False, 'from llama_index.core.utilities.sql_wrapper import SQLDatabase\n'), ((14934, 15012), 'llama_index.core.indices.struct_store.sql_query.NLSQLTableQueryEngine', 'NLSQLTableQueryEngine', ([], {'llm': 'model.llm', 'sql_database': 'sql_database', 'tables': 'tables'}), '(llm=model.llm, sql_database=sql_database, tables=tables)\n', (14955, 15012), False, 'from llama_index.core.indices.struct_store.sql_query import NLSQLTableQueryEngine\n'), ((15938, 15971), 'llama_index.core.selectors.LLMSingleSelector.from_defaults', 'LLMSingleSelector.from_defaults', ([], {}), '()\n', (15969, 15971), False, 'from llama_index.core.selectors import LLMSingleSelector\n'), ((16273, 16343), 'transformers.pipeline', 'pipeline', (['"""zero-shot-classification"""'], {'model': '"""facebook/bart-large-mnli"""'}), "('zero-shot-classification', model='facebook/bart-large-mnli')\n", (16281, 16343), False, 'from transformers import pipeline\n'), ((3127, 3158), 'app.models.LLMModel.model_validate', 'LLMModel.model_validate', (['llm_db'], {}), '(llm_db)\n', (3150, 3158), False, 'from app.models import LLMModel, ProjectModel, QuestionModel, ChatModel\n'), ((3357, 3382), 'app.model.Model', 'Model', (['llmName', 'llmm', 'llm'], {}), '(llmName, llmm, llm)\n', (3362, 3382), False, 'from app.model import Model\n'), ((4256, 4265), 'app.project.Project', 'Project', ([], {}), '()\n', (4263, 4265), False, 'from app.project import Project\n'), ((5635, 5687), 'llama_index.core.postprocessor.SimilarityPostprocessor', 'SimilarityPostprocessor', ([], {'similarity_cutoff': 'threshold'}), '(similarity_cutoff=threshold)\n', (5658, 5687), False, 'from llama_index.core.postprocessor import SimilarityPostprocessor\n'), ((9513, 9565), 'llama_index.core.postprocessor.SimilarityPostprocessor', 'SimilarityPostprocessor', ([], {'similarity_cutoff': 'threshold'}), '(similarity_cutoff=threshold)\n', (9536, 9565), False, 'from llama_index.core.postprocessor import SimilarityPostprocessor\n'), ((11596, 11608), 'app.llms.tools.dalle.DalleImage', 'DalleImage', ([], {}), '()\n', (11606, 11608), False, 'from app.llms.tools.dalle import DalleImage\n'), ((11622, 11644), 'app.llms.tools.stablediffusion.StableDiffusionImage', 'StableDiffusionImage', ([], {}), '()\n', (11642, 11644), False, 'from app.llms.tools.stablediffusion import StableDiffusionImage\n'), ((11658, 11673), 'app.llms.tools.describeimage.DescribeImage', 'DescribeImage', ([], {}), '()\n', (11671, 11673), False, 'from app.llms.tools.describeimage import DescribeImage\n'), ((11687, 11698), 'app.llms.tools.instantid.InstantID', 'InstantID', ([], {}), '()\n', (11696, 11698), False, 'from app.llms.tools.instantid import InstantID\n'), ((13403, 13450), 'llama_index.core.base.llms.types.ChatMessage', 'ChatMessage', ([], {'role': '"""system"""', 'content': 'sysTemplate'}), "(role='system', content=sysTemplate)\n", (13414, 13450), False, 'from llama_index.core.base.llms.types import ChatMessage\n'), ((13494, 13551), 'llama_index.core.base.llms.types.ChatMessage', 'ChatMessage', ([], {'role': '"""user"""', 'content': 'inferenceModel.question'}), "(role='user', content=inferenceModel.question)\n", (13505, 13551), False, 'from llama_index.core.base.llms.types import ChatMessage\n'), ((2679, 2702), 'ollama.show', 'ollama.show', (['model_name'], {}), '(model_name)\n', (2690, 2702), False, 'import ollama\n'), ((3178, 3206), 'app.tools.getLLMClass', 'getLLMClass', (['llmm.class_name'], {}), '(llmm.class_name)\n', (3189, 3206), False, 'from app.tools import getLLMClass\n'), ((4372, 4398), 'app.vectordb.vector_init', 'vector_init', (['self', 'project'], {}), '(self, project)\n', (4383, 4398), False, 'from app.vectordb import vector_init\n'), ((5203, 5325), 'llama_index.postprocessor.colbert_rerank.ColbertRerank', 'ColbertRerank', ([], {'top_n': 'k', 'model': '"""colbert-ir/colbertv2.0"""', 'tokenizer': '"""colbert-ir/colbertv2.0"""', 'keep_retrieval_score': '(True)'}), "(top_n=k, model='colbert-ir/colbertv2.0', tokenizer=\n    'colbert-ir/colbertv2.0', keep_retrieval_score=True)\n", (5216, 5325), False, 'from llama_index.postprocessor.colbert_rerank import ColbertRerank\n'), ((5473, 5527), 'llama_index.core.postprocessor.llm_rerank.LLMRerank', 'LLMRerank', ([], {'choice_batch_size': 'k', 'top_n': 'k', 'llm': 'model.llm'}), '(choice_batch_size=k, top_n=k, llm=model.llm)\n', (5482, 5527), False, 'from llama_index.core.postprocessor.llm_rerank import LLMRerank\n'), ((9053, 9175), 'llama_index.postprocessor.colbert_rerank.ColbertRerank', 'ColbertRerank', ([], {'top_n': 'k', 'model': '"""colbert-ir/colbertv2.0"""', 'tokenizer': '"""colbert-ir/colbertv2.0"""', 'keep_retrieval_score': '(True)'}), "(top_n=k, model='colbert-ir/colbertv2.0', tokenizer=\n    'colbert-ir/colbertv2.0', keep_retrieval_score=True)\n", (9066, 9175), False, 'from llama_index.postprocessor.colbert_rerank import ColbertRerank\n'), ((9351, 9405), 'llama_index.core.postprocessor.llm_rerank.LLMRerank', 'LLMRerank', ([], {'choice_batch_size': 'k', 'top_n': 'k', 'llm': 'model.llm'}), '(choice_batch_size=k, top_n=k, llm=model.llm)\n', (9360, 9405), False, 'from llama_index.core.postprocessor.llm_rerank import LLMRerank\n'), ((15841, 15907), 'llama_index.core.tools.ToolMetadata', 'ToolMetadata', ([], {'description': 'entrance.description', 'name': 'entrance.name'}), '(description=entrance.description, name=entrance.name)\n', (15853, 15907), False, 'from llama_index.core.tools import ToolMetadata\n'), ((2603, 2632), 'json.loads', 'json.loads', (['llm.props.options'], {}), '(llm.props.options)\n', (2613, 2632), False, 'import json\n'), ((3209, 3233), 'json.loads', 'json.loads', (['llmm.options'], {}), '(llmm.options)\n', (3219, 3233), False, 'import json\n'), ((2878, 2901), 'ollama.pull', 'ollama.pull', (['model_name'], {}), '(model_name)\n', (2889, 2901), False, 'import ollama\n'), ((6841, 6859), 'json.dumps', 'json.dumps', (['output'], {}), '(output)\n', (6851, 6859), False, 'import json\n'), ((7040, 7058), 'json.dumps', 'json.dumps', (['output'], {}), '(output)\n', (7050, 7058), False, 'import json\n'), ((10598, 10616), 'json.dumps', 'json.dumps', (['output'], {}), '(output)\n', (10608, 10616), False, 'import json\n'), ((10798, 10816), 'json.dumps', 'json.dumps', (['output'], {}), '(output)\n', (10808, 10816), False, 'import json\n'), ((12336, 12374), 'llama_index.core.schema.ImageDocument', 'ImageDocument', ([], {'image': 'visionInput.image'}), '(image=visionInput.image)\n', (12349, 12374), False, 'from llama_index.core.schema import ImageDocument\n')]