From 2999b83177dbf1186116e52113d67ed5c96a2c31 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Thu, 20 Mar 2025 04:01:20 +0000 Subject: [PATCH] Update slop_with_models.py --- slop_with_models.py | 173 +++++++++++++++++++++++++++++++------------- 1 file changed, 121 insertions(+), 52 deletions(-) diff --git a/slop_with_models.py b/slop_with_models.py index 0d1e5c1..e1f4521 100644 --- a/slop_with_models.py +++ b/slop_with_models.py @@ -1,6 +1,8 @@ from flask import Flask, request, jsonify from datetime import datetime import os +import json +from threading import Lock from openai import OpenAI import logging from flask_swagger_ui import get_swaggerui_blueprint @@ -8,10 +10,8 @@ from flask_swagger_ui import get_swaggerui_blueprint # Configure logging logging.basicConfig( level=logging.DEBUG, - handlers=[ - logging.FileHandler("slop_with_models.log"), # Log to a file - logging.StreamHandler(), # Also log to console - ] + format="%(asctime)s - %(levelname)s - %(message)s", + handlers=[logging.FileHandler("slop_with_models.log"), logging.StreamHandler()] ) logger = logging.getLogger(__name__) @@ -25,9 +25,48 @@ swaggerui_blueprint = get_swaggerui_blueprint( ) app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL) -# Global model-to-client map and memory +# Global model-to-client map MODEL_CLIENT_MAP = {} -memory = {} + +# Memory setup +DATA_DIR = "data" + +# Memory endpoints with lock and timeout +# Seconds to wait for lock acquisition +LOCK_TIMEOUT = 2 +MEMORY_FILE = os.path.join(DATA_DIR, "memory.json") +memory_lock = Lock() + +# Ensure data directory exists +if not os.path.exists(DATA_DIR): + os.makedirs(DATA_DIR) + logger.info(f"Created data directory: {DATA_DIR}") + +# File-based memory functions +def load_memory_from_file(): + try: + if os.path.exists(MEMORY_FILE): + with open(MEMORY_FILE, "r") as f: + data = json.load(f) + logger.debug(f"Loaded memory from {MEMORY_FILE}: {data}") + return data + logger.info(f"No memory file found at {MEMORY_FILE}, starting with empty memory") + return {} + except Exception as e: + logger.error(f"Error loading memory from {MEMORY_FILE}: {str(e)}", exc_info=True) + return {} + +def save_memory_to_file(memory_data): + try: + with open(MEMORY_FILE, "w") as f: + json.dump(memory_data, f) + logger.debug(f"Saved memory to {MEMORY_FILE}: {memory_data}") + except Exception as e: + logger.error(f"Error saving memory to {MEMORY_FILE}: {str(e)}", exc_info=True) + +# Initialize memory from file +memory = load_memory_from_file() +logger.info("Memory initialized from file") # Load endpoints ENDPOINTS = [] @@ -93,7 +132,81 @@ tools = { } resources = {"hello": {"id": "hello", "content": "Hello, SLOP!"}} -# Endpoints +@app.route("/memory", methods=["POST"]) +def store_memory(): + logger.info("Received /memory POST request") + data = request.json + logger.debug(f"Store memory data: {data}") + if not data or "key" not in data or "value" not in data: + logger.warning(f"Invalid memory store request: {data}") + return jsonify({"error": "Missing 'key' or 'value'"}), 400 + key, value = data["key"], data["value"] + if memory_lock.acquire(timeout=LOCK_TIMEOUT): + try: + memory[key] = value + save_memory_to_file(memory) + logger.info(f"Stored in memory: {key} = {value}") + logger.debug(f"Current memory state: {memory}") + return jsonify({"status": "stored"}), 200 + finally: + memory_lock.release() + else: + logger.error(f"Failed to acquire lock for storing {key} within {LOCK_TIMEOUT} seconds") + return jsonify({"error": "Memory lock timeout"}), 503 + +@app.route("/memory/", methods=["GET"]) +def get_memory(key): + logger.info(f"Received /memory/{key} GET request") + if memory_lock.acquire(timeout=LOCK_TIMEOUT): + try: + value = memory.get(key) + logger.debug(f"Retrieved memory for {key}: {value}") + if value is None: + logger.warning(f"Key not found in memory: {key}") + return jsonify({"value": value}), 200 + finally: + memory_lock.release() + else: + logger.error(f"Failed to acquire lock for retrieving {key} within {LOCK_TIMEOUT} seconds") + return jsonify({"error": "Memory lock timeout"}), 503 + +@app.route("/memory", methods=["GET"]) +def list_memory(): + logger.info("Received /memory GET request") + if memory_lock.acquire(timeout=LOCK_TIMEOUT): + try: + keys = list(memory.keys()) + memory_state = memory.copy() + logger.debug(f"Memory keys: {keys}") + logger.debug(f"Full memory state: {memory_state}") + return jsonify({"keys": keys}), 200 + finally: + memory_lock.release() + else: + logger.error(f"Failed to acquire lock for listing memory within {LOCK_TIMEOUT} seconds") + return jsonify({"error": "Memory lock timeout"}), 503 + +@app.route("/memory/", methods=["DELETE"]) +def delete_memory(key): + logger.info(f"Received /memory/{key} DELETE request") + if memory_lock.acquire(timeout=LOCK_TIMEOUT): + try: + if key not in memory: + logger.warning(f"Key not found for deletion: {key}") + return jsonify({"error": "Key not found"}), 404 + old_value = memory[key] + del memory[key] + save_memory_to_file(memory) + logger.info(f"Deleted from memory: {key} (was {old_value})") + logger.debug(f"Updated memory state: {memory}") + return jsonify({"status": "deleted"}), 200 + finally: + memory_lock.release() + else: + logger.error(f"Failed to acquire lock for deleting {key} within {LOCK_TIMEOUT} seconds") + return jsonify({"error": "Memory lock timeout"}), 503 + +# Other endpoints (unchanged for brevity) @app.route("/chat", methods=["POST"]) def chat(): logger.info("Received /chat request") @@ -105,11 +218,10 @@ def chat(): ) logger.info(f"Selected model: {model_id}, message: {message}") if not model_id or model_id not in MODEL_CLIENT_MAP: - logger.error(f"Invalid or missing model_id: {model_id}, available models: {list(MODEL_CLIENT_MAP.keys())}") + logger.error(f"Invalid or missing model_id: {model_id}") return jsonify({"error": "Model not found"}), 404 client = MODEL_CLIENT_MAP[model_id] try: - logger.debug(f"Sending chat request to model {model_id}") response = client.chat.completions.create( model=model_id, messages=[ @@ -170,49 +282,6 @@ def use_tool(tool_id): logger.error(f"Error executing tool {tool_id}: {str(e)}", exc_info=True) return jsonify({"error": str(e)}), 500 -@app.route("/memory", methods=["POST"]) -def store_memory(): - logger.info("Received /memory POST request") - data = request.json - logger.debug(f"Store memory data: {data}") - if not data or "key" not in data or "value" not in data: - logger.warning(f"Invalid memory store request: {data}") - return jsonify({"error": "Missing 'key' or 'value'"}), 400 - key, value = data["key"], data["value"] - memory[key] = value - logger.info(f"Stored in memory: {key} = {value}") - logger.debug(f"Current memory state: {memory}") - return jsonify({"status": "stored"}), 200 - -@app.route("/memory/", methods=["GET"]) -def get_memory(key): - logger.info(f"Received /memory/{key} GET request") - value = memory.get(key) - logger.debug(f"Retrieved memory for {key}: {value}") - if value is None: - logger.warning(f"Key not found in memory: {key}") - return jsonify({"value": value}), 200 - -@app.route("/memory", methods=["GET"]) -def list_memory(): - logger.info("Received /memory GET request") - keys = list(memory.keys()) - logger.debug(f"Memory keys: {keys}") - logger.debug(f"Full memory state: {memory}") - return jsonify({"keys": keys}), 200 - -@app.route("/memory/", methods=["DELETE"]) -def delete_memory(key): - logger.info(f"Received /memory/{key} DELETE request") - if key not in memory: - logger.warning(f"Key not found for deletion: {key}") - return jsonify({"error": "Key not found"}), 404 - old_value = memory[key] - del memory[key] - logger.info(f"Deleted from memory: {key} (was {old_value})") - logger.debug(f"Updated memory state: {memory}") - return jsonify({"status": "deleted"}), 200 - @app.route("/resources", methods=["GET"]) def list_resources(): logger.info("Received /resources request")