Sentry Support
This commit is contained in:
parent
14920bbf04
commit
010778ff0f
|
|
@ -13,3 +13,8 @@ OPENAI_API_BASE=
|
|||
OPENAI_API_VERSION=
|
||||
OPENAI_API_DEPLOYMENT_NAME=
|
||||
|
||||
# Sentry
|
||||
SENTRY_DSN=
|
||||
SENTRY_ENVIRONMENT=
|
||||
SENTRY_RELEASE=
|
||||
|
||||
|
|
|
|||
6
cache.py
6
cache.py
|
|
@ -8,26 +8,32 @@ import uuid
|
|||
from typing import List
|
||||
from langchain.schema import BaseMessage, Document
|
||||
from pydantic import BaseModel
|
||||
import sentry_sdk
|
||||
|
||||
class Conversation:
|
||||
"Wrapper Class for storing contexts between channels. Using an object to pass by reference avoid additional cache hits"
|
||||
@sentry_sdk.trace
|
||||
def __init__(self, mediator: SupabaseMediator, user_id: str, conversation_id: str = str(uuid.uuid4()), location_id: str = "web"):
|
||||
self.mediator: SupabaseMediator = mediator
|
||||
self.user_id: str = user_id
|
||||
self.conversation_id: str = conversation_id
|
||||
self.location_id: str = location_id
|
||||
|
||||
@sentry_sdk.trace
|
||||
def add_message(self, message_type: str, message: BaseMessage,) -> None:
|
||||
self.mediator.add_message(self.conversation_id, self.user_id, message_type, message)
|
||||
|
||||
@sentry_sdk.trace
|
||||
def messages(self, message_type: str) -> List[BaseMessage]:
|
||||
return self.mediator.messages(self.conversation_id, self.user_id, message_type)
|
||||
|
||||
# vector DB fn
|
||||
@sentry_sdk.trace
|
||||
def add_texts(self, texts: List[str]) -> None:
|
||||
metadatas = [{"conversation_id": self.conversation_id, "user_id": self.user_id} for _ in range(len(texts))]
|
||||
self.mediator.vector_table.add_texts(texts, metadatas)
|
||||
|
||||
# vector DB fn
|
||||
@sentry_sdk.trace
|
||||
def similarity_search(self, query: str, match_count: int = 5) -> List[Document]:
|
||||
return self.mediator.vector_table.similarity_search(query=query, k=match_count, filter={"user_id": self.user_id})
|
||||
|
|
|
|||
11
chain.py
11
chain.py
|
|
@ -7,6 +7,7 @@ from dotenv import load_dotenv
|
|||
from collections.abc import AsyncIterator
|
||||
from cache import Conversation
|
||||
from typing import List
|
||||
import sentry_sdk
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
|
@ -40,6 +41,7 @@ class BloomChain:
|
|||
pass
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
def think(cls, cache: Conversation, input: str):
|
||||
"""Generate Bloom's thought on the user."""
|
||||
# load message history
|
||||
|
|
@ -58,6 +60,7 @@ class BloomChain:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
def revise_thought(cls, cache: Conversation, input: str, thought: str):
|
||||
"""Revise Bloom's thought about the user with retrieved personal data"""
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ class BloomChain:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
def respond(cls, cache: Conversation, thought: str, input: str):
|
||||
"""Generate Bloom's response to the user."""
|
||||
response_prompt = ChatPromptTemplate.from_messages([
|
||||
|
|
@ -97,6 +101,7 @@ class BloomChain:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def think_user_prediction(cls, cache: Conversation, input: str):
|
||||
"""Generate a thought about what the user is going to say"""
|
||||
|
||||
|
|
@ -117,6 +122,7 @@ class BloomChain:
|
|||
return user_prediction_thought.content
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def revise_user_prediction_thought(cls, cache: Conversation, user_prediction_thought: str, input: str):
|
||||
"""Revise the thought about what the user is going to say based on retrieval of VoE facts"""
|
||||
|
||||
|
|
@ -142,6 +148,7 @@ class BloomChain:
|
|||
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def think_violation_of_expectation(cls, cache: Conversation, inp: str, user_prediction_thought_revision: str) -> None:
|
||||
"""Assess whether expectation was violated, derive and store facts"""
|
||||
|
||||
|
|
@ -161,6 +168,7 @@ class BloomChain:
|
|||
return voe_thought.content
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def violation_of_expectation(cls, cache: Conversation, inp: str, user_prediction_thought_revision: str, voe_thought: str) -> None:
|
||||
"""Assess whether expectation was violated, derive and store facts"""
|
||||
|
||||
|
|
@ -185,6 +193,7 @@ class BloomChain:
|
|||
return facts
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def check_voe_list(cls, cache: Conversation, facts: List[str]):
|
||||
"""Filter the facts to just new ones"""
|
||||
|
||||
|
|
@ -218,6 +227,7 @@ class BloomChain:
|
|||
cache.add_texts(data)
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def chat(cls, cache: Conversation, inp: str ) -> tuple[str, str]:
|
||||
# VoE has to happen first. If there's user prediction history, derive and store fact(s)
|
||||
if cache.messages('user_prediction_thought_revision'):
|
||||
|
|
@ -246,6 +256,7 @@ class BloomChain:
|
|||
return thought, response
|
||||
|
||||
@classmethod
|
||||
@sentry_sdk.trace
|
||||
async def stream(cls, cache: Conversation, inp: str ):
|
||||
# VoE has to happen first. If there's user prediction history, derive and store fact(s)
|
||||
try:
|
||||
|
|
|
|||
9
main.py
9
main.py
|
|
@ -8,9 +8,18 @@ from chain import BloomChain
|
|||
from mediator import SupabaseMediator
|
||||
from cache import Conversation
|
||||
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
import sentry_sdk
|
||||
load_dotenv()
|
||||
|
||||
rate = 0.2 if os.getenv("SENTRY_ENVIRONMENT") == "production" else 1.0
|
||||
sentry_sdk.init(
|
||||
dsn=os.environ['SENTRY_DSN'],
|
||||
traces_sample_rate=rate,
|
||||
profiles_sample_rate=rate
|
||||
)
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
MEDIATOR = SupabaseMediator()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from langchain.vectorstores import SupabaseVectorStore
|
|||
from langchain.embeddings.base import Embeddings
|
||||
from langchain.embeddings.openai import OpenAIEmbeddings
|
||||
import uuid
|
||||
import urllib
|
||||
import sentry_sdk
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
# Supabase for Postgres Management
|
||||
|
|
@ -16,6 +16,8 @@ import json
|
|||
load_dotenv()
|
||||
|
||||
class SupabaseMediator:
|
||||
|
||||
@sentry_sdk.trace
|
||||
def __init__(self):
|
||||
self.supabase: Client = create_client(os.environ['SUPABASE_URL'], os.environ['SUPABASE_KEY'])
|
||||
self.memory_table = os.environ["MEMORY_TABLE"]
|
||||
|
|
@ -42,15 +44,18 @@ class SupabaseMediator:
|
|||
|
||||
# self.vector_table.add_documents(seed_docs)
|
||||
|
||||
@sentry_sdk.trace
|
||||
def messages(self, session_id: str, user_id: str, message_type: str) -> List[BaseMessage]: # type: ignore
|
||||
response = self.supabase.table(self.memory_table).select("message").eq("session_id", session_id).eq("user_id", user_id).eq("message_type", message_type).order("id", desc=True).limit(10).execute()
|
||||
items = [record["message"] for record in response.data]
|
||||
messages = messages_from_dict(items)
|
||||
return messages[::-1]
|
||||
|
||||
@sentry_sdk.trace
|
||||
def add_message(self, session_id: str, user_id: str, message_type: str, message: BaseMessage) -> None:
|
||||
self.supabase.table(self.memory_table).insert({"session_id": session_id, "user_id": user_id, "message_type": message_type, "message": _message_to_dict(message)}).execute()
|
||||
|
||||
@sentry_sdk.trace
|
||||
def conversations(self, location_id: str, user_id: str) -> str | None:
|
||||
response = self.supabase.table(self.conversation_table).select("id").eq("location_id", location_id).eq("user_id", user_id).eq("isActive", True).maybe_single().execute()
|
||||
if response:
|
||||
|
|
@ -58,11 +63,13 @@ class SupabaseMediator:
|
|||
return conversation_id
|
||||
return None
|
||||
|
||||
@sentry_sdk.trace
|
||||
def add_conversation(self, location_id: str, user_id: str) -> str:
|
||||
conversation_id = str(uuid.uuid4())
|
||||
self.supabase.table(self.conversation_table).insert({"id": conversation_id, "user_id": user_id, "location_id": location_id}).execute()
|
||||
return conversation_id
|
||||
|
||||
@sentry_sdk.trace
|
||||
def delete_conversation(self, conversation_id: str) -> None:
|
||||
self.supabase.table(self.conversation_table).update({"isActive": False}).eq("id", conversation_id).execute()
|
||||
|
||||
|
|
|
|||
|
|
@ -1289,6 +1289,53 @@ urllib3 = ">=1.21.1,<3"
|
|||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.31.0"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "sentry-sdk-1.31.0.tar.gz", hash = "sha256:6de2e88304873484207fed836388e422aeff000609b104c802749fd89d56ba5b"},
|
||||
{file = "sentry_sdk-1.31.0-py2.py3-none-any.whl", hash = "sha256:64a7141005fb775b9db298a30de93e3b83e0ddd1232dc6f36eb38aebc1553291"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
fastapi = {version = ">=0.79.0", optional = true, markers = "extra == \"fastapi\""}
|
||||
urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""}
|
||||
|
||||
[package.extras]
|
||||
aiohttp = ["aiohttp (>=3.5)"]
|
||||
arq = ["arq (>=0.23)"]
|
||||
asyncpg = ["asyncpg (>=0.23)"]
|
||||
beam = ["apache-beam (>=2.12)"]
|
||||
bottle = ["bottle (>=0.12.13)"]
|
||||
celery = ["celery (>=3)"]
|
||||
chalice = ["chalice (>=1.16.0)"]
|
||||
clickhouse-driver = ["clickhouse-driver (>=0.2.0)"]
|
||||
django = ["django (>=1.8)"]
|
||||
falcon = ["falcon (>=1.4)"]
|
||||
fastapi = ["fastapi (>=0.79.0)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
|
||||
grpcio = ["grpcio (>=1.21.1)"]
|
||||
httpx = ["httpx (>=0.16.0)"]
|
||||
huey = ["huey (>=2)"]
|
||||
loguru = ["loguru (>=0.5)"]
|
||||
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
|
||||
opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"]
|
||||
pure-eval = ["asttokens", "executing", "pure-eval"]
|
||||
pymongo = ["pymongo (>=3.1)"]
|
||||
pyspark = ["pyspark (>=2.4.4)"]
|
||||
quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
|
||||
rq = ["rq (>=0.6)"]
|
||||
sanic = ["sanic (>=0.8)"]
|
||||
sqlalchemy = ["sqlalchemy (>=1.2)"]
|
||||
starlette = ["starlette (>=0.19.1)"]
|
||||
starlite = ["starlite (>=1.48)"]
|
||||
tornado = ["tornado (>=5)"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
|
|
@ -1798,4 +1845,4 @@ multidict = ">=4.0"
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "8ccc4a9baa19404ab5a5c62d06ad07b760f17df6a7d6bc045f34bc38a45ab2bc"
|
||||
content-hash = "79b717a6de797aab0ceb534b8ecf0b99ad17c2687ed0a2c8d6d97766ddf6d0e5"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ openai = "^0.28.0"
|
|||
pydantic = "^2.3.0"
|
||||
python-dotenv = "^1.0.0"
|
||||
uvicorn = "^0.23.2"
|
||||
sentry-sdk = {extras = ["fastapi"], version = "^1.31.0"}
|
||||
|
||||
|
||||
[build-system]
|
||||
|
|
|
|||
Loading…
Reference in New Issue