| import os |
| import sys |
| import argparse |
| import importlib.util |
| import signal |
| import logging |
|
|
| |
|
|
| PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) |
|
|
| def add_path(path): |
| if path not in sys.path: |
| sys.path.insert(0, path) |
|
|
| add_path(PROJECT_ROOT) |
|
|
| logging.basicConfig( |
| filename=os.path.join(PROJECT_ROOT, 'codette_bootstrap.log'), |
| level=logging.INFO, |
| format='%(asctime)s %(levelname)s %(message)s' |
| ) |
| logging.info("Codette Bootstrap - Starting up.") |
|
|
| |
|
|
| def check_exists(rel_path, required=True): |
| abs_path = os.path.join(PROJECT_ROOT, rel_path) |
| if not os.path.exists(abs_path): |
| if required: |
| logging.error(f"Required file '{rel_path}' not found!") |
| raise FileNotFoundError(f"Required file '{rel_path}' not found!") |
| else: |
| logging.warning(f"Optional file '{rel_path}' not found.") |
| else: |
| logging.info(f"Located: {rel_path}") |
| return abs_path |
|
|
| |
|
|
| def launch_tkinter_gui(): |
| from codette_desktop import CodetteApp |
| logging.info("Launching Codette Tkinter GUI...") |
| app = CodetteApp() |
| app.mainloop() |
|
|
| def launch_fastapi_server(): |
| from api_server import app as fastapi_app |
| import uvicorn |
| logging.info("Spawning Codette FastAPI server...") |
| uvicorn.run(fastapi_app, host="127.0.0.1", port=8000, log_level="info") |
|
|
| def test_cognitive_stack(): |
| |
| from universal_reasoning_local import UniversalReasoning, load_json_config |
| try: |
| config_path = check_exists("config.json") |
| config = load_json_config(config_path) |
| ur = UniversalReasoning(config) |
| import asyncio |
| print("Running self-test: 'What is the meaning of life?'") |
| result = asyncio.run(ur.generate_response("What is the meaning of life?")) |
| print("Codette:", result) |
| return True |
| except Exception as e: |
| logging.error(f"Stack self-test failed: {e}") |
| print(f"Error: {e}") |
| return False |
|
|
| def banner(): |
| print("CODDETTE / PIDETTE – Universal Reasoning Bootstrap") |
| print("Raiffs Bits LLC – Jonathan Harrison (2024)\n") |
|
|
| |
|
|
| def main(): |
| banner() |
| parser = argparse.ArgumentParser(description="Codette Multi-Agent AI Bootstrapper") |
| parser.add_argument('--gui', action="store_true", help="Launch the Tkinter GUI application") |
| parser.add_argument('--api', action="store_true", help="Launch FastAPI backend") |
| parser.add_argument('--test', action="store_true", help="Run logic self-test (no UI)") |
| args = parser.parse_args() |
|
|
| |
| _ = check_exists("config.json") |
| _ = check_exists("universal_reasoning_local.py") |
| _ = check_exists("codette_desktop.py") |
| _ = check_exists("api_server.py") |
| |
|
|
| |
| if args.test: |
| ok = test_cognitive_stack() |
| if not ok: |
| sys.exit(1) |
| return |
|
|
| processes = [] |
|
|
| if args.api: |
| |
| import multiprocessing |
| p_api = multiprocessing.Process(target=launch_fastapi_server) |
| p_api.daemon = True |
| p_api.start() |
| processes.append(p_api) |
| |
| if args.gui: |
| launch_tkinter_gui() |
| |
| |
| if not args.gui and not args.api and not args.test: |
| parser.print_help() |
| sys.exit(0) |
| |
| |
| for p in processes: |
| p.join() |
|
|
| def handle_interrupt(sig, frame): |
| print("Shutting down Codette...") |
| sys.exit(0) |
|
|
| signal.signal(signal.SIGINT, handle_interrupt) |
| signal.signal(signal.SIGTERM, handle_interrupt) |
|
|
| if __name__ == "__main__": |
| main() |
|
|