Repository: hagameai/hagamesai Branch: main Commit: c0ea1cf94ebf Files: 127 Total size: 282.6 KB Directory structure: gitextract_b3_afje9/ ├── .gitignore ├── .python-version ├── LICENSE ├── README.md ├── alembic/ │ ├── README │ ├── env.py │ └── script.py.mako ├── alembic.ini ├── api/ │ ├── __init__.py │ ├── ai.py │ ├── auth.py │ ├── games.py │ ├── llm.py │ ├── llm_service.py │ ├── llm_service_utils.py │ ├── routers/ │ │ └── ai_engine.py │ ├── tasks.py │ ├── test_llm.py │ └── users.py ├── core/ │ ├── __init__.py │ ├── ai_engine/ │ │ ├── __init__.py │ │ ├── ai_processing.py │ │ ├── ai_utilities.py │ │ ├── base.py │ │ ├── cognitive.py │ │ ├── cognitive_functions.py │ │ ├── collective.py │ │ ├── collective_intelligence.py │ │ ├── llm_utils.py │ │ ├── prediction.py │ │ ├── quantum.py │ │ ├── utils.py │ │ └── xai.py │ ├── auth.py │ ├── auth_utils.py │ ├── celery_app.py │ ├── database.py │ ├── llm_processing.py │ ├── llm_utilities.py │ ├── logging.py │ └── tasks.py ├── crud/ │ ├── __init__.py │ ├── ai_model.py │ ├── cognitive_profile.py │ ├── game_definition.py │ ├── game_instance.py │ └── user.py ├── docs/ │ ├── ai_engine.md │ ├── ai_engine_integration_guide.md │ ├── ai_engine_processing.md │ ├── ai_engine_utils.md │ ├── api_overview.md │ ├── api_reference.md │ ├── game_management.md │ ├── llm_api_documentation.md │ ├── llm_integration_guide.md │ ├── llm_service.md │ ├── roadmap.md │ ├── usage_guide.md │ ├── user_management_guide.md │ └── user_profile_management.md ├── llm_service/ │ ├── README.md │ ├── __init__.py │ ├── architecture.md │ ├── configuration.md │ ├── crud.py │ ├── faq.md │ ├── models.py │ ├── schemas.py │ ├── service.py │ ├── test_ai_engine_service.py │ ├── test_llm_service.py │ ├── test_llm_service_integration.py │ ├── test_service.py │ └── usage_examples.md ├── main.py ├── models/ │ ├── __init__.py │ ├── ai_model.py │ ├── cognitive_profile.py │ ├── game_definition.py │ ├── game_instance.py │ └── user.py ├── pyproject.toml ├── schemas/ │ ├── __init__.py │ ├── ai_engine.py │ ├── ai_model.py │ ├── cognitive_profile.py │ ├── game_definition.py │ ├── game_instance.py │ ├── llm_request.py │ ├── llm_response.py │ ├── task.py │ ├── user.py │ └── user_profile.py └── tests/ ├── integration/ │ ├── test_ai_engine.py │ ├── test_ai_engine_integration.py │ ├── test_auth.py │ ├── test_auth_integration.py │ ├── test_game_integration.py │ ├── test_game_management_integration.py │ ├── test_games.py │ ├── test_llm.py │ ├── test_llm_integration.py │ ├── test_llm_service.py │ ├── test_llm_service_integration.py │ ├── test_user_management.py │ └── test_user_management_integration.py └── unit/ ├── test_ai_engine.py ├── test_ai_engine_model.py ├── test_ai_engine_service.py ├── test_ai_processing.py ├── test_auth.py ├── test_cognitive_profile.py ├── test_game_definition.py ├── test_game_instance.py ├── test_game_management.py ├── test_game_model.py ├── test_games.py ├── test_llm.py ├── test_llm_processing.py ├── test_llm_response.py ├── test_llm_schema.py ├── test_llm_service.py ├── test_llm_service_integration.py ├── test_user_management.py ├── test_user_model.py └── test_user_profile.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec tec.md .cursor # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # UV # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. #uv.lock # poetry # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. #pdm.lock # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it # in version control. # https://pdm.fming.dev/latest/usage/project/#working-with-version-control .pdm.toml .pdm-python .pdm-build/ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ prd.env env.bak/ venv.bak/ config.toml # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ .project_structure.json # PyCharm # JetBrains specific template is maintained in a separate JetBrains.gitignore that can # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ # PyPI configuration file .pypirc # Python __pycache__/ *.pyc # Environment .env /scripts # VSCode .vscode/ ================================================ FILE: .python-version ================================================ 3.13 ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # HAGAMEAI HAGAMEAI is a training framework for AI game evolution. By constructing diverse game scenario components, from strategic confrontations to simulation, it enhances AI's learning mechanisms, decision-making processes, and its ability to collaborate or compete with humans in complex environments, providing foundational AI support for all game-related scenarios. Experience AviaFlick, an ecological game based on HAGAMEAI, by visiting: [t.me/HAGAMEAI_CHANNEL](https://t.me/HAGAMEAI_CHANNEL) --- ## Architecture & Technology Stack - **Language:** Python 3.10+ - **Framework:** FastAPI (async, high performance, Pydantic validation) - **Database:** PostgreSQL (with JSONB support) - **Async ORM:** SQLAlchemy (async) or Tortoise ORM - **Task Queue:** Celery (with Redis or RabbitMQ) - **LLM SDKs:** OpenAI, Google AI - **Cache:** Redis (for session, rate limit, and caching) - **Containerization:** Docker, Docker Compose - **Monitoring:** Prometheus, Grafana - **Logging:** ELK Stack or Grafana Loki - **Dependency Management:** [uv](https://github.com/astral-sh/uv) with `pyproject.toml` --- ## Environment Setup 1. Ensure you have Python 3.10+ installed. 2. Install dependencies using `uv`: ```bash uv pip install -r pyproject.toml ``` 3. Copy `.env.example` to `.env` and fill in your configuration: ```bash cp .env.example .env ``` **Required variables:** - `DATABASE_URL`: PostgreSQL async URL (e.g. `postgresql+asyncpg://user:password@localhost:5432/hagame_db`) - `SECRET_KEY`: Secret key for JWT - `ALGORITHM`: JWT algorithm (default: HS256) - `ACCESS_TOKEN_EXPIRE_MINUTES`: JWT expiration in minutes (default: 60) --- ## Running the Application ```bash uvicorn main:app --reload ``` Visit [http://localhost:8000/](http://localhost:8000/) for the health check (`{"status": "ok"}`) and [http://localhost:8000/docs](http://localhost:8000/docs) for the OpenAPI documentation. --- ## System Modules & API Overview ### 1. User Authentication & Profile Management - **Purpose:** Secure user registration, login (JWT), and management of user profiles and cognitive profiles. - **Key Endpoints:** - `POST /auth/register` — Register a new user - `POST /auth/login` — Obtain JWT access token - `GET /auth/me` — Retrieve current user info (JWT required) - `GET/PUT /users/me/profile` — Get or update user profile - `GET/PUT /users/me/cognitive-profile` — Get or update cognitive profile - **Features:** - JWT-based authentication - Pydantic validation - Logging of all key actions - Consistent error handling ### 2. Game Core Framework - **Purpose:** Define, manage, and run game definitions and instances, supporting plugin/strategy patterns for extensibility. - **Key Endpoints:** - `GET/POST /games/definitions` — List or create game definitions - `GET /games/definitions/{game_def_id}` — Get a game definition by ID - `POST /games/instances` — Create a new game instance - `GET /games/instances/{instance_id}` — Get a game instance by ID - `GET /games/my-instances` — List all game instances for the current user - **Features:** - Async endpoints - Pydantic schemas - JWT protection - Extensible game engine design ### 3. AI Engine - **Purpose:** Provide adaptive prediction, cognitive modeling, quantum uncertainty, collective wisdom aggregation, and explainable AI (XAI) services. - **Key Endpoints:** - `GET /ai-models/` — List all AI models - `POST /ai-models/` — Create a new AI model - `GET /ai-models/{model_id}` — Get an AI model by ID - **Features:** - Modular AI engine (prediction, cognitive modeling, XAI, etc.) - Integration with LLMs for advanced reasoning and feedback ### 4. LLM Integration Service - **Purpose:** Centralized gateway for all LLM API calls (OpenAI, Gemini, etc.), prompt management, and LLM call logging. - **Key Endpoints:** - `POST /llm/call` — Call an LLM API - `GET /llm/logs` — List all LLM call logs for the current user - **Features:** - Centralized API key management - Prompt versioning and management - Error handling and retries - Caching of LLM responses ### 5. Async Task Processing (Planned) - **Purpose:** Offload long-running or resource-intensive operations to background tasks using Celery. - **Planned Use Cases:** - AI model training and batch predictions - Cognitive profile analysis and updates - Generating detailed feedback reports - Long-running LLM interactions - Data aggregation and statistics - **Integration:** - Celery with Redis or RabbitMQ as broker and backend - Task definitions in `tasks.py` (to be implemented) ### 6. Monitoring & Logging - **Purpose:** Provide observability, performance monitoring, and structured logging for all modules. - **Stack:** - **Monitoring:** Prometheus, Grafana - **Logging:** ELK Stack (Elasticsearch, Logstash, Kibana) or Grafana Loki - **Features:** - Structured logging for all key actions and errors - Metrics for API performance and background tasks --- ## Data Models The backend uses async ORM models (SQLAlchemy/Tortoise) with Pydantic schemas for validation. Key entities include: - **User:** Authentication and profile data - **CognitiveProfile:** Dynamic user cognitive modeling (JSONB) - **GameDefinition:** Game rules, parameters, and configuration (JSONB) - **GameInstance:** Game session state, status, and results (JSONB) - **AIModel:** AI model configuration and metadata - **UserDecisionLog:** User actions and context during games - **Feedback:** System- or LLM-generated feedback for users --- ## Future Work Planned features and modules (see `docs/roadmap.md` for details): - Developer API/SDK - Multimodal interaction support - Emotion intelligence analysis - Advanced AI model integration - Federated learning support --- ## References - [Project Roadmap](docs/roadmap.md) - [OpenAPI Docs](http://localhost:8000/docs) --- ## License This project is licensed under the **Apache License 2.0**. You are free to use, modify, and distribute this software under the terms of the license. See the [LICENSE](LICENSE) file for the full license text and details. For questions or contributions, please refer to the technical documentation and roadmap, and follow the project coding and architectural guidelines strictly. # HAGAME AI Engine HAGAME AI Engine is an advanced artificial intelligence system designed for game environments, providing adaptive learning, cognitive modeling, and strategic decision-making capabilities. ## Features ### AI Engine Components 1. **Adaptive Prediction Engine** - Real-time prediction of game states and player behavior - Adaptive learning from gameplay patterns - Multi-model prediction system with confidence scoring 2. **Cognitive Model Builder** - Player cognitive profile generation - Learning style analysis - Skill level assessment and tracking - Adaptability measurement 3. **Quantum Uncertainty Generator** - Quantum-inspired uncertainty modeling - Multi-dimensional uncertainty factors - Entanglement-based correlation analysis - Dynamic decoherence rate adjustment 4. **Collective Wisdom Aggregator** - Pattern recognition across game sessions - Strategy effectiveness analysis - Meta-learning from collective experiences - Trend and anomaly detection 5. **Explainable AI (XAI)** - Natural language explanations of AI decisions - Feature importance analysis - Counterfactual reasoning - Confidence level assessment ## Installation 1. Clone the repository: ```bash git clone https://github.com/hagame/hagamesai.git cd hagamesai ``` 2. Create a virtual environment and activate it: ```bash python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate ``` 3. Install dependencies: ```bash pip install -e . ``` ## Configuration 1. Create a `.env` file in the project root with the following variables: ```env DATABASE_URL=postgresql+asyncpg://user:password@localhost/hagame REDIS_URL=redis://localhost:6379/0 SECRET_KEY=your-secret-key ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=30 ``` 2. Initialize the database: ```bash alembic upgrade head ``` ## Usage 1. Start the API server: ```bash uvicorn main:app --reload ``` 2. Start the Celery worker: ```bash celery -A core.celery_app worker --loglevel=info ``` ## API Documentation Once the server is running, access the API documentation at: - Swagger UI: `http://localhost:8000/docs` - ReDoc: `http://localhost:8000/redoc` ## Development ### Project Structure ``` hagamesai/ ├── alembic/ # Database migrations ├── api/ # API routes and endpoints ├── core/ # Core functionality │ ├── ai_engine/ # AI Engine components │ │ ├── base.py # Base AI component class │ │ ├── prediction.py # Adaptive Prediction Engine │ │ ├── cognitive.py # Cognitive Model Builder │ │ ├── quantum.py # Quantum Uncertainty Generator │ │ ├── collective.py # Collective Wisdom Aggregator │ │ └── xai.py # Explainable AI │ ├── auth.py # Authentication │ ├── config.py # Configuration │ └── database.py # Database setup ├── crud/ # Database operations ├── models/ # SQLAlchemy models ├── schemas/ # Pydantic schemas └── tests/ # Test suite ``` ### Running Tests ```bash pytest ``` ### Contributing 1. Fork the repository 2. Create a feature branch 3. Commit your changes 4. Push to the branch 5. Create a Pull Request ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Acknowledgments - The HAGAME Team - Contributors and maintainers - The open-source community ## Contact - Email: team@hagame.ai - GitHub: [https://github.com/hagame/hagamesai](https://github.com/hagame/hagamesai) ================================================ FILE: alembic/README ================================================ Generic single-database configuration. ================================================ FILE: alembic/env.py ================================================ from models.user import Base # Import your Base object here from logging.config import fileConfig from sqlalchemy import engine_from_config from sqlalchemy import pool from alembic import context import os from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config # Set the SQLAlchemy URL from environment variable config.set_main_option("sqlalchemy.url", os.environ.get("DATABASE_URL")) # Interpret the config file for Python logging. # This line sets up loggers basically. if config.config_file_name is not None: fileConfig(config.config_file_name) # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel target_metadata = Base.metadata # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. def run_migrations_offline() -> None: """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ url = config.get_main_option("sqlalchemy.url") context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() def run_migrations_online() -> None: """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata ) with context.begin_transaction(): context.run_migrations() if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online() ================================================ FILE: alembic/script.py.mako ================================================ """${message} Revision ID: ${up_revision} Revises: ${down_revision | comma,n} Create Date: ${create_date} """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa ${imports if imports else ""} # revision identifiers, used by Alembic. revision: str = ${repr(up_revision)} down_revision: Union[str, None] = ${repr(down_revision)} branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} def upgrade() -> None: """Upgrade schema.""" ${upgrades if upgrades else "pass"} def downgrade() -> None: """Downgrade schema.""" ${downgrades if downgrades else "pass"} ================================================ FILE: alembic.ini ================================================ # A generic, single database configuration. [alembic] # path to migration scripts # Use forward slashes (/) also on windows to provide an os agnostic path script_location = alembic # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time # see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file # for all available tokens # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s # sys.path path, will be prepended to sys.path if present. # defaults to the current working directory. prepend_sys_path = . # timezone to use when rendering the date within the migration file # as well as the filename. # If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library. # Any required deps can installed by adding `alembic[tz]` to the pip requirements # string value is passed to ZoneInfo() # leave blank for localtime # timezone = # max length of characters to apply to the "slug" field # truncate_slug_length = 40 # set to 'true' to run the environment during # the 'revision' command, regardless of autogenerate # revision_environment = false # set to 'true' to allow .pyc and .pyo files without # a source .py file to be detected as revisions in the # versions/ directory # sourceless = false # version location specification; This defaults # to alembic/versions. When using multiple version # directories, initial revisions must be specified with --version-path. # The path separator used here should be the separator specified by "version_path_separator" below. # version_locations = %(here)s/bar:%(here)s/bat:alembic/versions # version path separator; As mentioned above, this is the character used to split # version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. # If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. # Valid values for version_path_separator are: # # version_path_separator = : # version_path_separator = ; # version_path_separator = space # version_path_separator = newline # # Use os.pathsep. Default configuration used for new projects. version_path_separator = os # set to 'true' to search source files recursively # in each "version_locations" directory # new in Alembic version 1.10 # recursive_version_locations = false # the output encoding used when revision files # are written from script.py.mako # output_encoding = utf-8 # The sqlalchemy.url can be uncommented here, but it will be overridden by env.py # sqlalchemy.url = driver://user:pass@localhost/dbname [post_write_hooks] # post_write_hooks defines scripts or Python functions that are run # on newly generated revision scripts. See the documentation for further # detail and examples # format using "black" - use the console_scripts runner, against the "black" entrypoint # hooks = black # black.type = console_scripts # black.entrypoint = black # black.options = -l 79 REVISION_SCRIPT_FILENAME # lint with attempts to fix using "ruff" - use the exec runner, execute a binary # hooks = ruff # ruff.type = exec # ruff.executable = %(here)s/.venv/bin/ruff # ruff.options = check --fix REVISION_SCRIPT_FILENAME # Logging configuration [loggers] keys = root,sqlalchemy,alembic [handlers] keys = console [formatters] keys = generic [logger_root] level = WARNING handlers = console qualname = [logger_sqlalchemy] level = WARNING handlers = qualname = sqlalchemy.engine [logger_alembic] level = INFO handlers = qualname = alembic [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(levelname)-5.5s [%(name)s] %(message)s datefmt = %H:%M:%S ================================================ FILE: api/__init__.py ================================================ ================================================ FILE: api/ai.py ================================================ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List, Dict, Any, Optional from schemas.ai_model import AIModelCreate, AIModelRead, AIModelUpdate from services import AIModelService from core.database import get_db from models.cognitive_profile import CognitiveProfile router = APIRouter(prefix="/ai_models", tags=["ai_models"]) @router.post("/", response_model=AIModelRead) async def create_model( model_data: AIModelCreate, db: Session = Depends(get_db) ): """Create a new AI model.""" service = AIModelService(db) return await service.create_model(model_data) @router.get("/{model_id}", response_model=AIModelRead) async def get_model( model_id: int, db: Session = Depends(get_db) ): """Get AI model by ID.""" service = AIModelService(db) model = await service.get_model(model_id) if not model: raise HTTPException(status_code=404, detail="Model not found") return model @router.put("/{model_id}", response_model=AIModelRead) async def update_model( model_id: int, model_data: AIModelUpdate, db: Session = Depends(get_db) ): """Update AI model configuration.""" service = AIModelService(db) return await service.update_model(model_id, model_data) @router.post("/{model_id}/predict") async def predict( model_id: int, input_data: Dict[str, Any], cognitive_profile: Optional[CognitiveProfile] = None, db: Session = Depends(get_db) ): """Generate predictions using the AI model.""" service = AIModelService(db) return await service.predict(model_id, input_data, cognitive_profile) @router.post("/{model_id}/explain") async def explain( model_id: int, input_data: Dict[str, Any], db: Session = Depends(get_db) ): """Generate model explanations.""" service = AIModelService(db) return await service.explain(model_id, input_data) ================================================ FILE: api/auth.py ================================================ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from schemas.user import UserCreate, UserLogin, UserRead from crud.user import get_user_by_email, create_user from core.database import get_async_session from core.auth import verify_password, create_access_token, get_current_user from fastapi.responses import JSONResponse from core.logging import get_logger logger = get_logger(__name__) router = APIRouter(prefix="/auth", tags=["auth"]) @router.post( "/register", response_model=UserRead, status_code=status.HTTP_201_CREATED, summary="Register a new user", response_description="The newly registered user's information.", responses={ 201: { "description": "User registered successfully.", "content": { "application/json": { "example": { "id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "username": "testuser", "email": "test@example.com", "created_at": "2024-06-01T12:00:00Z", "updated_at": "2024-06-01T12:00:00Z" } } } }, 400: {"description": "Email already registered."} } ) async def register_user(user_in: UserCreate, session: AsyncSession = Depends(get_async_session)) -> UserRead: """ Register a new user with a unique email and username. """ logger.info(f"Registration attempt for email: {user_in.email}") existing = await get_user_by_email(session, user_in.email) if existing: logger.warning( f"Registration failed: Email already registered ({user_in.email})") raise HTTPException( status_code=400, detail="Email already registered.") user = await create_user(session, user_in) logger.info(f"User registered successfully: {user.email}") return UserRead.from_orm(user) @router.post( "/login", summary="Authenticate user and return JWT", response_description="JWT access token and token type.", responses={ 200: { "description": "Login successful.", "content": { "application/json": { "example": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer" } } } }, 401: {"description": "Invalid credentials."} } ) async def login_user(user_in: UserLogin, session: AsyncSession = Depends(get_async_session)): """ Authenticate user with email and password. Returns a JWT access token if successful. """ logger.info(f"Login attempt for email: {user_in.email}") user = await get_user_by_email(session, user_in.email) if not user or not verify_password(user_in.password, user.hashed_password): logger.warning(f"Login failed for email: {user_in.email}") raise HTTPException(status_code=401, detail="Invalid credentials.") token_data = {"sub": str(user.id), "email": user.email} access_token = create_access_token(token_data) logger.info(f"Login successful for email: {user.email}") return {"access_token": access_token, "token_type": "bearer"} @router.get( "/me", response_model=UserRead, summary="Get current authenticated user's info", response_description="The current user's information.", responses={ 200: { "description": "Current user info returned.", "content": { "application/json": { "example": { "id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "username": "testuser", "email": "test@example.com", "created_at": "2024-06-01T12:00:00Z", "updated_at": "2024-06-01T12:00:00Z" } } } }, 401: {"description": "Not authenticated."} } ) async def get_me(current_user=Depends(get_current_user)): """ Get the current authenticated user's information using the JWT access token. """ logger.info(f"Get current user info: {current_user.email}") return UserRead.from_orm(current_user) ================================================ FILE: api/games.py ================================================ from fastapi import APIRouter, HTTPException, Depends from typing import List from crud.game_definition import GameDefinitionCRUD from crud.game_instance import GameInstanceCRUD from schemas.game_definition import GameDefinitionCreate, GameDefinitionUpdate, GameDefinition from schemas.game_instance import GameInstanceCreate, GameInstanceUpdate, GameInstance router = APIRouter() def get_game_definition_crud(): return GameDefinitionCRUD() def get_game_instance_crud(): return GameInstanceCRUD() @router.post('/game-definitions/', response_model=GameDefinition) async def create_game_definition(game_definition: GameDefinitionCreate, crud: GameDefinitionCRUD = Depends(get_game_definition_crud)): return await crud.create(game_definition) @router.get('/game-definitions/', response_model=List[GameDefinition]) async def list_game_definitions(crud: GameDefinitionCRUD = Depends(get_game_definition_crud)): return await crud.get_all() @router.put('/game-definitions/{game_id}', response_model=GameDefinition) async def update_game_definition(game_id: int, game_definition: GameDefinitionUpdate, crud: GameDefinitionCRUD = Depends(get_game_definition_crud)): existing_definition = await crud.get(game_id) if not existing_definition: raise HTTPException(status_code=404, detail='Game definition not found') return await crud.update(game_id, game_definition) @router.delete('/game-definitions/{game_id}', status_code=204) async def delete_game_definition(game_id: int, crud: GameDefinitionCRUD = Depends(get_game_definition_crud)): existing_definition = await crud.get(game_id) if not existing_definition: raise HTTPException(status_code=404, detail='Game definition not found') await crud.delete(game_id) @router.post('/game-instances/', response_model=GameInstance) async def create_game_instance(game_instance: GameInstanceCreate, crud: GameInstanceCRUD = Depends(get_game_instance_crud)): return await crud.create(game_instance) @router.get('/game-instances/', response_model=List[GameInstance]) async def list_game_instances(crud: GameInstanceCRUD = Depends(get_game_instance_crud)): return await crud.get_all() @router.put('/game-instances/{instance_id}', response_model=GameInstance) async def update_game_instance(instance_id: int, game_instance: GameInstanceUpdate, crud: GameInstanceCRUD = Depends(get_game_instance_crud)): existing_instance = await crud.get(instance_id) if not existing_instance: raise HTTPException(status_code=404, detail='Game instance not found') return await crud.update(instance_id, game_instance) @router.delete('/game-instances/{instance_id}', status_code=204) async def delete_game_instance(instance_id: int, crud: GameInstanceCRUD = Depends(get_game_instance_crud)): existing_instance = await crud.get(instance_id) if not existing_instance: raise HTTPException(status_code=404, detail='Game instance not found') await crud.delete(instance_id) ================================================ FILE: api/llm.py ================================================ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from llm_service.schemas import LLMCallRequest, LLMCallResponse, LLMCallLogRead from llm_service.service import LLMIntegrationService from llm_service.crud import create_log, list_logs_by_user from core.database import get_async_session from core.auth import get_current_user from core.logging import get_logger from core.tasks import call_llm_task from schemas.task import TaskStatus import uuid logger = get_logger(__name__) # llm_service = LLMIntegrationService() # No longer instantiated directly in endpoint router = APIRouter(prefix="/llm", tags=["llm"]) @router.post("/call", response_model=TaskStatus, summary="Trigger async LLM API call") async def call_llm_endpoint( req: LLMCallRequest, current_user=Depends(get_current_user), ) -> TaskStatus: """Trigger an asynchronous LLM API call and return the task ID.""" logger.info( f"User {current_user.email} triggering async LLM call: {req.provider}/{req.model}") # Attach user_id to request data for the task req_data = req.dict() # Pass UUID as string for serialization req_data["user_id"] = str(current_user.id) # Trigger the Celery task task = call_llm_task.delay(req_data) # Return the task status immediately return TaskStatus(task_id=task.id, status=task.status) @router.get("/logs", response_model=list[LLMCallLogRead], summary="List user's LLM call logs") async def get_logs( session: AsyncSession = Depends(get_async_session), current_user=Depends(get_current_user), ): """List all LLM call logs for the current user.""" logger.info(f"Listing LLM call logs for user: {current_user.email}") logs = await list_logs_by_user(session, current_user.id) # Ensure orm_mode is True on LLMCallLogRead for serialization return [LLMCallLogRead.from_orm(log) for log in logs] ================================================ FILE: api/llm_service.py ================================================ from fastapi import APIRouter, HTTPException from pydantic import BaseModel router = APIRouter() class LLMRequest(BaseModel): prompt: str max_tokens: int = 100 class LLMResponse(BaseModel): result: str @router.post("/llm/generate", response_model=LLMResponse) async def generate_response(request: LLMRequest): """Generates a response from the LLM based on the given prompt.""" try: # Here you would integrate with your LLM service to generate a response # For now, we'll simulate a response simulated_response = f"Response to: {request.prompt}" return LLMResponse(result=simulated_response) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # Include this router in your main API application ================================================ FILE: api/llm_service_utils.py ================================================ """ Utility functions for LLM service This module contains utility functions that assist in the operation of the LLM services. These functions are designed to facilitate common tasks and enhance code reusability. """ from typing import Any, Dict, List def preprocess_input(input_data: Dict[str, Any]) -> Dict[str, Any]: """ Preprocess the input data for the LLM. Parameters: - input_data: A dictionary containing input data. Returns: A dictionary with preprocessed data. """ # Example preprocessing steps processed_data = { "text": input_data.get("text", "").strip(), "parameters": input_data.get("parameters", {}), } return processed_data def format_response(response_data: Any) -> Dict[str, Any]: """ Format the response data from the LLM into a standard structure. Parameters: - response_data: The raw response data from the LLM. Returns: A formatted dictionary containing the response. """ formatted_response = { "success": True, "data": response_data } return formatted_response def log_llm_request(request_data: Dict[str, Any]) -> None: """ Log the LLM request for auditing purposes. Parameters: - request_data: The data related to the LLM request. """ # Here you would implement logging logic, for example: # log.info(f"LLM Request: {request_data}") pass # Replace with actual logging implementation def handle_error(error: Exception) -> Dict[str, Any]: """ Handle errors that occur during LLM operations. Parameters: - error: The exception that was raised. Returns: A dictionary containing error information. """ return { "success": False, "message": str(error) } ================================================ FILE: api/routers/ai_engine.py ================================================ """API router for AI Engine endpoints.""" from typing import Dict, Any from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from core.database import get_db from core.auth import get_current_user from core.ai_engine import ( AIEngine, AdaptivePredictionEngine, CognitiveModelBuilder, QuantumUncertaintyGenerator, CollectiveWisdomAggregator, ExplainableAI ) from schemas.user import User from schemas.game import GameState router = APIRouter(prefix="/ai", tags=["AI Engine"]) # Initialize AI Engine components ai_engine = AIEngine() @router.on_event("startup") async def initialize_ai_engine(): """Initialize AI Engine components on startup.""" await ai_engine.initialize_components() @router.post("/predict") async def predict_game_state( game_state: GameState, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, Any]: """ Process current game state and make predictions. This endpoint: 1. Generates uncertainty factors 2. Updates cognitive model 3. Makes predictions 4. Aggregates collective wisdom 5. Provides explanations """ try: # Prepare input data input_data = { "game_id": game_state.game_id, "player_id": current_user.id, "game_state": game_state.dict(), "player_state": { "id": current_user.id, "profile": current_user.profile.dict() if current_user.profile else {} } } # Process game state through AI Engine result = await ai_engine.process_game_state(input_data) return result except Exception as e: raise HTTPException( status_code=500, detail=f"Error processing game state: {str(e)}" ) @router.post("/feedback") async def provide_feedback( feedback: Dict[str, Any], current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, str]: """ Provide feedback to update AI models. This endpoint accepts feedback about: - Prediction accuracy - Cognitive model accuracy - Uncertainty estimation accuracy - Collective wisdom relevance - Explanation clarity """ try: # Add user context to feedback feedback["player_id"] = current_user.id # Update AI components with feedback await ai_engine.update_components(feedback) return {"status": "Feedback processed successfully"} except Exception as e: raise HTTPException( status_code=500, detail=f"Error processing feedback: {str(e)}" ) @router.get("/cognitive-profile/{player_id}") async def get_cognitive_profile( player_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, Any]: """Get cognitive profile for a player.""" try: if current_user.id != player_id and not current_user.is_admin: raise HTTPException( status_code=403, detail="Not authorized to access this profile" ) cognitive_builder = ai_engine.cognitive_builder if not cognitive_builder: raise HTTPException( status_code=500, detail="Cognitive Model Builder not initialized" ) profile = cognitive_builder.profiles.get(player_id) if not profile: raise HTTPException( status_code=404, detail="Cognitive profile not found" ) return profile.dict() except HTTPException: raise except Exception as e: raise HTTPException( status_code=500, detail=f"Error retrieving cognitive profile: {str(e)}" ) @router.get("/collective-wisdom/{game_id}") async def get_collective_wisdom( game_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, Any]: """Get collective wisdom insights for a game.""" try: wisdom_aggregator = ai_engine.wisdom_aggregator if not wisdom_aggregator: raise HTTPException( status_code=500, detail="Collective Wisdom Aggregator not initialized" ) # Get latest knowledge for the game knowledge = next( (k for k in reversed(wisdom_aggregator.knowledge_base) if k.game_id == game_id), None ) if not knowledge: raise HTTPException( status_code=404, detail="No collective wisdom found for this game" ) return knowledge.dict() except HTTPException: raise except Exception as e: raise HTTPException( status_code=500, detail=f"Error retrieving collective wisdom: {str(e)}" ) @router.get("/explanations/{game_id}") async def get_explanations( game_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, Any]: """Get AI explanations for a game.""" try: xai_system = ai_engine.xai_system if not xai_system: raise HTTPException( status_code=500, detail="Explainable AI system not initialized" ) # Get latest explanation for the game explanation = next( (e for e in reversed(xai_system.explanation_history) if e.game_id == game_id), None ) if not explanation: raise HTTPException( status_code=404, detail="No explanations found for this game" ) return explanation.dict() except HTTPException: raise except Exception as e: raise HTTPException( status_code=500, detail=f"Error retrieving explanations: {str(e)}" ) @router.get("/uncertainty/{game_id}") async def get_uncertainty_factors( game_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ) -> Dict[str, Any]: """Get uncertainty factors for a game.""" try: uncertainty_generator = ai_engine.quantum_generator if not uncertainty_generator: raise HTTPException( status_code=500, detail="Quantum Uncertainty Generator not initialized" ) # Get latest uncertainty factors for the game factors = next( (f for f in reversed(uncertainty_generator.uncertainty_history) if f.game_id == game_id), None ) if not factors: raise HTTPException( status_code=404, detail="No uncertainty factors found for this game" ) return factors.dict() except HTTPException: raise except Exception as e: raise HTTPException( status_code=500, detail=f"Error retrieving uncertainty factors: {str(e)}" ) ================================================ FILE: api/tasks.py ================================================ from fastapi import APIRouter, Depends, HTTPException, status from schemas.task import TaskTrigger, TaskStatus from core.tasks import example_task from core.logging import get_logger from celery.result import AsyncResult logger = get_logger(__name__) router = APIRouter(prefix="/tasks", tags=["tasks"]) @router.post("/example", response_model=TaskStatus, summary="Trigger example async task") async def trigger_example_task(task_in: TaskTrigger) -> TaskStatus: """Trigger an example Celery task with a given sleep duration.""" logger.info( f"Triggering example task with {task_in.seconds} seconds sleep") task = example_task.delay(task_in.seconds) return TaskStatus(task_id=task.id, status=task.status, result=task.result) @router.get("/status/{task_id}", response_model=TaskStatus, summary="Get status of an async task") async def get_task_status(task_id: str) -> TaskStatus: """Get the current status and result of a Celery task by ID.""" task_result = AsyncResult(task_id) return TaskStatus(task_id=task_result.id, status=task_result.status, result=task_result.result) ================================================ FILE: api/test_llm.py ================================================ import pytest from fastapi.testclient import TestClient from api.llm import app # Create a test client using the FastAPI app client = TestClient(app) @pytest.fixture(scope="module") def test_client(): yield client def test_llm_endpoint_valid_request(test_client): # Test a valid request to the LLM endpoint response = test_client.post("/llm", json={ "prompt": "What is AI?", "max_tokens": 50 }) assert response.status_code == 200 assert "choices" in response.json() def test_llm_endpoint_invalid_request(test_client): # Test an invalid request to the LLM endpoint response = test_client.post("/llm", json={}) assert response.status_code == 422 # Unprocessable Entity assert "detail" in response.json() def test_llm_endpoint_edge_case(test_client): # Test an edge case request to the LLM endpoint response = test_client.post("/llm", json={ "prompt": "" }) assert response.status_code == 400 # Bad Request assert "detail" in response.json() ================================================ FILE: api/users.py ================================================ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from schemas.user import UserRead, UserUpdate from schemas.cognitive_profile import CognitiveProfileRead, CognitiveProfileUpdate from crud.user import update_user from crud.cognitive_profile import get_by_user_id, create_profile, update_profile from core.database import get_async_session from core.auth import get_current_user from core.logging import get_logger logger = get_logger(__name__) router = APIRouter(prefix="/users/me", tags=["users"]) @router.get( "/profile", response_model=UserRead, summary="Get current user's profile info", response_description="The current user's profile information.", responses={ 200: { "description": "Current user profile info returned.", "content": { "application/json": { "example": { "id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "username": "testuser", "email": "test@example.com", "created_at": "2024-06-01T12:00:00Z", "updated_at": "2024-06-01T12:00:00Z" } } } }, 401: {"description": "Not authenticated."} } ) async def get_profile(current_user=Depends(get_current_user)): """ Get the current user's profile information using the JWT access token. """ logger.info(f"Profile access for user: {current_user.email}") return UserRead.from_orm(current_user) @router.put( "/profile", response_model=UserRead, summary="Update current user's profile info", response_description="The updated user's profile information.", responses={ 200: { "description": "User profile updated successfully.", "content": { "application/json": { "example": { "id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "username": "updateduser", "email": "updated@example.com", "created_at": "2024-06-01T12:00:00Z", "updated_at": "2024-06-02T12:00:00Z" } } } }, 400: {"description": "Invalid update data."}, 401: {"description": "Not authenticated."} } ) async def update_profile_info( user_update: UserUpdate, current_user=Depends(get_current_user), session: AsyncSession = Depends(get_async_session), ): """ Update the current user's profile information. Only provided fields will be updated. """ logger.info(f"Profile update attempt for user: {current_user.email}") user = await update_user(session, current_user, user_update) logger.info(f"Profile updated for user: {user.email}") return UserRead.from_orm(user) @router.get( "/cognitive-profile", response_model=CognitiveProfileRead, summary="Get current user's cognitive profile", response_description="The current user's cognitive profile information.", responses={ 200: { "description": "Current user cognitive profile info returned.", "content": { "application/json": { "example": { "id": "c7e2b3b7-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "user_id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "profile_data": {"risk_aversion": 0.7, "decision_speed": "fast"}, "last_updated": "2024-06-01T12:00:00Z" } } } }, 401: {"description": "Not authenticated."}, 404: {"description": "Cognitive profile not found."} } ) async def get_cognitive_profile( current_user=Depends(get_current_user), session: AsyncSession = Depends(get_async_session), ): """ Get the current user's cognitive profile. Returns 404 if not found. """ logger.info(f"Cognitive profile access for user: {current_user.email}") profile = await get_by_user_id(session, current_user.id) if not profile: logger.warning( f"Cognitive profile not found for user: {current_user.email}") raise HTTPException( status_code=404, detail="Cognitive profile not found.") return CognitiveProfileRead.from_orm(profile) @router.put( "/cognitive-profile", response_model=CognitiveProfileRead, summary="Update or create current user's cognitive profile", response_description="The updated or newly created cognitive profile information.", responses={ 200: { "description": "Cognitive profile updated or created successfully.", "content": { "application/json": { "example": { "id": "c7e2b3b7-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "user_id": "b3b7c7e2-1c2d-4e2a-8e2b-1c2d4e2a8e2b", "profile_data": {"risk_aversion": 0.8, "decision_speed": "slow"}, "last_updated": "2024-06-02T12:00:00Z" } } } }, 400: {"description": "Invalid update data."}, 401: {"description": "Not authenticated."} } ) async def update_cognitive_profile( update_in: CognitiveProfileUpdate, current_user=Depends(get_current_user), session: AsyncSession = Depends(get_async_session), ): """ Update or create the current user's cognitive profile. If no profile exists, a new one will be created. """ logger.info( f"Cognitive profile update attempt for user: {current_user.email}") profile = await get_by_user_id(session, current_user.id) if profile: profile = await update_profile(session, profile, update_in) logger.info( f"Cognitive profile updated for user: {current_user.email}") else: profile = await create_profile(session, current_user.id, update_in.profile_data) logger.info( f"Cognitive profile created for user: {current_user.email}") return CognitiveProfileRead.from_orm(profile) ================================================ FILE: core/__init__.py ================================================ ================================================ FILE: core/ai_engine/__init__.py ================================================ """ AI Engine Module for HAGAME. This module provides the core AI functionality including: - Adaptive Prediction Engine - Cognitive Model Building System - Quantum Uncertainty Generator - Collective Wisdom Aggregation - Explainable AI (XAI) """ from .base import AIEngine from .prediction import AdaptivePredictionEngine from .cognitive import CognitiveModelBuilder from .quantum import QuantumUncertaintyGenerator from .collective import CollectiveWisdomAggregator from .xai import ExplainableAI __all__ = [ 'AIEngine', 'AdaptivePredictionEngine', 'CognitiveModelBuilder', 'QuantumUncertaintyGenerator', 'CollectiveWisdomAggregator', 'ExplainableAI', ] ================================================ FILE: core/ai_engine/ai_processing.py ================================================ # ai_processing.py """ Main processing logic for AI engine. This module contains the functions necessary for processing AI tasks, including cognitive modeling and decision-making processes based on input data. It provides an interface for integrating various AI algorithms and ensures seamless interaction with other components of the AI engine. """ from typing import Any, Dict import logging # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def process_ai_task(task_data: Dict[str, Any]) -> Dict[str, Any]: """ Process an AI task based on provided task data. Args: task_data (Dict[str, Any]): The input data for the AI task. Returns: Dict[str, Any]: The result of the AI task processing. """ logger.info("Starting AI task processing.") try: # Here, you would implement the specific AI processing logic. # This is just a placeholder for demonstration purposes. result = perform_cognitive_modeling(task_data) logger.info("AI task processing completed successfully.") return result except Exception as e: logger.error(f"Error during AI task processing: {e}") raise def perform_cognitive_modeling(data: Dict[str, Any]) -> Dict[str, Any]: """ Placeholder function for cognitive modeling logic. Args: data (Dict[str, Any]): The input data for cognitive modeling. Returns: Dict[str, Any]: The modeled output data. """ # Implement actual cognitive modeling logic here modeled_output = {"status": "success", "data": data} return modeled_output if __name__ == '__main__': # Example usage example_data = {"input": "sample data"} result = process_ai_task(example_data) print(result) ================================================ FILE: core/ai_engine/ai_utilities.py ================================================ # ai_utilities.py """ Utility functions for AI engine processing. This module contains helper functions for various AI engine tasks, such as processing input data, generating responses, and handling AI model interactions. """ from typing import Any, Dict, List import logging # Configure logging for this module logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def preprocess_input(data: Any) -> Dict[str, Any]: """ Preprocess input data for the AI model. Parameters: data (Any): Raw input data to be processed. Returns: Dict[str, Any]: Processed data ready for AI model. """ logger.info("Preprocessing input data...") # Add preprocessing logic here (e.g., normalization, encoding) processed_data = {} # Example placeholder return processed_data def generate_response(model_output: Any) -> str: """ Generate a human-readable response from the model output. Parameters: model_output (Any): Output from the AI model. Returns: str: Human-readable response. """ logger.info("Generating response from model output...") # Convert model output to a response string response = "" # Example placeholder return response def log_model_interaction(model_name: str, input_data: Any, output_data: Any) -> None: """ Log interaction with the AI model for auditing purposes. Parameters: model_name (str): Name of the AI model being interacted with. input_data (Any): Input data sent to the model. output_data (Any): Output data received from the model. """ logger.info(f"Model Interaction - {model_name}:\n Input: {input_data}\n Output: {output_data}") ================================================ FILE: core/ai_engine/base.py ================================================ """Base class for the AI Engine components.""" from typing import Any, Dict, Optional from abc import ABC, abstractmethod import logging from pydantic import BaseModel logger = logging.getLogger(__name__) class AIComponent(ABC): """Abstract base class for all AI components.""" @abstractmethod async def initialize(self) -> None: """Initialize the AI component.""" pass @abstractmethod async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Process input data and return results.""" pass @abstractmethod async def update(self, feedback: Dict[str, Any]) -> None: """Update the component based on feedback.""" pass class AIEngine: """Main AI Engine class that orchestrates all AI components.""" def __init__(self): self.prediction_engine: Optional['AdaptivePredictionEngine'] = None self.cognitive_builder: Optional['CognitiveModelBuilder'] = None self.quantum_generator: Optional['QuantumUncertaintyGenerator'] = None self.wisdom_aggregator: Optional['CollectiveWisdomAggregator'] = None self.xai_system: Optional['ExplainableAI'] = None async def initialize_components(self) -> None: """Initialize all AI components.""" from .prediction import AdaptivePredictionEngine from .cognitive import CognitiveModelBuilder from .quantum import QuantumUncertaintyGenerator from .collective import CollectiveWisdomAggregator from .xai import ExplainableAI self.prediction_engine = AdaptivePredictionEngine() self.cognitive_builder = CognitiveModelBuilder() self.quantum_generator = QuantumUncertaintyGenerator() self.wisdom_aggregator = CollectiveWisdomAggregator() self.xai_system = ExplainableAI() await self.prediction_engine.initialize() await self.cognitive_builder.initialize() await self.quantum_generator.initialize() await self.wisdom_aggregator.initialize() await self.xai_system.initialize() logger.info("All AI components initialized successfully") async def process_game_state(self, game_state: Dict[str, Any]) -> Dict[str, Any]: """Process the current game state through all AI components.""" try: # Generate quantum uncertainty factors uncertainty = await self.quantum_generator.process(game_state) # Build/update cognitive model cognitive_state = await self.cognitive_builder.process({ **game_state, "uncertainty": uncertainty }) # Make predictions predictions = await self.prediction_engine.process({ **game_state, "cognitive_state": cognitive_state, "uncertainty": uncertainty }) # Aggregate collective wisdom aggregated_wisdom = await self.wisdom_aggregator.process({ **game_state, "predictions": predictions, "cognitive_state": cognitive_state }) # Generate explanations explanations = await self.xai_system.process({ **game_state, "predictions": predictions, "cognitive_state": cognitive_state, "aggregated_wisdom": aggregated_wisdom }) return { "predictions": predictions, "cognitive_state": cognitive_state, "uncertainty": uncertainty, "aggregated_wisdom": aggregated_wisdom, "explanations": explanations } except Exception as e: logger.error(f"Error processing game state: {str(e)}") raise async def update_components(self, feedback: Dict[str, Any]) -> None: """Update all components based on feedback.""" try: await self.prediction_engine.update(feedback) await self.cognitive_builder.update(feedback) await self.quantum_generator.update(feedback) await self.wisdom_aggregator.update(feedback) await self.xai_system.update(feedback) logger.info("All AI components updated successfully") except Exception as e: logger.error(f"Error updating AI components: {str(e)}") raise ================================================ FILE: core/ai_engine/cognitive.py ================================================ """Cognitive Model Builder for HAGAME.""" from typing import Any, Dict, List, Optional import logging import numpy as np from pydantic import BaseModel from .base import AIComponent logger = logging.getLogger(__name__) class CognitiveProfile(BaseModel): """Model for cognitive profile data.""" player_id: str learning_style: str decision_making: Dict[str, float] attention_patterns: Dict[str, float] skill_levels: Dict[str, float] adaptability: float last_updated: float class CognitiveModelBuilder(AIComponent): """Component for building and updating cognitive models of players.""" def __init__(self): self.profiles: Dict[str, CognitiveProfile] = {} self.feature_weights: Dict[str, np.ndarray] = { "learning": np.random.randn(5), "decision": np.random.randn(4), "attention": np.random.randn(3), "skill": np.random.randn(6) } async def initialize(self) -> None: """Initialize cognitive modeling system.""" logger.info("Initializing Cognitive Model Builder") # Initialize base cognitive modeling parameters self._initialize_feature_extractors() def _initialize_feature_extractors(self) -> None: """Initialize feature extraction components.""" self.extractors = { "learning": self._create_learning_extractor(), "decision": self._create_decision_extractor(), "attention": self._create_attention_extractor(), "skill": self._create_skill_extractor() } def _create_learning_extractor(self) -> Dict[str, Any]: """Create extractor for learning style features.""" return { "features": [ "improvement_rate", "error_correction", "pattern_recognition", "knowledge_retention", "adaptation_speed" ], "weights": self.feature_weights["learning"] } def _create_decision_extractor(self) -> Dict[str, Any]: """Create extractor for decision-making features.""" return { "features": [ "reaction_time", "risk_taking", "strategic_depth", "tactical_awareness" ], "weights": self.feature_weights["decision"] } def _create_attention_extractor(self) -> Dict[str, Any]: """Create extractor for attention pattern features.""" return { "features": [ "focus_duration", "distraction_resistance", "multi_tasking" ], "weights": self.feature_weights["attention"] } def _create_skill_extractor(self) -> Dict[str, Any]: """Create extractor for skill level features.""" return { "features": [ "mechanical_skill", "strategic_planning", "resource_management", "spatial_awareness", "timing_precision", "coordination" ], "weights": self.feature_weights["skill"] } async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Process player data and update cognitive model.""" try: player_id = input_data.get("player_id") game_state = input_data.get("game_state", {}) # Extract cognitive features learning_features = self._extract_learning_features(game_state) decision_features = self._extract_decision_features(game_state) attention_features = self._extract_attention_features(game_state) skill_features = self._extract_skill_features(game_state) # Update or create cognitive profile profile = self._update_cognitive_profile( player_id, learning_features, decision_features, attention_features, skill_features ) return profile.dict() except Exception as e: logger.error(f"Error in cognitive model processing: {str(e)}") raise def _extract_learning_features(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Extract learning-related features from game state.""" features = {} extractor = self.extractors["learning"] for feature in extractor["features"]: value = self._calculate_learning_metric(feature, game_state) features[feature] = float(value) return features def _extract_decision_features(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Extract decision-making features from game state.""" features = {} extractor = self.extractors["decision"] for feature in extractor["features"]: value = self._calculate_decision_metric(feature, game_state) features[feature] = float(value) return features def _extract_attention_features(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Extract attention-related features from game state.""" features = {} extractor = self.extractors["attention"] for feature in extractor["features"]: value = self._calculate_attention_metric(feature, game_state) features[feature] = float(value) return features def _extract_skill_features(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Extract skill-related features from game state.""" features = {} extractor = self.extractors["skill"] for feature in extractor["features"]: value = self._calculate_skill_metric(feature, game_state) features[feature] = float(value) return features def _calculate_learning_metric(self, feature: str, game_state: Dict[str, Any]) -> float: """Calculate specific learning-related metric.""" metrics = { "improvement_rate": lambda: self._calc_improvement_rate(game_state), "error_correction": lambda: self._calc_error_correction(game_state), "pattern_recognition": lambda: self._calc_pattern_recognition(game_state), "knowledge_retention": lambda: self._calc_knowledge_retention(game_state), "adaptation_speed": lambda: self._calc_adaptation_speed(game_state) } return metrics.get(feature, lambda: 0.0)() def _calculate_decision_metric(self, feature: str, game_state: Dict[str, Any]) -> float: """Calculate specific decision-making metric.""" metrics = { "reaction_time": lambda: self._calc_reaction_time(game_state), "risk_taking": lambda: self._calc_risk_taking(game_state), "strategic_depth": lambda: self._calc_strategic_depth(game_state), "tactical_awareness": lambda: self._calc_tactical_awareness(game_state) } return metrics.get(feature, lambda: 0.0)() def _calculate_attention_metric(self, feature: str, game_state: Dict[str, Any]) -> float: """Calculate specific attention-related metric.""" metrics = { "focus_duration": lambda: self._calc_focus_duration(game_state), "distraction_resistance": lambda: self._calc_distraction_resistance(game_state), "multi_tasking": lambda: self._calc_multi_tasking(game_state) } return metrics.get(feature, lambda: 0.0)() def _calculate_skill_metric(self, feature: str, game_state: Dict[str, Any]) -> float: """Calculate specific skill-related metric.""" metrics = { "mechanical_skill": lambda: self._calc_mechanical_skill(game_state), "strategic_planning": lambda: self._calc_strategic_planning(game_state), "resource_management": lambda: self._calc_resource_management(game_state), "spatial_awareness": lambda: self._calc_spatial_awareness(game_state), "timing_precision": lambda: self._calc_timing_precision(game_state), "coordination": lambda: self._calc_coordination(game_state) } return metrics.get(feature, lambda: 0.0)() # Calculation methods for learning metrics def _calc_improvement_rate(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("performance_delta", 0.0)) def _calc_error_correction(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("error_correction_rate", 0.0)) def _calc_pattern_recognition(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("pattern_recognition_score", 0.0)) def _calc_knowledge_retention(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("knowledge_retention_rate", 0.0)) def _calc_adaptation_speed(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("adaptation_speed", 0.0)) # Calculation methods for decision metrics def _calc_reaction_time(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("avg_reaction_time", 0.0)) def _calc_risk_taking(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("risk_taking_score", 0.0)) def _calc_strategic_depth(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("strategic_depth_score", 0.0)) def _calc_tactical_awareness(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("tactical_awareness_score", 0.0)) # Calculation methods for attention metrics def _calc_focus_duration(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("focus_duration", 0.0)) def _calc_distraction_resistance(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("distraction_resistance", 0.0)) def _calc_multi_tasking(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("multi_tasking_score", 0.0)) # Calculation methods for skill metrics def _calc_mechanical_skill(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("mechanical_skill_score", 0.0)) def _calc_strategic_planning(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("strategic_planning_score", 0.0)) def _calc_resource_management(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("resource_management_score", 0.0)) def _calc_spatial_awareness(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("spatial_awareness_score", 0.0)) def _calc_timing_precision(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("timing_precision_score", 0.0)) def _calc_coordination(self, game_state: Dict[str, Any]) -> float: return float(game_state.get("coordination_score", 0.0)) def _update_cognitive_profile( self, player_id: str, learning_features: Dict[str, float], decision_features: Dict[str, float], attention_features: Dict[str, float], skill_features: Dict[str, float] ) -> CognitiveProfile: """Update or create cognitive profile for player.""" import time # Calculate learning style learning_style = self._determine_learning_style(learning_features) # Create or update profile profile = CognitiveProfile( player_id=player_id, learning_style=learning_style, decision_making=decision_features, attention_patterns=attention_features, skill_levels=skill_features, adaptability=self._calculate_adaptability(learning_features), last_updated=time.time() ) self.profiles[player_id] = profile return profile def _determine_learning_style(self, learning_features: Dict[str, float]) -> str: """Determine player's learning style based on features.""" styles = { "visual": self._calc_visual_score(learning_features), "kinesthetic": self._calc_kinesthetic_score(learning_features), "analytical": self._calc_analytical_score(learning_features) } return max(styles.items(), key=lambda x: x[1])[0] def _calc_visual_score(self, features: Dict[str, float]) -> float: """Calculate score for visual learning style.""" return features.get("pattern_recognition", 0.0) * 0.6 + features.get("knowledge_retention", 0.0) * 0.4 def _calc_kinesthetic_score(self, features: Dict[str, float]) -> float: """Calculate score for kinesthetic learning style.""" return features.get("improvement_rate", 0.0) * 0.5 + features.get("adaptation_speed", 0.0) * 0.5 def _calc_analytical_score(self, features: Dict[str, float]) -> float: """Calculate score for analytical learning style.""" return features.get("error_correction", 0.0) * 0.7 + features.get("pattern_recognition", 0.0) * 0.3 def _calculate_adaptability(self, learning_features: Dict[str, float]) -> float: """Calculate player's adaptability score.""" weights = { "improvement_rate": 0.3, "adaptation_speed": 0.4, "error_correction": 0.3 } adaptability = sum( learning_features.get(feature, 0.0) * weight for feature, weight in weights.items() ) return float(max(0.0, min(1.0, adaptability))) async def update(self, feedback: Dict[str, Any]) -> None: """Update cognitive model based on feedback.""" try: player_id = feedback.get("player_id") if player_id not in self.profiles: logger.warning( f"No cognitive profile found for player {player_id}") return # Update feature weights based on feedback self._update_feature_weights(feedback) # Re-initialize feature extractors with updated weights self._initialize_feature_extractors() logger.info(f"Updated cognitive model for player {player_id}") except Exception as e: logger.error(f"Error updating cognitive model: {str(e)}") raise def _update_feature_weights(self, feedback: Dict[str, Any]) -> None: """Update feature weights based on feedback.""" learning_rate = 0.01 for feature_type, weights in self.feature_weights.items(): if f"{feature_type}_accuracy" in feedback: accuracy = feedback[f"{feature_type}_accuracy"] gradient = np.array(feedback.get( f"{feature_type}_gradient", [0] * len(weights))) self.feature_weights[feature_type] += learning_rate * \ accuracy * gradient ================================================ FILE: core/ai_engine/cognitive_functions.py ================================================ # cognitive_functions.py """ Module for implementing cognitive functions for the AI engine. This module contains various cognitive processing capabilities that can be utilized by the AI engine to enhance gameplay and decision-making processes. """ from typing import Any, Dict, List def process_cognitive_input(input_data: Dict[str, Any]) -> Dict[str, Any]: """ Process the cognitive input data and perform necessary computations. Args: input_data (Dict[str, Any]): The input data containing cognitive parameters. Returns: Dict[str, Any]: Processed output data with cognitive insights. """ # Placeholder for cognitive processing logic # Here we could apply cognitive models or algorithms # For demonstration, we will just return the input data augmented with a result. output_data = {"result": "Processed cognitive insights based on input"} output_data.update(input_data) # Augment the output with input data return output_data def cognitive_analysis(data: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """ Analyze a list of cognitive data entries and return insights. Args: data (List[Dict[str, Any]]): List of cognitive data entries. Returns: List[Dict[str, Any]]: List of processed data with insights. """ insights = [] for entry in data: insight = process_cognitive_input(entry) insights.append(insight) return insights # Example usage: if __name__ == '__main__': sample_data = [{"cognitive_param": 1}, {"cognitive_param": 2}] results = cognitive_analysis(sample_data) print(results) # Outputs processed insights ================================================ FILE: core/ai_engine/collective.py ================================================ """Collective Wisdom Aggregator for HAGAME.""" from typing import Any, Dict, List, Optional, Tuple import logging import numpy as np from pydantic import BaseModel from .base import AIComponent logger = logging.getLogger(__name__) class CollectiveKnowledge(BaseModel): """Model for collective knowledge data.""" game_id: str timestamp: float patterns: Dict[str, float] strategies: Dict[str, float] meta_insights: Dict[str, Any] confidence_scores: Dict[str, float] class CollectiveWisdomAggregator(AIComponent): """Component for aggregating and analyzing collective game knowledge.""" def __init__(self): self.knowledge_base: List[CollectiveKnowledge] = [] self.pattern_weights: Dict[str, np.ndarray] = {} self.strategy_weights: Dict[str, np.ndarray] = {} self.meta_analyzers: Dict[str, Any] = {} self.confidence_threshold: float = 0.7 async def initialize(self) -> None: """Initialize collective wisdom system.""" logger.info("Initializing Collective Wisdom Aggregator") self._initialize_pattern_recognition() self._initialize_strategy_analysis() self._initialize_meta_analyzers() def _initialize_pattern_recognition(self) -> None: """Initialize pattern recognition components.""" self.pattern_weights = { "behavioral": np.random.randn(5), # Behavioral patterns "temporal": np.random.randn(4), # Time-based patterns "spatial": np.random.randn(6), # Spatial patterns "strategic": np.random.randn(4) # Strategic patterns } def _initialize_strategy_analysis(self) -> None: """Initialize strategy analysis components.""" self.strategy_weights = { "offensive": np.random.randn(3), # Offensive strategies "defensive": np.random.randn(3), # Defensive strategies "resource": np.random.randn(4), # Resource management strategies "social": np.random.randn(3) # Social interaction strategies } def _initialize_meta_analyzers(self) -> None: """Initialize meta-analysis components.""" self.meta_analyzers = { "trend_analyzer": self._create_trend_analyzer(), "correlation_analyzer": self._create_correlation_analyzer(), "anomaly_detector": self._create_anomaly_detector() } def _create_trend_analyzer(self) -> Dict[str, Any]: """Create trend analysis component.""" return { "window_size": 10, "weights": np.random.randn(10), "threshold": 0.5 } def _create_correlation_analyzer(self) -> Dict[str, Any]: """Create correlation analysis component.""" return { "matrix_size": 8, "correlation_matrix": np.random.randn(8, 8), "significance_threshold": 0.3 } def _create_anomaly_detector(self) -> Dict[str, Any]: """Create anomaly detection component.""" return { "baseline": np.zeros(5), "variance_threshold": 2.0, "history_size": 100 } async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Process game data and aggregate collective wisdom.""" try: game_id = input_data.get("game_id") game_state = input_data.get("game_state", {}) predictions = input_data.get("predictions", {}) cognitive_state = input_data.get("cognitive_state", {}) # Analyze patterns patterns = self._analyze_patterns(game_state, predictions) # Analyze strategies strategies = self._analyze_strategies(game_state, cognitive_state) # Perform meta-analysis meta_insights = self._perform_meta_analysis(patterns, strategies) # Calculate confidence scores confidence_scores = self._calculate_confidence_scores( patterns, strategies, meta_insights ) # Create collective knowledge model import time knowledge = CollectiveKnowledge( game_id=game_id, timestamp=time.time(), patterns=patterns, strategies=strategies, meta_insights=meta_insights, confidence_scores=confidence_scores ) self.knowledge_base.append(knowledge) return knowledge.dict() except Exception as e: logger.error(f"Error in collective wisdom processing: {str(e)}") raise def _analyze_patterns( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, float]: """Analyze various patterns in game data.""" patterns = {} # Analyze behavioral patterns behavioral = self._analyze_behavioral_patterns(game_state, predictions) patterns.update(behavioral) # Analyze temporal patterns temporal = self._analyze_temporal_patterns(game_state) patterns.update(temporal) # Analyze spatial patterns spatial = self._analyze_spatial_patterns(game_state) patterns.update(spatial) # Analyze strategic patterns strategic = self._analyze_strategic_patterns(game_state, predictions) patterns.update(strategic) return patterns def _analyze_behavioral_patterns( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, float]: """Analyze behavioral patterns.""" features = self._extract_behavioral_features(game_state, predictions) weights = self.pattern_weights["behavioral"] scores = np.dot(features, weights) return { "aggression_pattern": float(self._sigmoid(scores[0])), "cooperation_pattern": float(self._sigmoid(scores[1])), "risk_pattern": float(self._sigmoid(scores[2])), "learning_pattern": float(self._sigmoid(scores[3])), "adaptation_pattern": float(self._sigmoid(scores[4])) } def _analyze_temporal_patterns(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Analyze temporal patterns.""" features = self._extract_temporal_features(game_state) weights = self.pattern_weights["temporal"] scores = np.dot(features, weights) return { "cycle_pattern": float(self._sigmoid(scores[0])), "progression_pattern": float(self._sigmoid(scores[1])), "timing_pattern": float(self._sigmoid(scores[2])), "sequence_pattern": float(self._sigmoid(scores[3])) } def _analyze_spatial_patterns(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Analyze spatial patterns.""" features = self._extract_spatial_features(game_state) weights = self.pattern_weights["spatial"] scores = np.dot(features, weights) return { "clustering_pattern": float(self._sigmoid(scores[0])), "distribution_pattern": float(self._sigmoid(scores[1])), "movement_pattern": float(self._sigmoid(scores[2])), "territory_pattern": float(self._sigmoid(scores[3])), "position_pattern": float(self._sigmoid(scores[4])), "formation_pattern": float(self._sigmoid(scores[5])) } def _analyze_strategic_patterns( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, float]: """Analyze strategic patterns.""" features = self._extract_strategic_features(game_state, predictions) weights = self.pattern_weights["strategic"] scores = np.dot(features, weights) return { "resource_pattern": float(self._sigmoid(scores[0])), "combat_pattern": float(self._sigmoid(scores[1])), "development_pattern": float(self._sigmoid(scores[2])), "social_pattern": float(self._sigmoid(scores[3])) } def _analyze_strategies( self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> Dict[str, float]: """Analyze various strategies in game data.""" strategies = {} # Analyze offensive strategies offensive = self._analyze_offensive_strategies(game_state) strategies.update(offensive) # Analyze defensive strategies defensive = self._analyze_defensive_strategies(game_state) strategies.update(defensive) # Analyze resource strategies resource = self._analyze_resource_strategies(game_state) strategies.update(resource) # Analyze social strategies social = self._analyze_social_strategies(game_state, cognitive_state) strategies.update(social) return strategies def _analyze_offensive_strategies(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Analyze offensive strategies.""" features = self._extract_offensive_features(game_state) weights = self.strategy_weights["offensive"] scores = np.dot(features, weights) return { "aggressive_strategy": float(self._sigmoid(scores[0])), "tactical_strategy": float(self._sigmoid(scores[1])), "opportunistic_strategy": float(self._sigmoid(scores[2])) } def _analyze_defensive_strategies(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Analyze defensive strategies.""" features = self._extract_defensive_features(game_state) weights = self.strategy_weights["defensive"] scores = np.dot(features, weights) return { "protective_strategy": float(self._sigmoid(scores[0])), "reactive_strategy": float(self._sigmoid(scores[1])), "preventive_strategy": float(self._sigmoid(scores[2])) } def _analyze_resource_strategies(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Analyze resource management strategies.""" features = self._extract_resource_features(game_state) weights = self.strategy_weights["resource"] scores = np.dot(features, weights) return { "gathering_strategy": float(self._sigmoid(scores[0])), "conservation_strategy": float(self._sigmoid(scores[1])), "investment_strategy": float(self._sigmoid(scores[2])), "distribution_strategy": float(self._sigmoid(scores[3])) } def _analyze_social_strategies( self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> Dict[str, float]: """Analyze social interaction strategies.""" features = self._extract_social_features(game_state, cognitive_state) weights = self.strategy_weights["social"] scores = np.dot(features, weights) return { "cooperative_strategy": float(self._sigmoid(scores[0])), "competitive_strategy": float(self._sigmoid(scores[1])), "diplomatic_strategy": float(self._sigmoid(scores[2])) } def _perform_meta_analysis( self, patterns: Dict[str, float], strategies: Dict[str, float] ) -> Dict[str, Any]: """Perform meta-analysis on patterns and strategies.""" meta_insights = {} # Analyze trends trends = self._analyze_trends(patterns, strategies) meta_insights["trends"] = trends # Analyze correlations correlations = self._analyze_correlations(patterns, strategies) meta_insights["correlations"] = correlations # Detect anomalies anomalies = self._detect_anomalies(patterns, strategies) meta_insights["anomalies"] = anomalies return meta_insights def _analyze_trends( self, patterns: Dict[str, float], strategies: Dict[str, float] ) -> Dict[str, List[float]]: """Analyze trends in patterns and strategies.""" analyzer = self.meta_analyzers["trend_analyzer"] combined_data = list(patterns.values()) + list(strategies.values()) if len(self.knowledge_base) >= analyzer["window_size"]: historical_data = np.array([ list(k.patterns.values()) + list(k.strategies.values()) for k in self.knowledge_base[-analyzer["window_size"]:] ]) trends = np.mean( (historical_data - np.mean(historical_data, axis=0)) * analyzer["weights"][:len(combined_data)], axis=0 ) else: trends = np.zeros(len(combined_data)) return { "pattern_trends": trends[:len(patterns)].tolist(), "strategy_trends": trends[len(patterns):].tolist() } def _analyze_correlations( self, patterns: Dict[str, float], strategies: Dict[str, float] ) -> Dict[str, List[Tuple[str, str, float]]]: """Analyze correlations between patterns and strategies.""" analyzer = self.meta_analyzers["correlation_analyzer"] combined_data = list(patterns.items()) + list(strategies.items()) significant_correlations = [] for i, (name1, value1) in enumerate(combined_data): for j, (name2, value2) in enumerate(combined_data[i+1:], i+1): correlation = analyzer["correlation_matrix"][i, j] if abs(correlation) > analyzer["significance_threshold"]: significant_correlations.append( (name1, name2, float(correlation))) return { "significant_correlations": significant_correlations } def _detect_anomalies( self, patterns: Dict[str, float], strategies: Dict[str, float] ) -> Dict[str, List[str]]: """Detect anomalies in patterns and strategies.""" analyzer = self.meta_analyzers["anomaly_detector"] combined_data = np.array( list(patterns.values()) + list(strategies.values())) # Update baseline if enough history if len(self.knowledge_base) > 0: historical_data = np.array([ list(k.patterns.values()) + list(k.strategies.values()) for k in self.knowledge_base[-analyzer["history_size"]:] ]) analyzer["baseline"] = np.mean(historical_data, axis=0) # Detect anomalies deviations = np.abs(combined_data - analyzer["baseline"]) anomaly_indices = np.where( deviations > analyzer["variance_threshold"])[0] # Map anomalies to pattern/strategy names combined_names = list(patterns.keys()) + list(strategies.keys()) anomalies = [combined_names[i] for i in anomaly_indices] return { "detected_anomalies": anomalies } def _calculate_confidence_scores( self, patterns: Dict[str, float], strategies: Dict[str, float], meta_insights: Dict[str, Any] ) -> Dict[str, float]: """Calculate confidence scores for different aspects.""" confidence_scores = {} # Pattern confidence pattern_confidence = np.mean(list(patterns.values())) confidence_scores["pattern_confidence"] = float(pattern_confidence) # Strategy confidence strategy_confidence = np.mean(list(strategies.values())) confidence_scores["strategy_confidence"] = float(strategy_confidence) # Trend confidence trend_confidence = self._calculate_trend_confidence( meta_insights["trends"]) confidence_scores["trend_confidence"] = float(trend_confidence) # Correlation confidence correlation_confidence = self._calculate_correlation_confidence( meta_insights["correlations"] ) confidence_scores["correlation_confidence"] = float( correlation_confidence) # Overall confidence confidence_scores["overall_confidence"] = float(np.mean([ pattern_confidence, strategy_confidence, trend_confidence, correlation_confidence ])) return confidence_scores def _calculate_trend_confidence(self, trends: Dict[str, List[float]]) -> float: """Calculate confidence in trend analysis.""" all_trends = trends["pattern_trends"] + trends["strategy_trends"] return float(np.mean(np.abs(all_trends))) def _calculate_correlation_confidence( self, correlations: Dict[str, List[Tuple[str, str, float]]] ) -> float: """Calculate confidence in correlation analysis.""" if not correlations["significant_correlations"]: return 0.0 return float(np.mean([abs(c[2]) for c in correlations["significant_correlations"]])) def _extract_behavioral_features( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> np.ndarray: """Extract behavioral features from game state.""" return np.array([ float(game_state.get("aggression_level", 0.0)), float(game_state.get("cooperation_level", 0.0)), float(game_state.get("risk_level", 0.0)), float(game_state.get("learning_rate", 0.0)), float(game_state.get("adaptation_rate", 0.0)) ]) def _extract_temporal_features(self, game_state: Dict[str, Any]) -> np.ndarray: """Extract temporal features from game state.""" return np.array([ float(game_state.get("cycle_phase", 0.0)), float(game_state.get("progression_rate", 0.0)), float(game_state.get("timing_accuracy", 0.0)), float(game_state.get("sequence_position", 0.0)) ]) def _extract_spatial_features(self, game_state: Dict[str, Any]) -> np.ndarray: """Extract spatial features from game state.""" return np.array([ float(game_state.get("clustering_density", 0.0)), float(game_state.get("distribution_spread", 0.0)), float(game_state.get("movement_speed", 0.0)), float(game_state.get("territory_control", 0.0)), float(game_state.get("position_advantage", 0.0)), float(game_state.get("formation_cohesion", 0.0)) ]) def _extract_strategic_features( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> np.ndarray: """Extract strategic features from game state.""" return np.array([ float(game_state.get("resource_efficiency", 0.0)), float(game_state.get("combat_effectiveness", 0.0)), float(game_state.get("development_progress", 0.0)), float(game_state.get("social_influence", 0.0)) ]) def _extract_offensive_features(self, game_state: Dict[str, Any]) -> np.ndarray: """Extract offensive strategy features.""" return np.array([ float(game_state.get("attack_frequency", 0.0)), float(game_state.get("tactical_advantage", 0.0)), float(game_state.get("opportunity_usage", 0.0)) ]) def _extract_defensive_features(self, game_state: Dict[str, Any]) -> np.ndarray: """Extract defensive strategy features.""" return np.array([ float(game_state.get("protection_level", 0.0)), float(game_state.get("reaction_speed", 0.0)), float(game_state.get("prevention_effectiveness", 0.0)) ]) def _extract_resource_features(self, game_state: Dict[str, Any]) -> np.ndarray: """Extract resource strategy features.""" return np.array([ float(game_state.get("gathering_rate", 0.0)), float(game_state.get("conservation_rate", 0.0)), float(game_state.get("investment_ratio", 0.0)), float(game_state.get("distribution_efficiency", 0.0)) ]) def _extract_social_features( self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> np.ndarray: """Extract social strategy features.""" return np.array([ float(game_state.get("cooperation_rate", 0.0)), float(game_state.get("competition_level", 0.0)), float(game_state.get("diplomatic_influence", 0.0)) ]) def _sigmoid(self, x: float) -> float: """Apply sigmoid function to scalar value.""" return 1 / (1 + np.exp(-x)) async def update(self, feedback: Dict[str, Any]) -> None: """Update collective wisdom model based on feedback.""" try: # Update pattern recognition weights self._update_pattern_weights(feedback) # Update strategy analysis weights self._update_strategy_weights(feedback) # Update meta-analyzers self._update_meta_analyzers(feedback) logger.info("Updated collective wisdom model") except Exception as e: logger.error(f"Error updating collective wisdom model: {str(e)}") raise def _update_pattern_weights(self, feedback: Dict[str, Any]) -> None: """Update pattern recognition weights based on feedback.""" learning_rate = 0.01 for pattern_type, weights in self.pattern_weights.items(): if f"{pattern_type}_accuracy" in feedback: accuracy = feedback[f"{pattern_type}_accuracy"] gradient = np.array(feedback.get( f"{pattern_type}_gradient", [0] * len(weights))) self.pattern_weights[pattern_type] += learning_rate * \ accuracy * gradient def _update_strategy_weights(self, feedback: Dict[str, Any]) -> None: """Update strategy analysis weights based on feedback.""" learning_rate = 0.01 for strategy_type, weights in self.strategy_weights.items(): if f"{strategy_type}_accuracy" in feedback: accuracy = feedback[f"{strategy_type}_accuracy"] gradient = np.array(feedback.get( f"{strategy_type}_gradient", [0] * len(weights))) self.strategy_weights[strategy_type] += learning_rate * \ accuracy * gradient def _update_meta_analyzers(self, feedback: Dict[str, Any]) -> None: """Update meta-analyzers based on feedback.""" # Update trend analyzer if "trend_accuracy" in feedback: self.meta_analyzers["trend_analyzer"]["weights"] *= ( 1 + 0.1 * (feedback["trend_accuracy"] - 0.5)) # Update correlation analyzer if "correlation_matrix_update" in feedback: update = np.array(feedback["correlation_matrix_update"]) self.meta_analyzers["correlation_analyzer"]["correlation_matrix"] += 0.1 * update # Update anomaly detector if "anomaly_feedback" in feedback: self.meta_analyzers["anomaly_detector"]["variance_threshold"] *= ( 1 + 0.1 * (feedback["anomaly_feedback"] - 0.5) ) ================================================ FILE: core/ai_engine/collective_intelligence.py ================================================ from typing import List, Dict, Any class CollectiveIntelligence: """ A class to implement collective intelligence features for the AI engine. This class includes methods for aggregating knowledge, decision-making, and collaborative learning. """ def __init__(self): self.knowledge_base: List[Dict[str, Any]] = [] def aggregate_knowledge(self, new_knowledge: Dict[str, Any]) -> None: """ Aggregates new knowledge into the existing knowledge base. :param new_knowledge: A dictionary containing the new knowledge to be added. """ self.knowledge_base.append(new_knowledge) def make_decision(self, criteria: Dict[str, Any]) -> Any: """ Makes a decision based on the aggregated knowledge and the provided criteria. :param criteria: A dictionary containing the criteria for decision-making. :return: The decision made based on the criteria. """ # Example logic for decision-making (to be implemented as needed) for knowledge in self.knowledge_base: if all(knowledge.get(key) == value for key, value in criteria.items()): return knowledge return None # No decision found def learn_collaboratively(self, external_data: List[Dict[str, Any]]) -> None: """ Updates the knowledge base with external data to enhance collective learning. :param external_data: A list of dictionaries containing external data. """ for data in external_data: self.aggregate_knowledge(data) def get_knowledge_base(self) -> List[Dict[str, Any]]: """ Returns the current knowledge base. :return: List of knowledge entries. """ return self.knowledge_base # Example usage: # ci = CollectiveIntelligence() # ci.aggregate_knowledge({'topic': 'AI', 'data': 'New findings in AI research.'}) # decision = ci.make_decision({'topic': 'AI'}) # print(decision) ================================================ FILE: core/ai_engine/llm_utils.py ================================================ import logging from typing import Any, Dict # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def preprocess_llm_input(user_input: str) -> Dict[str, Any]: """ Preprocess the user input for LLM. Args: user_input (str): The raw input from the user. Returns: Dict[str, Any]: A dictionary containing the processed input. """ try: processed_input = user_input.strip().lower() logger.info("Input processed successfully.") return {'input': processed_input} except Exception as e: logger.error(f"Error processing input: {e}") raise def format_llm_response(response: Any) -> str: """ Format the response from LLM for user display. Args: response (Any): The raw response from LLM. Returns: str: A formatted string for display. """ try: formatted_response = str(response) logger.info("Response formatted successfully.") return formatted_response except Exception as e: logger.error(f"Error formatting response: {e}") raise def log_llm_interaction(user_input: str, response: Any) -> None: """ Log the interaction between user input and LLM response. Args: user_input (str): The input provided by the user. response (Any): The response generated by LLM. """ logger.info(f"User Input: {user_input}") logger.info(f"LLM Response: {response}") ================================================ FILE: core/ai_engine/prediction.py ================================================ """Adaptive Prediction Engine for HAGAME.""" from typing import Any, Dict, List, Optional import logging import numpy as np from pydantic import BaseModel from .base import AIComponent logger = logging.getLogger(__name__) class PredictionModel(BaseModel): """Model for prediction data.""" game_id: str player_id: str prediction_type: str confidence: float predicted_values: Dict[str, Any] context: Dict[str, Any] class AdaptivePredictionEngine(AIComponent): """Component for making adaptive predictions about game states and player behavior.""" def __init__(self): self.models: Dict[str, Any] = {} # Game-specific prediction models self.history: List[PredictionModel] = [] self.learning_rate: float = 0.01 async def initialize(self) -> None: """Initialize prediction models and parameters.""" logger.info("Initializing Adaptive Prediction Engine") # Initialize base prediction models self.models = { "behavior": self._create_behavior_model(), "outcome": self._create_outcome_model(), "strategy": self._create_strategy_model() } def _create_behavior_model(self) -> Dict[str, Any]: """Create model for predicting player behavior.""" return { "weights": np.random.randn(10), # Initial random weights "bias": np.random.randn(), "features": ["action_history", "cognitive_state", "game_context"] } def _create_outcome_model(self) -> Dict[str, Any]: """Create model for predicting game outcomes.""" return { "weights": np.random.randn(8), "bias": np.random.randn(), "features": ["game_state", "player_stats", "uncertainty"] } def _create_strategy_model(self) -> Dict[str, Any]: """Create model for predicting optimal strategies.""" return { "weights": np.random.randn(12), "bias": np.random.randn(), "features": ["game_state", "player_profile", "historical_patterns"] } async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Process current game state and make predictions.""" try: game_id = input_data.get("game_id") player_id = input_data.get("player_id") game_state = input_data.get("game_state", {}) cognitive_state = input_data.get("cognitive_state", {}) uncertainty = input_data.get("uncertainty", {}) # Make different types of predictions behavior_pred = self._predict_behavior(game_state, cognitive_state) outcome_pred = self._predict_outcome(game_state, uncertainty) strategy_pred = self._predict_strategy(game_state, cognitive_state) prediction = PredictionModel( game_id=game_id, player_id=player_id, prediction_type="composite", confidence=self._calculate_confidence( behavior_pred, outcome_pred, strategy_pred), predicted_values={ "behavior": behavior_pred, "outcome": outcome_pred, "strategy": strategy_pred }, context={ "game_state": game_state, "cognitive_state": cognitive_state, "uncertainty": uncertainty } ) self.history.append(prediction) return prediction.dict() except Exception as e: logger.error(f"Error in prediction processing: {str(e)}") raise def _predict_behavior(self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any]) -> Dict[str, Any]: """Predict player behavior based on game state and cognitive state.""" features = self._extract_features( game_state, cognitive_state, self.models["behavior"]["features"]) prediction = np.dot( features, self.models["behavior"]["weights"]) + self.models["behavior"]["bias"] return { "predicted_actions": self._normalize_prediction(prediction), "confidence": float(np.mean(np.abs(prediction))) } def _predict_outcome(self, game_state: Dict[str, Any], uncertainty: Dict[str, Any]) -> Dict[str, Any]: """Predict game outcome based on current state and uncertainty.""" features = self._extract_features( game_state, uncertainty, self.models["outcome"]["features"]) prediction = np.dot( features, self.models["outcome"]["weights"]) + self.models["outcome"]["bias"] return { "win_probability": float(self._sigmoid(prediction)), "confidence": float(self._calculate_outcome_confidence(prediction, uncertainty)) } def _predict_strategy(self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any]) -> Dict[str, Any]: """Predict optimal strategy based on game state and cognitive state.""" features = self._extract_features( game_state, cognitive_state, self.models["strategy"]["features"]) prediction = np.dot( features, self.models["strategy"]["weights"]) + self.models["strategy"]["bias"] return { "recommended_actions": self._strategy_to_actions(prediction), "confidence": float(self._calculate_strategy_confidence(prediction, cognitive_state)) } def _extract_features(self, state: Dict[str, Any], context: Dict[str, Any], feature_list: List[str]) -> np.ndarray: """Extract relevant features from state and context.""" features = [] for feature in feature_list: value = state.get(feature, 0) or context.get(feature, 0) features.append(float(value) if isinstance( value, (int, float)) else 0.0) return np.array(features) def _normalize_prediction(self, prediction: np.ndarray) -> List[float]: """Normalize prediction values to probabilities.""" exp_pred = np.exp(prediction - np.max(prediction)) return (exp_pred / exp_pred.sum()).tolist() def _sigmoid(self, x: float) -> float: """Apply sigmoid function to scalar value.""" return 1 / (1 + np.exp(-x)) def _calculate_confidence(self, *predictions: Dict[str, Any]) -> float: """Calculate overall confidence based on individual predictions.""" confidences = [p.get("confidence", 0.0) for p in predictions] return float(np.mean(confidences)) def _calculate_outcome_confidence(self, prediction: float, uncertainty: Dict[str, Any]) -> float: """Calculate confidence in outcome prediction.""" base_confidence = self._sigmoid(abs(prediction)) uncertainty_factor = uncertainty.get("outcome_uncertainty", 0.5) return base_confidence * (1 - uncertainty_factor) def _calculate_strategy_confidence(self, prediction: float, cognitive_state: Dict[str, Any]) -> float: """Calculate confidence in strategy prediction.""" base_confidence = self._sigmoid(abs(prediction)) cognitive_factor = cognitive_state.get("certainty", 0.5) return base_confidence * cognitive_factor def _strategy_to_actions(self, prediction: float) -> List[Dict[str, Any]]: """Convert strategy prediction to concrete actions.""" return [ { "action_type": "move", "probability": self._sigmoid(prediction), "parameters": {"direction": "optimal"} }, { "action_type": "attack", "probability": self._sigmoid(-prediction), "parameters": {"target": "nearest"} } ] async def update(self, feedback: Dict[str, Any]) -> None: """Update prediction models based on feedback.""" try: actual_outcome = feedback.get("actual_outcome", {}) predicted_outcome = feedback.get("predicted_outcome", {}) # Calculate prediction error error = self._calculate_prediction_error( actual_outcome, predicted_outcome) # Update model weights self._update_weights(error, feedback) # Adjust learning rate based on error self._adjust_learning_rate(error) logger.info(f"Updated prediction models with error: {error}") except Exception as e: logger.error(f"Error updating prediction models: {str(e)}") raise def _calculate_prediction_error(self, actual: Dict[str, Any], predicted: Dict[str, Any]) -> float: """Calculate error between actual and predicted outcomes.""" actual_value = actual.get("value", 0.0) predicted_value = predicted.get("value", 0.0) return float(abs(actual_value - predicted_value)) def _update_weights(self, error: float, feedback: Dict[str, Any]) -> None: """Update model weights based on prediction error.""" for model_name, model in self.models.items(): features = self._extract_features( feedback.get("game_state", {}), feedback.get("context", {}), model["features"] ) gradient = error * features model["weights"] -= self.learning_rate * gradient model["bias"] -= self.learning_rate * error def _adjust_learning_rate(self, error: float) -> None: """Adjust learning rate based on prediction error.""" if error > 0.5: self.learning_rate *= 0.95 # Decrease learning rate if error is high else: self.learning_rate *= 1.05 # Increase learning rate if error is low # Keep learning rate in reasonable bounds self.learning_rate = max(0.001, min(0.1, self.learning_rate)) ================================================ FILE: core/ai_engine/quantum.py ================================================ """Quantum Uncertainty Generator for HAGAME.""" from typing import Any, Dict, List, Optional import logging import numpy as np from pydantic import BaseModel from .base import AIComponent logger = logging.getLogger(__name__) class UncertaintyFactors(BaseModel): """Model for uncertainty factors.""" game_id: str timestamp: float player_uncertainty: Dict[str, float] game_state_uncertainty: Dict[str, float] environmental_uncertainty: Dict[str, float] composite_uncertainty: float class QuantumUncertaintyGenerator(AIComponent): """Component for generating quantum-inspired uncertainty factors.""" def __init__(self): self.uncertainty_history: List[UncertaintyFactors] = [] self.quantum_states: Dict[str, np.ndarray] = {} self.entanglement_matrix: Optional[np.ndarray] = None self.decoherence_rate: float = 0.1 async def initialize(self) -> None: """Initialize quantum uncertainty system.""" logger.info("Initializing Quantum Uncertainty Generator") self._initialize_quantum_states() self._initialize_entanglement_matrix() def _initialize_quantum_states(self) -> None: """Initialize quantum states for different uncertainty types.""" self.quantum_states = { # Player-related uncertainties "player": self._create_quantum_state(3), # Game state uncertainties "game": self._create_quantum_state(4), # Environmental uncertainties "environment": self._create_quantum_state(2) } def _initialize_entanglement_matrix(self) -> None: """Initialize entanglement matrix for uncertainty correlations.""" total_states = sum(state.shape[0] for state in self.quantum_states.values()) self.entanglement_matrix = np.random.randn(total_states, total_states) # Make it symmetric for realistic entanglement self.entanglement_matrix = ( self.entanglement_matrix + self.entanglement_matrix.T) / 2 def _create_quantum_state(self, dimensions: int) -> np.ndarray: """Create a normalized quantum state vector.""" state = np.random.randn(dimensions) + 1j * np.random.randn(dimensions) return state / np.linalg.norm(state) async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Generate uncertainty factors for current game state.""" try: game_id = input_data.get("game_id") game_state = input_data.get("game_state", {}) player_state = input_data.get("player_state", {}) # Apply quantum evolution self._evolve_quantum_states(game_state) # Calculate uncertainty factors player_uncertainty = self._calculate_player_uncertainty( player_state) game_uncertainty = self._calculate_game_uncertainty(game_state) env_uncertainty = self._calculate_environmental_uncertainty( game_state) # Apply entanglement effects self._apply_entanglement_effects( player_uncertainty, game_uncertainty, env_uncertainty) # Calculate composite uncertainty composite = self._calculate_composite_uncertainty( player_uncertainty, game_uncertainty, env_uncertainty ) # Create uncertainty factors model import time factors = UncertaintyFactors( game_id=game_id, timestamp=time.time(), player_uncertainty=player_uncertainty, game_state_uncertainty=game_uncertainty, environmental_uncertainty=env_uncertainty, composite_uncertainty=composite ) self.uncertainty_history.append(factors) return factors.dict() except Exception as e: logger.error(f"Error generating uncertainty factors: {str(e)}") raise def _evolve_quantum_states(self, game_state: Dict[str, Any]) -> None: """Evolve quantum states based on game state.""" # Apply unitary evolution for state_type, state in self.quantum_states.items(): evolution_matrix = self._create_evolution_matrix( state.shape[0], game_state) self.quantum_states[state_type] = evolution_matrix @ state # Renormalize self.quantum_states[state_type] /= np.linalg.norm( self.quantum_states[state_type]) def _create_evolution_matrix(self, size: int, game_state: Dict[str, Any]) -> np.ndarray: """Create unitary evolution matrix based on game state.""" # Create Hermitian matrix h_matrix = np.random.randn(size, size) + \ 1j * np.random.randn(size, size) h_matrix = (h_matrix + h_matrix.T.conj()) / 2 # Add game state influence game_factor = min(1.0, max(0.0, game_state.get("complexity", 0.5))) h_matrix *= game_factor # Convert to unitary matrix using matrix exponential from scipy.linalg import expm return expm(-1j * h_matrix * self.decoherence_rate) def _calculate_player_uncertainty(self, player_state: Dict[str, Any]) -> Dict[str, float]: """Calculate player-related uncertainty factors.""" state = self.quantum_states["player"] probabilities = np.abs(state) ** 2 return { "decision_uncertainty": float(probabilities[0]), "skill_uncertainty": float(probabilities[1]), "intention_uncertainty": float(probabilities[2]) } def _calculate_game_uncertainty(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Calculate game state uncertainty factors.""" state = self.quantum_states["game"] probabilities = np.abs(state) ** 2 return { "state_uncertainty": float(probabilities[0]), "outcome_uncertainty": float(probabilities[1]), "interaction_uncertainty": float(probabilities[2]), "emergence_uncertainty": float(probabilities[3]) } def _calculate_environmental_uncertainty(self, game_state: Dict[str, Any]) -> Dict[str, float]: """Calculate environmental uncertainty factors.""" state = self.quantum_states["environment"] probabilities = np.abs(state) ** 2 return { "external_uncertainty": float(probabilities[0]), "context_uncertainty": float(probabilities[1]) } def _apply_entanglement_effects( self, player_uncertainty: Dict[str, float], game_uncertainty: Dict[str, float], env_uncertainty: Dict[str, float] ) -> None: """Apply quantum entanglement effects to uncertainty factors.""" # Combine all uncertainties into a vector combined = np.array([ *player_uncertainty.values(), *game_uncertainty.values(), *env_uncertainty.values() ]) # Apply entanglement effects entangled = self.entanglement_matrix @ combined # Normalize and update uncertainties entangled = np.abs(entangled) / np.sum(np.abs(entangled)) # Update individual uncertainties idx = 0 for uncertainties in [player_uncertainty, game_uncertainty, env_uncertainty]: for key in uncertainties: uncertainties[key] = float(entangled[idx]) idx += 1 def _calculate_composite_uncertainty( self, player_uncertainty: Dict[str, float], game_uncertainty: Dict[str, float], env_uncertainty: Dict[str, float] ) -> float: """Calculate composite uncertainty score.""" # Weights for different uncertainty types weights = { "player": 0.4, "game": 0.4, "environment": 0.2 } # Calculate weighted averages player_score = np.mean( list(player_uncertainty.values())) * weights["player"] game_score = np.mean(list(game_uncertainty.values())) * weights["game"] env_score = np.mean(list(env_uncertainty.values()) ) * weights["environment"] return float(player_score + game_score + env_score) async def update(self, feedback: Dict[str, Any]) -> None: """Update quantum uncertainty model based on feedback.""" try: # Update decoherence rate based on feedback self._update_decoherence_rate(feedback) # Update entanglement matrix self._update_entanglement_matrix(feedback) # Re-initialize quantum states with feedback influence self._reinitialize_quantum_states(feedback) logger.info("Updated quantum uncertainty model") except Exception as e: logger.error(f"Error updating quantum uncertainty model: {str(e)}") raise def _update_decoherence_rate(self, feedback: Dict[str, Any]) -> None: """Update decoherence rate based on feedback.""" accuracy = feedback.get("uncertainty_accuracy", 0.5) adjustment = 0.1 * (accuracy - 0.5) # Adjust based on accuracy self.decoherence_rate = max( 0.01, min(0.5, self.decoherence_rate + adjustment)) def _update_entanglement_matrix(self, feedback: Dict[str, Any]) -> None: """Update entanglement matrix based on feedback.""" if "correlation_feedback" in feedback: correlation = np.array(feedback["correlation_feedback"]) # Update entanglement matrix while maintaining symmetry update = 0.1 * correlation self.entanglement_matrix += update self.entanglement_matrix = ( self.entanglement_matrix + self.entanglement_matrix.T) / 2 def _reinitialize_quantum_states(self, feedback: Dict[str, Any]) -> None: """Reinitialize quantum states with feedback influence.""" feedback_factor = feedback.get("quantum_feedback", 1.0) for state_type in self.quantum_states: current_state = self.quantum_states[state_type] new_state = self._create_quantum_state(current_state.shape[0]) # Blend current and new states based on feedback self.quantum_states[state_type] = ( current_state * (1 - feedback_factor) + new_state * feedback_factor ) # Renormalize self.quantum_states[state_type] /= np.linalg.norm( self.quantum_states[state_type]) ================================================ FILE: core/ai_engine/utils.py ================================================ # Utility functions for AI engine processing from typing import Any, Dict, List, Optional import json def load_json(file_path: str) -> Dict[str, Any]: """ Load a JSON file and return its content as a dictionary. :param file_path: Path to the JSON file. :return: Dictionary containing the JSON data. :raises FileNotFoundError: If the file does not exist. :raises json.JSONDecodeError: If the file cannot be decoded. """ with open(file_path, 'r') as f: return json.load(f) def save_json(data: Dict[str, Any], file_path: str) -> None: """ Save a dictionary as a JSON file. :param data: Dictionary to save. :param file_path: Destination path for the JSON file. """ with open(file_path, 'w') as f: json.dump(data, f, indent=4) def extract_keys(data: List[Dict[str, Any]], keys: List[str]) -> List[Dict[str, Any]]: """ Extract specific keys from a list of dictionaries. :param data: List of dictionaries to extract keys from. :param keys: List of keys to extract. :return: List of dictionaries containing only the specified keys. """ return [{k: d[k] for k in keys if k in d} for d in data] def validate_input(data: Any, expected_type: type) -> bool: """ Validate if the input data is of the expected type. :param data: The data to validate. :param expected_type: The expected type of the data. :return: True if data is of expected type, False otherwise. """ return isinstance(data, expected_type) ================================================ FILE: core/ai_engine/xai.py ================================================ """Explainable AI (XAI) component for HAGAME.""" from typing import Any, Dict, List, Optional import logging import numpy as np from pydantic import BaseModel from .base import AIComponent logger = logging.getLogger(__name__) class Explanation(BaseModel): """Model for AI explanation data.""" game_id: str timestamp: float decision_explanations: Dict[str, str] feature_importance: Dict[str, float] counterfactuals: List[Dict[str, Any]] confidence_levels: Dict[str, float] class ExplainableAI(AIComponent): """Component for generating explanations of AI decisions.""" def __init__(self): self.explanation_history: List[Explanation] = [] self.feature_weights: Dict[str, np.ndarray] = { "decision": np.random.randn(5), "outcome": np.random.randn(4), "strategy": np.random.randn(6) } self.explanation_templates: Dict[str, str] = self._initialize_templates() def _initialize_templates(self) -> Dict[str, str]: """Initialize explanation templates.""" return { "decision": ( "The AI made this decision because {main_factor}, " "considering {secondary_factor}. " "This was influenced by {context_factor}." ), "outcome": ( "The predicted outcome is based on {main_factor}, " "with {secondary_factor} playing a significant role. " "Historical data suggests {historical_factor}." ), "strategy": ( "The recommended strategy focuses on {main_factor}, " "while accounting for {secondary_factor}. " "This approach was chosen because {reasoning_factor}." ), "counterfactual": ( "If {changed_factor} had been {alternative_value}, " "the outcome would likely have been {alternative_outcome}." ) } async def initialize(self) -> None: """Initialize XAI system.""" logger.info("Initializing Explainable AI component") self._initialize_feature_analyzers() def _initialize_feature_analyzers(self) -> None: """Initialize feature analysis components.""" self.analyzers = { "decision": self._create_decision_analyzer(), "outcome": self._create_outcome_analyzer(), "strategy": self._create_strategy_analyzer() } def _create_decision_analyzer(self) -> Dict[str, Any]: """Create decision analysis component.""" return { "features": [ "player_state", "game_context", "historical_actions", "predicted_outcomes", "uncertainty_factors" ], "weights": self.feature_weights["decision"] } def _create_outcome_analyzer(self) -> Dict[str, Any]: """Create outcome analysis component.""" return { "features": [ "current_state", "player_performance", "game_dynamics", "external_factors" ], "weights": self.feature_weights["outcome"] } def _create_strategy_analyzer(self) -> Dict[str, Any]: """Create strategy analysis component.""" return { "features": [ "player_profile", "game_objectives", "resource_state", "opponent_analysis", "risk_factors", "temporal_context" ], "weights": self.feature_weights["strategy"] } async def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]: """Generate explanations for AI decisions and predictions.""" try: game_id = input_data.get("game_id") game_state = input_data.get("game_state", {}) predictions = input_data.get("predictions", {}) cognitive_state = input_data.get("cognitive_state", {}) # Generate decision explanations decision_explanations = self._explain_decisions( game_state, predictions, cognitive_state ) # Calculate feature importance feature_importance = self._calculate_feature_importance( game_state, predictions ) # Generate counterfactuals counterfactuals = self._generate_counterfactuals( game_state, predictions ) # Calculate confidence levels confidence_levels = self._calculate_confidence_levels( game_state, predictions, feature_importance ) # Create explanation model import time explanation = Explanation( game_id=game_id, timestamp=time.time(), decision_explanations=decision_explanations, feature_importance=feature_importance, counterfactuals=counterfactuals, confidence_levels=confidence_levels ) self.explanation_history.append(explanation) return explanation.dict() except Exception as e: logger.error(f"Error generating explanations: {str(e)}") raise def _explain_decisions( self, game_state: Dict[str, Any], predictions: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> Dict[str, str]: """Generate natural language explanations for decisions.""" explanations = {} # Explain decision making decision_factors = self._analyze_decision_factors( game_state, predictions) explanations["decision"] = self._format_decision_explanation( decision_factors) # Explain outcome predictions outcome_factors = self._analyze_outcome_factors( game_state, predictions) explanations["outcome"] = self._format_outcome_explanation( outcome_factors) # Explain strategy recommendations strategy_factors = self._analyze_strategy_factors( game_state, cognitive_state) explanations["strategy"] = self._format_strategy_explanation( strategy_factors) return explanations def _analyze_decision_factors( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, Any]: """Analyze factors influencing decisions.""" analyzer = self.analyzers["decision"] features = self._extract_decision_features(game_state, predictions) importance = features * analyzer["weights"] return { "main_factor": self._get_most_important_factor( importance, analyzer["features"] ), "secondary_factor": self._get_secondary_factor( importance, analyzer["features"] ), "context_factor": self._get_context_factor(game_state) } def _analyze_outcome_factors( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, Any]: """Analyze factors influencing outcome predictions.""" analyzer = self.analyzers["outcome"] features = self._extract_outcome_features(game_state, predictions) importance = features * analyzer["weights"] return { "main_factor": self._get_most_important_factor( importance, analyzer["features"] ), "secondary_factor": self._get_secondary_factor( importance, analyzer["features"] ), "historical_factor": self._get_historical_factor(game_state) } def _analyze_strategy_factors( self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> Dict[str, Any]: """Analyze factors influencing strategy recommendations.""" analyzer = self.analyzers["strategy"] features = self._extract_strategy_features(game_state, cognitive_state) importance = features * analyzer["weights"] return { "main_factor": self._get_most_important_factor( importance, analyzer["features"] ), "secondary_factor": self._get_secondary_factor( importance, analyzer["features"] ), "reasoning_factor": self._get_reasoning_factor(cognitive_state) } def _calculate_feature_importance( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> Dict[str, float]: """Calculate importance scores for different features.""" importance_scores = {} # Calculate decision feature importance decision_features = self._extract_decision_features( game_state, predictions) importance_scores.update(self._calculate_feature_scores( decision_features, self.analyzers["decision"]["features"], self.feature_weights["decision"] )) # Calculate outcome feature importance outcome_features = self._extract_outcome_features( game_state, predictions) importance_scores.update(self._calculate_feature_scores( outcome_features, self.analyzers["outcome"]["features"], self.feature_weights["outcome"] )) # Calculate strategy feature importance strategy_features = self._extract_strategy_features(game_state, {}) importance_scores.update(self._calculate_feature_scores( strategy_features, self.analyzers["strategy"]["features"], self.feature_weights["strategy"] )) return importance_scores def _generate_counterfactuals( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> List[Dict[str, Any]]: """Generate counterfactual explanations.""" counterfactuals = [] # Generate decision counterfactuals decision_cf = self._generate_decision_counterfactuals( game_state, predictions) counterfactuals.extend(decision_cf) # Generate outcome counterfactuals outcome_cf = self._generate_outcome_counterfactuals( game_state, predictions) counterfactuals.extend(outcome_cf) # Generate strategy counterfactuals strategy_cf = self._generate_strategy_counterfactuals( game_state, predictions) counterfactuals.extend(strategy_cf) return counterfactuals def _calculate_confidence_levels( self, game_state: Dict[str, Any], predictions: Dict[str, Any], feature_importance: Dict[str, float] ) -> Dict[str, float]: """Calculate confidence levels for explanations.""" confidence_levels = {} # Calculate decision explanation confidence confidence_levels["decision_confidence"] = self._calculate_decision_confidence( game_state, predictions, feature_importance ) # Calculate outcome explanation confidence confidence_levels["outcome_confidence"] = self._calculate_outcome_confidence( game_state, predictions, feature_importance ) # Calculate strategy explanation confidence confidence_levels["strategy_confidence"] = self._calculate_strategy_confidence( game_state, predictions, feature_importance ) # Calculate overall explanation confidence confidence_levels["overall_confidence"] = np.mean( list(confidence_levels.values())) return confidence_levels def _extract_decision_features( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> np.ndarray: """Extract features for decision explanation.""" return np.array([ float(game_state.get("player_state_value", 0.0)), float(game_state.get("game_context_value", 0.0)), float(game_state.get("historical_actions_value", 0.0)), float(predictions.get("predicted_outcome_value", 0.0)), float(predictions.get("uncertainty_value", 0.0)) ]) def _extract_outcome_features( self, game_state: Dict[str, Any], predictions: Dict[str, Any] ) -> np.ndarray: """Extract features for outcome explanation.""" return np.array([ float(game_state.get("current_state_value", 0.0)), float(game_state.get("player_performance_value", 0.0)), float(game_state.get("game_dynamics_value", 0.0)), float(game_state.get("external_factors_value", 0.0)) ]) def _extract_strategy_features( self, game_state: Dict[str, Any], cognitive_state: Dict[str, Any] ) -> np.ndarray: """Extract features for strategy explanation.""" return np.array([ float(game_state.get("player_profile_value", 0.0)), float(game_state.get("game_objectives_value", 0.0)), float(game_state.get("resource_state_value", 0.0)), float(game_state.get("opponent_analysis_value", 0.0)), float(game_state.get("risk_factors_value", 0.0)), float(game_state.get("temporal_context_value", 0.0)) ]) async def update(self, feedback: Dict[str, Any]) -> None: """Update XAI model based on feedback.""" try: # Update feature weights self._update_feature_weights(feedback) # Update explanation templates if provided self._update_templates(feedback) # Re-initialize analyzers with updated weights self._initialize_feature_analyzers() logger.info("Updated XAI model") except Exception as e: logger.error(f"Error updating XAI model: {str(e)}") raise def _update_feature_weights(self, feedback: Dict[str, Any]) -> None: """Update feature weights based on feedback.""" learning_rate = 0.01 for feature_type, weights in self.feature_weights.items(): if f"{feature_type}_accuracy" in feedback: accuracy = feedback[f"{feature_type}_accuracy"] gradient = np.array(feedback.get( f"{feature_type}_gradient", [0] * len(weights))) self.feature_weights[feature_type] += learning_rate * \ accuracy * gradient def _update_templates(self, feedback: Dict[str, Any]) -> None: """Update explanation templates based on feedback.""" if "template_updates" in feedback: updates = feedback["template_updates"] for template_type, new_template in updates.items(): if template_type in self.explanation_templates: self.explanation_templates[template_type] = new_template ================================================ FILE: core/auth.py ================================================ import os from datetime import datetime, timedelta from typing import Any from jose import jwt, JWTError from passlib.context import CryptContext from pydantic import BaseSettings from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from sqlalchemy.ext.asyncio import AsyncSession from core.database import get_async_session from crud.user import get_user_by_id import uuid class AuthSettings(BaseSettings): SECRET_KEY: str ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 class Config: env_file = ".env" auth_settings = AuthSettings() pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login") def verify_password(plain_password: str, hashed_password: str) -> bool: """Verify a plain password against a hash.""" return pwd_context.verify(plain_password, hashed_password) def get_password_hash(password: str) -> str: """Hash a password for storage.""" return pwd_context.hash(password) def create_access_token(data: dict[str, Any], expires_delta: timedelta | None = None) -> str: """Create a JWT access token.""" to_encode = data.copy() expire = datetime.utcnow() + \ (expires_delta or timedelta(minutes=auth_settings.ACCESS_TOKEN_EXPIRE_MINUTES)) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode( to_encode, auth_settings.SECRET_KEY, algorithm=auth_settings.ALGORITHM) return encoded_jwt def decode_access_token(token: str) -> dict[str, Any]: """Decode a JWT access token.""" try: payload = jwt.decode(token, auth_settings.SECRET_KEY, algorithms=[auth_settings.ALGORITHM]) return payload except JWTError: raise ValueError("Invalid token") async def get_current_user( token: str = Depends(oauth2_scheme), session: AsyncSession = Depends(get_async_session), ): """FastAPI dependency to get the current user from JWT token.""" credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = decode_access_token(token) user_id: str = payload.get("sub") if user_id is None: raise credentials_exception user_uuid = uuid.UUID(user_id) except Exception: raise credentials_exception user = await get_user_by_id(session, user_uuid) if user is None: raise credentials_exception return user ================================================ FILE: core/auth_utils.py ================================================ import hashlib from datetime import datetime, timedelta from typing import Dict, Any, Optional class AuthUtils: """ Utility functions for authentication processes. """ @staticmethod def hash_password(password: str) -> str: """ Hash a password using SHA-256. :param password: The plaintext password to be hashed. :return: The hashed password as a hexadecimal string. """ return hashlib.sha256(password.encode()).hexdigest() @staticmethod def generate_jwt_token(user_id: str, secret: str, expiration_minutes: int = 60) -> str: """ Generate a JSON Web Token (JWT) for a user. :param user_id: The ID of the user. :param secret: The secret key used to encode the token. :param expiration_minutes: The expiration time of the token in minutes. :return: The encoded JWT as a string. """ expiration = datetime.utcnow() + timedelta(minutes=expiration_minutes) # Normally you would use a library like PyJWT to create the token. # Here we would just return a dummy string for demonstration purposes. return f"token-{user_id}-{expiration.timestamp()}" @staticmethod def validate_jwt_token(token: str, secret: str) -> Optional[Dict[str, Any]]: """ Validate the JWT token and return the payload. :param token: The JWT token to validate. :param secret: The secret key used to decode the token. :return: The payload if valid, otherwise None. """ # Normally you would use a library like PyJWT to decode and validate the token. # Here we would just return a dummy payload for demonstration purposes. if "token-" in token: parts = token.split("-") return {"user_id": parts[1], "exp": float(parts[2])} return None ================================================ FILE: core/celery_app.py ================================================ # Celery configuration for HAGAME Backend import os from celery import Celery # Read Celery configuration from environment variables CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0") CELERY_RESULT_BACKEND = os.getenv( "CELERY_RESULT_BACKEND", "redis://localhost:6379/0") celery_app = Celery( "hagame_tasks", broker=CELERY_BROKER_URL, backend=CELERY_RESULT_BACKEND, include=["core.tasks"], # Include task modules here ) # Optional: Celery configuration dictionary # celery_app.conf.update( # task_ignore_result=False, # task_track_started=True, # ) ================================================ FILE: core/database.py ================================================ import os from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from sqlalchemy.orm import sessionmaker from pydantic import BaseSettings from typing import AsyncGenerator class Settings(BaseSettings): """Settings for database configuration.""" DATABASE_URL: str class Config: env_file = ".env" settings = Settings() engine = create_async_engine(settings.DATABASE_URL, echo=True, future=True) AsyncSessionLocal = async_sessionmaker( engine, expire_on_commit=False, class_=AsyncSession) async def get_async_session() -> AsyncGenerator[AsyncSession, None]: """FastAPI dependency that provides an async database session.""" async with AsyncSessionLocal() as session: yield session ================================================ FILE: core/llm_processing.py ================================================ import logging from typing import Any, Dict # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class LLMProcessor: """ A class for processing interactions with the LLM (Large Language Model). """ def __init__(self, model: str) -> None: """ Initialize the LLMProcessor with a specified model. Args: model (str): The name of the LLM model to be used. """ self.model = model def process_input(self, user_input: str) -> Dict[str, Any]: """ Process the user input and interact with the LLM. Args: user_input (str): The input text from the user. Returns: Dict[str, Any]: A dictionary containing the LLM's response and any metadata. """ logger.info("Processing input: %s", user_input) # Placeholder for LLM interaction logic response = self._interact_with_llm(user_input) return response def _interact_with_llm(self, user_input: str) -> Dict[str, Any]: """ Simulate interaction with the LLM. In a real implementation, this would involve calling the LLM API and handling the response. Args: user_input (str): The input text from the user. Returns: Dict[str, Any]: Simulated LLM response. """ # Simulate processing logic simulated_response = f"Response to: {user_input}" logger.info("Simulated LLM response: %s", simulated_response) return { 'response': simulated_response, 'model': self.model } # Example usage: # if __name__ == '__main__': # processor = LLMProcessor(model='GPT-4') # result = processor.process_input('Hello, how are you?') # print(result) ================================================ FILE: core/llm_utilities.py ================================================ """ Utility functions for LLM processing. This module provides various utility functions that assist in the processing of LLM requests and responses within the application. """ from typing import Any, Dict, List def preprocess_input(text: str) -> str: """ Preprocess the input text for the LLM. Args: text (str): The input text to preprocess. Returns: str: The preprocessed text. """ # Example preprocessing steps return text.strip().lower() def postprocess_output(output: Any) -> str: """ Postprocess the output from the LLM. Args: output (Any): The raw output from the LLM. Returns: str: A formatted string representation of the output. """ # Example of formatting output return str(output) def extract_entities(data: Dict[str, Any]) -> List[str]: """ Extract entities from the LLM response data. Args: data (Dict[str, Any]): The response data from the LLM. Returns: List[str]: A list of extracted entities. """ # Placeholder logic for entity extraction entities = [] if 'entities' in data: entities = data['entities'] return entities # Additional utility functions can be added as needed. ================================================ FILE: core/logging.py ================================================ import logging LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) def get_logger(name: str) -> logging.Logger: """Get a logger instance for a given module name.""" return logging.getLogger(name) ================================================ FILE: core/tasks.py ================================================ import logging from celery import shared_task # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @shared_task def process_llm_response(response_data): """ Process the response data from the LLM. This function handles the asynchronous processing of LLM responses, including logging and further actions based on the response. Args: response_data (dict): The response data from the LLM containing the results. """ try: logger.info("Starting LLM response processing") # Simulate processing the response data # TODO: Implement actual processing logic processed_data = response_data # Replace with actual processing code logger.info("Successfully processed LLM response") return processed_data except Exception as e: logger.error(f"Error processing LLM response: {str(e)}") raise @shared_task def generate_llm_prompt(game_context): """ Generate a prompt for the LLM based on the game context. This function prepares the input for the LLM based on the current game state. Args: game_context (dict): The current context of the game to generate a prompt. """ try: logger.info("Generating LLM prompt") # TODO: Implement prompt generation logic prompt = f"Generate response based on context: {game_context}" logger.info("LLM prompt generated successfully") return prompt except Exception as e: logger.error(f"Error generating LLM prompt: {str(e)}") raise ================================================ FILE: crud/__init__.py ================================================ ================================================ FILE: crud/ai_model.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from models.ai_model import AIModel from schemas.ai_model import AIModelCreate async def get_by_id(session: AsyncSession, id: uuid.UUID) -> AIModel | None: """Get an AI model by id.""" result = await session.execute(select(AIModel).where(AIModel.id == id)) return result.scalars().first() async def create(session: AsyncSession, data: AIModelCreate) -> AIModel: """Create a new AI model.""" model = AIModel( name=data.name, type=data.type, version=data.version, config_params=data.config_params, file_path=data.file_path ) session.add(model) await session.commit() await session.refresh(model) return model async def list_all(session: AsyncSession) -> list[AIModel]: """List all AI models.""" result = await session.execute(select(AIModel)) return result.scalars().all() ================================================ FILE: crud/cognitive_profile.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from models.cognitive_profile import CognitiveProfile from schemas.cognitive_profile import CognitiveProfileUpdate async def get_by_user_id(session: AsyncSession, user_id: uuid.UUID) -> CognitiveProfile | None: """Get cognitive profile by user_id.""" result = await session.execute(select(CognitiveProfile).where(CognitiveProfile.user_id == user_id)) return result.scalars().first() async def create_profile(session: AsyncSession, user_id: uuid.UUID, profile_data: dict) -> CognitiveProfile: """Create a new cognitive profile for a user.""" profile = CognitiveProfile(user_id=user_id, profile_data=profile_data) session.add(profile) await session.commit() await session.refresh(profile) return profile async def update_profile(session: AsyncSession, profile: CognitiveProfile, update_in: CognitiveProfileUpdate) -> CognitiveProfile: """Update cognitive profile data.""" profile.profile_data = update_in.profile_data await session.commit() await session.refresh(profile) return profile ================================================ FILE: crud/game_definition.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from models.game_definition import GameDefinition from schemas.game_definition import GameDefinitionCreate async def get_by_id(session: AsyncSession, id: uuid.UUID) -> GameDefinition | None: """Get a game definition by id.""" result = await session.execute(select(GameDefinition).where(GameDefinition.id == id)) return result.scalars().first() async def get_by_name(session: AsyncSession, name: str) -> GameDefinition | None: """Get a game definition by name.""" result = await session.execute(select(GameDefinition).where(GameDefinition.name == name)) return result.scalars().first() async def create(session: AsyncSession, data: GameDefinitionCreate) -> GameDefinition: """Create a new game definition.""" game_def = GameDefinition( name=data.name, description=data.description, rules_config=data.rules_config, version=data.version ) session.add(game_def) await session.commit() await session.refresh(game_def) return game_def async def list_all(session: AsyncSession) -> list[GameDefinition]: """List all game definitions.""" result = await session.execute(select(GameDefinition)) return result.scalars().all() ================================================ FILE: crud/game_instance.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from models.game_instance import GameInstance from schemas.game_instance import GameInstanceCreate async def get_by_id(session: AsyncSession, id: uuid.UUID) -> GameInstance | None: """Get a game instance by id.""" result = await session.execute(select(GameInstance).where(GameInstance.id == id)) return result.scalars().first() async def create(session: AsyncSession, data: GameInstanceCreate) -> GameInstance: """Create a new game instance.""" instance = GameInstance( game_definition_id=data.game_definition_id, user_id=data.user_id, game_state=data.game_state, ai_model_id=data.ai_model_id ) session.add(instance) await session.commit() await session.refresh(instance) return instance async def list_by_user(session: AsyncSession, user_id: uuid.UUID) -> list[GameInstance]: """List all game instances for a user.""" result = await session.execute(select(GameInstance).where(GameInstance.user_id == user_id)) return result.scalars().all() ================================================ FILE: crud/user.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from sqlalchemy.exc import NoResultFound from models.user import User from schemas.user import UserCreate, UserUpdate from passlib.context import CryptContext from core.auth import get_password_hash pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") async def get_user_by_email(session: AsyncSession, email: str) -> User | None: """Get a user by email.""" result = await session.execute(select(User).where(User.email == email)) return result.scalars().first() async def get_user_by_id(session: AsyncSession, user_id: uuid.UUID) -> User | None: """Get a user by id.""" result = await session.execute(select(User).where(User.id == user_id)) return result.scalars().first() async def create_user(session: AsyncSession, user_in: UserCreate) -> User: """Create a new user with hashed password.""" hashed_password = get_password_hash(user_in.password) user = User( username=user_in.username, email=user_in.email, hashed_password=hashed_password ) session.add(user) await session.commit() await session.refresh(user) return user async def update_user(session: AsyncSession, user: User, user_in: UserUpdate) -> User: """Update user fields.""" if user_in.username is not None: user.username = user_in.username if user_in.email is not None: user.email = user_in.email if user_in.password is not None: user.hashed_password = pwd_context.hash(user_in.password) await session.commit() await session.refresh(user) return user ================================================ FILE: docs/ai_engine.md ================================================ # docs/ai_engine.md # AI Engine Module Documentation ## Overview The AI Engine module provides functionality for managing AI models, including: - Model creation and configuration - Adaptive predictions based on cognitive profiles - Explainable AI (XAI) features using SHAP values - Model metadata management ## Components ### AIModel The core model class that represents an AI model in the system. #### Fields: - `id`: Unique identifier - `name`: Model name - `description`: Optional model description - `config`: JSON configuration for model parameters - `metadata`: Optional JSON metadata - `file_path`: Path to the saved model file - `created_at`: Creation timestamp - `updated_at`: Last update timestamp ### API Endpoints #### Create Model ```http POST /ai_models/ ``` Creates a new AI model with the specified configuration. #### Get Model ```http GET /ai_models/{model_id} ``` Retrieves model details by ID. #### Update Model ```http PUT /ai_models/{model_id} ``` Updates model configuration and metadata. #### Predict ```http POST /ai_models/{model_id}/predict ``` Generates predictions using the model, with optional cognitive profile adaptation. #### Explain ```http POST /ai_models/{model_id}/explain ``` Provides model explanations using SHAP values. ## Usage Examples ### Creating a New Model ```python model_data = { "name": "sentiment_classifier", "description": "Sentiment analysis model", "config": { "model_type": "transformer", "parameters": { "max_length": 512 } } } response = client.post("/ai_models/", json=model_data) ``` ### Making Predictions ```python input_data = { "text": "This is a sample input" } response = client.post("/ai_models/1/predict", json=input_data) ``` ### Getting Model Explanations ```python response = client.post("/ai_models/1/explain", json=input_data) ``` ## Dependencies - SHAP: For model explanations - joblib: For model serialization - numpy: For numerical computations ## Testing Run tests using pytest: ```bash pytest tests/test_ai_engine/ ``` ================================================ FILE: docs/ai_engine_integration_guide.md ================================================ # AI Engine Integration Guide This document provides a comprehensive guide for integrating AI engine services into your applications using the hagamesai backend. ## Overview The AI engine services are designed to provide advanced functionalities for human-vs-AI gameplay, leveraging large language models (LLMs) and cognitive modeling. This guide will help you understand how to utilize these services effectively. ## Prerequisites Before you begin integration, ensure that you have the following: - Access to the hagamesai backend API. - An understanding of FastAPI endpoints. - Required libraries and dependencies installed, including `httpx` for API requests. ## Integration Steps ### 1. Setting Up Your Environment Ensure your development environment is configured. You can use a virtual environment to maintain project dependencies. ```bash # Create a virtual environment python -m venv venv # Activate the virtual environment source venv/bin/activate # On Windows use `venv\Scripts\activate` # Install required packages pip install httpx ``` ### 2. Making API Requests to the AI Engine Use the following example to make requests to the AI engine service endpoints: ```python import httpx async def call_ai_engine(prompt: str): url = "http://localhost:8000/api/llm" payload = {'prompt': prompt} async with httpx.AsyncClient() as client: response = await client.post(url, json=payload) return response.json() ``` ### 3. Handling Responses The AI engine will return a JSON response. You should handle this response appropriately: ```python response_data = await call_ai_engine("Hello AI, how can you assist me today?") if response_data['success']: print("AI Response:", response_data['data']) else: print("Error:", response_data['error']) ``` ### 4. Error Handling Implement error handling to manage potential issues during the API call: ```python async def call_ai_engine(prompt: str): url = "http://localhost:8000/api/llm" payload = {'prompt': prompt} try: async with httpx.AsyncClient() as client: response = await client.post(url, json=payload) response.raise_for_status() # Raises an error for bad responses return response.json() except httpx.HTTPStatusError as e: print(f"HTTP Error: {e.response.status_code} - {e.response.text}") return {'success': False, 'error': str(e)} except Exception as e: print("An error occurred:", str(e)) return {'success': False, 'error': str(e)} ``` ## Conclusion This guide provides a starting point for integrating AI engine services with your application. Ensure you adapt the integration to your specific use case and error handling needs. For further details, refer to the API documentation. ## Additional Resources - [FastAPI Documentation](https://fastapi.tiangolo.com/) - [HTTPX Documentation](https://www.python-httpx.org/) --- This guide is part of the hagamesai project documentation, which aims to support developers in building innovative AI-powered applications. ================================================ FILE: docs/ai_engine_processing.md ================================================ # AI Engine Processing Documentation This documentation outlines the processing logic utilized by the AI engine in the hagamesai project. The AI engine is designed to facilitate human-vs-AI gameplay by leveraging advanced cognitive modeling and large language models (LLMs). This document serves as a guide for developers to understand the core functionality and implementation details of the AI processing modules. ## Overview The AI engine processing logic is responsible for: - Handling incoming game state data from users. - Performing cognitive functions to simulate AI behavior. - Generating responses based on the current game context using LLMs. ## Components ### 1. Data Processing The AI engine receives data from the game instance, which includes player actions, game state, and other contextual information. This data undergoes the following processing steps: - **Input Validation**: Ensures that the incoming data is in the correct format and contains all required fields. - **Normalization**: Converts the data into a standardized format suitable for processing by the AI models. ### 2. Cognitive Modeling The cognitive modeling component simulates the decision-making process of the AI. It includes: - **Predictive Analysis**: Estimates the most likely player actions based on historical data. - **Strategy Development**: Generates strategies for the AI to adopt during gameplay. ### 3. Response Generation Once the cognitive model has processed the input, the AI generates a response using the following: - **LLM Integration**: Utilizes large language models to create dynamic and contextually relevant responses based on the current game state. - **Output Formatting**: Prepares the generated response to be sent back to the game interface. ## Usage Developers can interact with the AI engine by calling the `process_game_state` function from the core AI processing module. Here is an example of how to use this function: ```python from core.ai_engine.ai_processing import process_game_state # Example game state data game_state = { 'player_action': 'move', 'current_state': 'waiting', 'context': {'level': 1, 'score': 100} } # Processing the game state with AI engine ai_response = process_game_state(game_state) print(ai_response) ``` ## Conclusion The AI engine's processing logic is a critical component of the hagamesai project, enabling engaging and intelligent gameplay experiences. Developers are encouraged to explore the various components and enhance the AI capabilities further. ## References - [Core AI Processing Module](../core/ai_engine/ai_processing.py) --- For further information, please refer to the project's README or the API documentation. ================================================ FILE: docs/ai_engine_utils.md ================================================ # AI Engine Utility Functions Documentation This document provides an overview of the utility functions used in the AI engine module of the hagamesai project. The utility functions are designed to facilitate various operations related to cognitive modeling and AI processing. ## Overview The AI engine utility functions are responsible for supporting core functionalities such as data preprocessing, model evaluation, and cognitive processing. These functions are utilized across different components of the AI engine to ensure modularity and reusability. ## Utility Functions ### 1. Data Normalization ```python def normalize_data(data: List[float]) -> List[float]: """ Normalize the input data to a range between 0 and 1. Parameters: - data (List[float]): A list of float values to be normalized. Returns: - List[float]: A list of normalized float values. """ min_val = min(data) max_val = max(data) return [(x - min_val) / (max_val - min_val) for x in data] ``` ### 2. Cognitive Load Calculation ```python def calculate_cognitive_load(task_difficulty: float, user_expertise: float) -> float: """ Calculate the cognitive load based on task difficulty and user expertise. Parameters: - task_difficulty (float): The difficulty level of the task. - user_expertise (float): The expertise level of the user. Returns: - float: The calculated cognitive load. """ return task_difficulty / (user_expertise + 1e-5) # Prevent division by zero ``` ### 3. Performance Evaluation ```python def evaluate_performance(predictions: List[float], actuals: List[float]) -> float: """ Evaluate the performance of the AI model using Mean Squared Error (MSE). Parameters: - predictions (List[float]): The predictions made by the model. - actuals (List[float]): The actual values. Returns: - float: The calculated Mean Squared Error. """ return sum((p - a) ** 2 for p, a in zip(predictions, actuals)) / len(actuals) ``` ## Usage These utility functions can be imported and utilized in various components of the AI engine. Ensure to handle exceptions and edge cases appropriately when using these functions in production. ## Conclusion The utility functions outlined in this document play a vital role in the functionality of the AI engine. By maintaining a modular approach, we can enhance, test, and maintain these functions independently as the project evolves. For further information, refer to the source code and related documentation. ================================================ FILE: docs/api_overview.md ================================================ # API Overview This document provides a detailed overview of the API endpoints available in the `hagamesai` project. The API is built using FastAPI and offers various functionalities to support human-vs-AI game scenarios, advanced cognitive modeling, and LLM-powered services. ## Base URL The base URL for all the API endpoints is: ``` http:///api ``` ## Authentication Most endpoints require user authentication. You can obtain a JWT token by using the `/auth/login` endpoint after registering a user via `/auth/register`. ## Endpoints ### User Endpoints 1. **Register User** - **Endpoint:** `/auth/register` - **Method:** `POST` - **Request Body:** ```json { "username": "", "password": "" } ``` - **Response:** - **201 Created** on successful registration. - **400 Bad Request** if the input data is invalid. 2. **Login User** - **Endpoint:** `/auth/login` - **Method:** `POST` - **Request Body:** ```json { "username": "", "password": "" } ``` - **Response:** - **200 OK** with JWT token on successful login. - **401 Unauthorized** if credentials are invalid. ### Game Management Endpoints 1. **Get Game Definitions** - **Endpoint:** `/games/definitions` - **Method:** `GET` - **Response:** - **200 OK** with a list of game definitions. 2. **Create Game Instance** - **Endpoint:** `/games/instances` - **Method:** `POST` - **Request Body:** ```json { "game_id": "", "user_id": "" } ``` - **Response:** - **201 Created** on successful creation. - **400 Bad Request** if the input data is invalid. ### AI Services Endpoints 1. **AI Engine Prediction** - **Endpoint:** `/llm/predict` - **Method:** `POST` - **Request Body:** ```json { "input_data": "" } ``` - **Response:** - **200 OK** with AI prediction result. ## Error Handling All API responses include a status code and a message. Common status codes include: - **200 OK:** Successful request. - **201 Created:** Resource successfully created. - **400 Bad Request:** Invalid input data. - **401 Unauthorized:** Authentication error. - **404 Not Found:** Resource not found. - **500 Internal Server Error:** An unexpected error occurred. ## Conclusion This overview provides a high-level understanding of the available API endpoints in the `hagamesai` project. For more detailed information about specific endpoints, refer to the endpoint documentation in the respective modules. ================================================ FILE: docs/api_reference.md ================================================ # API Reference for hagamesai This document serves as a detailed API reference for the endpoints available in the hagamesai project. Each endpoint is described with its functionality, required parameters, and response structure. ## Authentication ### POST /auth/login - **Description:** Authenticate a user and return a JWT token. - **Request Body:** - `email` (string): The user's email address. - `password` (string): The user's password. - **Response:** - **200 OK** - `access_token` (string): JWT token for authorized access. - `token_type` (string): Type of token (usually "bearer"). - **401 Unauthorized** - Error message indicating invalid credentials. ### POST /auth/register - **Description:** Register a new user. - **Request Body:** - `email` (string): The new user's email address. - `password` (string): The new user's password. - `name` (string): The user's name. - **Response:** - **201 Created** - `user_id` (integer): ID of the newly created user. - **400 Bad Request** - Error message indicating validation issues. ## Game Management ### GET /games - **Description:** Retrieve a list of all games. - **Response:** - **200 OK** - `games` (array): Array of game objects containing details such as ID, name, and description. ### POST /games - **Description:** Create a new game definition. - **Request Body:** - `name` (string): Name of the game. - `description` (string): Description of the game. - **Response:** - **201 Created** - `game_id` (integer): ID of the newly created game. - **400 Bad Request** - Error message indicating validation issues. ## AI Services ### POST /llm/predict - **Description:** Get predictions from the LLM based on input data. - **Request Body:** - `input` (string): The input data for the prediction. - **Response:** - **200 OK** - `prediction` (string): Predicted output from the LLM. - **400 Bad Request** - Error message indicating invalid input. ## Error Handling All endpoints will return appropriate HTTP status codes and error messages for any failures. Common error responses include: - **400 Bad Request:** The request was invalid. - **401 Unauthorized:** Authentication is required or failed. - **404 Not Found:** The requested resource was not found. - **500 Internal Server Error:** An unexpected error occurred on the server side. ## Conclusion This API reference provides a comprehensive overview of the endpoints available for the hagamesai project. For further assistance, please consult the project's documentation or contact the development team. ================================================ FILE: docs/game_management.md ================================================ # Game Management Documentation ## Overview The game management feature provides the functionality to create, manage, and interact with game definitions and instances. This is integral to the backend for the human-vs-AI gaming scenarios facilitated by the application. ## Features - **Create Game Definitions**: Allows the creation of new game types with defined rules and settings. - **Manage Game Instances**: Enables the initiation and management of game sessions for users. - **User Interaction**: Facilitates user interactions with the game instances through API endpoints. ## API Endpoints ### 1. Create Game Definition - **Endpoint**: `POST /api/games` - **Description**: Create a new game definition. - **Request Body**: ```json { "name": "string", "description": "string", "rules": "string", "settings": { "max_players": "integer", "game_type": "string" } } ``` - **Response**: - **Success**: Returns the created game definition object. - **Error**: Returns an error message if the creation fails. ### 2. Get Game Definitions - **Endpoint**: `GET /api/games` - **Description**: Retrieve all game definitions. - **Response**: - Returns a list of game definitions. ### 3. Start Game Instance - **Endpoint**: `POST /api/games/start` - **Description**: Start a new game instance based on a game definition. - **Request Body**: ```json { "game_id": "string", "players": ["string"] } ``` - **Response**: - **Success**: Returns the created game instance object. - **Error**: Returns an error message if the instance creation fails. ### 4. Get Game Instance - **Endpoint**: `GET /api/games/{instance_id}` - **Description**: Retrieve a specific game instance by its ID. - **Response**: - Returns the game instance details, including its current state and players. ## Conclusion The game management feature is designed to provide a comprehensive interface for managing games within the application, ensuring that users can easily create and engage in various game scenarios. This documentation will be updated as the feature evolves and further functionalities are added. ================================================ FILE: docs/llm_api_documentation.md ================================================ # LLM API Documentation ## Overview This document provides detailed information about the LLM (Large Language Model) API endpoints available in the hagamesai project. The LLM API is designed to facilitate communication with the AI engine for various functionalities including natural language processing, cognitive modeling, and game interactions. ## Base URL The base URL for all LLM API requests is: ``` http:///api/llm ``` ## Endpoints ### 1. Generate Text - **Endpoint:** `/generate` - **Method:** `POST` - **Description:** Generates text based on the provided prompt. - **Request Body:** - `prompt`: (string) The input text to generate a response from. - `max_length`: (integer) The maximum length of the generated response. Example: ```json { "prompt": "Once upon a time", "max_length": 100 } ``` - **Response:** - `200 OK` ```json { "generated_text": "Once upon a time, in a land far away..." } ``` - `400 Bad Request` ```json { "error": "Invalid input" } ``` ### 2. Analyze Sentiment - **Endpoint:** `/analyze/sentiment` - **Method:** `POST` - **Description:** Analyzes the sentiment of the provided text. - **Request Body:** - `text`: (string) The input text for sentiment analysis. Example: ```json { "text": "I love playing games!" } ``` - **Response:** - `200 OK` ```json { "sentiment": "positive" } ``` - `400 Bad Request` ```json { "error": "Invalid input" } ``` ### 3. Cognitive Task - **Endpoint:** `/cognitive/task` - **Method:** `POST` - **Description:** Executes a cognitive task based on the input data. - **Request Body:** - `task_data`: (object) The data required to perform the cognitive task. Example: ```json { "task_data": { "question": "What is the capital of France?" } } ``` - **Response:** - `200 OK` ```json { "answer": "Paris" } ``` - `400 Bad Request` ```json { "error": "Invalid input" } ``` ## Error Handling All error responses will include an error message indicating the nature of the issue. Ensure to handle error responses appropriately in client applications. ## Conclusion This documentation serves as a comprehensive guide to the LLM API endpoints. For further details on implementation and usage, please refer to the source code and additional documentation available in the project. ================================================ FILE: docs/llm_integration_guide.md ================================================ # LLM Integration Guide This document provides guidance on integrating LLM (Large Language Model) services into the hagamesai backend. This integration is crucial for enhancing the AI capabilities in human-vs-AI gameplay and cognitive modeling. ## Prerequisites Before integrating LLM services, ensure you have the following: - Python 3.10+ - FastAPI - Required libraries for LLM integration (e.g., `transformers`, `torch`, etc.) ## Setting Up the LLM Service 1. **Install Required Packages**: You need to install the necessary libraries via pip: ```bash pip install transformers torch ``` 2. **Configure the LLM Service**: In the `llm_service/service.py` file, set up the LLM model and tokenizer: ```python from transformers import AutoModelForCausalLM, AutoTokenizer class LLMService: def __init__(self, model_name: str): self.tokenizer = AutoTokenizer.from_pretrained(model_name) self.model = AutoModelForCausalLM.from_pretrained(model_name) def generate_text(self, prompt: str, max_length: int = 50): inputs = self.tokenizer(prompt, return_tensors="pt") outputs = self.model.generate(**inputs, max_length=max_length) return self.tokenizer.decode(outputs[0], skip_special_tokens=True) ``` 3. **Integrate with FastAPI**: Create an API endpoint to utilize the LLM service in `api/llm.py`: ```python from fastapi import APIRouter, HTTPException from llm_service.service import LLMService llm_router = APIRouter() llm_service = LLMService("gpt2") # Example model @llm_router.post("/generate") async def generate_text(prompt: str): try: return llm_service.generate_text(prompt) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) ``` 4. **Testing the Integration**: Ensure to create unit and integration tests for the new LLM functionalities. Tests should cover: - Valid input generation - Error handling for invalid inputs ## Conclusion This guide outlines the steps necessary for integrating LLM services into the hagamesai project. Ensure to refer to the official documentation of the libraries used for any advanced configurations and optimizations. For further assistance, consult the project's documentation or reach out to the development team. ================================================ FILE: docs/llm_service.md ================================================ # LLM Service Integration Documentation ## Overview The LLM (Large Language Model) service provides advanced AI capabilities for human-vs-AI gameplay within the hagamesai application. This documentation outlines the integration points, usage, and configuration of the LLM service, which is built using FastAPI. ## Features - **AI-Powered Gameplay**: Leverages LLMs to create intelligent behaviors in non-playable characters (NPCs). - **Cognitive Modeling**: Supports advanced decision-making processes and cognitive profiles for game entities. ## Integration Points The LLM service is integrated through the following components: - **API Endpoints**: LLM service exposes several API endpoints that can be consumed by the frontend or other services. - **Background Tasks**: Utilizes Celery for asynchronous processing of LLM requests and responses. ## Configuration To configure the LLM service, ensure that the following environment variables are set: | Environment Variable | Description | |----------------------|-------------| | `LLM_SERVICE_URL` | The URL of the LLM service endpoint. | | `LLM_API_KEY` | API key for authenticating requests to the LLM service. | ## Usage ### API Endpoints The LLM service provides the following endpoints: 1. **Generate Response** `POST /api/llm/generate` - **Request Body**: ```json { "input": "string" } ``` - **Response**: ```json { "output": "string" } ``` - **Description**: This endpoint generates a response based on the provided input string. ### Background Tasks The processing of requests to the LLM service is handled asynchronously. Ensure that your Celery workers are running to process LLM tasks. ## Error Handling The LLM service implements standard error handling. Common HTTP status codes include: - `200 OK`: The request was successful. - `400 Bad Request`: The request was invalid. - `500 Internal Server Error`: An unexpected error occurred. ## Conclusion Integrating the LLM service within the hagamesai project enhances the gaming experience by providing intelligent and responsive AI capabilities. Ensure that the necessary configurations are set up properly and that the API endpoints are utilized as intended. For further updates, please refer to the project's [roadmap](roadmap.md) and API overview documentation. ================================================ FILE: docs/roadmap.md ================================================ # project roadmap ## Technical Requirements - Python 3.10+ - FastAPI (async, high performance, Pydantic validation) - PostgreSQL (with JSONB support) - Async ORM: SQLAlchemy (async) or Tortoise ORM - Celery (with Redis or RabbitMQ) - LLM SDKs: OpenAI, Google AI - Redis (cache, session, rate limit) - Docker, Docker Compose, Kubernetes (for deployment) - Monitoring: Prometheus, Grafana - Logging: ELK Stack or Grafana Loki - Git for version control ## System Architecture - API Server (FastAPI) - User Authentication & Profile Management - Game Core Framework - AI Engine (Prediction, Cognitive Modeling, XAI, etc.) - LLM Integration Service - Data Persistence & Management - Async Task Queue (Celery) - Monitoring & Logging ## Planned Modules & Implementation Sequence 1. User Authentication & Profile Management - User registration, login, JWT/OAuth2, profile CRUD - CognitiveProfile management 2. Game Core Framework - Game definition, instance management, state engine - Game lifecycle, plugin/strategy pattern 3. AI Engine - Adaptive Prediction Engine - Cognitive Model Builder - Quantum Uncertainty Generator - Collective Wisdom Aggregation - Explainable AI (XAI) 4. LLM Integration Service - Centralized LLM API gateway - Prompt management, error handling, caching 5. Data Persistence & Management - Async ORM models for all entities - CRUD utilities, session management 6. API Routers & Endpoints - RESTful API for all modules - Pydantic schemas, status codes, error handling 7. Async Task Processing - Celery task definitions, idempotency, error handling 8. Monitoring & Logging - Structured logging, Prometheus metrics ## To Be Implemented - Developer API/SDK - Multimodal interaction support - Emotion intelligence analysis - Advanced AI model integration - Federated learning support --- **After each module is implemented, update this roadmap to reflect progress and next steps.** ================================================ FILE: docs/usage_guide.md ================================================ # Usage Guide for API Endpoints This guide provides examples of how to use the API endpoints in the `hagamesai` backend service. Each section outlines the request format, required parameters, and example responses for common API functionalities. ## User Authentication ### Register a New User **Endpoint:** `POST /api/auth/register` **Request Body:** ```json { "username": "example_user", "password": "securepassword", "email": "user@example.com" } ``` **Response:** - **201 Created** on success: ```json { "message": "User registered successfully." } ``` - **400 Bad Request** on validation error: ```json { "detail": "Username already exists." } ``` ### User Login **Endpoint:** `POST /api/auth/login` **Request Body:** ```json { "username": "example_user", "password": "securepassword" } ``` **Response:** - **200 OK** on success: ```json { "access_token": "your_jwt_token", "token_type": "bearer" } ``` - **401 Unauthorized** if credentials are invalid: ```json { "detail": "Invalid username or password." } ``` ## Game Management ### Create a New Game **Endpoint:** `POST /api/games` **Request Body:** ```json { "game_name": "Chess", "description": "A strategic board game for two players." } ``` **Response:** - **201 Created** on success: ```json { "game_id": "123", "message": "Game created successfully." } ``` ### Get Game Details **Endpoint:** `GET /api/games/{game_id}` **Response:** - **200 OK** on success: ```json { "game_id": "123", "game_name": "Chess", "description": "A strategic board game for two players." } ``` - **404 Not Found** if the game does not exist: ```json { "detail": "Game not found." } ``` ## AI Engine Services ### Request AI Service **Endpoint:** `POST /api/llm/request` **Request Body:** ```json { "input_text": "What is the capital of France?" } ``` **Response:** - **200 OK** on success: ```json { "response": "The capital of France is Paris." } ``` - **500 Internal Server Error** if the AI service fails: ```json { "detail": "Error processing request." } ``` ## Conclusion This usage guide serves as a reference for interacting with the API endpoints of `hagamesai`. Always ensure to handle responses properly, especially error cases, to provide a smooth user experience. ================================================ FILE: docs/user_management_guide.md ================================================ # User Management Guide This guide provides an overview of the user management features available in the hagamesai project. The user management system includes functionalities for user registration, authentication, and profile management. It is designed to ensure secure interactions and ease of use for end users. ## Features ### User Registration - **Endpoint**: `POST /api/auth/register` - **Description**: Allows new users to create an account. - **Request Body**: - `username`: A unique identifier for the user. - `password`: A secure password for account access. - `email`: The user's email address for account verification. - **Response**: - `201 Created`: User successfully registered. - `400 Bad Request`: Validation errors or username already taken. ### User Login - **Endpoint**: `POST /api/auth/login` - **Description**: Authenticates a user and provides a JWT token. - **Request Body**: - `username`: The user's unique identifier. - `password`: The user's password. - **Response**: - `200 OK`: JWT token is returned for further authenticated requests. - `401 Unauthorized`: Invalid credentials. ### User Profile Management - **Endpoints**: - `GET /api/users/me`: Retrieves the currently authenticated user's profile. - `PUT /api/users/me`: Updates the user's profile information. - **Request Body for Update**: - `email`: Updated email address. - `password`: Updated password (optional). - **Response**: - `200 OK`: User profile updated successfully. - `404 Not Found`: User does not exist. ## Security Considerations - Passwords must be hashed before storage. - Implement measures to prevent brute force attacks on login endpoints. - Consider implementing two-factor authentication for added security. ## Conclusion This guide provides the essential information for developers and users regarding the user management features of hagamesai. For further details, please refer to the API documentation and the source code in the `api/auth.py` and `core/auth.py` files. ================================================ FILE: docs/user_profile_management.md ================================================ # User Profile Management API Documentation ## Overview The User Profile Management API allows for the creation, retrieval, updating, and deletion of user profiles. This API provides endpoints for managing user-specific information and preferences, enabling personalized user experiences within the application. ## Base URL ```plaintext http://{host}:{port}/api/users/ ``` ## Endpoints ### 1. Create User Profile - **Endpoint:** `/profiles` - **Method:** `POST` - **Description:** Create a new user profile. - **Request Body:** ```json { "username": "string", "email": "string", "preferences": { "theme": "string", "notifications": "boolean" } } ``` - **Response:** - **Status 201:** Profile created successfully. - **Status 400:** Invalid request data. ### 2. Retrieve User Profile - **Endpoint:** `/profiles/{user_id}` - **Method:** `GET` - **Description:** Retrieve a user profile by ID. - **Response:** - **Status 200:** Returns user profile data. - **Status 404:** Profile not found. ### 3. Update User Profile - **Endpoint:** `/profiles/{user_id}` - **Method:** `PUT` - **Description:** Update an existing user profile. - **Request Body:** ```json { "email": "string", "preferences": { "theme": "string", "notifications": "boolean" } } ``` - **Response:** - **Status 200:** Profile updated successfully. - **Status 404:** Profile not found. - **Status 400:** Invalid request data. ### 4. Delete User Profile - **Endpoint:** `/profiles/{user_id}` - **Method:** `DELETE` - **Description:** Delete a user profile. - **Response:** - **Status 204:** Profile deleted successfully. - **Status 404:** Profile not found. ## Error Handling The API uses standard HTTP status codes to indicate the outcome of API requests. All error responses will include a JSON object containing an error message. ## Conclusion This documentation provides an overview of the User Profile Management API, including its endpoints, request and response formats, and error handling mechanisms. This API is essential for maintaining user information and enhancing user experience in the application. For further details, please refer to the API overview documentation or contact the API support team. ================================================ FILE: llm_service/README.md ================================================ # LLM Service Overview The LLM (Large Language Model) Service is a crucial component of the hagamesai project, enabling advanced AI capabilities to facilitate human-vs-AI gameplay. This service provides endpoints that allow for interactions with the LLM, handling requests and responses efficiently. ## Purpose The LLM Service is designed to: - Provide a seamless interface for integrating LLM functionalities into game scenarios. - Support various cognitive tasks such as conversation, problem-solving, and decision-making. - Offer robust processing capabilities to handle multiple user requests simultaneously. ## Usage Instructions To utilize the LLM Service, ensure that the service is running and follow the steps below: ### 1. Setup Make sure to install the required dependencies. If you are using a virtual environment, activate it and run: ```bash pip install -r requirements.txt ``` ### 2. Running the Service You can start the LLM Service by running the following command in your terminal: ```bash uvicorn llm_service.service:app --host 0.0.0.0 --port 8000 ``` ### 3. API Endpoints The LLM Service exposes several API endpoints that you can use to interact with the model: - **POST /llm/request**: This endpoint allows you to send a request to the LLM. - **Request Body**: ```json { "prompt": "Your input text here", "parameters": { "max_tokens": 100, "temperature": 0.7 } } ``` - **Response**: ```json { "response": "Generated response from LLM" } ``` ### 4. Example Request Here is an example of how to make a request to the LLM endpoint using `curl`: ```bash curl -X POST "http://localhost:8000/llm/request" -H "Content-Type: application/json" -d '{"prompt":"What is the capital of France?","parameters":{"max_tokens":10}}' ``` ## Conclusion This LLM Service is a key building block for enhancing gameplay experiences in hagamesai by leveraging advanced AI technologies. For further integration details and examples, please refer to the API documentation. ## License This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details. ================================================ FILE: llm_service/__init__.py ================================================ ================================================ FILE: llm_service/architecture.md ================================================ # LLM Service Architecture Overview ## Introduction The LLM Service (Large Language Model Service) is designed to facilitate human-vs-AI interactions in the game scenarios provided by the hagamesai backend. This document outlines the architecture of the LLM Service, detailing its major components, interactions, and data flow. ## Core Components The architecture of the LLM Service can be broken down into the following core components: 1. **API Layer** The API layer serves as the entry point for all client requests related to LLM functionalities. It handles incoming HTTP requests and routes them to the appropriate service handlers. - **Endpoints:** - `/llm/generate` - Generates a response based on user input. - `/llm/configure` - Configures model parameters for specific game scenarios. 2. **Service Layer** This layer contains the core business logic of the LLM Service. It processes requests from the API layer, orchestrating interactions with the underlying models and managing responses. - **Key Functions:** - `generate_response(user_input: str) -> str` Generates a response based on user input using the LLM. - `configure_model(params: Dict[str, Any]) -> None` Configures the model with specified parameters for optimal performance. 3. **Model Layer** The Model layer is responsible for interacting with the Large Language Model, executing the necessary computations to generate responses. This layer abstracts the complexities of model interactions, providing a clean interface for the service layer. - **Key Models:** - Transformer-based models optimized for dialogue generation and multi-turn conversations. 4. **Database Layer** This layer includes all database interactions required for storing user profiles, game states, and any other persistent data necessary for the LLM Service. - **Database Technology:** - PostgreSQL for structured data storage. 5. **Caching Layer** To improve performance and reduce latency, we utilize Redis as a caching layer to store frequently accessed data, such as user sessions and previous interactions. ## Data Flow The interaction flow within the LLM Service can be summarized as follows: 1. A user sends a request through the API layer. 2. The API layer forwards the request to the service layer. 3. The service layer processes the request, potentially querying the database or caching layer for necessary data. 4. The service layer invokes the model layer to generate a response. 5. The response is then formatted and returned to the user via the API layer. ## Conclusion This architecture is designed to ensure scalability, performance, and maintainability. The separation of concerns allows for easier updates and enhancements to individual components without affecting the overall system. ## Future Considerations As the project evolves, further enhancements may include: - Advanced error handling strategies for API requests. - Implementation of additional caching strategies to support more complex queries. - Exploration of multi-model setups for improved response accuracy and diversity. --- ================================================ FILE: llm_service/configuration.md ================================================ # LLM Service Configuration Options This document outlines the configuration options available for the LLM (Large Language Model) service within the hagamesai project. Proper configuration is crucial for optimizing the performance and capabilities of our AI engine services. ## Configuration Parameters ### 1. LLM Endpoint - **Description:** The endpoint to access the LLM service. - **Default:** `http://localhost:8000/llm` ### 2. API Key - **Description:** The API key for authenticating requests to the LLM service. - **Default:** `None` (must be provided for production). ### 3. Timeout - **Description:** The maximum time to wait for a response from the LLM service, in seconds. - **Default:** `30` ### 4. Max Tokens - **Description:** The maximum number of tokens to generate in the response. - **Default:** `150` ### 5. Temperature - **Description:** Controls the randomness of the output. Lower values make the output more focused and deterministic. Higher values increase creativity and randomness. - **Default:** `0.7` ### 6. Top P - **Description:** The cumulative probability for token selection. This can be used to restrict the output to a certain subset of tokens, enhancing quality. - **Default:** `1.0` (no restrictions) ## Example Configuration ```json { "llm_endpoint": "http://localhost:8000/llm", "api_key": "your_api_key_here", "timeout": 30, "max_tokens": 150, "temperature": 0.7, "top_p": 1.0 } ``` ## Conclusion This configuration file allows you to customize various aspects of the LLM service to better fit your application needs. Ensure that you adjust these settings based on your requirements and the environment in which the service is deployed. ================================================ FILE: llm_service/crud.py ================================================ import uuid from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from llm_service.models import LLMCallLog from llm_service.schemas import LLMCallRequest async def create_log(session: AsyncSession, req: LLMCallRequest, response: str, status: str) -> LLMCallLog: """Create a new LLM call log entry.""" log = LLMCallLog( user_id=req.user_id, provider=req.provider, model=req.model, prompt=req.prompt, response=response, status=status ) session.add(log) await session.commit() await session.refresh(log) return log async def list_logs_by_user(session: AsyncSession, user_id: uuid.UUID) -> list[LLMCallLog]: """List all LLM call logs for a user.""" result = await session.execute(select(LLMCallLog).where(LLMCallLog.user_id == user_id)) return result.scalars().all() ================================================ FILE: llm_service/faq.md ================================================ # Frequently Asked Questions (FAQ) about LLM Service ## What is the LLM Service? The LLM (Large Language Model) Service is a component of the hagamesai project that provides advanced AI capabilities for human-vs-AI gameplay. It utilizes state-of-the-art machine learning techniques to enhance the gaming experience. ## How do I integrate the LLM Service with my application? To integrate the LLM Service, you can use the API endpoints provided in the `llm.py` file located in the `api` directory. Make sure to refer to the API documentation for detailed instructions on how to make requests and handle responses. ## What kind of functionalities does the LLM Service provide? The LLM Service offers various functionalities, including: - Natural language understanding - Text generation - Sentiment analysis - Customizable AI behavior based on user interactions ## Is there a limit on the number of requests I can make to the LLM Service? Yes, there may be rate limits imposed on the API to ensure fair usage and maintain service quality. Please check the API documentation for specific rate limits and guidelines. ## How can I report issues or provide feedback about the LLM Service? Feedback and issues can be reported through the project's GitHub repository. Please open an issue and provide as much detail as possible regarding the problem or suggestion. ## Where can I find more information about the AI models used in the LLM Service? You can find more information about the AI models in the `llm_service` directory, specifically within the `models.py` and `schemas.py` files. These files contain the definitions and structures of the models utilized by the service. ## Who can I contact for support? For support, please reach out to the project maintainers through the GitHub repository's contact options. You can also check the existing issues for similar queries. ================================================ FILE: llm_service/models.py ================================================ import uuid from datetime import datetime from sqlalchemy import String, Text, DateTime, ForeignKey from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID from models.user import Base class LLMCallLog(Base): """LLMCallLog model for logging LLM API calls and responses.""" __tablename__ = "llm_call_logs" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) provider: Mapped[str] = mapped_column(String(50), nullable=False) model: Mapped[str] = mapped_column(String(100), nullable=False) prompt: Mapped[str] = mapped_column(Text, nullable=False) response: Mapped[str] = mapped_column(Text, nullable=True) status: Mapped[str] = mapped_column(String(20), nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, nullable=False) ================================================ FILE: llm_service/schemas.py ================================================ import uuid from datetime import datetime from pydantic import BaseModel, Field class LLMCallRequest(BaseModel): """Schema for making an LLM call.""" provider: str = Field(..., max_length=50) model: str = Field(..., max_length=100) prompt: str user_id: uuid.UUID | None = None class LLMCallResponse(BaseModel): """Schema for LLM call response.""" response: str status: str class LLMCallLogRead(BaseModel): """Schema for reading LLM call log info.""" id: uuid.UUID user_id: uuid.UUID | None provider: str model: str prompt: str response: str | None status: str created_at: datetime class Config: orm_mode = True ================================================ FILE: llm_service/service.py ================================================ import requests import logging class LLMService: """ A service class to handle integration with the LLM (Large Language Model) API. """ def __init__(self, api_key: str, api_url: str): """ Initialize the LLM service with API key and URL. """ self.api_key = api_key self.api_url = api_url self.logger = logging.getLogger(__name__) def generate_response(self, prompt: str) -> str: """ Generate a response from the LLM based on the provided prompt. :param prompt: The input prompt for the LLM. :return: The generated response from the LLM. """ headers = { 'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json' } data = { 'prompt': prompt, 'max_tokens': 150 } try: response = requests.post(self.api_url, headers=headers, json=data) response.raise_for_status() # Raise an error for bad responses response_data = response.json() return response_data.get('choices')[0].get('text').strip() except requests.exceptions.HTTPError as http_err: self.logger.error(f'HTTP error occurred: {http_err}') except Exception as err: self.logger.error(f'An error occurred: {err}') return "" # Return empty string in case of error # Example usage: # llm_service = LLMService(api_key='your_api_key', api_url='https://api.llmprovider.com/v1/generate') # response = llm_service.generate_response('What is the capital of France?') # print(response) ================================================ FILE: llm_service/test_ai_engine_service.py ================================================ import pytest from llm_service.service import AIEngineService class TestAIEngineService: @pytest.fixture(scope="class") def service(self): """Fixture to initialize the AIEngineService for testing.""" return AIEngineService() def test_initialization(self, service): """Test the initialization of the AIEngineService.""" assert service is not None, "Service should be initialized" def test_method_1(self, service): """Test method 1 of AIEngineService.""" result = service.method_1() # Replace with actual method assert result == expected_value, "Method 1 should return expected value" def test_method_2(self, service): """Test method 2 of AIEngineService.""" result = service.method_2(arg1, arg2) # Replace with actual method and arguments assert result == expected_value, "Method 2 should return expected value" def test_method_3(self, service): """Test method 3 of AIEngineService with edge case.""" result = service.method_3(edge_case_arg) # Replace with actual method and edge case argument assert result == expected_value, "Method 3 should handle edge case correctly" # Add more tests for additional methods as necessary ================================================ FILE: llm_service/test_llm_service.py ================================================ import unittest from llm_service.service import LLMService class TestLLMService(unittest.TestCase): """Unit tests for LLM service functionality.""" def setUp(self): """Set up test fixtures, if any.""" self.llm_service = LLMService() def test_generate_response(self): """Test the response generation from LLM service.""" input_text = "What is the capital of France?" expected_output = "Paris" # This should match the expected output based on the service logic response = self.llm_service.generate_response(input_text) self.assertEqual(response, expected_output, f"Expected '{expected_output}' but got '{response}'") def test_invalid_input(self): """Test LLM service with invalid input.""" input_text = "" with self.assertRaises(ValueError): self.llm_service.generate_response(input_text) def test_performance(self): """Test the performance of the LLM service.""" import time input_text = "Tell me a joke" start_time = time.time() self.llm_service.generate_response(input_text) duration = time.time() - start_time self.assertLess(duration, 1, "Response time should be less than 1 second") if __name__ == '__main__': unittest.main() ================================================ FILE: llm_service/test_llm_service_integration.py ================================================ import pytest from fastapi.testclient import TestClient from llm_service.service import app @pytest.fixture(scope="module") def test_client(): """Fixture to create a test client for the FastAPI app.""" client = TestClient(app) yield client def test_llm_service_integration(test_client): """Integration tests for LLM service with external APIs.""" # Example test case for LLM service response = test_client.post("/llm_service/endpoint", json={ "input_data": "Test input" }) assert response.status_code == 200 assert "output_data" in response.json() assert response.json()["output_data"] == "Expected output" # Replace with actual expected output # Additional tests can be added here to cover more scenarios def test_llm_service_error_handling(test_client): """Test error handling in LLM service.""" response = test_client.post("/llm_service/endpoint", json={ "input_data": "Invalid data" }) assert response.status_code == 400 assert "error" in response.json() # Ensure response has error key ================================================ FILE: llm_service/test_service.py ================================================ import pytest from llm_service.service import LLMService @pytest.fixture def llm_service(): """Fixture for LLMService instance.""" return LLMService() def test_llm_service_integration(llm_service): """Test LLM service integration with valid input.""" response = llm_service.process_request({ 'input_data': 'Test input for LLM', 'parameters': {'max_tokens': 50} }) assert response is not None, "Expected a response from LLM service" assert 'output_data' in response, "Response should contain 'output_data' key" def test_llm_service_error_handling(llm_service): """Test LLM service integration with invalid input.""" with pytest.raises(ValueError): llm_service.process_request({ 'input_data': '', # Invalid input 'parameters': {'max_tokens': 50} }) @pytest.mark.parametrize('input_data, expected_output', [ ('Hello, world!', 'Expected output for Hello'), ('Goodbye!', 'Expected output for Goodbye') ]) def test_llm_service_multiple_cases(llm_service, input_data, expected_output): """Test LLM service with multiple input cases.""" response = llm_service.process_request({ 'input_data': input_data, 'parameters': {'max_tokens': 50} }) assert response['output_data'] == expected_output, f"Expected {expected_output} but got {response['output_data']}" ================================================ FILE: llm_service/usage_examples.md ================================================ # Usage Examples for LLM Service Endpoints This document provides examples of how to use the LLM (Large Language Model) service endpoints exposed by the API. The LLM service is designed to facilitate interactions with advanced AI functionalities, including text generation, summarization, and more. ## Endpoint: Generate Text ### Request To generate text using the LLM service, send a POST request to the following endpoint: ```http POST /api/llm/generate ``` ### Sample Request Body ```json { "prompt": "Once upon a time in a distant galaxy...", "max_tokens": 150, "temperature": 0.7 } ``` ### Example using Python's `requests` library ```python import requests url = "http://localhost:8000/api/llm/generate" headers = {"Content-Type": "application/json"} payload = { "prompt": "Once upon a time in a distant galaxy...", "max_tokens": 150, "temperature": 0.7 } response = requests.post(url, json=payload, headers=headers) if response.status_code == 200: result = response.json() print("Generated Text:", result['text']) else: print("Error:", response.status_code, response.text) ``` ## Endpoint: Summarize Text ### Request To summarize a given text, send a POST request to: ```http POST /api/llm/summarize ``` ### Sample Request Body ```json { "text": "The quick brown fox jumps over the lazy dog. This sentence is often used as a pangram in English, demonstrating the usage of every letter in the alphabet.", "max_tokens": 50 } ``` ### Example using Python's `requests` library ```python import requests url = "http://localhost:8000/api/llm/summarize" headers = {"Content-Type": "application/json"} payload = { "text": "The quick brown fox jumps over the lazy dog. This sentence is often used as a pangram in English, demonstrating the usage of every letter in the alphabet.", "max_tokens": 50 } response = requests.post(url, json=payload, headers=headers) if response.status_code == 200: result = response.json() print("Summary:", result['summary']) else: print("Error:", response.status_code, response.text) ``` ## Conclusion These examples demonstrate how to effectively interact with the LLM service endpoints. Ensure that the API is running and accessible at the specified URL before making requests. Adjust the `max_tokens` and `temperature` parameters as needed to tailor the output to your specific requirements. ================================================ FILE: main.py ================================================ """Main application module for HAGAME AI Engine.""" from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware import uvicorn import logging from api.routers import auth, users, games, ai_engine from core.config import settings # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) app = FastAPI( title="HAGAME AI Engine", description="Advanced AI system for game environments", version="0.1.0" ) # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include routers app.include_router(auth.router) app.include_router(users.router) app.include_router(games.router) app.include_router(ai_engine.router) @app.on_event("startup") async def startup_event(): """Initialize services on application startup.""" logger.info("Starting HAGAME AI Engine") @app.on_event("shutdown") async def shutdown_event(): """Cleanup on application shutdown.""" logger.info("Shutting down HAGAME AI Engine") @app.get("/") async def root(): """Root endpoint.""" return { "name": "HAGAME AI Engine", "version": "0.1.0", "status": "running" } if __name__ == "__main__": uvicorn.run( "main:app", host=settings.HOST, port=settings.PORT, reload=settings.DEBUG ) ================================================ FILE: models/__init__.py ================================================ ================================================ FILE: models/ai_model.py ================================================ import uuid from sqlalchemy import String, Text, Column, Integer, JSON from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID, JSONB from models.user import Base class AIModel(Base): """AIModel model for storing AI model configuration and metadata.""" __tablename__ = "ai_models" id = Column(Integer, primary_key=True, index=True) name = Column(String, nullable=False, unique=True) description = Column(String, nullable=True) config = Column(JSON, nullable=False) metadata = Column(JSON, nullable=True) file_path = Column(String, nullable=True) created_at = Column(String, nullable=False) updated_at = Column(String, nullable=True) ================================================ FILE: models/cognitive_profile.py ================================================ import uuid from datetime import datetime from sqlalchemy import DateTime, ForeignKey from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID, JSONB from models.user import Base class CognitiveProfile(Base): """CognitiveProfile model for storing user cognitive data.""" __tablename__ = "cognitive_profiles" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), unique=True, nullable=False) profile_data: Mapped[dict] = mapped_column( JSONB, nullable=False, default=dict) last_updated: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) ================================================ FILE: models/game_definition.py ================================================ import uuid from sqlalchemy import String, Text from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID, JSONB from models.user import Base class GameDefinition(Base): """GameDefinition model for storing game metadata and rules.""" __tablename__ = "game_definitions" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name: Mapped[str] = mapped_column( String(100), unique=True, nullable=False, index=True) description: Mapped[str] = mapped_column(Text, nullable=False) rules_config: Mapped[dict] = mapped_column( JSONB, nullable=False, default=dict) version: Mapped[str] = mapped_column(String(20), nullable=False) ================================================ FILE: models/game_instance.py ================================================ import uuid from datetime import datetime from sqlalchemy import String, Integer, DateTime, ForeignKey from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID, JSONB from models.user import Base class GameInstance(Base): """GameInstance model for storing game session data.""" __tablename__ = "game_instances" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) game_definition_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("game_definitions.id"), nullable=False) user_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) status: Mapped[str] = mapped_column( String(20), nullable=False, default="pending") game_state: Mapped[dict] = mapped_column( JSONB, nullable=False, default=dict) start_time: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, nullable=False) end_time: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) score: Mapped[int | None] = mapped_column(Integer, nullable=True) ai_model_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), nullable=True) ================================================ FILE: models/user.py ================================================ import uuid from datetime import datetime from sqlalchemy import String, DateTime from sqlalchemy.orm import Mapped, mapped_column, declarative_base from sqlalchemy.dialects.postgresql import UUID Base = declarative_base() class User(Base): """User model for authentication and profile management.""" __tablename__ = "users" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) username: Mapped[str] = mapped_column( String(50), unique=True, nullable=False, index=True) email: Mapped[str] = mapped_column( String(255), unique=True, nullable=False, index=True) hashed_password: Mapped[str] = mapped_column(String(255), nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) ================================================ FILE: pyproject.toml ================================================ [project] name = "hagamesai" version = "0.1.0" description = "HAGAME AI Engine - An advanced game AI system" authors = [{ name = "HAGAME Team", email = "team@hagame.ai" }] dependencies = [ "fastapi>=0.68.0", "uvicorn>=0.15.0", "sqlalchemy>=1.4.23", "alembic>=1.7.1", "pydantic>=1.8.2", "python-jose[cryptography]>=3.3.0", "passlib[bcrypt]>=1.7.4", "python-multipart>=0.0.5", "numpy>=1.21.2", "scipy>=1.7.1", "scikit-learn>=0.24.2", "pandas>=1.3.2", "celery>=5.1.2", "redis>=3.5.3", "python-dotenv>=0.19.0", "structlog>=21.1.0", "psycopg2-binary>=2.9.1", "asyncpg>=0.24.0", "aiohttp>=3.7.4", "httpx>=0.18.2", "pyyaml>=6.0.2", ] requires-python = ">=3.10" readme = "README.md" license = { file = "LICENSE" } [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" [tool.pdm.dev-dependencies] test = ["pytest>=6.2.5", "pytest-asyncio>=0.15.1", "pytest-cov>=2.12.1", "httpx>=0.18.2"] [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] [tool.black] line-length = 88 target-version = ["py310"] include = '\.pyi?$' [tool.isort] profile = "black" multi_line_output = 3 ================================================ FILE: schemas/__init__.py ================================================ ================================================ FILE: schemas/ai_engine.py ================================================ """Pydantic schemas for AI Engine data models.""" from typing import Dict, List, Any, Optional from pydantic import BaseModel, Field from datetime import datetime class GameState(BaseModel): """Schema for game state data.""" game_id: str state_type: str = Field(..., description="Type of game state (e.g., 'in_progress', 'completed')") player_states: Dict[str, Dict[str, Any] ] = Field(..., description="States of all players") game_variables: Dict[str, Any] = Field(..., description="Game-specific variables") timestamp: datetime = Field(default_factory=datetime.utcnow) metadata: Optional[Dict[str, Any]] = Field( default=None, description="Additional metadata") class PredictionRequest(BaseModel): """Schema for prediction request.""" game_state: GameState context: Optional[Dict[str, Any]] = Field( default=None, description="Additional context") class PredictionResponse(BaseModel): """Schema for prediction response.""" predictions: Dict[str, Any] = Field(..., description="Predicted outcomes and actions") cognitive_state: Dict[str, Any] = Field(..., description="Current cognitive model state") uncertainty: Dict[str, Any] = Field(..., description="Uncertainty factors") collective_wisdom: Dict[str, Any] = Field(..., description="Aggregated insights") explanations: Dict[str, str] = Field(..., description="Natural language explanations") confidence_scores: Dict[str, float] = Field(..., description="Confidence levels") timestamp: datetime = Field(default_factory=datetime.utcnow) class FeedbackRequest(BaseModel): """Schema for feedback data.""" game_id: str prediction_accuracy: Dict[str, float] = Field(..., description="Accuracy of predictions") cognitive_accuracy: Dict[str, float] = Field(..., description="Accuracy of cognitive model") uncertainty_accuracy: Dict[str, float] = Field( ..., description="Accuracy of uncertainty estimates") wisdom_relevance: Dict[str, float] = Field( ..., description="Relevance of collective insights") explanation_clarity: Dict[str, float] = Field(..., description="Clarity of explanations") context: Optional[Dict[str, Any]] = Field( default=None, description="Additional context") class CognitiveProfile(BaseModel): """Schema for cognitive profile data.""" player_id: str learning_style: str = Field(..., description="Identified learning style") decision_making: Dict[str, float] = Field(..., description="Decision-making metrics") attention_patterns: Dict[str, float] = Field(..., description="Attention-related metrics") skill_levels: Dict[str, float] = Field(..., description="Various skill measurements") adaptability: float = Field(..., description="Overall adaptability score") last_updated: datetime = Field(default_factory=datetime.utcnow) metadata: Optional[Dict[str, Any]] = Field( default=None, description="Additional metadata") class CollectiveKnowledge(BaseModel): """Schema for collective wisdom data.""" game_id: str patterns: Dict[str, float] = Field(..., description="Identified patterns") strategies: Dict[str, float] = Field(..., description="Effective strategies") meta_insights: Dict[str, Any] = Field(..., description="Meta-level insights") confidence_scores: Dict[str, float] = Field(..., description="Confidence in insights") timestamp: datetime = Field(default_factory=datetime.utcnow) class UncertaintyFactors(BaseModel): """Schema for uncertainty data.""" game_id: str player_uncertainty: Dict[str, float] = Field( ..., description="Player-related uncertainties") game_state_uncertainty: Dict[str, float] = Field( ..., description="Game state uncertainties") environmental_uncertainty: Dict[str, float] = Field( ..., description="Environmental uncertainties") composite_uncertainty: float = Field(..., description="Overall uncertainty score") timestamp: datetime = Field(default_factory=datetime.utcnow) class Explanation(BaseModel): """Schema for AI explanations.""" game_id: str decision_explanations: Dict[str, str] = Field(..., description="Decision explanations") feature_importance: Dict[str, float] = Field(..., description="Feature importance scores") counterfactuals: List[Dict[str, Any] ] = Field(..., description="Counterfactual scenarios") confidence_levels: Dict[str, float] = Field(..., description="Confidence in explanations") timestamp: datetime = Field(default_factory=datetime.utcnow) # Response models for API endpoints class CognitiveProfileResponse(BaseModel): """Response model for cognitive profile endpoint.""" profile: CognitiveProfile metadata: Optional[Dict[str, Any]] = None class CollectiveWisdomResponse(BaseModel): """Response model for collective wisdom endpoint.""" knowledge: CollectiveKnowledge metadata: Optional[Dict[str, Any]] = None class UncertaintyResponse(BaseModel): """Response model for uncertainty factors endpoint.""" factors: UncertaintyFactors metadata: Optional[Dict[str, Any]] = None class ExplanationResponse(BaseModel): """Response model for explanations endpoint.""" explanation: Explanation metadata: Optional[Dict[str, Any]] = None ================================================ FILE: schemas/ai_model.py ================================================ import uuid from pydantic import BaseModel, Field from typing import Optional, Dict, Any from datetime import datetime class AIModelBase(BaseModel): name: str description: Optional[str] = None config: Dict[str, Any] metadata: Optional[Dict[str, Any]] = None file_path: Optional[str] = None class AIModelCreate(AIModelBase): """Schema for creating a new AI model.""" type: str = Field(..., max_length=50) version: str = Field(..., max_length=20) class AIModelUpdate(BaseModel): name: Optional[str] = None description: Optional[str] = None config: Optional[Dict[str, Any]] = None metadata: Optional[Dict[str, Any]] = None file_path: Optional[str] = None class AIModelRead(AIModelBase): """Schema for reading AI model info.""" id: int created_at: datetime updated_at: Optional[datetime] = None class Config: from_attributes = True ================================================ FILE: schemas/cognitive_profile.py ================================================ import uuid from datetime import datetime from pydantic import BaseModel, Field class CognitiveProfileRead(BaseModel): """Schema for reading cognitive profile info.""" id: uuid.UUID user_id: uuid.UUID profile_data: dict last_updated: datetime class CognitiveProfileUpdate(BaseModel): """Schema for updating cognitive profile info.""" profile_data: dict = Field(...) ================================================ FILE: schemas/game_definition.py ================================================ from pydantic import BaseModel, Field from typing import List, Optional class GameDefinition(BaseModel): id: int = Field(..., description="Unique identifier for the game definition") name: str = Field(..., description="Name of the game") description: Optional[str] = Field(None, description="Description of the game") rules: str = Field(..., description="Rules of the game") created_at: str = Field(..., description="Timestamp of when the game was created") updated_at: str = Field(..., description="Timestamp of when the game was last updated") class GameDefinitionCreate(BaseModel): name: str = Field(..., description="Name of the game") description: Optional[str] = Field(None, description="Description of the game") rules: str = Field(..., description="Rules of the game") class GameDefinitionUpdate(BaseModel): name: Optional[str] = Field(None, description="Name of the game") description: Optional[str] = Field(None, description="Description of the game") rules: Optional[str] = Field(None, description="Rules of the game") class GameDefinitionResponse(BaseModel): id: int name: str description: Optional[str] rules: str created_at: str updated_at: str class Config: orm_mode = True ================================================ FILE: schemas/game_instance.py ================================================ from pydantic import BaseModel, Field from typing import Optional class GameInstance(BaseModel): id: int = Field(..., description="Unique identifier for the game instance") game_id: int = Field(..., description="Identifier for the associated game") user_id: int = Field(..., description="Identifier for the user playing this game instance") status: str = Field(..., description="Current status of the game instance (e.g., 'in_progress', 'completed')") created_at: str = Field(..., description="Timestamp when the game instance was created") updated_at: Optional[str] = Field(None, description="Timestamp when the game instance was last updated") class Config: schema_extra = { "example": { "id": 1, "game_id": 101, "user_id": 201, "status": "in_progress", "created_at": "2023-01-01T12:00:00Z", "updated_at": "2023-01-01T12:30:00Z" } } ================================================ FILE: schemas/llm_request.py ================================================ from pydantic import BaseModel, Field from typing import Optional class LLMRequest(BaseModel): prompt: str = Field(..., description="The input prompt for the LLM.") model: str = Field(..., description="The name of the LLM model to use.") max_tokens: Optional[int] = Field(100, ge=1, description="The maximum number of tokens to generate.") temperature: Optional[float] = Field(0.7, ge=0.0, le=1.0, description="Sampling temperature for the model.") top_p: Optional[float] = Field(1.0, ge=0.0, le=1.0, description="Cumulative probability for top-p sampling.") stop: Optional[list] = Field(None, description="List of stop sequences for the LLM.") class Config: schema_extra = { "example": { "prompt": "What is the capital of France?", "model": "gpt-3.5-turbo", "max_tokens": 50, "temperature": 0.5, "top_p": 1.0, "stop": ["\n"] } } ================================================ FILE: schemas/llm_response.py ================================================ from pydantic import BaseModel, Field from typing import Any, List, Optional class LLMResponse(BaseModel): id: str = Field(..., description="The unique identifier for the response") prompt: str = Field(..., description="The input prompt given to the LLM") response: str = Field(..., description="The generated response from the LLM") tokens_used: int = Field(..., description="The number of tokens used in the response") completion_time: float = Field(..., description="Time taken to generate the response in seconds") metadata: Optional[dict[str, Any]] = Field(None, description="Optional metadata related to the response") class LLMResponseList(BaseModel): responses: List[LLMResponse] = Field(..., description="List of LLM responses") ================================================ FILE: schemas/task.py ================================================ from pydantic import BaseModel class TaskTrigger(BaseModel): """Schema for triggering an example task.""" seconds: int class TaskStatus(BaseModel): """Schema for returning task status.""" task_id: str status: str result: str | None = None ================================================ FILE: schemas/user.py ================================================ import uuid from datetime import datetime from pydantic import BaseModel, EmailStr, Field class UserCreate(BaseModel): """Schema for user registration.""" username: str = Field(..., max_length=50) email: EmailStr password: str = Field(..., min_length=8) class UserLogin(BaseModel): """Schema for user login.""" email: EmailStr password: str class UserRead(BaseModel): """Schema for reading user info.""" id: uuid.UUID username: str email: EmailStr created_at: datetime updated_at: datetime class Config: orm_mode = True class UserUpdate(BaseModel): """Schema for updating user info.""" username: str | None = None email: EmailStr | None = None password: str | None = Field(default=None, min_length=8) ================================================ FILE: schemas/user_profile.py ================================================ from pydantic import BaseModel, EmailStr from typing import Optional class UserProfile(BaseModel): id: int user_id: int # Foreign key to associate with User display_name: str bio: Optional[str] = None email: Optional[EmailStr] = None # Email validation profile_picture: Optional[str] = None # URL to profile picture class Config: orm_mode = True # Allows compatibility with ORM class UserProfileCreate(BaseModel): user_id: int display_name: str bio: Optional[str] = None email: Optional[EmailStr] = None profile_picture: Optional[str] = None class UserProfileUpdate(BaseModel): display_name: Optional[str] = None bio: Optional[str] = None email: Optional[EmailStr] = None profile_picture: Optional[str] = None ================================================ FILE: tests/integration/test_ai_engine.py ================================================ import pytest from fastapi.testclient import TestClient from llm_service.service import app # Initialize the test client client = TestClient(app) @pytest.fixture def sample_data(): # Sample input data for the AI engine services return { 'input': 'sample input', 'parameters': {'param1': 'value1', 'param2': 'value2'} } def test_ai_engine_service_integration(sample_data): # Test for the AI engine service integration response = client.post('/api/ai/engine', json=sample_data) assert response.status_code == 200 assert 'output' in response.json() def test_ai_engine_service_error_handling(): # Test for error handling in the AI engine service response = client.post('/api/ai/engine', json={}) # Missing required data assert response.status_code == 422 # Unprocessable Entity assert 'detail' in response.json() # Additional tests can be added here to cover more scenarios ================================================ FILE: tests/integration/test_ai_engine_integration.py ================================================ import pytest from fastapi.testclient import TestClient from core.ai_engine import app # Assuming your FastAPI app is in core/ai_engine.py @pytest.fixture def client(): """Create a test client for the FastAPI app.""" return TestClient(app) def test_ai_engine_integration(client): """Test integration of AI engine with valid input.""" response = client.post("/api/llm/engine", json={ "input_data": "Sample input for AI engine" }) assert response.status_code == 200 assert "output_data" in response.json() def test_ai_engine_integration_invalid_data(client): """Test integration of AI engine with invalid input.""" response = client.post("/api/llm/engine", json={ "input_data": "" }) assert response.status_code == 422 # Unprocessable Entity assert "detail" in response.json() def test_ai_engine_integration_error_handling(client): """Test AI engine's error handling with incorrect endpoint.""" response = client.post("/api/llm/non_existing_endpoint", json={ "input_data": "Sample input" }) assert response.status_code == 404 # Not Found assert "detail" in response.json() ================================================ FILE: tests/integration/test_auth.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app # Test client for the FastAPI app client = TestClient(app) @pytest.mark.parametrize("username, password, expected_status", [ ("testuser", "testpass", 200), # Successful login ("invaliduser", "testpass", 401), # Invalid user ("testuser", "wrongpass", 401), # Invalid password ]) def test_login(username, password, expected_status): response = client.post("/auth/login", json={ "username": username, "password": password }) assert response.status_code == expected_status def test_register(): response = client.post("/auth/register", json={ "username": "newuser", "password": "newpass", "email": "newuser@example.com" }) assert response.status_code == 201 assert "access_token" in response.json() def test_register_existing_user(): response = client.post("/auth/register", json={ "username": "testuser", "password": "testpass", "email": "testuser@example.com" }) assert response.status_code == 400 # User already exists ================================================ FILE: tests/integration/test_auth_integration.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app @pytest.fixture def client(): return TestClient(app) @pytest.fixture def create_user(client): response = client.post('/auth/register', json={ 'username': 'test_user', 'password': 'test_pass', 'email': 'test_user@example.com' }) return response.json() @pytest.fixture def login_user(client, create_user): response = client.post('/auth/login', json={ 'username': 'test_user', 'password': 'test_pass' }) return response.json() def test_user_registration(client): response = client.post('/auth/register', json={ 'username': 'new_user', 'password': 'new_pass', 'email': 'new_user@example.com' }) assert response.status_code == 201 assert 'access_token' in response.json() def test_user_login(client, create_user): response = client.post('/auth/login', json={ 'username': 'test_user', 'password': 'test_pass' }) assert response.status_code == 200 assert 'access_token' in response.json() def test_login_with_invalid_credentials(client): response = client.post('/auth/login', json={ 'username': 'wrong_user', 'password': 'wrong_pass' }) assert response.status_code == 401 assert 'detail' in response.json() def test_login_without_password(client): response = client.post('/auth/login', json={ 'username': 'test_user' }) assert response.status_code == 422 assert 'detail' in response.json() def test_registration_with_existing_username(client): client.post('/auth/register', json={ 'username': 'existing_user', 'password': 'pass', 'email': 'existing_user@example.com' }) # Register first time response = client.post('/auth/register', json={ 'username': 'existing_user', 'password': 'pass', 'email': 'existing_user2@example.com' }) assert response.status_code == 400 assert 'detail' in response.json() ================================================ FILE: tests/integration/test_game_integration.py ================================================ import pytest from fastapi.testclient import TestClient from main import app # Create a test client using the FastAPI app client = TestClient(app) @pytest.fixture def create_game(): # Sample payload for creating a game payload = { "name": "Test Game", "description": "A game for testing purposes", "rules": "Test rules for the game." } response = client.post("/games/", json=payload) assert response.status_code == 201 return response.json() def test_create_game(create_game): game = create_game assert "id" in game assert game["name"] == "Test Game" assert game["description"] == "A game for testing purposes" def test_get_game(create_game): game_id = create_game["id"] response = client.get(f"/games/{game_id}") assert response.status_code == 200 game = response.json() assert game["id"] == game_id assert game["name"] == "Test Game" def test_update_game(create_game): game_id = create_game["id"] update_payload = { "name": "Updated Game", "description": "An updated description for the game." } response = client.put(f"/games/{game_id}", json=update_payload) assert response.status_code == 200 updated_game = response.json() assert updated_game["name"] == "Updated Game" def test_delete_game(create_game): game_id = create_game["id"] response = client.delete(f"/games/{game_id}") assert response.status_code == 204 # Ensure the game was deleted response = client.get(f"/games/{game_id}") assert response.status_code == 404 ================================================ FILE: tests/integration/test_game_management_integration.py ================================================ import pytest from fastapi.testclient import TestClient from main import app # Initialize the test client client = TestClient(app) @pytest.fixture def game_data(): return { "name": "Test Game", "description": "A game for testing purposes", "rules": "Test rules for the game", "max_players": 4 } def test_create_game(game_data): response = client.post("/games/", json=game_data) assert response.status_code == 201 data = response.json() assert data["name"] == game_data["name"] assert "id" in data def test_get_game(game_data): # First, create a game to retrieve create_response = client.post("/games/", json=game_data) game_id = create_response.json()["id"] # Now retrieve the created game response = client.get(f"/games/{game_id}") assert response.status_code == 200 data = response.json() assert data["id"] == game_id assert data["name"] == game_data["name"] def test_update_game(game_data): # First, create a game to update create_response = client.post("/games/", json=game_data) game_id = create_response.json()["id"] updated_data = {"name": "Updated Game", "description": "Updated description"} # Now update the created game response = client.put(f"/games/{game_id}", json=updated_data) assert response.status_code == 200 data = response.json() assert data["name"] == updated_data["name"] def test_delete_game(game_data): # First, create a game to delete create_response = client.post("/games/", json=game_data) game_id = create_response.json()["id"] # Now delete the created game response = client.delete(f"/games/{game_id}") assert response.status_code == 204 # Ensure the game no longer exists response = client.get(f"/games/{game_id}") assert response.status_code == 404 ================================================ FILE: tests/integration/test_games.py ================================================ import pytest from fastapi.testclient import TestClient from api.games import app # Initialize the test client client = TestClient(app) @pytest.mark.parametrize("game_data", [ {"name": "Chess", "description": "A classic strategy game."}, {"name": "Checkers", "description": "A classic board game for two players."}, ]) def test_create_game(game_data): response = client.post("/games/", json=game_data) assert response.status_code == 201 assert "id" in response.json() assert response.json()["name"] == game_data["name"] def test_get_all_games(): response = client.get("/games/") assert response.status_code == 200 assert isinstance(response.json(), list) def test_get_game_by_id(): game_id = 1 # assuming a game with ID 1 exists response = client.get(f"/games/{game_id}") assert response.status_code == 200 assert "name" in response.json() def test_update_game(): game_id = 1 # assuming a game with ID 1 exists updated_data = {"name": "Updated Chess", "description": "An updated description for the chess game."} response = client.put(f"/games/{game_id}", json=updated_data) assert response.status_code == 200 assert response.json()["name"] == updated_data["name"] def test_delete_game(): game_id = 1 # assuming a game with ID 1 exists response = client.delete(f"/games/{game_id}") assert response.status_code == 204 # Check if game is deleted response = client.get(f"/games/{game_id}") assert response.status_code == 404 ================================================ FILE: tests/integration/test_llm.py ================================================ import pytest from fastapi.testclient import TestClient from api.llm import app @pytest.fixture(scope="module") def test_client(): """Fixture to create a test client for the FastAPI app.""" client = TestClient(app) return client def test_llm_endpoint(client): """Test the LLM service API endpoint.""" response = client.post("/llm/endpoint", json={ "input": "Test input data" }) assert response.status_code == 200, assert "output" in response.json(), assert response.json()["output"] == "Expected output" # Replace with expected output def test_llm_invalid_input(client): """Test LLM service API with invalid input.""" response = client.post("/llm/endpoint", json={ "input": 12345 # Invalid input type }) assert response.status_code == 422, assert "detail" in response.json(), assert response.json()["detail"] == "Input validation error" # Replace with actual error message ================================================ FILE: tests/integration/test_llm_integration.py ================================================ import pytest from fastapi.testclient import TestClient from api.llm import app # Initialize the test client for the FastAPI app client = TestClient(app) @pytest.fixture(scope="module") def setup_module(): # Code to run before tests in this module (e.g., setup database) yield # This will run after tests in this module # Code to run after tests in this module (e.g., teardown database) def test_llm_integration_setup(setup_module): """Test the LLM API setup and basic connectivity""" response = client.get("/llm/") assert response.status_code == 200 assert "message" in response.json() def test_llm_integration_prediction(setup_module): """Test LLM prediction endpoint""" payload = {"input_text": "What is AI?"} response = client.post("/llm/predict", json=payload) assert response.status_code == 200 assert "prediction" in response.json() def test_llm_integration_error_handling(setup_module): """Test LLM prediction endpoint with invalid input""" payload = {"input_text": ""} response = client.post("/llm/predict", json=payload) assert response.status_code == 422 # Unprocessable Entity assert "detail" in response.json() # Validate error response def test_llm_integration_performance(setup_module): """Test LLM prediction performance""" import time payload = {"input_text": "Explain quantum computing."} start_time = time.time() response = client.post("/llm/predict", json=payload) end_time = time.time() assert response.status_code == 200 assert (end_time - start_time) < 2 # Ensure response time is under 2 seconds ================================================ FILE: tests/integration/test_llm_service.py ================================================ import pytest from fastapi.testclient import TestClient from llm_service.service import app # Test client for the FastAPI application client = TestClient(app) @pytest.mark.parametrize("input_data, expected_status", [ ({"prompt": "What is AI?"}, 200), ({"prompt": ""}, 422), # Invalid input case ]) def test_llm_service(input_data, expected_status): response = client.post("/llm/service", json=input_data) assert response.status_code == expected_status # Add more tests to cover different scenarios def test_llm_service_response_format(): input_data = {"prompt": "Explain quantum computing."} response = client.post("/llm/service", json=input_data) assert response.status_code == 200 assert "response" in response.json() # Check if response key exists assert isinstance(response.json()["response"], str) # Ensure the response is a string def test_llm_service_invalid_method(): response = client.get("/llm/service") # Using GET instead of POST assert response.status_code == 405 # Method not allowed # Further tests can be implemented to validate specific LLM outputs based on known inputs ================================================ FILE: tests/integration/test_llm_service_integration.py ================================================ import pytest from fastapi.testclient import TestClient from llm_service.service import app # Create a TestClient for the FastAPI app client = TestClient(app) @pytest.mark.parametrize("input_data, expected_response_code", [ ("{\"prompt\": \"Hello, AI!\"}", 200), ("{\"prompt\": \"What is the capital of France?\"}", 200), ("{\"prompt\": \"Tell me a joke.\"}", 200), ("{\"prompt\": \"\"}", 400) # Testing with empty prompt ]) def test_llm_response(input_data, expected_response_code): response = client.post("/llm/respond", json=input_data) assert response.status_code == expected_response_code # Additional tests for LLM service integration def test_llm_service_integration(): # Test a valid request response = client.post("/llm/respond", json={"prompt": "What is AI?"}) assert response.status_code == 200 assert "response" in response.json() # Test invalid request response = client.post("/llm/respond", json={}) # No prompt assert response.status_code == 400 assert response.json() == {"detail": "Prompt is required."} # Test LLM service with unexpected input response = client.post("/llm/respond", json={"prompt": 12345}) assert response.status_code == 422 # Unprocessable Entity assert "detail" in response.json() ================================================ FILE: tests/integration/test_user_management.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app client = TestClient(app) @pytest.fixture(scope="module") def setup_module(): # Setup for the tests, if needed (e.g., create a test user) yield # Teardown if needed def test_user_registration(setup_module): response = client.post("/api/auth/register", json={ "username": "testuser", "password": "testpassword", "email": "testuser@example.com" }) assert response.status_code == 201 assert response.json()["username"] == "testuser" def test_user_login(setup_module): response = client.post("/api/auth/login", json={ "username": "testuser", "password": "testpassword" }) assert response.status_code == 200 assert "access_token" in response.json() def test_user_profile_retrieval(setup_module): login_response = client.post("/api/auth/login", json={ "username": "testuser", "password": "testpassword" }) access_token = login_response.json()["access_token"] headers = {"Authorization": f"Bearer {access_token}"} profile_response = client.get("/api/users/me", headers=headers) assert profile_response.status_code == 200 assert profile_response.json()["username"] == "testuser" def test_user_profile_update(setup_module): login_response = client.post("/api/auth/login", json={ "username": "testuser", "password": "testpassword" }) access_token = login_response.json()["access_token"] headers = {"Authorization": f"Bearer {access_token}"} update_response = client.put("/api/users/me", headers=headers, json={ "email": "updateduser@example.com" }) assert update_response.status_code == 200 assert update_response.json()["email"] == "updateduser@example.com" ================================================ FILE: tests/integration/test_user_management_integration.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app from crud.user import UserCRUD @pytest.fixture(scope="module") def test_client(): client = TestClient(app) return client @pytest.fixture(scope="module") def setup_user(): # Create a test user user_data = { "username": "testuser", "email": "testuser@example.com", "password": "securepassword" } user = UserCRUD.create_user(user_data) yield user # This is where the tests will run # Teardown logic goes here if needed UserCRUD.delete_user(user.id) def test_user_registration(test_client): response = test_client.post("/auth/register", json={ "username": "testuser", "email": "testuser@example.com", "password": "securepassword" }) assert response.status_code == 201 assert "access_token" in response.json() def test_user_login(test_client, setup_user): response = test_client.post("/auth/login", json={ "username": setup_user.username, "password": "securepassword" }) assert response.status_code == 200 assert "access_token" in response.json() def test_user_profile_retrieval(test_client, setup_user): # Simulate login to get access token login_response = test_client.post("/auth/login", json={ "username": setup_user.username, "password": "securepassword" }) access_token = login_response.json()["access_token"] headers = { "Authorization": f"Bearer {access_token}" } response = test_client.get(f"/users/{setup_user.id}", headers=headers) assert response.status_code == 200 assert response.json()["username"] == setup_user.username def test_user_profile_update(test_client, setup_user): login_response = test_client.post("/auth/login", json={ "username": setup_user.username, "password": "securepassword" }) access_token = login_response.json()["access_token"] headers = { "Authorization": f"Bearer {access_token}" } updated_data = { "username": "updateduser", "email": "updated@example.com" } response = test_client.put(f"/users/{setup_user.id}", json=updated_data, headers=headers) assert response.status_code == 200 assert response.json()["username"] == "updateduser" ================================================ FILE: tests/unit/test_ai_engine.py ================================================ import pytest from core.ai_engine import cognitive, collective, prediction def test_cognitive_functionality(): # Test cognitive processing logic input_data = {'some_key': 'some_value'} result = cognitive.process(input_data) assert result is not None # Add more assertions as necessary def test_collective_functionality(): # Test collective intelligence features participants = ['user1', 'user2'] result = collective.analyze(participants) assert isinstance(result, dict) assert 'analysis' in result def test_prediction_algorithm(): # Test prediction algorithm historical_data = {'past_events': [1, 2, 3]} future_prediction = prediction.forecast(historical_data) assert future_prediction is not None assert isinstance(future_prediction, float) # Assuming a float return type @pytest.fixture def setup_data(): # Setup any necessary data for tests return {'test_key': 'test_value'} def test_prediction_with_setup(setup_data): # Test prediction algorithm with setup data future_prediction = prediction.forecast(setup_data) assert future_prediction is not None assert isinstance(future_prediction, float) # Assuming a float return type ================================================ FILE: tests/unit/test_ai_engine_model.py ================================================ import pytest from core.ai_engine.base import AIModel # Adjust path based on actual model location @pytest.fixture def sample_ai_model(): return AIModel(name="Test Model", version="1.0") def test_ai_model_initialization(sample_ai_model): assert sample_ai_model.name == "Test Model" assert sample_ai_model.version == "1.0" def test_ai_model_prediction(sample_ai_model): input_data = [1, 2, 3] prediction = sample_ai_model.predict(input_data) assert prediction is not None # Assuming predict should return some output def test_ai_model_update(sample_ai_model): new_version = "1.1" sample_ai_model.update_version(new_version) assert sample_ai_model.version == new_version def test_ai_model_invalid_prediction(sample_ai_model): with pytest.raises(ValueError): sample_ai_model.predict(None) # Assuming it raises an error on invalid input ================================================ FILE: tests/unit/test_ai_engine_service.py ================================================ import pytest from llm_service.service import AIEngineService @pytest.fixture def ai_engine_service(): # Setup AIEngineService instance for testing service = AIEngineService() return service def test_ai_engine_service_prediction(ai_engine_service): # Test the prediction method with a sample input input_data = {'user_input': 'Tell me a joke'} expected_output = 'Why did the scarecrow win an award? Because he was outstanding in his field!' # Call the prediction method result = ai_engine_service.predict(input_data) # Assert the expected output assert result == expected_output, f"Expected {expected_output}, but got {result}" def test_ai_engine_service_error_handling(ai_engine_service): # Test error handling in the prediction method input_data = {'invalid_key': 'Some input'} # Call the prediction method and validate error handling with pytest.raises(ValueError): ai_engine_service.predict(input_data) ================================================ FILE: tests/unit/test_ai_processing.py ================================================ import pytest from core.ai_engine.ai_processing import process_data, some_other_function class TestAIProcessing: def test_process_data_valid_input(self): # Test with valid input input_data = {'key': 'value'} expected_output = {'processed_key': 'processed_value'} # Expected output should be defined assert process_data(input_data) == expected_output def test_process_data_invalid_input(self): # Test with invalid input input_data = None with pytest.raises(ValueError): process_data(input_data) def test_some_other_function(self): # Test another function from ai_processing input_value = 10 expected_result = 20 # Expected result should be defined assert some_other_function(input_value) == expected_result def test_some_other_function_invalid(self): # Test function with invalid input input_value = -1 with pytest.raises(ValueError): some_other_function(input_value) ================================================ FILE: tests/unit/test_auth.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app @pytest.fixture() def client(): """Create a test client for the FastAPI application.""" return TestClient(app) def test_user_registration(client): """Test user registration endpoint.""" response = client.post("/auth/register", json={ "username": "testuser", "password": "testpass" }) assert response.status_code == 201 assert response.json() == {"msg": "User created successfully"} def test_user_login(client): """Test user login endpoint.""" response = client.post("/auth/login", json={ "username": "testuser", "password": "testpass" }) assert response.status_code == 200 assert "access_token" in response.json() assert "token_type" in response.json() def test_invalid_login(client): """Test login with invalid credentials.""" response = client.post("/auth/login", json={ "username": "wronguser", "password": "wrongpass" }) assert response.status_code == 401 assert response.json() == {"detail": "Invalid credentials"} ================================================ FILE: tests/unit/test_cognitive_profile.py ================================================ import pytest from models.cognitive_profile import CognitiveProfile def test_cognitive_profile_initialization(): """ Test the initialization of the CognitiveProfile class. """ profile = CognitiveProfile(name="Test Profile", attributes={"intelligence": 100}) assert profile.name == "Test Profile" assert profile.attributes == {"intelligence": 100} def test_cognitive_profile_add_attribute(): """ Test adding an attribute to the CognitiveProfile. """ profile = CognitiveProfile(name="Test Profile", attributes={}) profile.add_attribute("creativity", 85) assert profile.attributes["creativity"] == 85 def test_cognitive_profile_remove_attribute(): """ Test removing an attribute from the CognitiveProfile. """ profile = CognitiveProfile(name="Test Profile", attributes={"intelligence": 100}) profile.remove_attribute("intelligence") assert "intelligence" not in profile.attributes def test_cognitive_profile_update_attribute(): """ Test updating an existing attribute in the CognitiveProfile. """ profile = CognitiveProfile(name="Test Profile", attributes={"intelligence": 100}) profile.update_attribute("intelligence", 120) assert profile.attributes["intelligence"] == 120 ================================================ FILE: tests/unit/test_game_definition.py ================================================ import pytest from crud.game_definition import GameDefinition def test_create_game_definition(): """ Test the creation of a game definition. """ game_def = GameDefinition(name="Test Game", description="A test game") assert game_def.name == "Test Game" assert game_def.description == "A test game" def test_update_game_definition(): """ Test the updating of a game definition. """ game_def = GameDefinition(name="Test Game", description="A test game") game_def.update(name="Updated Game") assert game_def.name == "Updated Game" def test_delete_game_definition(): """ Test the deletion of a game definition. """ game_def = GameDefinition(name="Test Game", description="A test game") game_def.delete() assert game_def.is_deleted() is True def test_game_definition_repr(): """ Test the string representation of a game definition. """ game_def = GameDefinition(name="Test Game", description="A test game") assert repr(game_def) == "GameDefinition(name='Test Game', description='A test game')" ================================================ FILE: tests/unit/test_game_instance.py ================================================ import pytest from crud.game_instance import GameInstanceCRUD # Import your CRUD operations from models.game_instance import GameInstance # Import your GameInstance model @pytest.fixture def game_instance_data(): return { "name": "Test Game", "description": "A game for testing purposes", "status": "active" } def test_create_game_instance(game_instance_data): instance = GameInstanceCRUD.create(**game_instance_data) assert instance.id is not None assert instance.name == game_instance_data['name'] assert instance.description == game_instance_data['description'] assert instance.status == game_instance_data['status'] def test_read_game_instance(game_instance_data): instance = GameInstanceCRUD.create(**game_instance_data) fetched_instance = GameInstanceCRUD.read(instance.id) assert fetched_instance.id == instance.id assert fetched_instance.name == instance.name def test_update_game_instance(game_instance_data): instance = GameInstanceCRUD.create(**game_instance_data) updated_data = {"name": "Updated Game"} updated_instance = GameInstanceCRUD.update(instance.id, **updated_data) assert updated_instance.name == updated_data['name'] def test_delete_game_instance(game_instance_data): instance = GameInstanceCRUD.create(**game_instance_data) GameInstanceCRUD.delete(instance.id) fetched_instance = GameInstanceCRUD.read(instance.id) assert fetched_instance is None # Assuming None is returned when not found ================================================ FILE: tests/unit/test_game_management.py ================================================ import pytest from fastapi.testclient import TestClient from api.games import app from crud.game_definition import GameDefinitionCRUD @pytest.fixture(scope="module") def test_client(): client = TestClient(app) yield client @pytest.fixture(scope="module") def setup_game_definition(): # Sample game definition to be used in tests game_definition = { "name": "Sample Game", "description": "A sample game for testing.", "rules": "Sample rules" } # Assuming there is a method to create a game definition in the CRUD GameDefinitionCRUD.create(game_definition) yield game_definition # Yield the created game definition for tests # Cleanup can be performed here if needed def test_create_game(test_client, setup_game_definition): response = test_client.post("/games/", json=setup_game_definition) assert response.status_code == 201 assert response.json()["name"] == setup_game_definition["name"] def test_get_games(test_client): response = test_client.get("/games/") assert response.status_code == 200 assert isinstance(response.json(), list) # Ensure it returns a list def test_update_game(test_client, setup_game_definition): updated_game = {"name": "Updated Game", "description": "Updated description", "rules": "Updated rules"} response = test_client.put(f"/games/{setup_game_definition['id']}/", json=updated_game) assert response.status_code == 200 assert response.json()["name"] == updated_game["name"] def test_delete_game(test_client, setup_game_definition): response = test_client.delete(f"/games/{setup_game_definition['id']}/") assert response.status_code == 204 # No content response for successful deletion # Verify that the game no longer exists response = test_client.get(f"/games/{setup_game_definition['id']}/") assert response.status_code == 404 # Should return 404 Not Found after deletion ================================================ FILE: tests/unit/test_game_model.py ================================================ import pytest from models.game_definition import GameDefinition # Import the GameDefinition model to be tested def test_game_definition_creation(): """ Test the creation of a GameDefinition object. """ game = GameDefinition(name="Chess", description="A strategic board game.") assert game.name == "Chess" assert game.description == "A strategic board game." def test_game_definition_str(): """ Test the string representation of the GameDefinition object. """ game = GameDefinition(name="Checkers", description="A game played on an 8x8 board.") assert str(game) == "Checkers: A game played on an 8x8 board." def test_game_definition_update(): """ Test updating the GameDefinition attributes. """ game = GameDefinition(name="Tic Tac Toe", description="A simple game.") game.name = "Tic Tac Toe Updated" game.description = "An updated description." assert game.name == "Tic Tac Toe Updated" assert game.description == "An updated description." def test_game_definition_invalid_name(): """ Test creating a GameDefinition with an invalid name (e.g., empty string). """ with pytest.raises(ValueError): GameDefinition(name="", description="Invalid game definition.") def test_game_definition_invalid_description(): """ Test creating a GameDefinition with an invalid description (e.g., none). """ with pytest.raises(ValueError): GameDefinition(name="Valid Game", description=None) ================================================ FILE: tests/unit/test_games.py ================================================ import pytest from fastapi.testclient import TestClient from api.games import app # Initialize the TestClient with the FastAPI app client = TestClient(app) # Test cases for game management class TestGameManagement: @pytest.fixture def create_game(self): # Helper function to create a game response = client.post("/games/", json={ "name": "Test Game", "description": "A game for testing purposes." }) return response.json() def test_create_game(self, create_game): assert create_game['name'] == "Test Game" assert create_game['description'] == "A game for testing purposes." def test_get_game(self, create_game): game_id = create_game['id'] response = client.get(f"/games/{game_id}") assert response.status_code == 200 assert response.json()['name'] == "Test Game" def test_update_game(self, create_game): game_id = create_game['id'] response = client.put(f"/games/{game_id}", json={ "name": "Updated Game", "description": "An updated game for testing purposes." }) assert response.status_code == 200 assert response.json()['name'] == "Updated Game" def test_delete_game(self, create_game): game_id = create_game['id'] response = client.delete(f"/games/{game_id}") assert response.status_code == 204 # Ensure the game is deleted response = client.get(f"/games/{game_id}") assert response.status_code == 404 ================================================ FILE: tests/unit/test_llm.py ================================================ import pytest from fastapi.testclient import TestClient from api.llm import app # Create a test client using the FastAPI app client = TestClient(app) # Test cases for LLM API endpoints class TestLLMAPI: def test_llm_endpoint(self): # Test the LLM API endpoint with a sample request payload payload = { "input_text": "Hello, AI!", "model": "gpt-3.5-turbo" } response = client.post("/llm/generate", json=payload) assert response.status_code == 200 data = response.json() assert "output_text" in data assert isinstance(data["output_text"], str) def test_llm_endpoint_invalid_model(self): # Test the LLM API endpoint with an invalid model payload = { "input_text": "Hello, AI!", "model": "invalid-model" } response = client.post("/llm/generate", json=payload) assert response.status_code == 400 assert "error" in response.json() def test_llm_endpoint_missing_fields(self): # Test the LLM API endpoint with missing fields payload = {"input_text": "Hello, AI!"} response = client.post("/llm/generate", json=payload) assert response.status_code == 422 assert "detail" in response.json() def test_llm_endpoint_empty_input(self): # Test the LLM API endpoint with empty input text payload = { "input_text": "", "model": "gpt-3.5-turbo" } response = client.post("/llm/generate", json=payload) assert response.status_code == 400 assert "error" in response.json() ================================================ FILE: tests/unit/test_llm_processing.py ================================================ import unittest from core.llm_processing import process_llm_request class TestLLMProcessing(unittest.TestCase): def test_process_llm_request_valid_input(self): # Test with valid input input_data = {'prompt': 'Hello, AI!', 'max_tokens': 50} expected_output = {'response': 'AI response here...'} # Update with expected response result = process_llm_request(input_data) self.assertEqual(result, expected_output) def test_process_llm_request_empty_prompt(self): # Test with empty prompt input_data = {'prompt': '', 'max_tokens': 50} with self.assertRaises(ValueError): process_llm_request(input_data) def test_process_llm_request_invalid_max_tokens(self): # Test with invalid max_tokens input_data = {'prompt': 'Hello, AI!', 'max_tokens': -1} with self.assertRaises(ValueError): process_llm_request(input_data) def test_process_llm_request_missing_keys(self): # Test with missing keys input_data = {'prompt': 'Hello, AI!'} # Missing max_tokens with self.assertRaises(KeyError): process_llm_request(input_data) if __name__ == '__main__': unittest.main() ================================================ FILE: tests/unit/test_llm_response.py ================================================ import pytest from schemas.llm_response import LLMResponse def test_llm_response_initialization(): """ Test the initialization of LLMResponse schema. """ response_data = { 'id': '123', 'status': 'success', 'data': {'message': 'Hello, world!'} } llm_response = LLMResponse(**response_data) assert llm_response.id == '123' assert llm_response.status == 'success' assert llm_response.data['message'] == 'Hello, world!' def test_llm_response_invalid_data(): """ Test LLMResponse initialization with invalid data. """ with pytest.raises(ValueError): LLMResponse(id='123', status='success', data='Invalid data') def test_llm_response_missing_fields(): """ Test LLMResponse initialization with missing required fields. """ with pytest.raises(TypeError): LLMResponse(status='success') def test_llm_response_empty_data(): """ Test LLMResponse with empty data field. """ response_data = { 'id': '124', 'status': 'success', 'data': {} } llm_response = LLMResponse(**response_data) assert llm_response.data == {} if __name__ == '__main__': pytest.main() ================================================ FILE: tests/unit/test_llm_schema.py ================================================ import pytest from pydantic import ValidationError from schemas.llm_request import LLMRequestSchema from schemas.llm_response import LLMResponseSchema def test_llm_request_schema_valid(): # Test valid LLM request schema valid_data = { 'prompt': 'What is the capital of France?', 'max_tokens': 50, 'temperature': 0.7, } schema = LLMRequestSchema(**valid_data) assert schema.prompt == valid_data['prompt'] assert schema.max_tokens == valid_data['max_tokens'] assert schema.temperature == valid_data['temperature'] def test_llm_request_schema_invalid(): # Test invalid LLM request schema invalid_data = { 'prompt': 12345, # Invalid type for prompt 'max_tokens': -10, # Invalid value for max_tokens 'temperature': 2.0, # Invalid value for temperature } with pytest.raises(ValidationError): LLMRequestSchema(**invalid_data) def test_llm_response_schema_valid(): # Test valid LLM response schema valid_response_data = { 'id': 'response_123', 'choices': [{'text': 'Paris', 'index': 0}] } schema = LLMResponseSchema(**valid_response_data) assert schema.id == valid_response_data['id'] assert len(schema.choices) == len(valid_response_data['choices']) def test_llm_response_schema_invalid(): # Test invalid LLM response schema invalid_response_data = { 'id': 'response_123', 'choices': [{'text': 12345}] # Invalid type for text } with pytest.raises(ValidationError): LLMResponseSchema(**invalid_response_data) ================================================ FILE: tests/unit/test_llm_service.py ================================================ import pytest from llm_service.service import LLMService @pytest.fixture def llm_service(): """ Fixture to create an instance of `LLMService` for testing. """ return LLMService() def test_service_initialization(llm_service): """ Test that the LLMService initializes correctly. """ assert llm_service is not None def test_process_request_valid(llm_service): """ Test processing a valid request. """ request_data = {'input': 'Hello, AI!'} response = llm_service.process_request(request_data) assert response is not None assert 'output' in response assert response['output'] == 'Hello, AI! processed' # Example expected behavior def test_process_request_invalid(llm_service): """ Test processing an invalid request. """ request_data = {'wrong_key': 'Invalid data'} with pytest.raises(ValueError, match='Invalid request format'): llm_service.process_request(request_data) def test_service_response_format(llm_service): """ Test that the response format is correct. """ request_data = {'input': 'Test response format.'} response = llm_service.process_request(request_data) assert isinstance(response, dict) assert 'output' in response assert isinstance(response['output'], str) ================================================ FILE: tests/unit/test_llm_service_integration.py ================================================ import pytest from llm_service.service import LLMService class TestLLMServiceIntegration: @pytest.fixture(scope="class") def llm_service(self): """Fixture to provide an instance of LLMService for testing.""" service = LLMService() yield service def test_llm_service_initialization(self, llm_service): """Test initialization of the LLM service.""" assert llm_service is not None, "LLM Service should be initialized" def test_llm_service_functionality(self, llm_service): """Test a sample functionality of the LLM service.""" # Assuming LLMService has a method called `process_request` sample_request = {'input': 'Sample input for LLM'} response = llm_service.process_request(sample_request) assert response is not None, "Response should not be None" assert 'output' in response, "Response should contain output key" def test_llm_service_error_handling(self, llm_service): """Test error handling of the LLM service.""" invalid_request = {'wrong_key': 'Sample input'} with pytest.raises(ValueError): llm_service.process_request(invalid_request) ================================================ FILE: tests/unit/test_user_management.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app from crud.user import UserCRUD @pytest.fixture def client(): return TestClient(app) @pytest.fixture def user_data(): return { "username": "testuser", "password": "testpassword", "email": "testuser@example.com" } @pytest.fixture def create_user(client, user_data): response = client.post('/auth/register', json=user_data) return response def test_user_registration(client, user_data): response = client.post('/auth/register', json=user_data) assert response.status_code == 201 assert "access_token" in response.json() assert response.json()["user"]['username'] == user_data['username'] def test_user_login(client, create_user, user_data): response = client.post('/auth/login', json={ "username": user_data['username'], "password": user_data['password'] }) assert response.status_code == 200 assert "access_token" in response.json() def test_user_login_with_incorrect_password(client, create_user, user_data): response = client.post('/auth/login', json={ "username": user_data['username'], "password": "wrongpassword" }) assert response.status_code == 401 assert "detail" in response.json() assert response.json()["detail"] == "Incorrect username or password" def test_user_profile(client, create_user): response = client.get('/auth/profile') assert response.status_code == 200 assert "username" in response.json() ================================================ FILE: tests/unit/test_user_model.py ================================================ import pytest from models.user import User def test_user_creation(): """Test the creation of a User instance.""" user = User(username='test_user', email='test@example.com') assert user.username == 'test_user' assert user.email == 'test@example.com' def test_user_str(): """Test the string representation of a User instance.""" user = User(username='test_user', email='test@example.com') assert str(user) == 'User(test_user, test@example.com)' def test_user_email_validation(): """Test email validation for User instance.""" with pytest.raises(ValueError): User(username='test_user', email='invalid_email') def test_user_update(): """Test updating user details.""" user = User(username='test_user', email='test@example.com') user.update(username='new_user', email='new@example.com') assert user.username == 'new_user' assert user.email == 'new@example.com' def test_user_profile_link(): """Test the link to the user profile.""" user = User(username='test_user', email='test@example.com') assert user.get_profile_link() == '/profiles/test_user' ================================================ FILE: tests/unit/test_user_profile.py ================================================ import pytest from fastapi.testclient import TestClient from api.auth import app # Adjust the import based on your project structure # Create a test client using the FastAPI app client = TestClient(app) @pytest.fixture def create_user(): """Fixture to create a user for testing""" response = client.post("/auth/register", json={ "username": "testuser", "password": "testpassword", "email": "testuser@example.com" }) return response.json() def test_user_profile_creation(create_user): """Test user profile creation""" response = client.post("/users/profile", json={ "bio": "This is a test user profile." }, headers={ "Authorization": f"Bearer {create_user['access_token']}" }) assert response.status_code == 201 assert "profile_id" in response.json() def test_get_user_profile(create_user): """Test fetching user profile""" response = client.get("/users/profile", headers={ "Authorization": f"Bearer {create_user['access_token']}" }) assert response.status_code == 200 assert "bio" in response.json() def test_update_user_profile(create_user): """Test updating user profile""" response = client.put("/users/profile", json={ "bio": "Updated test user profile." }, headers={ "Authorization": f"Bearer {create_user['access_token']}" }) assert response.status_code == 200 assert response.json()["bio"] == "Updated test user profile." def test_delete_user_profile(create_user): """Test deleting user profile""" response = client.delete("/users/profile", headers={ "Authorization": f"Bearer {create_user['access_token']}" }) assert response.status_code == 204 # Verify profile is deleted response = client.get("/users/profile", headers={ "Authorization": f"Bearer {create_user['access_token']}" }) assert response.status_code == 404