Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 26 additions & 19 deletions ai_adapter.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import json
from azure.ai.inference.models import SystemMessage, UserMessage
from alkemio_virtual_contributor_engine.events.response import Response
from alkemio_virtual_contributor_engine.events.input import Input
from create_context import create_context
from logger import setup_logger
from logger import setup_logger
from models import get_retriever, invoke_model
from models import invoke_model
from alkemio_virtual_contributor_engine.utils import (
combine_documents,
get_language_by_code,
history_as_text,
)
from prompts import chat_system_prompt, condense_prompt
from prompts import (
condense_prompt,
bok_system_prompt,
response_system_prompt,
)
from config import env

logger = setup_logger(__name__)
Expand Down Expand Up @@ -60,32 +63,36 @@ async def query_chain(input: Input) -> Response:
else:
logger.info("No history to handle, initial interaction")

documents = get_retriever().invoke(message)
logger.info("Context retrieved.")
logger.debug(f"Context is {documents}")
context = combine_documents(documents)
documents, context = create_context(message)

messages = [
SystemMessage(
content=chat_system_prompt.format(
context=context, language=get_language_by_code(input.language)
)
),
SystemMessage(content=bok_system_prompt.format(knowledge=context)),
SystemMessage(content=response_system_prompt.format(context=context)),
UserMessage(content=message),
]

logger.info("Invoking LLM.")
result = invoke_model(messages)
response = json.loads(invoke_model(messages))
logger.info("LLM invocation completed.")
logger.info(f"LLM message is: {result}")
logger.info(f"LLM message is: {response}")

sources = []
for index, metadata in enumerate(documents["metadatas"][0]):
index = str(index)
if (
{"uri": metadata["source"]} not in sources
and index in response["source_scores"]
and response["source_scores"][index] > 0
):
sources.append({"uri": metadata["source"]})

return Response(
{
"result": result,
"original_result": result,
"result": response["result"],
"original_result": response["result"],
"human_language": input.language,
"result_language": input.language,
"knowledge_language": "en",
"sources": [{"uri": document.metadata["source"]} for document in documents],
"sources": sources,
}
)
4 changes: 4 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
class Env:
model_name: str
embeddings_model_name: str
openai_api_key: str
openai_endpoint: str
openai_api_version: str
site_url: str
welcome_site_url: str
Expand Down Expand Up @@ -41,6 +43,8 @@ def __init__(self):

self.model_name = os.getenv("LLM_DEPLOYMENT_NAME", "")
self.embeddings_model_name = os.getenv("EMBEDDINGS_DEPLOYMENT_NAME", "")
self.openai_api_key = os.getenv("AZURE_OPENAI_API_KEY", "")
self.openai_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT", "")
self.openai_api_version = os.getenv("OPENAI_API_VERSION", "")

self.site_url = os.getenv("AI_SOURCE_WEBSITE", "")
Expand Down
57 changes: 57 additions & 0 deletions create_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from chromadb.api.types import IncludeEnum
from models import embed_func
from logger import setup_logger

from alkemio_virtual_contributor_engine.chromadb_client import chromadb_client


logger = setup_logger(__name__)


def combine_documents(docs, document_separator="\n\n"):
chunks_array = []
for index, document in enumerate(docs["documents"][0]):
chunks_array.append(f"[source:{index}] {document}")

return document_separator.join(chunks_array)


def get_documents(message: str):

collections = [
"alkem.io-knowledge",
"welcome.alkem.io-knowledge",
"www.alkemio.org-knowledge",
]
result = {"documents": [[]], "metadatas": [[]], "distances": [[]]}

for collection in collections:
collection = chromadb_client.get_collection(
collection, embedding_function=embed_func
)
tmp_result = collection.query(
query_texts=[message],
include=[
IncludeEnum.documents,
IncludeEnum.metadatas,
IncludeEnum.distances,
],
n_results=3,
)
if (
tmp_result
and tmp_result["documents"]
and tmp_result["distances"]
and tmp_result["metadatas"]
):
result["distances"][0] += tmp_result["distances"][0]
result["documents"][0] += tmp_result["documents"][0]
result["metadatas"][0] += tmp_result["metadatas"][0]
return result


def create_context(message):
documents = get_documents(message)
logger.info("Context retrieved.")
logger.debug(f"Context is {documents}")
return documents, combine_documents(documents)
177 changes: 0 additions & 177 deletions ingest.py

This file was deleted.

18 changes: 4 additions & 14 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
import ai_adapter
import asyncio

import ai_adapter
from alkemio_virtual_contributor_engine.alkemio_vc_engine import (
AlkemioVirtualContributorEngine,
)
from alkemio_virtual_contributor_engine.events.input import Input, InvocationOperation
from alkemio_virtual_contributor_engine.events import Input
from alkemio_virtual_contributor_engine.events.response import Response

from ingest import ensure_ingested
from logger import setup_logger

logger = setup_logger(__name__)

# Lock to prevent multiple ingestions from happening at the same time
ingestion_lock = asyncio.Lock()
engine = AlkemioVirtualContributorEngine()


async def query(input: Input) -> Response:
logger.info("Query method invoked.")
if input.operation is InvocationOperation.INGEST:
logger.info("Operation is INGEST.")
async with ingestion_lock:
await ensure_ingested(True)
# return empty response - we can extend this to give valid feedback
return Response()

logger.info("Operation is QUERY.")
result = await ai_adapter.invoke(input)
logger.info("Query method completed.")
return result


engine = AlkemioVirtualContributorEngine()
engine.register_handler(query)
asyncio.run(engine.start())
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ spec:
secretKeyRef:
name: alkemio-rabbitmq-cluster-default-user
key: password
- name: RABBITMQ_QUEUE
value: virtual-contributor-engine-guidance
envFrom:
- secretRef:
name: alkemio-secrets
Expand Down
Loading
Loading