Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: starting the llm-client #254

Merged
merged 1 commit into from
Jul 30, 2024
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
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
10 changes: 10 additions & 0 deletions services/llm-client/components/base_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from abc import ABC, abstractmethod

class BaseComponent(ABC):
@abstractmethod
def initialize(self):
pass

@abstractmethod
def close(self):
pass
32 changes: 32 additions & 0 deletions services/llm-client/components/component_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import List, Type
from components.scylla_connection import ScyllaConnection
from components.base_component import BaseComponent

components_to_initialize: List[Type[BaseComponent]] = [
ScyllaConnection
]

class ComponentManager:
components: dict[Type[BaseComponent], BaseComponent] = {}

@classmethod
def initialize_components(cls) -> None:
for component_type in components_to_initialize:
try:
component_instance = component_type()
component_instance.initialize()
cls.components[component_type] = component_instance
except Exception as e:
print(f"Failed to initialize {component_type.__name__}: {e}")

@classmethod
def get_component(cls, component_type: Type[BaseComponent]) -> BaseComponent:
return cls.components.get(component_type)

@classmethod
def close_components(cls) -> None:
for component in cls.components.values():
try:
component.close()
except Exception as e:
print(f"Failed to close component: {e}")
18 changes: 18 additions & 0 deletions services/llm-client/components/scylla_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from cassandra.cluster import Cluster
from components.base_component import BaseComponent

class ScyllaConnection(BaseComponent):
def __init__(self):
self.cluster = None
self.session = None

def initialize(self):
self.cluster = Cluster(['127.0.0.1'], port=9042)
self.session = self.cluster.connect()

def get_session(self):
return self.session

def close(self):
if self.cluster:
self.cluster.shutdown()
19 changes: 19 additions & 0 deletions services/llm-client/diplomat/http_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from openai import OpenAI

client = OpenAI(
api_key=""
#os.environ['OPENAI_API_KEY'], # this is also the default, it can be omitted
)

def complete():
completion = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": "Hello, how are you?",
},
],
)
print(completion.choices[0].message.content)
return completion.choices[0].message.content
24 changes: 24 additions & 0 deletions services/llm-client/diplomat/http_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from fastapi import FastAPI
from wires.inputs.interactions import Interaction
from components.component_manager import ComponentManager
from components.scylla_connection import ScyllaConnection

app = FastAPI()

@app.on_event("startup")
async def startup_event():
ComponentManager.initialize_components()

@app.on_event("shutdown")
async def shutdown_event():
ComponentManager.close_components()

@app.post("/api/llm/interactions")
def greet(interaction: Interaction):
a = ComponentManager.get_component(ScyllaConnection)
query = "select * from configuration.prompts where prompt_name = 'tick_shopping_items' ;"
prepared = a.session.prepare(query)
#bound = prepared.bind(('value',)) # Replace 'value' with the actual value you want to query
rows = a.session.execute(query)
for row in rows:
print(row)
19 changes: 19 additions & 0 deletions services/llm-client/diplomat/scylla.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider

# If your ScyllaDB is running without authentication, you can omit the auth_provider part
# auth_provider = PlainTextAuthProvider(username='your_username', password='your_password')

cluster = Cluster(['127.0.0.1'], port=9042) # Change to your Docker host's IP if necessary
session = cluster.connect()

# Optional: Set the keyspace if you have one
# session.set_keyspace('your_keyspace')

# Execute a simple query
rows = session.execute('SELECT key FROM system.local')
for row in rows:
print(row.key)

# Close the connection
cluster.shutdown()
4 changes: 4 additions & 0 deletions services/llm-client/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

if __name__ == "__main__":
import uvicorn
uvicorn.run("diplomat.http_server:app", host="127.0.0.1", port=8000)
Empty file.
25 changes: 25 additions & 0 deletions services/llm-client/migrations/migrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os
import importlib.util
from cassandra.cluster import Cluster

def apply_migrations(session, migrations_dir='scripts'):
migration_files = sorted(f for f in os.listdir(migrations_dir) if f.endswith('.py') and f != "__init__.py")
for migration_file in migration_files:
migration_path = os.path.join(migrations_dir, migration_file)
spec = importlib.util.spec_from_file_location(migration_file, migration_path)
migration_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(migration_module)
migration_module.run_migration(session)
print(f"Applied {migration_file}")

def get_session():
cluster = Cluster(['127.0.0.1'], port=9042)
return cluster.connect()

def close_session(cluster):
cluster.shutdown()

if __name__ == "__main__":
session = get_session()
apply_migrations(session)
session.cluster.shutdown()
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from cassandra.cluster import Cluster

def run_migration(session):
session.execute("""
CREATE KEYSPACE IF NOT EXISTS execution
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
""")
session.execute("""
CREATE TABLE IF NOT EXISTS execution.interactions (
interaction_id UUID PRIMARY KEY,
input text,
response text,
request_date date,
status int,
timeout int
);
""")
13 changes: 13 additions & 0 deletions services/llm-client/migrations/scripts/002_create_prompts_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from cassandra.cluster import Cluster

def run_migration(session):
session.execute("""
CREATE KEYSPACE IF NOT EXISTS configuration
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
""")
session.execute("""
CREATE TABLE IF NOT EXISTS configuration.prompts (
prompt_name text PRIMARY KEY,
prompt text
);
""")
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from cassandra.cluster import Cluster

def run_migration(session):
session.execute("""
INSERT INTO configuration.prompts (prompt_name, prompt)
VALUES('tick_shopping_items', 'Are you able to tick items on a cart if I send you a picture?')
""")

Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8 changes: 8 additions & 0 deletions services/llm-client/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Requirements
- cassandra-driver

Needs:
Get variables from the OS
Make it works on doker


Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
7 changes: 7 additions & 0 deletions services/llm-client/wires/inputs/interactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel
from typing import Dict, Any

class Interaction(BaseModel):
promptName: str
variables: Dict[str, Any] = {}
images: Dict[str, Any] = {}
Loading