From 439c069b86b8078756dbbd16e7ed71ec8bf81950 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Sat, 28 Oct 2023 20:27:32 +0200 Subject: [PATCH] slight improvements, moving to short answer, adding docker compose --- science.py => api.py | 35 +++++++++++++++++++++++++---------- docker-compose.yaml | 20 ++++++++++++++++++++ science-bot.py | 36 +++++++++++++++++++++++++++--------- 3 files changed, 72 insertions(+), 19 deletions(-) rename science.py => api.py (52%) create mode 100644 docker-compose.yaml diff --git a/science.py b/api.py similarity index 52% rename from science.py rename to api.py index eea567c..ff32afa 100644 --- a/science.py +++ b/api.py @@ -5,8 +5,6 @@ from quart import Quart, request, jsonify logging.basicConfig(stream=sys.stdout, level=logging.INFO) - - app = Quart(__name__) @app.route('/ask') @@ -16,28 +14,45 @@ async def ask(): if not query: return {'error': 'Please provide a query parameter'}, 400 - # Only await if cybrex.start() needs to be called for each request - # Otherwise, consider initializing cybrex outside the route await cybrex.start() # Assuming chat_science is an asynchronous method, it should be awaited - answer = await cybrex.chat_science(query=query, n_chunks=4, n_documents=10) + answer = await cybrex.chat_science(query=query, n_chunks=1, n_documents=20) + + payload = format_cybrex_response(answer) + return payload + +@app.route('/research') +async def research(): + cybrex = CybrexAI() + query = request.args.get('query') + if not query: + return {'error': 'Please provide a query parameter'}, 400 + + await cybrex.start() + + # Assuming chat_science is an asynchronous method, it should be awaited + answer = await cybrex.chat_science(query=query, n_chunks=10, n_documents=20) payload = format_cybrex_response(answer) return payload def format_cybrex_response(answer): + # Extract the answer chunks = answer.chunks + #print(chunks) reply = answer.answer - formatted_response = "Short answer:\n" + reply + "\n\nExcerpts from articles:\n" - + formatted_response = f'Short answer:\n {reply}' + + # # Extract and format each chunk - for chunk in chunks: - formatted_response += "\n" + chunk.title + "\n" + chunk.text + "\n" - + #for chunk in chunks: + # formatted_response += f'\n + {chunk.title} - {chunk.document_id} \n {chunk.text} \n' + return formatted_response + if __name__ == '__main__': app.run(debug=True, port=6000) diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..b2efef0 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +version: '3' +services: + ipfs_host: + image: ipfs/kubo:latest + volumes: + - ./ipfs/staging/:/export + - ./ipfs/data:/data/ipfs + ports: + - 4001:4001 + - 4001:4001/udp + - 127.0.0.1:8080:8080 + - 127.0.0.1:5001:5001 + restart: always + + qdrant: + image: qdrant/qdrant + ports: + - 6333:6333 + - 6334:6334 + restart: always \ No newline at end of file diff --git a/science-bot.py b/science-bot.py index 85b0f0d..430c6ba 100644 --- a/science-bot.py +++ b/science-bot.py @@ -2,7 +2,7 @@ from nostr_sdk import Keys, Client, Event, EventBuilder, Filter, HandleNotificat import time import requests from settings import * - +import sqlite3 init_logger(LogLevel.DEBUG) @@ -17,6 +17,12 @@ client = Client(keys) client.add_relay("wss://relay.damus.io") client.add_relay("wss://nostr.mom") client.add_relay("wss://nostr.oxtr.dev") +client.add_relay("wss://purplepag.es") +client.add_relay("wss://a.nos.lol") +client.add_relay("wss://nostr-01.bolt.observer") +client.add_relay("wss://e.nos.lol") +client.add_relay("wss://nostr-pub.semisol.dev") +client.add_relay("wss://relay.snort.social") client.connect() filter = Filter().pubkey(pk).kind(4).since(Timestamp.now()) @@ -29,25 +35,37 @@ def format_answer(response): formatted_response = "Short answer:\n" + response["short_answer"] + "\n\nExcerpts from articles:\n" + response["chunks"] return formatted_response +# function to interact with local database +def interact_with_db(event_id, action): + conn = sqlite3.connect('events.db') + c = conn.cursor() + if action == "check": + c.execute("SELECT * FROM events WHERE id=?", (str(event_id),)) + return c.fetchone() is not None + elif action == "insert": + c.execute("INSERT INTO events VALUES (?)", (str(event_id),)) + conn.commit() + conn.close() + class NotificationHandler(HandleNotification): def handle(self, relay_url, event): print(f"Received new event from {relay_url}: {event.as_json()}") if event.kind() == 4: - print("Decrypting event") try: msg = nip04_decrypt(sk, event.pubkey(), event.content()) - print(f"Received new msg: {msg}") + print(f"Received new question: {msg}") params = {'query': str(msg)} try: resp = requests.get('http://127.0.0.1:6000/ask', params=params) + if resp.status_code == 200: + print("Sending answer") + event = EventBuilder.new_encrypted_direct_msg(keys, event.pubkey(), f"{resp.text}", event.id()).to_event(keys) + client.send_event(event) + else: + print(f"Error querying API: status code: {resp.status_code}, response: {resp.t}") except Exception as e: print(f"Error during request: {e}") - if resp.status_code == 200: - print("Sending answer") - event = EventBuilder.new_encrypted_direct_msg(keys, event.pubkey(), f"{resp.text}", event.id()).to_event(keys) - client.send_event(event) - else: - print(f"Error during content decryption: {resp.text}") + except Exception as e: print(f"Error during content decryption: {e}")