diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c439c091..2bc02fdf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,35 +10,11 @@ repos: - repo: local hooks: - - id: autoflake - name: autoflake - entry: poetry run autoflake + - id: lint_fixning + name: lint fixning + entry: make lint-fix language: system - types: [python] - args: ["--in-place", "--recursive", "--remove-unused-variables", "--ignore-init-module-imports"] - - id: autopep8 - name: autopep8 - entry: poetry run autopep8 - language: system - types: [python] - args: ["--in-place", "--recursive"] - - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - - - repo: https://github.com/psf/black - rev: 24.10.0 - hooks: - - id: black - - - repo: https://github.com/pycqa/flake8 - rev: 7.1.1 - hooks: - - id: flake8 - args: ["--max-line-length=88", "--extend-ignore=E203"] - repo: https://github.com/PyCQA/bandit rev: 1.8.3 diff --git a/benchmark.json b/benchmark.json deleted file mode 100644 index 4de491da..00000000 --- a/benchmark.json +++ /dev/null @@ -1,562 +0,0 @@ -{ - "meta": { - "xcore_version": "2.1.2", - "python_version": "3.14.4", - "platform": "linux", - "timestamp": "2026-04-29T11:04:53.472846", - "cpu_count": 8, - "total_duration_s": 90.74864666199937, - "system_info": { - "cpu_count": 8, - "cpu_freq_mhz": 1287.0510000000002, - "total_ram_gb": 15.3, - "available_ram_gb": 7.4 - } - }, - "results": [ - { - "name": "single_plugin_load", - "category": "plugin_lifecycle", - "iterations": 1000, - "total_ms": 1653.8354479707778, - "mean_ms": 1.6538354479707778, - "median_ms": 1.0576224995020311, - "p95_ms": 2.2267910007940372, - "p99_ms": 18.81043200046406, - "min_ms": 0.8524500008206815, - "max_ms": 61.980675000086194, - "std_ms": 3.700601990736283, - "throughput_ops_sec": 604.655076916497, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "1000 runs" - }, - { - "name": "single_plugin_unload", - "category": "plugin_lifecycle", - "iterations": 1000, - "total_ms": 262.9234420037392, - "mean_ms": 0.2629234420037392, - "median_ms": 0.2353315003347234, - "p95_ms": 0.36601899955712724, - "p99_ms": 1.0726239997893572, - "min_ms": 0.20125400078541134, - "max_ms": 2.1960899994155625, - "std_ms": 0.12980287681590708, - "throughput_ops_sec": 3803.3885163643126, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "1000 runs" - }, - { - "name": "plugin_reload", - "category": "plugin_lifecycle", - "iterations": 1000, - "total_ms": 619.2345519848459, - "mean_ms": 0.6192345519848459, - "median_ms": 0.5641699999614502, - "p95_ms": 0.7921790002001217, - "p99_ms": 1.595661000465043, - "min_ms": 0.47513000026810914, - "max_ms": 19.42086199960613, - "std_ms": 0.6220941984513612, - "throughput_ops_sec": 1614.8969672229664, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "batch_load_5_plugins", - "category": "plugin_lifecycle", - "iterations": 5, - "total_ms": 278.03283799948986, - "mean_ms": 55.60656759989797, - "median_ms": 55.60656759989797, - "p95_ms": 83.40985139984696, - "p99_ms": 111.21313519979594, - "min_ms": 0, - "max_ms": 278.03283799948986, - "std_ms": 0, - "throughput_ops_sec": 17.983487259908394, - "memory_delta_mb": 8.79296875, - "errors": -1, - "notes": "6/5 loaded, 1.76MB/plugin" - }, - { - "name": "batch_load_20_plugins", - "category": "plugin_lifecycle", - "iterations": 20, - "total_ms": 280.6563129997812, - "mean_ms": 14.032815649989061, - "median_ms": 14.032815649989061, - "p95_ms": 21.04922347498359, - "p99_ms": 28.065631299978122, - "min_ms": 0, - "max_ms": 280.6563129997812, - "std_ms": 0, - "throughput_ops_sec": 71.26153616938447, - "memory_delta_mb": 0.01953125, - "errors": -1, - "notes": "21/20 loaded, 0.00MB/plugin" - }, - { - "name": "batch_load_50_plugins", - "category": "plugin_lifecycle", - "iterations": 50, - "total_ms": 456.491613000253, - "mean_ms": 9.12983226000506, - "median_ms": 9.12983226000506, - "p95_ms": 13.69474839000759, - "p99_ms": 18.25966452001012, - "min_ms": 0, - "max_ms": 456.491613000253, - "std_ms": 0, - "throughput_ops_sec": 109.53103753950522, - "memory_delta_mb": 0.0078125, - "errors": -1, - "notes": "51/50 loaded, 0.00MB/plugin" - }, - { - "name": "sequential_call_ping", - "category": "plugin_calls", - "iterations": 1000, - "total_ms": 549.8288080034399, - "mean_ms": 0.5498288080034399, - "median_ms": 0.5462260005515418, - "p95_ms": 0.6609619995288085, - "p99_ms": 0.7332519999181386, - "min_ms": 0.37818799864908215, - "max_ms": 18.01899300153309, - "std_ms": 0.5595776948326894, - "throughput_ops_sec": 1818.7479183406913, - "memory_delta_mb": 0.0, - "errors": 1000, - "notes": "single plugin, 1000 calls" - }, - { - "name": "sequential_call_echo_payload", - "category": "plugin_calls", - "iterations": 1000, - "total_ms": 531.5483460144605, - "mean_ms": 0.5315483460144605, - "median_ms": 0.5326665004758979, - "p95_ms": 0.6623869994655252, - "p99_ms": 0.7814060008968227, - "min_ms": 0.37976399835315533, - "max_ms": 0.9061159998964285, - "std_ms": 0.08243008392172911, - "throughput_ops_sec": 1881.2964192212826, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "concurrent_10_calls", - "category": "plugin_calls", - "iterations": 10, - "total_ms": 6.712553000397747, - "mean_ms": 0.6712553000397747, - "median_ms": 0.6712553000397747, - "p95_ms": 0.8726318900517072, - "p99_ms": 1.006882950059662, - "min_ms": 0, - "max_ms": 6.712553000397747, - "std_ms": 0, - "throughput_ops_sec": 1489.7461516367107, - "memory_delta_mb": 0.0, - "errors": 10, - "notes": "asyncio.gather(10)" - }, - { - "name": "concurrent_50_calls", - "category": "plugin_calls", - "iterations": 50, - "total_ms": 39.98580899860826, - "mean_ms": 0.7997161799721653, - "median_ms": 0.7997161799721653, - "p95_ms": 1.0396310339638148, - "p99_ms": 1.199574269958248, - "min_ms": 0, - "max_ms": 39.98580899860826, - "std_ms": 0, - "throughput_ops_sec": 1250.4436261809856, - "memory_delta_mb": 0.0, - "errors": 50, - "notes": "asyncio.gather(50)" - }, - { - "name": "concurrent_100_calls", - "category": "plugin_calls", - "iterations": 100, - "total_ms": 93.88338000098884, - "mean_ms": 0.9388338000098884, - "median_ms": 0.9388338000098884, - "p95_ms": 1.2204839400128549, - "p99_ms": 1.4082507000148325, - "min_ms": 0, - "max_ms": 93.88338000098884, - "std_ms": 0, - "throughput_ops_sec": 1065.1512546623985, - "memory_delta_mb": 0.0, - "errors": 100, - "notes": "asyncio.gather(100)" - }, - { - "name": "routing_5_plugins", - "category": "plugin_calls", - "iterations": 200, - "total_ms": 42.57786499147187, - "mean_ms": 0.21288932495735935, - "median_ms": 0.07892800022091251, - "p95_ms": 0.09425499956705607, - "p99_ms": 0.2733080000325572, - "min_ms": 0.053650999689125456, - "max_ms": 27.0948600009433, - "std_ms": 1.9104920019930742, - "throughput_ops_sec": 4697.2763909148325, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "6 loaded, 200 calls round-robin" - }, - { - "name": "routing_20_plugins", - "category": "plugin_calls", - "iterations": 200, - "total_ms": 13.121534997480921, - "mean_ms": 0.06560767498740461, - "median_ms": 0.06274550014495617, - "p95_ms": 0.08325999988301191, - "p99_ms": 0.12489999971876387, - "min_ms": 0.055982000048970804, - "max_ms": 0.21046499932708684, - "std_ms": 0.013054642492955359, - "throughput_ops_sec": 15242.119160479022, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "21 loaded, 200 calls round-robin" - }, - { - "name": "pipeline_0_middlewares", - "category": "middleware", - "iterations": 2000, - "total_ms": 6.521591951241135, - "mean_ms": 0.0032607959756205673, - "median_ms": 0.0025069994080695324, - "p95_ms": 0.004637000529328361, - "p99_ms": 0.004888999683316797, - "min_ms": 0.0021790001483168453, - "max_ms": 0.025078001272049733, - "std_ms": 0.001183324370529185, - "throughput_ops_sec": 306673.58751560294, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "pipeline_4_middlewares", - "category": "middleware", - "iterations": 2000, - "total_ms": 23.53243399193161, - "mean_ms": 0.011766216995965806, - "median_ms": 0.011150001228088513, - "p95_ms": 0.015556001017102972, - "p99_ms": 0.016503001461387612, - "min_ms": 0.009588000466465019, - "max_ms": 0.0949909990595188, - "std_ms": 0.003427922820594405, - "throughput_ops_sec": 84989.0836062995, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_no_handlers", - "category": "events", - "iterations": 2000, - "total_ms": 9.18424001247331, - "mean_ms": 0.004592120006236655, - "median_ms": 0.0044720000005327165, - "p95_ms": 0.004659001206164248, - "p99_ms": 0.004847999662160873, - "min_ms": 0.004166000508121215, - "max_ms": 0.0911999995878432, - "std_ms": 0.002467249294366055, - "throughput_ops_sec": 217764.34384159796, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_1_handler", - "category": "events", - "iterations": 2000, - "total_ms": 79.13077196644736, - "mean_ms": 0.03956538598322368, - "median_ms": 0.043199999709031545, - "p95_ms": 0.04741500015370548, - "p99_ms": 0.0628220004728064, - "min_ms": 0.027657999453367665, - "max_ms": 0.3801000002567889, - "std_ms": 0.01203053598454082, - "throughput_ops_sec": 25274.617576687237, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_10_handlers", - "category": "events", - "iterations": 2000, - "total_ms": 202.94466797167843, - "mean_ms": 0.10147233398583921, - "median_ms": 0.09965049957827432, - "p95_ms": 0.11356899995007552, - "p99_ms": 0.15094599984877277, - "min_ms": 0.089948000095319, - "max_ms": 0.1985950002563186, - "std_ms": 0.010555282168575956, - "throughput_ops_sec": 9854.902915109386, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_wildcard_matching", - "category": "events", - "iterations": 2000, - "total_ms": 62.355292961001396, - "mean_ms": 0.031177646480500698, - "median_ms": 0.03010399996128399, - "p95_ms": 0.03481399835436605, - "p99_ms": 0.049606000175117515, - "min_ms": 0.02903099994000513, - "max_ms": 0.10097499944095034, - "std_ms": 0.003929790401716499, - "throughput_ops_sec": 32074.261943582744, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "hookmanager_5_priority_hooks", - "category": "events", - "iterations": 1000, - "total_ms": 618.4966150176479, - "mean_ms": 0.6184966150176479, - "median_ms": 0.6060270006855717, - "p95_ms": 0.8415030006290181, - "p99_ms": 1.1398449987609638, - "min_ms": 0.47312200149463024, - "max_ms": 2.049806998911663, - "std_ms": 0.13544462934080997, - "throughput_ops_sec": 1616.8237233949396, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "permission_check_cold", - "category": "permissions", - "iterations": 30000, - "total_ms": 94.13857905383338, - "mean_ms": 0.003137952635127779, - "median_ms": 0.0024870005290722474, - "p95_ms": 0.0028720005502691492, - "p99_ms": 0.005308998879627325, - "min_ms": 0.002061000486719422, - "max_ms": 16.65858600063075, - "std_ms": 0.09616561230116766, - "throughput_ops_sec": 318679.1249828025, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "permission_check_cached", - "category": "permissions", - "iterations": 30000, - "total_ms": 46.59688580795773, - "mean_ms": 0.0015532295269319245, - "median_ms": 0.001526999767520465, - "p95_ms": 0.001670001438469626, - "p99_ms": 0.002586999471532181, - "min_ms": 0.0013760000001639128, - "max_ms": 0.038047999623813666, - "std_ms": 0.0003534346220896545, - "throughput_ops_sec": 643819.8493272839, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_set_single", - "category": "cache", - "iterations": 3000, - "total_ms": 8.480978016450536, - "mean_ms": 0.0028269926721501784, - "median_ms": 0.0026470006559975445, - "p95_ms": 0.0031969993870006874, - "p99_ms": 0.004724999598693103, - "min_ms": 0.0022599997464567423, - "max_ms": 0.14715299948875327, - "std_ms": 0.003119987371805583, - "throughput_ops_sec": 353732.78815024707, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_get_hot", - "category": "cache", - "iterations": 3000, - "total_ms": 4.004473043096368, - "mean_ms": 0.0013348243476987893, - "median_ms": 0.0012429991329554468, - "p95_ms": 0.0016499998309882358, - "p99_ms": 0.0021579999156529084, - "min_ms": 0.0011350002750987187, - "max_ms": 0.020790001144632697, - "std_ms": 0.0006348142416934207, - "throughput_ops_sec": 749162.2412521768, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_mset_100_keys", - "category": "cache", - "iterations": 300, - "total_ms": 30.281595991255017, - "mean_ms": 0.10093865330418339, - "median_ms": 0.09859700003289618, - "p95_ms": 0.1105069986806484, - "p99_ms": 0.1468110003770562, - "min_ms": 0.09195600068778731, - "max_ms": 0.1541719993838342, - "std_ms": 0.00817448206686219, - "throughput_ops_sec": 9907.007546320763, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_mget_100_keys", - "category": "cache", - "iterations": 300, - "total_ms": 12.505856009738636, - "mean_ms": 0.04168618669912879, - "median_ms": 0.041201000385626685, - "p95_ms": 0.04277799962437712, - "p99_ms": 0.06069599839975126, - "min_ms": 0.040077999074128456, - "max_ms": 0.07302099947992247, - "std_ms": 0.00281464258349221, - "throughput_ops_sec": 23988.761726217075, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - } - ], - "capacity": { - "100": { - "n_requested": 100, - "n_loaded": 101, - "load_time_ms": 973.9, - "ms_per_plugin": 9.64, - "mem_delta_mb": 0.18, - "mb_per_plugin": 0.002, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 146.5 - }, - "200": { - "n_requested": 200, - "n_loaded": 201, - "load_time_ms": 2032.6, - "ms_per_plugin": 10.11, - "mem_delta_mb": 0.0, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 367.0 - }, - "300": { - "n_requested": 300, - "n_loaded": 301, - "load_time_ms": 3269.6, - "ms_per_plugin": 10.86, - "mem_delta_mb": 0.01, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 376.2 - }, - "400": { - "n_requested": 400, - "n_loaded": 401, - "load_time_ms": 4360.4, - "ms_per_plugin": 10.87, - "mem_delta_mb": 0.01, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 482.3 - }, - "500": { - "n_requested": 500, - "n_loaded": 501, - "load_time_ms": 5700.2, - "ms_per_plugin": 11.38, - "mem_delta_mb": 0.01, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 481.4 - }, - "600": { - "n_requested": 600, - "n_loaded": 601, - "load_time_ms": 7051.5, - "ms_per_plugin": 11.73, - "mem_delta_mb": 0.01, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 487.4 - }, - "700": { - "n_requested": 700, - "n_loaded": 701, - "load_time_ms": 8113.9, - "ms_per_plugin": 11.57, - "mem_delta_mb": 0.04, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 552.6 - }, - "800": { - "n_requested": 800, - "n_loaded": 801, - "load_time_ms": 7394.8, - "ms_per_plugin": 9.23, - "mem_delta_mb": 0.02, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 377.1 - }, - "900": { - "n_requested": 900, - "n_loaded": 901, - "load_time_ms": 8846.2, - "ms_per_plugin": 9.82, - "mem_delta_mb": 0.08, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 529.2 - }, - "1000": { - "n_requested": 1000, - "n_loaded": 1001, - "load_time_ms": 10968.7, - "ms_per_plugin": 10.96, - "mem_delta_mb": 0.43, - "mb_per_plugin": 0.0, - "concurrent_calls_ok": 0, - "concurrent_call_ms": 550.5 - } - } -} diff --git a/docgen/aggregator.py b/docgen/aggregator.py index e7de6e77..8a525d0e 100644 --- a/docgen/aggregator.py +++ b/docgen/aggregator.py @@ -40,7 +40,8 @@ def aggregate_file_summaries(file_map, cfg): else: final_prompt = f"""You are writing technical documentation for a software project. -The following are partial summaries of different chunks of the same source file: `{path}`. +The following are partial summaries of different chunks of the same source file: +`{path}`. Merge them into a single, unified technical summary as if the file had been read in full. Rules: diff --git a/docgen/cache/summaries.json b/docgen/cache/summaries.json deleted file mode 100644 index 0544c99f..00000000 --- a/docgen/cache/summaries.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "/home/eliezer/devs/xcore/xcore/__version__.py:77d71a4b024d689d0d4bfbb4f9657d1243adede21aae0442bfdf291ba55dd8dd": "This Python file serves as the versioning and metadata module for a software project. It provides information about the current version of the codebase (2.0.0), its authors, and the license under which it is distributed. The purpose of this file is to provide essential details about the system's version, author(s) and licensing conditions.\n\nKey components: \n1. __version__ : A string that holds the current software version (\"2.0.0\").\n2. __version_info__ : A tuple containing numerical representations of the version (2, 0, 0).\n3. __author__ : The name(s) of the author(s) who developed this codebase (\"xcore contributors\").\n4. __license__ : The software license under which it is distributed (\"MIT\").\n\nDependencies: This file has no dependencies on other internal modules or external libraries as all its data are static and do not require any dynamic resources to function properly. \n\nInteractions: As this file provides metadata about the system, it does not directly interact with other parts of the codebase but is used by them for reference purposes (e.g., displaying version information). It may be called upon in situations where developers need to understand or manage their software's current state and/or needs updates on changes made over time.\n", - "/home/eliezer/devs/xcore/xcore/__init__.py:7188ddc59c7158d7683e3d2f5475abca1087ca924f95afd068b2a7e607142f6c": "This file is the main entry point for a software project named xcore. It serves as an orchestrator, managing various subsystems such as services (database, cache, scheduler), event bus and hook manager, plugin supervisor, observability tools like logging, metrics, tracing, health checker etc., among others.\n\n1. Purpose: The file provides a single class Xcore that acts as the main entry point for xcore v2 framework. It orchestrates various subsystems and manages interactions between them to provide an integrated system. \n\n2. Key components: \n - `Xcore` Class: This is the primary class in this file, serving as a central hub that coordinates all other functionalities of xcore v2 framework. It provides methods for bootstrapping (boot), shutting down (shutdown) and attaching FastAPI routers to an existing application instance.\n - `ServiceContainer` Class: This is used to manage various services integrated into the system, such as database service (db), cache service (cache), scheduler etc., which are initialized lazily during bootstrapping process. \n - Other classes and functions include PluginLoader, LifecycleManager, PluginSupervisor, EventBus, HookManager, BasePlugin, TrustedBase, sign_plugin, verify_plugin, ServiceContainer, PluginRegistry, get_logger etc., which are used for managing plugins, handling events, hooks, plugin permissions and security signatures respectively.\n \n3. Dependencies: This file imports a number of internal modules like __version__, kernel.api.contract, kernel.events.bus, kernel.events.hooks, kernel.observability, kernel.runtime.lifecycle, kernel.runtime.loader, kernel.runtime.supervisor, kernel.security.signature, registry.index and services which are used by the Xcore class to perform its operations.\n\n4. Interactions: The file interacts with other parts of the codebase through various classes and functions it provides. It calls into these classes for their functionalities during bootstrapping process (like initializing services), handling events, hooks etc., and also produces or consumes data from them like configuration details, service instances etc.\n", - "/home/eliezer/devs/xcore/xcore/configurations/helper.py:2ee05c729386b2d654bc4c38ba5de17687a207e8bce408b741a62bb4ecfe5d51": "This Python file serves as a configuration helper module within the xcore project. Its main purpose is to assist with environment variable substitution and data type resolution during YAML parsing. \n\nKey Components:\n1. `_resolve` function - This function takes an input value, checks its instance type, and performs different actions based on it. If the input is a string that matches the regular expression for environment variables (${VAR}), it replaces these with their corresponding values from the operating system's environment variable dictionary. For dictionaries or lists of such strings, this function recursively applies itself to each item in order to resolve all nested occurrences.\n\nDependencies: \n1. `from __future__ import annotations` - This line allows for type annotation syntax as described in PEP 563.\n2. `import logging` and `import os` - These are standard Python libraries used for logging messages and accessing the operating system's environment variables, respectively.\n3. `import re` - The regular expression library is needed to match strings containing ${VAR} patterns.\n4. `from typing import Any` - This line allows for type hinting in function signatures as described in PEP 484.\n\nInteractions:\n1. It's called by the main xcore module, which uses this helper to parse YAML configuration files and replace ${VAR} placeholders with actual environment variable values before using them.\n2. The `_resolve` function calls os.environ.get() method when it encounters a string that matches the _ENV_PATTERN regular expression pattern, which is used for identifying strings containing variables to be replaced by their corresponding OS environment variables. \n3. It produces or consumes data in YAML format and replaces ${VAR} placeholders with actual values from the operating system's environment variable dictionary. The produced output will not contain any unresolved ${VAR} placeholders, ensuring that all necessary configuration details are properly substituted before use.\n", - "/home/eliezer/devs/xcore/xcore/configurations/__init__.py:9a3ccd86d7f31f41f36585fa79e4c6bf2ee88e8a6eac22ee858c50a459cfc774": "This file serves as the entry point for configuration management in a software project. Its purpose is to load and manage various types of configurations, including application-specific settings, database connections, cache details, observability parameters, plugin configurations, scheduling preferences, security credentials, and service endpoints. \n\nKey components include:\n1. ConfigLoader - This class loads configuration files from different sources (local filesystem or remote URLs) into memory for further processing. It uses the XcoreConfig object to hold these loaded configurations.\n2. XcoreConfig - A data structure that holds all types of configurations, including AppConfig, CacheConfig, DatabaseConfig, ObservabilityConfig, PluginConfig, SchedulerConfig, SecurityConfig and ServicesConfig. \n3. All other classes (AppConfig, CacheConfig, DatabaseConfig, ObservabilityConfig, PluginConfig, SchedulerConfig, SecurityConfig, ServicesConfig) - These are configuration sections that hold specific settings for different aspects of the application's behavior or integration with external services/resources.\n \nThis file imports ConfigLoader and XcoreConfig from its own loader module and sections modules respectively. It also relies on these internal modules to provide it with functionality related to loading, parsing, validating and managing configurations. \n\nAs for interactions, this file is called by other parts of the codebase that require configuration settings (like initializing services or setting up connections). The loaded configurations are produced by ConfigLoader which can be consumed by various modules in the application. It does not call into any external libraries directly as all its functionality relies on internal Python features and standard library modules.\n", - "/home/eliezer/devs/xcore/xcore/configurations/loader.py:4baa2c5782855323aca477d30fadbb67a4cf8c0e18ca530a2d79bfcc21e233b6": "This Python file, `loader.py`, is a part of the xCore project and serves as a configuration loader for various settings in the system. It's responsible for loading configurations from different sources including YAML/JSON files, environment variables, command-line arguments (through substitution), among others.\n\nKey components: \n1. `ConfigLoader` class - This is the main component that orchestrates all operations related to configuration management in xCore. It has methods for reading and parsing configurations from various sources as well as applying environment variable overrides.\n2. `XcoreConfig` dataclass - A complex data structure representing a complete set of configurations required by an instance of the application running on xCore platform. \n3. Various helper functions - These are used to parse and validate different parts of configuration, such as app settings, plugin settings, service settings (database, cache), observability settings etc.\n4. Logger `logger` - A Python logging object for tracking events related to the ConfigLoader's operations. \n5. Dependencies: The file imports several internal modules and external libraries like yaml/json for parsing configuration files, dotenv for managing environment variables, os for accessing system-level functions etc.\n6. Interactions - This module interacts with other parts of the codebase by loading configurations from various sources (YAML/JSON files, environment variables) into a unified `XcoreConfig` dataclass and using it throughout the application. It also logs events related to its operations for debugging purposes.\n", - "/home/eliezer/devs/xcore/xcore/configurations/loader.py:7a054b254edc098b25ff6aa846640126748dfb91403600f620c7562e81f3ab40": "This Python file serves as a configuration loader for the xCore system, specifically managing security and marketplace configurations. It provides two static methods (_parse_security & _parse_marketplace), which parse dictionaries into specific config objects (SecurityConfig & MarketplaceConfig). The main classes involved are SecurityConfig and MarketplaceConfig, both of them seem to be data transfer objects used for storing configuration details related to security and marketplaces.\n\nThe file also contains a global singleton instance (_config) that is loaded by the get_config function on first call. It provides an interface (reload_config) to re-read this config from disk, which can be useful in cases where changes are made while the system is running. \n\nThis module depends on two external libraries: json and pathlib for handling JSON data and file paths respectively. The get_config function calls ConfigLoader's load method to fetch these configurations. This dependency allows this configuration loader to work with any class that implements a similar interface, providing flexibility in the system design. \n\nThe interactions of this module are limited to its own methods (static) as well as the XcoreConfig object it produces or consumes by calling ConfigLoader's load method and returning an instance of XcoreConfig. It does not call any other modules directly but is called by various parts of the system that require configuration details for security and marketplace operations.\n", - "/home/eliezer/devs/xcore/xcore/configurations/sections.py:87f537c0e39ec25d2b9c146f9361e64f035e0a8b8ef4745db5868e47240cff69": "This Python file serves as a configuration module for the xcore application. It defines several data classes that represent different sections of the system's configurations. The main purpose of this file is to provide default values for various settings in the xcore ecosystem, which can be customized according to user preferences or environment variables during runtime.\n\nKey components: \n1. AppConfig - Contains configuration related to the application itself such as its name, environment (development/staging/production), debug mode status, secret key and plugin prefix.\n2. DatabaseConfig - Defines configurations for database connections like type of DB (sqlite/MongoDB etc.), URLs, pool size, max overflow limit, echoing SQL statements, MongoDB's database name or Redis connection details.\n3. CacheConfig - Configures the cache backend and its TTL(Time to Live), maximum size and a URL for redis-based caching systems.\n4. SchedulerConfig - Defines whether scheduling is enabled, type of scheduler (memory/redis/database) and timezone along with jobs list which contains details about scheduled tasks. \n5. ServicesConfig - Contains configurations related to services like databases, cache configuration, schedulers and extensions.\n6. PluginConfig - Configures the plugin directory location, secret key for plugins, watcher interval (in seconds), entry point of a plugin file and snapshot settings including excluded file types/names and hidden files visibility. \n7. LoggingConfig - Defines logging level, format, log file name, max bytes per file and backup count.\n8. MetricsConfig - Configures whether metrics are enabled, backend (memory/prometheus/statsd) and prefix for metric names.\n9. TracingConfig - Enables or disables tracing, sets the type of backend (noop/opentelemetry/jaeger), service name and endpoint URLs for distributed tracing systems like Jaeger. \n10. ObservabilityConfig - Contains configurations related to observability i.e., logging, metrics and tracing configuration.\n11. SecurityConfig - Configures allowed import statements, forbidden ones along with rate limit details (call count & period in seconds).\n12. MarketplaceConfig - Defines the URL of marketplace service, API key for authentication, timeout duration and TTL for cache. \n13. XcoreConfig - Aggregates all configurations into one single class which can be used to access different sections' configuration easily. It also contains a raw dictionary that holds any other unidentified keys from the yaml file.\n\nDependencies: This file imports several modules like `dataclasses`, `typing` and uses annotations for type hinting in Python 3.7+. The external libraries used are not mentioned as they're built-in to Python or part of its standard library.\n\nInteractions: It does not directly interact with other files/modules but is called by the main xcore application when it needs configuration details from this file for setting up various services and functionalities in the system. The configurations defined here are used as defaults, which can be overridden based on user inputs or environment variables during runtime.\n", - "/home/eliezer/devs/xcore/xcore/kernel/__init__.py:4decd0e6b9b05a1102a3baab007b2d82d85efc6a7e340bdd1f39ac779c0fe602": "This source file is part of the \"xcore\" project and it serves as an entry point for initializing various components of the system such as the kernel's runtime environment, event handling, permission management, observability features, and security measures. \n\n1. **Purpose** - This module sets up the core functionalities required by other parts of the application to function properly. It manages aspects like runtime initialization, sandboxing for isolated execution environments, event processing, permissions control, monitoring and logging system activities, as well as ensuring security measures are in place.\n\n2. **Key components** - The main classes involved include: \n a) `Kernel` class responsible for setting up the environment and managing various aspects of the application's operation.\n b) `EventManager` class handling events emitted by different parts of the system.\n c) `PermissionHandler` class controlling access to resources based on user roles and permissions.\n d) `ObservabilityService` class providing tools for monitoring and logging activities in the system.\n e) `SecurityModule` class ensuring data integrity, confidentiality, and availability by implementing security measures like encryption and authentication.\n \n3. **Dependencies** - This file imports or relies on internal modules such as: \n a) `xcore.kernel.runtime` for setting up the runtime environment.\n b) `xcore.events` for managing events emitted by different parts of the system.\n c) `xcore.permissions` for controlling access to resources based on user roles and permissions.\n d) `xcore.observability` for providing tools for monitoring and logging activities in the system.\n e) `xcore.security` for implementing security measures like encryption and authentication.\n \n4. **Interactions** - This file interacts with other parts of the codebase by: \n a) Initializing various components when an instance of this module is created (called upon).\n b) Handling events emitted by different modules using `EventManager` class.\n c) Managing permissions for accessing resources through `PermissionHandler` class.\n d) Providing monitoring and logging tools via the `ObservabilityService` class.\n e) Ensuring security measures are in place with help of `SecurityModule` class. \n \nIn summary, this file is a crucial part of xcore's architecture as it sets up key functionalities required for proper operation of other parts of the system and ensures overall security.\n", - "/home/eliezer/devs/xcore/xcore/kernel/api/__init__.py:1e7dbe0391c90966fe82aa7688e7c1dad40a503f2c415d41c00fdbc8bf79696f": "This source file serves as the main entry point for a software project named \"xcore\". It is responsible for defining and initializing various classes, functions, and modules that are integral to this system. \n\n1. **Purpose** - This file sets up the foundation of xcore's plugin architecture by providing base classes (BasePlugin, TrustedBase) and utility functionalities (ok, error). It also defines an APIVersion class for versioning control and a check_compatibility function to ensure compatibility between different versions.\n\n2. **Key components** - The main classes are BasePlugin, which provides the basic structure of any plugin; TrustedBase, providing security measures against unauthorized access or manipulation; ok and error functions as utility for handling success/failure states in a consistent manner across the system; ExecutionMode to define different execution modes (e.g., test mode); PluginContext provides contextual information about plugins; APIVersion controls versioning of xcore's APIs; check_compatibility checks compatibility between versions.\n\n3. **Dependencies** - This file relies on its own internal modules for defining the plugin structure, security measures, and utility functionalities (context, contract, versioning). It does not have any external dependencies as it is a part of xcore's core functionality.\n\n4. **Interactions** - The interactions with other parts of the codebase are primarily through import statements at the beginning of this file which bring in necessary classes and functions for its operation. This module interacts by defining these classes, functions, and modules that can be used elsewhere within xcore's plugin architecture.\n", - "/home/eliezer/devs/xcore/xcore/kernel/api/router.py:ca9b89f983d0507206cc646d8b7b0c1fcd83f01e83cefbbe55ee859d01496b81": "This file serves as the API Router for a FastAPI application, specifically designed to manage and control plugins within an application using HTTP requests. It's built dynamically from a PluginSupervisor instance. The purpose of this file is to provide endpoints that allow interaction with these plugins via HTTP calls. \n\nKey components include:\n1. `CallRequest` class, which represents the request body for making plugin calls.\n2. `CallResponse` class, which defines how a response from a call should be structured.\n3. The `build_router()` function, responsible for building and configuring the API Router with various settings including security measures like hashing of secret keys using PBKDF2 HMAC-SHA256 algorithm. \n4. Several route handlers (like `call_plugin`, `plugins_status`, etc.) that define different HTTP methods for interacting with plugins and the application's state.\n\nDependencies include:\n1. FastAPI library for building APIs.\n2. Pydantic models for data validation.\n3. External libraries like hashlib (for hashing), hmac (for secure comparison). \n4. Internal modules including observability metrics and health checker classes, which are used to monitor the application's state and performance respectively.\n\nInteractions involve:\n1. The router is called by FastAPI app for routing HTTP requests.\n2. It calls into PluginSupervisor instance (an internal module) to manage plugins. \n3. Data it produces includes responses from plugin interactions, status of the application's state and performance metrics. Consumed data includes incoming API keys for security checks.\n", - "/home/eliezer/devs/xcore/xcore/kernel/api/versioning.py:f7a57148cc1c26436374d285c5f342f74f9b24cba770e616626e028e851dc5e7": "This Python file serves as the versioning module for a software system. It provides classes and functions to handle API versions in string format (e.g., \"1.2.3\") into an object-oriented representation, which includes comparison operators. The main class `APIVersion` represents a specific version of an application programming interface (API). \n\nThe file also contains the function `check_compatibility()` that verifies if a given core version is compatible with a framework's required version as specified in a yaml manifest using different comparison operators. It relies on the `APIVersion` class for parsing and comparing versions, which it imports from Python\u2019s built-in library. \n\nThis file interacts with other parts of the codebase by defining classes (`APIVersion`) that are used elsewhere in the system to represent API versioning information. It also provides a function `check_compatibility()` for use in determining if an application's core version is compatible with framework requirements, which could be called from anywhere else in the software project where this kind of compatibility check might be needed.\n", - "/home/eliezer/devs/xcore/xcore/kernel/api/context.py:876ac089cffdd27795dac17c1c302f55f5fd0c3d075e2b07d6a7ab396496040a": "This Python file serves as the context for each Trusted plugin at load time, providing access to various services and utilities such as event buses, hook managers, environment variables, and plugin configurations. \n\nKey Components:\n1. `PluginContext` class - This is a dataclass that holds information about plugins including their name, services (shared dictionary of services), events (EventBus), hooks (HookManager), env vars from the plugin's configuration file, config data from manifest files and various utilities like metrics registry, tracer, health checker.\n2. `get_service` method - This is a secure way to access available services with clear error messages if requested service isn\u2019t found in the context. \n3. `has_service` method - Checks whether a specific service exists within the plugin's context.\n4. `__repr__` method - Provides an understandable representation of PluginContext object for debugging purposes.\n\nDependencies:\n1. External Libraries/Modules \u2014 None as per this file, but it relies on other modules like EventBus, HookManager which are not imported here.\n2. Internal Modules - This module does not depend directly on any internal Python files or packages. It depends only on standard library and future-futures for type hinting. \n\nInteractions:\n1. Calls into this file by other modules/files that need to create a PluginContext object, access services in it etc.\n2. Called by - None as per the current state of the codebase. It is called by other files which use or interact with plugins and their contexts. \n3. Data produced - This module produces instances (PluginContext objects) that contain information about a specific plugin's context, including services, events, hooks etc., which are consumed/used elsewhere in the system to manage and control these aspects of each individual plugin.\n4. Consumes data from - The PluginContext object consumes data like service dictionaries (from other modules), environment variables dictionary (from configuration files) and config data (manifest files). \n", - "/home/eliezer/devs/xcore/xcore/kernel/api/auth.py:6ed57693a36a5e4fe6c0a1414cec9f066983c21df6f325b9905e633f5f23ae76": "This file, `/home/eliezer/devs/xcore/xcore/kernel/api/auth.py`, serves as the interface for authentication in a software system. It defines classes and functions related to user authorization, including token decoding, extraction from requests, permission checking, backend registration, unregistration, retrieval of registered backends, and checks if any are present.\n\nKey Components: \n1. `AuthPayload` class - A TypedDict that represents the structure of an authentication payload containing a subject (sub), roles, and permissions.\n2. `RequestAdapter` protocol - Defines what properties should be in a request object for token extraction purposes.\n3. `AuthBackend` protocol - Specifies methods required by any class implementing this protocol: decoding tokens, extracting tokens from requests, checking if the user has a specific permission.\n4. Registry singleton (_backend) - A global variable that holds an instance of AuthBackend or None. It provides ways to register (register_auth_backend), unregister (unregister_auth_backend), and retrieve backends (get_auth_backend, has_auth_backend).\n \nDependencies: \n1. This file imports `annotations` from the future module for type hinting support in Python versions < 3.7. It also uses typing features like List, NotRequired, Protocol, TypedDict and runtime_checkable to define complex types.\n2. The external library or internal modules it relies on are not explicitly mentioned as they're standard libraries used here. \n \nInteractions: \n1. This file is called by other parts of the codebase that need authentication, such as routes handlers and middlewares. It provides a way to extract tokens from requests, decode them into payloads, check if users have specific permissions.\n2. Other modules or plugins can register an instance of their own class implementing AuthBackend with `register_auth_backend()` function. This file then uses this registered backend for token handling and permission checks. \n3. It produces a global singleton (_backend) that other parts of the codebase use to interact with authentication backends, like getting an instance or checking if any are present.\n", - "/home/eliezer/devs/xcore/xcore/kernel/api/rbac.py:54603373bc16d7c25323f321f59d26bb66d066e524e091f9e59ed723fb2b6bf3": "This Python file is a part of the xcore project's API layer. It provides role-based access control (RBAC) functionality for FastAPI routes using HTTP Bearer tokens and an authentication backend provided by another module in the same directory. \n\nKey Components:\n1. `HTTPBearer` class from fastapi security is used to handle bearer token based authorization.\n2. The `get_auth_backend()` function retrieves the current instance of a registered authentication backend, which could be JWT or session-based auth system. \n3. Two main classes are defined: `RBACChecker` and its factory functions `require_role` and `require_permission`. These handle checking if user roles/permissions match the required ones for a route.\n4. The `__call__()` method of RBACChecker is invoked when an HTTP request hits a FastAPI route that depends on it, providing access control based on token-based authentication and authorization rules defined by its callers. \n5. If no backend is registered (in dev mode), the system behaves as per `strict` flag in RBACChecker instance or globally configured behavior.\n6. The file also raises HTTP exceptions with appropriate status codes for various scenarios like missing token, invalid/expired tokens and insufficient permissions. \n\nDependencies: This module depends on external libraries such as FastAPI and its security modules along with the `get_auth_backend()` function from another internal module in kernel.api package. It also relies on an instance of a registered authentication backend to decode, validate and extract tokens for authorization checks.\n\nInteractions: This file is called by other parts of xcore project's API layer (FastAPI routes) that need role-based access control based on HTTP Bearer token provided in the request headers. It produces user data from an authentication backend which it uses to check if a route should be accessible or not for different users with varying roles and permissions.\n", - "/home/eliezer/devs/xcore/xcore/__version__.py:9a0b494b638e72521fa95c5a52c6ef82e7bd7d23928f501fe41dd8b5c5ff0a82": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/__version__.py`\n\n#### Purpose\nThis file contains the version information for the xcore project. It provides details about the current release, including the version number, its components, and the author responsible for maintaining it.\n\n#### Key Components\n- **__version__**: A string representing the version of the package.\n - Example: `\"2.1.1\"`\n- **__version_info__**: A tuple containing the major, minor, and patch versions of the package.\n - Example: `(2, 1, 1)`\n- **__author__**: A string specifying the contributors to the project.\n - Example: `\"xcore contributors\"`\n- **__license__**: A string indicating the license under which the project is distributed.\n - Example: `\"MIT\"`\n\n#### Dependencies\nThis file does not import or rely on any external libraries.\n\n#### Interactions\nThe `__version__.py` file interacts with other parts of the codebase through direct imports and calls. It provides version information to other modules that need it, such as setup scripts or documentation generators.", - "/home/eliezer/devs/xcore/xcore/__init__.py:9809aded8b8b96a85cc14f9106a2b249a3c2391a69f19f7a614d3281c2d35bdc": "### Technical Summary\n\n**Purpose**: The file `/home/eliezer/devs/xcore/xcore/__init__.py` is the entry point for the xcore framework version 2. It serves as the central hub for managing the system's components, including plugins and services.\n\n**Key Components**:\n- **Xcore Class**: The main class that orchestrates the entire system. It initializes various subsystems such as services, events, hooks, registry, and kernel context.\n- **PluginLoader**: Manages the loading of plugins from a configuration file.\n- **LifecycleManager**: Handles the lifecycle management of plugins and services.\n- **PluginSupervisor**: Supervises the execution of plugins and manages their interactions with the system.\n- **EventBus**: A message bus for communication between different parts of the system.\n- **HookManager**: Manages hooks that can be triggered at specific points in the system's lifecycle.\n\n**Dependencies**:\n- The file imports several internal modules and external libraries, such as `ConfigLoader` for configuration management, `ServiceContainer` for service management, and `PluginSupervisor` for plugin supervision.\n\n**Interactions**:\n- The `Xcore` class initializes the system by configuring logging, setting up observability components, loading services, event bus, hooks, registry, and kernel context.\n- It also manages the lifecycle of plugins and services, ensuring they are properly initialized and shut down.\n- The file includes methods to attach a FastAPI router if an application is provided, which routes requests to different parts of the system based on plugin names.\n\nThis file serves as the glue that connects all the components of the xcore framework, enabling seamless integration and management of plugins and services.", - "/home/eliezer/devs/xcore/xcore/__init__.py:2361f1cdf07b767ba88dcd0a0d2216db38eae227416598e69c918c83dd81c1cf": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/__init__.py`\n\n#### Purpose\nThis file contains the initialization logic for the Xcore application. It sets up the environment, initializes plugins, and handles errors gracefully.\n\n#### Key Components\n1. **Error Handling**:\n - An `ImeError` is raised if the default `PLUGIN_SECRET_KEY` is detected in production.\n - The error message provides instructions on how to configure the secret key in the `xcore.yaml` file.\n\n2. **Initialization**:\n - The `__init__.py` file initializes the Xcore application by setting up plugins and handling errors.\n\n3. **Representation**:\n - The `__repr__` method returns a string representation of the Xcore instance, indicating its status (booted or idle) and version.\n\n#### Dependencies\n- This file imports no external libraries.\n- It relies on internal modules such as `xcore.version`, which likely contains the version number of the Xcore application.\n\n#### Interactions\n- The `__init__.py` file interacts with other parts of the codebase through calls to plugins and error handling mechanisms.", - "/home/eliezer/devs/xcore/xcore/kernel/context.py:0f0c1e5d54565c699b494baea917c40c7eda2bae22b8daa0a8729c67fcbe33d0": "### Technical Summary: KernelContext\n\n#### Purpose\nThe `KernelContext` class is designed to encapsulate all core dependencies required by kernel-level components. It resolves the \"prop drilling\" problem by providing a unified interface for accessing these dependencies.\n\n#### Key Components\n- **config**: An instance of `PluginConfig`, which holds configuration settings specific to the plugin.\n- **services**: A `ServiceContainer` that manages and provides services needed by the kernel.\n- **registry**: An optional `PluginRegistry` that allows plugins to register themselves with the context.\n- **events**: An optional `EventBus` for handling events within the kernel.\n- **hooks**: An optional `HookManager` for managing hooks in the kernel.\n- **metrics**: An optional `MetricsRegistry` for collecting and reporting metrics.\n- **tracer**: An optional `Tracer` for tracing the execution of code within the kernel.\n- **health**: An optional `HealthChecker` for monitoring the health of the kernel.\n\n#### Dependencies\nThe `KernelContext` imports several internal modules and external libraries:\n- `dataclasses`\n- `typing`\n- `__future__`\n- `PluginConfig`\n- `ServiceContainer`\n- `PluginRegistry`\n- `EventBus`\n- `HookManager`\n- `MetricsRegistry`\n- `Tracer`\n\n#### Interactions\nThe `KernelContext` interacts with the rest of the codebase through its methods and properties. It provides a unified interface for accessing all core dependencies, making it easier to manage and maintain the kernel-level components.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/__init__.py:3729a0cdc0f9390e5be157fbf0cdda0153eb1c23a8db6e0f1825ddaa6eed5fdb": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/runtime/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for runtime management in the XCore kernel. It initializes and manages various plugins, lifecycle components, and state machines necessary for the system's operation.\n\n#### Key Components:\n1. **LifecycleManager**: Manages the lifecycle of plugins, ensuring they are properly initialized and shut down.\n2. **PluginLoader**: Loads and registers plugins based on their type and configuration.\n3. **PluginState**: Represents the current state of a plugin instance.\n4. **StateMachine**: Manages the transitions between different states of a plugin.\n\n#### Dependencies:\n- Internal modules: `lifecycle`, `loader`, `state_machine`, `supervisor`.\n- External libraries (if any).\n\n#### Interactions:\n- The file imports and initializes these components, which are then used throughout the kernel to manage plugins effectively.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/dependency.py:fb51fecb930c09aeb9b8ab151108405e59d160e10c697e9e8e06e90bd69f01d8": "### Technical Summary: Dependency Management Utility\n\n**Purpose**: The `dependency.py` file is a utility designed to manage plugin dependency graphs within the XCore system. It allows for the creation of directed acyclic graphs (DAGs) where each node represents an item and edges represent dependencies between these items.\n\n**Key Components**:\n- **DependencyGraph Class**: A generic class that implements a DAG structure. It includes methods to add nodes, add dependencies, and retrieve nodes in topological order.\n - `add_node(name: str, data: T)`: Adds a node with associated data to the graph.\n - `add_dependency(node: str, depends_on: str)`: Adds a directed edge from 'node' to 'depends_on', indicating that 'node' requires 'depends_on'.\n - `get_ordered()`: Returns nodes in topological order using Kahn's algorithm. Raises an error if a circular dependency is detected.\n- **__contains__(name: str) and get_data(name: str)**: Methods to check if a node exists in the graph and retrieve its associated data.\n\n**Dependencies**:\n- The file imports `logging` for logging purposes and `collections.deque` for efficient queue operations. It also uses type annotations for better code readability.\n\n**Interactions**:\n- This file is called by other parts of the XCore system to manage plugin dependencies, ensuring that plugins are loaded in the correct order to avoid circular dependencies and ensure proper initialization.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/state_machine.py:b35435f768ebcbfcbd8f80cbe8db18512175f5726a9af994da184939a95a2ecc": "### Technical Summary of `state_machine.py`\n\n#### Purpose\nThe file `state_machine.py` is designed to manage the lifecycle of a plugin in a thread-safe manner. It provides a finite state machine (FSM) that transitions between different states based on various events such as loading, calling, unloading, reloading, and error handling.\n\n#### Key Components\n1. **PluginState Enum**: Defines the possible states of the plugin (`UNLOADED`, `LOADING`, `READY`, `UNLOADING`, `RELOADING`, `FAILED`).\n2. **_TRANSITIONS Dict**: Maps each state to a dictionary of valid transitions and their corresponding next states.\n3. **InvalidTransition Exception**: Custom exception for invalid transitions.\n4. **StateMachine Class**:\n - Initializes with the plugin name and an optional callback function for state changes.\n - Provides methods to transition between states, handle errors, and force a specific state.\n - Includes properties to check if the plugin is in various states.\n\n#### Dependencies\n- No external dependencies are required for this file.\n\n#### Interactions\nThe `StateMachine` class interacts with other parts of the system through its callback function (`on_change`). It also allows transitions between states based on predefined events, ensuring that the plugin's lifecycle is managed correctly.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/activator.py:dffae2127cacb91b646dd6a7c2233d42795b6bccac69b6d3e3bc82cad116c43e": "### Technical Summary: Activator Module in XCore Kernel Runtime\n\n#### Purpose\nThe `activator.py` file in the XCore kernel runtime is responsible for managing the activation of plugins. It provides a registry to store and retrieve different activation strategies based on the execution mode of the plugin.\n\n#### Key Components\n1. **ActivatorRegistry**: A class that manages the registration and retrieval of `PluginActivator` instances. It logs when an activator is registered.\n2. **PluginActivator**: An abstract base class defining the interface for activating plugins. Subclasses must implement the `activate` method, which takes a plugin manifest and a `PluginLoader` instance to activate the plugin and return its handler.\n\n#### Dependencies\n- The file imports `logging`, `abc`, and type hints.\n- It relies on internal modules (`..api.contract`) and external libraries (`..security.signature`, `..sandbox.process_manager`).\n\n#### Interactions\n- The `ActivatorRegistry` class is used to register different activation strategies based on the execution mode of a plugin.\n- Each activation strategy implements the `activate` method, which performs various checks (e.g., signature verification) and then starts the lifecycle manager for the plugin.\n- The `PluginLoader` instance provides the necessary context and caller information for activating plugins.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/lifecycle.py:d19e5b197fa4dc89d0d66fca3c94a41243f41dc25584daa860d222dcd2f71157": "### Technical Summary\n\n#### Purpose\nThe `lifecycle.py` file is responsible for managing the lifecycle of a Trusted plugin within an XCore system. It ensures that the plugin is properly loaded, initialized, and ready to handle requests.\n\n#### Key Components\n- **LifecycleManager Class**: Manages the state transitions and interactions with other components.\n - **State Machine**: Tracks the current state of the plugin (`load`, `ok`, `error`).\n - **PluginContext**: Provides a rich context for the plugin instance, including services and environment variables.\n\n- **LoadError Exception**: A custom exception raised when there is an error during the loading process.\n\n#### Dependencies\n- **Python Standard Library Modules**:\n - `asyncio`\n - `importlib.util`\n - `inspect`\n - `logging`\n - `sys`\n - `time`\n - `types`\n - `pathlib`\n\n- **External Libraries** (if used):\n - None\n\n#### Interactions\n- **Plugin Loading**: The file imports the Python module from the specified path, injects services into the instance, and calls hooks like `on_init`, `on_load`, and `on_start`.\n- **API Router**: If the plugin exposes a custom HTTP router, it is distributed to the shared container (mems).\n- **Middlewares**: The file collects and distributes middlewares if any are defined by the plugin.\n\n#### Notes\n- The file uses a package namespace for isolation between plugins, ensuring that each plugin has its own unique module name.\n- It handles exceptions during loading and provides a clear error message.\n- The `call` method allows external requests to be handled by the plugin instance within the specified timeout.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/lifecycle.py:c33a91e6f5bbe39a46f8a3345b985c74f20dec9537439be715429d80e63bbd21": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/runtime/lifecycle.py`\n\n#### Purpose\nThis file is responsible for managing the lifecycle of plugins in a XCore application. It handles actions such as loading, unloading, and reloading plugins, as well as collecting and propagating services.\n\n#### Key Components\n- **`_instance`**: The main instance of the plugin.\n- **`plugin_router`**: A custom HTTP router provided by the plugin.\n- **`plugin_middlewares`**: A dictionary containing middleware functions for the plugin.\n- **`propagate_services`**: A method to propagate services from the plugin to the container, handling collisions and ensuring proper registration.\n\n#### Dependencies\n- `asyncio`\n- `sys`\n- `time`\n- `logging`\n- `xcore_plugin_*.main`: The main module of each plugin.\n- `xcore_plugin_*.router`: The router provided by each plugin.\n- `xcore_plugin_*.add_state`: The middleware function provided by each plugin.\n\n#### Interactions\n- **Loading**: The file initiates the loading process, calling hooks and methods to prepare the plugin for use.\n- **Unloading**: It handles the unloading of plugins, cleaning up resources and unregistering services from the container.\n- **Reloading**: It reloads plugins, updating their state and propagating new services.\n\nThis file is crucial for maintaining the dynamic nature of XCore applications by ensuring that plugins can be seamlessly integrated and managed.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/lifecycle.py:f8242f17adae8a4f0118236cf4f873dd8435e756512a021c71d20ad9451529ff": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/runtime/lifecycle.py`\n\n#### Purpose\nThis file provides a runtime lifecycle management system for the XCore kernel. It handles the initialization and state changes of various components within the kernel, ensuring smooth operation.\n\n#### Key Components\n1. **State Management**:\n - `_sm`: An instance of `StateMachine` that manages the current state of the kernel.\n - `_instance`: A reference to the main instance of the kernel or a related component.\n\n2. **Uptime Calculation**:\n - `_uptime`: The duration since the kernel was started, calculated in seconds.\n\n3. **Data Output**:\n - `self._sm.state.value`: The current state of the system.\n - `self._instance is not None`: Whether the main instance of the kernel or a related component exists.\n - `round(self.uptime, 1) if self.uptime else None`: The uptime rounded to one decimal place.\n\n#### Dependencies\n- **Internal Modules**: `StateMachine`, `KernelInstance`.\n- **External Libraries**: Not explicitly listed in this snippet but assumed to be used by the functions and classes defined here.\n\n#### Interactions\n- This file is called by other parts of the kernel, such as the main entry point or other subsystems.\n- It calls into other modules like `StateMachine` and `KernelInstance`.\n- The data it produces or consumes includes the current state of the system, whether the main instance exists, and the uptime.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/loader.py:b517f7bd12c55888137343456db7f11c8d5e48b91cf27a8139e5ce8e156b6729": "### Technical Summary\n\n**Purpose**: The `loader.py` file is responsible for discovering, ordering, and loading plugins from a specified directory. It ensures that dependencies are met and handles the activation of each plugin based on its execution mode.\n\n**Key Components**:\n- **PluginLoader Class**: Manages the loading process, including scanning directories, parsing manifest files, and orchestrating the activation of plugins.\n- **ActivatorRegistry**: A strategy pattern to manage different activation strategies (trusted and sandboxed).\n- **DependencyGraph**: Used for managing topological dependencies between plugins.\n\n**Dependencies**:\n- `ManifestValidator`: Validates plugin manifests against predefined rules.\n- `PluginHandler`: Interface for interacting with plugins, providing methods like calling methods on the plugin.\n- `ActivatorRegistry`, `TrustedActivator`, and `SandboxedActivator`: Implementations of different activation strategies.\n- `DependencyGraph`: Manages the graph of dependencies between plugins.\n\n**Interactions**:\n- The `PluginLoader` class interacts with other components such as the kernel context, services, events, hooks, registry, metrics, tracer, and health to orchestrate the loading process.\n- It uses the `ActivatorRegistry` to select the appropriate activation strategy based on the plugin's execution mode.\n- The `DependencyGraph` is used to manage the topological dependencies between plugins, ensuring that they are loaded in the correct order.\n\n**Summary**: This file provides a robust mechanism for managing and loading plugins dynamically within an application, ensuring that all dependencies are met and that plugins can be activated based on their execution modes.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/loader.py:b492ac8a3e6e124a53b991b4e375766b6541f926355b2244bf349bf1dc6b5966": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/runtime/loader.py`\n\n#### 1. Purpose\nThis file serves as the runtime loader for plugins in the Xcore system, responsible for activating, reloading, and unloading plugins dynamically.\n\n#### 2. Key Components\n- **lf._activate(manifest)**: Activates a plugin by calling its `__init__` method.\n- **async def reload(self, plugin_name: str)**: Reloads a plugin if it has a `reload` method. It stops the current handler and activates a new one based on the updated manifest.\n- **async def unload(self, plugin_name: str)**: Unloads a plugin by stopping its handler and removing it from the internal dictionary.\n\n#### 3. Dependencies\nThis file imports:\n- `lf._activate(manifest)`\n- `self._flush_services([plugin_name])`\n- `logger.info(f\"[{plugin_name}] \u2705 charg\u00e9\")`\n- `asyncio.wait_for(coro, timeout=10.0)`\n- `handler.status()`\n- `graph.add_node(m.name, m)`\n- `graph.add_dependency(m.name, dep_name)`\n\n#### 4. Interactions\n- **Access Methods**:\n - `get(self, name: str) -> PluginHandler`: Retrieves a plugin handler by its name.\n - `has(self, name: str) -> bool`: Checks if a plugin is loaded.\n - `all_names(self) -> list[str]`: Returns all names of the loaded plugins.\n - `status(self) -> list[dict]`: Returns a list of status dictionaries for each loaded plugin.\n- **Flush Services**:\n - `_flush_services(self, plugin_names: list[str])`: Propagates services exposed by each plugin to the shared container.\n- **Topological Sort (Kahn)**:\n - `_topo_sort(manifests: list)`: Performs a topological sort on the plugins based on their dependencies.\n- **Shutdown**:\n - `shutdown(self) -> None`: Shuts down all loaded plugins properly by stopping each handler and clearing the dictionary.\n- **Collect Plugin Routers**:\n - `collect_plugin_routers(self) -> list[tuple[str, Any]]`: Collects API routes exposed by trusted plugins.\n- **Collect App State**:\n - `collect_app_state(self) -> list[Any]`: Collects middlewares exposed by trusted plugins.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/supervisor.py:6c9a0e170141c80b649c6de2fafaa7073485c04d518b187089b14bd2b94587fe": "### Technical Summary\n\n**Purpose**: The `supervisor.py` file is the orchestrator for the plugins in a software system. It manages the loading and execution of plugins, including handling rate limiting, retries, and tracing.\n\n**Key Components**:\n- **PluginLoader**: Manages the loading and instantiation of plugins.\n- **PermissionEngine**: Handles permission checks for plugin actions.\n- **RateLimiterRegistry**: Registers and manages rate limits for different plugins.\n- **MiddlewarePipeline**: Composes middleware to handle requests before and after plugin execution.\n- **TracingMiddleware**: Adds tracing logs to each request.\n- **RetryMiddleware**: Implements retry logic for failed requests.\n- **PermissionMiddleware**: Checks permissions before executing a plugin action.\n\n**Dependencies**:\n- The file imports `contextlib`, `logging`, and type annotations from the current package.\n- It relies on internal modules (`PluginLoader`, `PermissionEngine`, `RateLimiterRegistry`) and external libraries (not specified).\n\n**Interactions**:\n- The supervisor subscribes to events related to plugin services registration.\n- When a plugin is registered, it triggers the `_on_plugin_services_registered` handler, which loads permissions and rate limits for that plugin.\n- The supervisor initializes the pipeline of middlewares using the `MiddlewareRegistry`, ensuring that requests pass through the correct middleware stack before reaching the final handler (`_dispatch`).\n- The supervisor handles calls to plugins via the pipeline, including tracing, retry, rate limiting, and permission checks.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/supervisor.py:230b68b26ec718b3b542126ce6c069289116877dd4e36d5cd14228eb32e1c15a": "### Technical Summary: Supervisor Module in XCore Kernel\n\n#### Purpose\nThe `supervisor.py` file in the XCore kernel is responsible for managing and executing plugins dynamically. It acts as a central hub that coordinates the execution of various plugins based on user actions or events.\n\n#### Key Components\n1. **Plugin Execution**:\n - The `_dispatch` method handles the dispatching of actions to specific handlers.\n - Middleware can be registered using `register_middleware`, which allows for dynamic modification of plugin behavior.\n\n2. **Dynamic Plugin Management**:\n - `load`, `reload`, and `unload` methods allow plugins to be loaded, reloaded, or unloaded dynamically.\n - The `_load_permissions`, `_register_rate_limits`, and `_register_events` methods manage permissions, rate limits, and event listeners respectively.\n\n3. **Observability**:\n - `status`, `list_plugins`, `collect_plugin_routers`, `collect_app_state`, and `permissions_status` provide various forms of observability into the plugin system.\n - The `permissions_audit` method allows for auditing of permissions with a specified limit.\n\n4. **Shutdown**:\n - The `shutdown` method gracefully shuts down the supervisor, ensuring all resources are properly released.\n\n5. **Helpers**:\n - A static method `_err` is used to create error responses in a standardized format.\n\n#### Dependencies\n- Internal modules: `Middleware`, `PluginLoader`, `PermissionsManager`\n- External libraries: None\n\n#### Interactions\n- The `supervisor.py` file interacts with other parts of the system through methods like `load`, `reload`, and `unload`. It also communicates with middleware to execute actions and manages permissions, rate limits, and event listeners.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/kernel_handler.py:f6a38349750523634a69f315da7db78f0b7cf112dc72360d3c0b6c93caccb62b": "### Technical Summary\n\n**Purpose**: The `kernel_handler.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/runtime/` directory is a plugin virtual 'xcore' that exposes the internals of the kernel via Inter-Process Communication (IPC). It provides various management functions such as listing plugins, taking metrics snapshots, running health checks, auditing permissions, and retrieving registry services.\n\n**Key Components**:\n1. **KernelHandler Class**: This class manages the lifecycle of the plugin and handles incoming IPC requests.\n2. **PluginState Enum**: Defines the state of the kernel handler, which is always set to `READY`.\n3. **__init__ Method**: Initializes the `KernelHandler` with a `KernelContext` and a `PluginSupervisor`.\n4. **is_available Property**: Returns `True` indicating that the plugin is available.\n5. **start and stop Methods**: Placeholder methods for starting and stopping the kernel handler, which are not implemented in this file.\n\n**Dependencies**:\n- The file imports `supervisor` from `..context` and `PluginState` from `.state_machine`.\n- It also depends on internal modules and external libraries that are not explicitly listed here.\n\n**Interactions**:\n- The `KernelHandler` class interacts with the `PluginSupervisor` to list plugins, take metrics snapshots, run health checks, audit permissions, and retrieve registry services.\n- It uses a dictionary `_ACTIONS` to map IPC actions to corresponding handler functions.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/retry.py:6662e055dd389c68067481f15c23cee2698ac5eaa13532dbd7ac7cc26c61d8f0": "### Technical Summary: Retry Middleware for Plugin Calls\n\n#### Purpose\nThe `retry.py` file is a middleware designed to handle retries for plugin calls. It leverages the configuration specified in the manifest of the plugin, including details such as maximum attempts and backoff times.\n\n#### Key Components\n- **RetryMiddleware Class**: This class extends the `Middleware` class and implements the logic for retrying failed plugin calls.\n - **__call__ Method**: This method is called when a plugin call fails. It retrieves the manifest and retry configuration, then iterates through the specified number of attempts.\n - **Exponential Backoff**: The middleware uses an exponential backoff strategy to increase the delay between retries, capped at 60 seconds.\n - **Error Handling**: If all attempts fail, it logs the error and returns a failure response.\n\n#### Dependencies\n- **asyncio**: Required for asynchronous operations.\n- **logging**: Used for logging retry attempts and errors.\n- **typing**: For type annotations.\n\n#### Interactions\n- The `RetryMiddleware` class is called by the plugin system when a call fails. It interacts with the rest of the codebase through the `next_call` function, which is responsible for executing the actual plugin action.\n- The middleware retrieves configuration settings from the manifest and uses them to determine how many attempts should be made and the delay between retries.\n\nThis middleware ensures that plugins can handle transient failures gracefully by retrying calls with increasing delays.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/tracing.py:fb2c9ea55e7225c1a6a9894a9dd804a36289d340410364ee8dad37bc6be542d6": "### Technical Summary: Tracing Middleware for XCore Kernel\n\n#### Purpose\nThe `tracing.py` file is a middleware designed to integrate OpenTelemetry tracing into the XCore kernel. It encapsulates each call made by plugins, creating spans that track the flow of data and operations within the system.\n\n#### Key Components\n- **TracingMiddleware Class**: This class extends the `Middleware` class provided by the XCore framework.\n - **Initialization**: The constructor takes an optional tracer and metrics object to manage tracing and monitoring.\n - **Call Method**: The `__call__` method is responsible for handling each plugin call. It logs the start time, creates a span if available, executes the next call, and records the result.\n - **Metrics Tracking**: If metrics are enabled, it increments counters for calls and errors, and histograms for latency.\n\n#### Dependencies\n- The file imports `logging` for logging and `time` for timing operations. It also uses type hints from `typing`.\n- It relies on the `Middleware` class provided by the XCore framework.\n\n#### Interactions\n- The middleware connects to the rest of the codebase through the `next_call` parameter, which is a callable that executes the actual plugin logic.\n- It logs the start and end times for each call, including the duration in milliseconds if tracing is enabled. This helps in monitoring the performance of plugins.\n\nThis middleware enhances the system's observability by providing detailed traces of plugin interactions, which can be crucial for debugging and performance optimization.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/middleware_registry.py:056867b74c63be0290e3951f7d8e2d0ee7ac70e920c373ce8865598292351b91": "### Technical Summary\n\n**Purpose**: This file serves as a registry for managing and creating middleware pipelines in the XCore runtime. It allows decoupling the creation of middleware from the supervisor, enabling flexibility and modularity in the system.\n\n**Key Components**:\n- **MiddlewareRegistry Class**: Manages the registration and creation of middleware factories.\n - `register(name: str, factory: Callable[[dict[str, Any]], \"Middleware\"])`: Registers a new middleware factory with its name and callable function.\n - `create_pipeline(names: list[str], context: dict[str, Any], final_handler: Callable) -> \"MiddlewarePipeline\"`: Creates a middleware pipeline by calling the registered factories in sequence.\n\n**Dependencies**:\n- The file imports `logging` for logging purposes and `typing` for type hints.\n- It relies on internal modules (`middleware`) and external libraries (not explicitly listed).\n\n**Interactions**:\n- The `MiddlewareRegistry` class is called by the supervisor to register middleware factories.\n- When creating a middleware pipeline, it calls each registered factory with the provided context and final handler. If any factory fails, an error message is logged.\n\nThis design ensures that middleware can be easily added or removed without modifying the supervisor code, enhancing maintainability and scalability of the system.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/middleware.py:2b6ab3b319f4b6da9eaa48058bdd214cb40bb85f869c88e6c87d32af26ca7b4c": "### Technical Summary: Middleware Pipeline for Plugin Supervision\n\n#### Purpose\nThe `middleware.py` file serves as a pipeline for executing middleware functions in the XCore runtime. It manages a sequence of middleware classes that are called sequentially to process plugin actions.\n\n#### Key Components\n1. **Middleware Class (`Middleware`)**:\n - Abstract base class defining the interface for middleware.\n - Contains an abstract method `__call__` that must be implemented by subclasses to define the middleware logic.\n\n2. **MiddlewarePipeline Class (`MiddlewarePipeline`)**:\n - Manages a list of middleware instances and compiles them into a single callable chain.\n - The compiled chain is used to execute middleware in sequence for each plugin action.\n - Supports adding new middlewares dynamically at runtime.\n\n#### Dependencies\n- Imports from `__future__`, `abc`, and `typing`.\n- Uses the `logging` module for logging purposes.\n\n#### Interactions\n- **Initialization**: The pipeline is initialized with a list of middleware instances and a final handler function.\n- **Execution**: When an action is triggered, the pipeline executes each middleware in sequence until it reaches the final handler.\n- **Dynamic Middleware Addition**: Middlewares can be added to the pipeline dynamically at runtime.\n\nThis design ensures that middleware functions are executed sequentially, allowing for flexible and modular supervision of plugin actions within the XCore system.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/__init__.py:ce156f904e28e06b7113ae9bba753e3ad80131b9af697497338dbe8aa669b04c": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for middleware components in the XCore kernel runtime. It defines a collection of middleware classes that are used to enhance the functionality and security of the system.\n\n#### Key Components:\n1. **Middleware**: A base class for all middleware components, providing common methods and properties.\n2. **MiddlewarePipeline**: Manages a sequence of middleware instances, allowing them to be executed in order.\n3. **MiddlewareRegistry**: Registers and manages middleware classes, facilitating easy access and configuration.\n4. **PermissionMiddleware**: Middleware that enforces permissions on requests.\n5. **RateLimitMiddleware**: Middleware that limits the number of requests per user or IP address.\n6. **RetryMiddleware**: Middleware that retries failed requests with exponential backoff.\n7. **TracingMiddleware**: Middleware that logs request details for debugging and monitoring.\n\n#### Dependencies:\n- The file imports several internal modules and external libraries, such as `os`, `sys`, and `logging`.\n- It relies on the `xcore` package, which likely contains other middleware components or utilities.\n\n#### Interactions:\n- **Called by**: Other parts of the XCore kernel runtime, particularly in the `middleware.py` module.\n- **Calls into**: The middleware classes themselves, where methods like `process_request`, `process_response`, and `handle_exception` are implemented.\n- **Data produced or consumed**: Middleware instances produce logs and responses, while consuming requests for processing.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/permissions.py:4ccb3ac312ba569245612afeddf21d2cd26d4de9dfd73d3eb281013101b6c32b": "### Technical Summary: Permissions Middleware for Plugin Permission Checks\n\n#### Purpose:\nThe `permissions.py` file serves as a middleware in the XCore runtime that ensures plugin permissions are checked before executing any actions. It provides a centralized way to manage and enforce access control policies.\n\n#### Key Components:\n1. **Permission Denied Exception**: The `PermissionDenied` exception is defined in the `permissions.engine` module, which is used by the `PermissionMiddleware` to raise an error when permission checks fail.\n2. **Middleware Class**: The `PermissionMiddleware` class inherits from the `Middleware` class and implements the `__call__` method. This method is responsible for checking permissions before passing the request to the next middleware or handler.\n\n#### Dependencies:\n- The `permissions.engine` module contains the `PermissionDenied` exception.\n- The `Middleware` class is assumed to be a base class that provides common functionality for middleware in the XCore runtime.\n\n#### Interactions:\n- The `PermissionMiddleware` interacts with the `permissions.engine` module to perform permission checks. It retrieves the necessary permissions from the configuration and uses them to determine if the request should proceed.\n- If a permission check fails, it logs a warning message and returns an error response to the client.\n- If the permission check passes, it allows the request to proceed by calling the `next_call` function.\n\nThis middleware ensures that all plugin actions are authenticated and authorized before they reach the application logic, enhancing security and maintaining compliance with access control policies.", - "/home/eliezer/devs/xcore/xcore/kernel/runtime/middlewares/ratelimit.py:5a3bea00c9aa993989fa745e6dfef380223a7b99482b372885d59c05cc62353d": "### Technical Summary: Ratelimit Middleware for Plugin Rate Limiting\n\n#### Purpose\nThe `ratelimit.py` file is a middleware designed to manage plugin rate limits within the XCore system. It ensures that each plugin can only execute certain actions at a specified rate to prevent abuse and maintain system stability.\n\n#### Key Components\n- **RateLimitExceeded**: An exception raised when a plugin exceeds its rate limit.\n- **Middleware**: A base class for middleware components in the system.\n- **RateLimitMiddleware**: A specific implementation of the `Middleware` class that checks if a plugin can execute an action within the defined rate limits.\n\n#### Dependencies\nThe file imports:\n- `__future__.annotations`: For type hinting.\n- `...sandbox.limits.RateLimitExceeded`: An exception for rate limit exceeded errors.\n- `.middleware.Middleware`: The base middleware class.\n\n#### Interactions\n- **Calls into**: This middleware is called by the system to check if a plugin can execute an action before proceeding with the request.\n- **Data produced or consumed**: It does not produce or consume any data directly but checks the rate limits for each plugin action.", - "/home/eliezer/devs/xcore/xcore/kernel/api/auth.py:ee665255cfae412196593ee7157a050940be3e4fd839f6b67155579029bb3627": "### Technical Summary: xcore/kernel/api/auth.py\n\n#### Purpose\nThis file contains the implementation of an authentication API for the xcore kernel. It provides functions to decode tokens, extract them from requests, and check permissions based on decoded payloads.\n\n#### Key Components\n- **AuthPayload**: A dictionary representing the payload extracted from a token.\n - `sub`: The subject (user ID).\n - `roles` (Optional): List of roles associated with the user.\n - `permissions` (Optional): List of permissions granted to the user.\n\n- **RequestAdapter**: An interface for accessing request headers, cookies, and query parameters.\n - `headers`: A dictionary containing HTTP headers.\n - `cookies`: A dictionary containing HTTP cookies.\n - `query_params`: A dictionary containing URL query parameters.\n\n- **AuthBackend**: A protocol defining methods to decode tokens, extract them from requests, and check permissions.\n - `decode_token(self, token: str) -> AuthPayload | None`: Decodes a JWT token into an `AuthPayload`.\n - `extract_token(self, request: RequestAdapter) -> str | None`: Extracts the JWT token from a request.\n - `has_permission(self, payload: AuthPayload, permission: str) -> bool`: Checks if a user has a specific permission.\n\n#### Dependencies\n- The file imports `typing` for type annotations and `runtime_checkable` from `typing_extensions`.\n- It relies on the `AuthBackend` protocol to define the interface for authentication backends.\n\n#### Interactions\n- The file is registered and unregistered by plugins, allowing for dynamic switching between different authentication implementations.\n- The `get_auth_backend()` function returns the currently active authentication backend, if any.", - "/home/eliezer/devs/xcore/xcore/kernel/api/rbac.py:d4592a8a6dc315a626f2fa7ea267d5af3e6f55a53bf0b9d34102fd710f0995d3": "### Technical Summary\n\n#### Purpose\nThe `rbac.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/api/` directory is responsible for managing user authentication and role-based access control (RBAC) within an API. It provides functions to resolve the current authenticated user, retrieve their session ID, and enforce RBAC checks on routes.\n\n#### Key Components\n1. **_resolve_user**:\n - This function retrieves the currently authenticated user from the request state or decodes a token using the configured authentication backend.\n - It caches the decoded user in the request state to avoid redundant decoding for subsequent requests.\n\n2. **get_current_user**:\n - A FastAPI dependency that returns the payload of the authenticated user.\n - It uses `_resolve_user` to fetch the user and is used in route handlers to access the user data.\n\n3. **get_user_session_id**:\n - Another FastAPI dependency that returns only the `sub` (user identifier) from the authenticated user.\n - It also uses `_resolve_user` to fetch the user and extracts the session ID.\n\n4. **RBACChecker**:\n - A class that can be used as a FastAPI dependency to enforce RBAC checks on routes.\n - It takes a list of required permissions or roles and a strict mode setting.\n - If no authentication backend is registered, it either raises an error if strict mode is enabled or returns an empty dictionary in dev mode.\n\n#### Dependencies\n- **fastapi**: For handling HTTP requests and responses.\n- **httpx**: For making HTTP requests to the authentication backend (if needed).\n- **auth**: A custom authentication module that provides methods for token extraction, decoding, and user retrieval.\n\n#### Interactions\n- The `get_current_user` dependency is used in route handlers to access the authenticated user's data.\n- The `RBACChecker` class can be used to enforce RBAC checks on routes by passing a list of required permissions or roles.\n- The authentication backend is responsible for extracting and decoding tokens, which are then passed to the `get_current_user` dependency.\n\nThis file plays a crucial role in securing the API by ensuring that only authorized users with the correct roles can access certain endpoints.", - "/home/eliezer/devs/xcore/xcore/kernel/api/versioning.py:348499d5bd7bf1eec46ec67c5146fa3956c48ba0195c4cef2ef389010d9e7fd8": "### Technical Summary: Versioning Module in xcore Kernel API\n\n#### Purpose\nThe `versioning.py` file in the `xcore/kernel/api` directory is responsible for managing and verifying the compatibility of plugin versions with the core system. It provides a class `APIVersion` to represent version numbers and functions to parse, compare, and validate these versions.\n\n#### Key Components\n1. **APIVersion Class**:\n - **Description**: This class represents a version number in the format `major.minor[.patch]`. It is immutable using the `frozen=True` decorator.\n - **Methods**:\n - `parse(v: str) -> APIVersion`: Parses a string representation of a version into an `APIVersion` object.\n - `__ge__(self, other: APIVersion) -> bool`: Checks if the current version is greater than or equal to another version.\n - `__le__(self, other: APIVersion) -> bool`: Checks if the current version is less than or equal to another version.\n - `__str__(self) -> str`: Returns a string representation of the version number.\n\n2. **check_compatibility(framework_version_expr: str, core_version: str) -> bool**:\n - **Description**: This function takes two strings representing version expressions and checks if the framework version is compatible with the core version.\n - **Parameters**:\n - `framework_version_expr`: A string in the format `>=1.0`, `>=1.0,<3.0`, or `==2.0`.\n - `core_version`: A string representing the current core version.\n - **Return**: Returns `True` if the framework version is compatible with the core version, otherwise `False`.\n\n#### Dependencies\n- The file imports `re` for regular expression operations and `dataclasses` for defining data classes.\n\n#### Interactions\n- This module interacts with other parts of the codebase through functions like `check_compatibility`, which is called by higher-level components to ensure compatibility between different versions of plugins.", - "/home/eliezer/devs/xcore/xcore/kernel/api/router.py:a39c21f13fd0397d13d894680fa6732b6023218f4d70c31cd2dcf636f638ca84": "### Technical Summary: Router FastAPI Unique for All Plugins\n\n#### Purpose\nThis file, `/home/eliezer/devs/xcore/xcore/kernel/api/router.py`, serves as the entry point for a FastAPI-based API that manages communication with plugins. It dynamically constructs routes based on the `PluginSupervisor` and provides secure authentication through an API key header.\n\n#### Key Components\n1. **CallRequest and CallResponse Models**: These models define the structure of the request and response bodies, respectively.\n2. **Security Function**: `_hash_key` generates a hash for API keys to ensure security against timing attacks.\n3. **build_router Function**: This function sets up the FastAPI router with dependencies, including authentication using the `verify_api_key` function.\n4. **Routes**:\n - `/ipc/{plugin_name}/{action}`: Handles calls to plugins, verifying the API key before processing.\n - `/status`: Returns the status of all plugins.\n - `/{plugin_name}/reload`, `/{plugin_name}/load`, `/{plugin_name}/unload`: Manage plugin loading and unloading.\n - `/health`: Checks the health of the system using a `HealthChecker`.\n - `/metrics`: Provides metrics snapshot from a `MetricsRegistry`.\n\n#### Dependencies\n- **FastAPI**: The main framework for building APIs.\n- **Pydantic**: For data validation in request bodies.\n- **hashlib** and **hmac**: For hashing API keys to ensure security.\n- **PluginSupervisor**: An internal module responsible for managing plugins.\n- **MetricsRegistry** and **HealthChecker**: External modules used for monitoring and health checks.\n\n#### Interactions\nThis file interacts with the `PluginSupervisor` to manage plugin interactions, ensuring secure communication and proper handling of requests. It also integrates with external services like metrics and health checks to provide comprehensive system status and performance data.", - "/home/eliezer/devs/xcore/xcore/kernel/api/contract.py:f90086fb7d14600b5245c2115d34a5ce50cf9fa01c1cb827b8fe9454be8ebc7e": "### Technical Summary\n\n**Purpose**: The `contract.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/api/contract.py` directory defines a contract for v2 plugins. It outlines the minimal requirements and interfaces that plugins must implement to function correctly within the system.\n\n**Key Components**:\n- **BasePlugin**: A structural protocol (duck typing) with no inheritance required, focusing on handling actions and payloads.\n- **TrustedBase**: An abstract base class with rich context injection, ensuring all lifecycle methods are called and services are accessible.\n- **ExecutionMode**: An enumeration of execution modes for plugins, such as trusted, sandboxed, and legacy.\n\n**Dependencies**:\n- The file imports several types from the `typing` module, including `Awaitable`, `Callable`, `Literal`, and `TypeVar`.\n- It also includes a type alias `T` for generic types.\n- The file uses `TYPE_CHECKING` to avoid circular dependencies during type checking.\n\n**Interactions**:\n- **BasePlugin**: Plugins must implement the `handle` method, which takes an action and payload as arguments and returns a dictionary.\n- **TrustedBase**: Plugins can override lifecycle methods like `on_init`, `on_start`, and `on_stop`.\n- **call_plugin**: A method to call plugins dynamically, using the context injected by the framework.\n- **get_service**: A method to retrieve services from the container, with type hints for specific types (e.g., `AsyncSQLAdapter`).\n- **get_service_as**: A strongly typed version of `get_service` that allows specifying the exact type of the service.\n- **get_router**: An optional method to expose custom HTTP routes using FastAPI.\n\nThis contract ensures that plugins are well-defined and can be easily integrated into the system, adhering to best practices for plugin development.", - "/home/eliezer/devs/xcore/xcore/kernel/api/contract.py:6243dd9953687c3eacdd2c124b1507125967cc6850d32122d83a5420c5e60a3b": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/api/contract.py`\n\n#### 1. Purpose\nThis file defines a middleware for execution, responsible for handling various lifecycle events and providing standardized responses.\n\n#### 2. Key Components\n- **Middleware Function**: `execute_middleware`\n - **Purpose**: Executes the middleware logic.\n - **Parameters**:\n - `data`: Optional dictionary containing additional data to be included in the response.\n - **kwargs**: Additional keyword arguments for customization.\n - **Return Value**: A dictionary with a status of \"ok\" and optional data.\n\n- **Hooks Cycle of Life (Optional)**: `on_init`, `on_load`, `on_start`, `on_reload`, `on_stop`, `on_unload`\n - **Purpose**: Define asynchronous methods that can be called at different stages of the middleware's lifecycle.\n - **Parameters**:\n - `None`: No parameters are required for these methods.\n - **Return Value**: None.\n\n#### 3. Dependencies\n- **Internal Modules**: None (the file does not import any internal modules).\n- **External Libraries**: None (the file does not rely on external libraries).\n\n#### 4. Interactions\n- **Calls into**: The middleware function is called by the system to execute its logic.\n- **Data Produced or Consumed**: The middleware can produce a response dictionary that includes status, data, and optional error messages.\n\nThis file serves as a foundational component for managing middleware in the xcore kernel API, providing a standardized way to handle lifecycle events and responses.", - "/home/eliezer/devs/xcore/xcore/kernel/api/context.py:d5a78e1eddd0027fbcefa7a1601de04ae41cecabc3aa08e5b4c14bbf0336ff62": "### Technical Summary: PluginContext Class\n\n#### Purpose\nThe `PluginContext` class is designed to provide a comprehensive context for each Trusted plugin at load time. It encapsulates essential services, event bus, hooks, environment variables, and configuration settings. The context includes methods to access these resources securely through the registry if available, otherwise falling back to the shared container.\n\n#### Key Components\n- **name**: The name of the plugin.\n- **services**: A dictionary containing shared services such as database, cache, other plugins, etc.\n- **events**: An instance of `EventBus` for emitting and subscribing to events.\n- **hooks**: An instance of `HookManager` with priority hooks that support wildcards.\n- **env**: A dictionary of environment variables resolved from the plugin's configuration file (`plugin.yaml`).\n- **config**: The `extra` block of the manifest containing arbitrary plugin configuration.\n\n#### Dependencies\nThe `PluginContext` class imports and relies on:\n- `dataclasses`: For defining data classes.\n- `typing`: For type annotations.\n- `asyncio`: For asynchronous operations if needed.\n- `os`: For accessing environment variables.\n- `jsonschema`: For validating the manifest.\n- `logging`: For logging purposes.\n\n#### Interactions\nThe `PluginContext` class interacts with other parts of the codebase through:\n- **registry**: To access services and manage scopes.\n- **events**: To emit and subscribe to events.\n- **hooks**: To trigger hooks with wildcards.\n- **env**: To resolve environment variables from the manifest.\n- **config**: To access arbitrary plugin configuration.\n\n#### Security\nThe `PluginContext` class ensures secure access to services by:\n- Prioritizing the registry for scope-based access control.\n- Fallbacking to the shared container if the registry is not available or if a service is not found in the registry.\n\nThis context is crucial for plugins to function properly within the system, providing a consistent and reliable environment for all operations.", - "/home/eliezer/devs/xcore/xcore/kernel/api/proto.py:def38029adf7bacec3c80c3b30b64494602612cf3698d4aa3e8e2104db2471bc": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/api/proto.py`\n\n#### Purpose:\nThis file defines the API for event handling and hook management within the XCore kernel. It provides interfaces for interacting with an event bus, a hook manager, and various health checks.\n\n#### Key Components:\n1. **EventBus**:\n - A protocol defining methods to subscribe to events (`on`), emit events (`emit`), and register one-time event listeners (`once`).\n - Example usage:\n ```python\n from xcore.kernel.events.section import EventBus\n\n class MyEventHandler(EventBus):\n def on(self, event_name: str, priority: int = 50,\n name: str | None = None) -> Callable: ...\n async def emit(self, event_name: str,\n data: dict[str, Any] | None = None) -> list[Any]: ...\n ```\n\n2. **HookManager**:\n - A protocol defining methods to register and manage hooks with priority.\n - Example usage:\n ```python\n from xcore.kernel.observability import MetricsRegistry\n\n class MyHookManager(HookManager):\n def register(\n self,\n event_name: str,\n func: Callable,\n priority: int = 50,\n once: bool = False,\n timeout: Optional[float] = None,\n ) -> Callable: ...\n ```\n\n3. **HealthChecker**:\n - A protocol defining a decorator to register functions to be called when an event is emitted.\n - Example usage:\n ```python\n from xcore.kernel.events.section import EventBus\n\n class MyHealthChecker(HealthChecker):\n def register(self, name: str) -> Callable:\n \"\"\"\n Decorator to register a function to be called when an event is emitted.\n Args:\n name (str): The name of the event to register the function for.\n \"\"\"\n ...\n ```\n\n4. **PluginRegistry**:\n - A protocol defining methods to manage plugins.\n - Example usage:\n ```python\n from xcore.kernel.events.section import EventBus\n\n class MyPluginRegistry(PluginRegistry):\n ...\n ```\n\n5. **PluginContext**:\n - A dataclass representing the context injected into each Trusted plugin at load time.\n - Attributes include:\n - `name`: The name of the plugin.\n - `services`: A dictionary of shared services (e.g., database, cache).\n - `events`: An instance of `EventBus`.\n - `hooks`: An instance of `HookManager`.\n - `caller`: A callable to handle events.\n - `metrics`: An instance of `MetricsRegistry`.\n - `tracer`: An instance of `Tracer`.\n - `health`: An instance of `HealthChecker`.\n - `registry`: An instance of `PluginRegistry`.\n\n#### Dependencies:\n- The file imports from the following modules:\n - `dataclasses`\n - `typing`\n - `xcore.kernel.events.section`\n - `xcore.kernel.observability`\n\n#### Interactions:\n- This file interacts with other parts of the codebase through methods like `emit`, `register`, and `unregister` in the `EventBus`, `HookManager`, and `HealthChecker` protocols.\n- It also uses the `PluginContext` dataclass to provide a structured context for plugins.", - "/home/eliezer/devs/xcore/xcore/kernel/events/__init__.py:6ccd4660b6d20f91d5139f04be6e34ca6e22631617595838a1f477ab37ef4a03": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/events/__init__.py`\n\n#### Purpose\nThis file serves as the entry point for event handling in the XCore kernel. It defines classes and functions responsible for managing events, hooking into them, and dispatching them throughout the system.\n\n#### Key Components\n1. **EventBus**: Manages the communication between different parts of the system that need to react to events.\n2. **EventDispatcher**: Dispatches events to their respective handlers based on their type.\n3. **HookManager**: Manages hooks that can be triggered at specific points in the event handling process.\n4. **HookResult**: Represents the result of a hook, indicating whether it was successful or not.\n5. **Event**: Represents an individual event with data and metadata.\n\n#### Dependencies\n- Internal modules: `bus`, `dispatcher`, `hooks`\n- External libraries: None\n\n#### Interactions\n- The `EventBus` is responsible for creating and managing event instances.\n- The `EventDispatcher` uses the `EventBus` to dispatch events to their handlers.\n- The `HookManager` allows hooks to be registered, triggered, and managed within the system.\n- Hooks can interact with the `EventBus` to send or receive data during the event handling process.", - "/home/eliezer/devs/xcore/xcore/kernel/events/dispatcher.py:f90f492b11daf456c6f960e78f8103ff8529e39259ea85e984d79bf2c3ebcb8a": "### Technical Summary\n\n**Purpose**: The `dispatcher.py` file serves as a bridge between the EventBus and HookManager in the XCore kernel. It coordinates these systems to facilitate event handling and priority hook execution.\n\n**Key Components**:\n- **EventDispatcher Class**: Manages the coordination of events between the EventBus and HookManager.\n - **__init__ Method**: Initializes the dispatcher with an instance of `EventBus` and a `HookManager`.\n - **forward Method**: Redirects events from a specified bus pattern to the hooks. If no hooks are present or if the pattern does not match, it returns without any action.\n - **emit Method**: Emits an event using the EventBus. It also triggers the corresponding hook if the HookManager is available.\n\n**Dependencies**:\n- The `EventDispatcher` class imports the `EventBus` and `HookManager` classes from their respective modules (`xcore.kernel.events.bus` and `xcore.kernel.hooks.manager`, respectively).\n\n**Interactions**:\n- The `EventDispatcher` connects to the EventBus using its `on` method, which registers a callback function for specific event patterns.\n- When an event is emitted by the EventBus, it triggers the corresponding hook if the HookManager is present. This allows for flexible and prioritized handling of events across different parts of the system.", - "/home/eliezer/devs/xcore/xcore/kernel/events/hooks.py:4dff5997cb679052081b9bd34894f3779cf4d346f6f7c1de4bfdaf70c15fa043": "### Technical Summary\n\n**Purpose**: The file `/home/eliezer/devs/xcore/xcore/kernel/events/hooks.py` is a Python module designed to manage event hooks within the XCore kernel. It provides a flexible and extensible framework for handling events, allowing developers to register functions that are triggered when specific events occur.\n\n**Key Components**:\n1. **HookManager Class**: This class manages all registered hooks for different event names. It includes methods to register, unregister, and emit events.\n2. **HookInfo Class**: This class encapsulates information about each hook, including the function, priority, and other metadata.\n3. **Event Class**: This class represents an emitted event with a name and optional data.\n\n**Dependencies**:\n- The file imports several internal modules (`__future__`, `asyncio`, `fnmatch`, `inspect`, `logging`, `time`) and external libraries (`typing`).\n- It relies on the `xcore.events.section.Event` class for handling events.\n\n**Interactions**:\n1. **Registration**: Functions can be registered using the `register` method, which takes an event name, a function, and optional parameters like priority, once flag, and timeout.\n2. **Emission**: Events are emitted using the `emit` method, which triggers all matching hooks for the specified event name. Hooks are executed asynchronously if they are asynchronous functions.\n3. **Metrics Collection**: The module collects metrics such as total emissions, hooks executed, errors, and execution time to provide insights into the system's performance.\n\nThis file serves as a central hub for managing event handling in the XCore kernel, ensuring that events are processed efficiently and reliably.", - "/home/eliezer/devs/xcore/xcore/kernel/events/hooks.py:03fa621ec4a99e9020c872715b89e61d17186370ec0a62da12f9a5d46161a934": "### Technical Summary: Events Hooks Module\n\n#### Purpose\nThe `events/hooks.py` file is responsible for managing event hooks in the XCore kernel. It provides functionalities to track and manage hooks executed during events, calculate metrics, list all hooks, and clear the bus or specific events.\n\n#### Key Components\n1. **Event Hook Tracking**:\n - `_hooks`: A dictionary that stores hooks associated with different event names.\n - Each hook is an instance of a class implementing `Hook` interface, which includes methods like `func`, `priority`, and `once`.\n\n2. **Metrics Calculation**:\n - `_metrics`: A dictionary to store metrics for each event, including total time taken and number of hooks executed.\n\n3. **Event Listing**:\n - `_pre_interceptors`, `_post_interceptors`, `_result_processors`: Dictionaries that store interceptors, post-processors, and result processors respectively.\n - Each interceptor, post-processor, or result processor is an instance of a class implementing `Interceptor` interface.\n\n4. **Clearing the Bus**:\n - The `clear` method allows clearing the bus or a specific event by removing hooks from the respective dictionaries.\n\n#### Dependencies\n- Internal modules: None.\n- External libraries: `fnmatch`.\n\n#### Interactions\n- This file interacts with other parts of the codebase through methods like `get_metrics`, `list_hooks`, and `clear`.\n- It calls into the `_hooks` dictionary to execute hooks, processes metrics, and manages interceptors, post-processors, and result processors.", - "/home/eliezer/devs/xcore/xcore/kernel/events/bus.py:b02f400a46045f2d08929f9f207c11fa6ff481afc40a137cfbd3e6be2f6b5271": "### Technical Summary\n\n**Purpose**: The `bus.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/events/` directory consolidates event handling for both application and compatibility with HookManager v1. It provides an asynchronous event bus with priorities and one-shot handlers, removing duplicates from the original integration/core/events.py and hooks/hooks.py files.\n\n**Key Components**:\n- **EventBus Class**: Manages subscriptions and emissions of events.\n - `on(event_name: str, priority: int = 50, name: str | None = None)`: Decorator for subscribing to an event with optional priority and name.\n - `once(event_name: str, priority: int = 50)`: Decorator for subscribing to a one-shot event.\n - `subscribe(event_name: str, handler: Callable, priority: int = 50, once: bool = False, name: str | None = None)`: Manually subscribes an event with various options.\n - `unsubscribe(event_name: str, handler: Callable)`: Unsubscribes a specific handler from an event.\n\n- **Emission Functions**:\n - `emit(event_name: str, data: dict[str, Any] | None = None, source: str | None = None, gather: bool = True)`: Issues an event with optional data, source, and gathering of results.\n - `emit_sync(event_name: str, data: dict[str, Any] | None = None)`: Fire-and-forget synchronous emit.\n\n- **Introspection Functions**:\n - `list_events()`: Returns a dictionary of all events and their handlers.\n - `handler_count(event_name: str)`: Returns the number of handlers for an event.\n - `clear(event_name: str | None = None)`: Clears the bus or a specific event.\n\n**Dependencies**: The file imports from internal modules (`__future__`, `asyncio`, `contextlib`, `fnmatch`, `inspect`, `logging`, `re`) and external libraries (not explicitly listed).\n\n**Interactions**:\n- The EventBus class interacts with other parts of the codebase through methods like `emit` and `subscribe`.\n- Handlers are called asynchronously when an event is emitted, respecting priorities.\n- The EventBus can be cleared or filtered to manage events effectively.", - "/home/eliezer/devs/xcore/xcore/kernel/events/section.py:f59570a29ece66430fc0dcbcbcda6b5a78b04e76a3985423a6795eef576edf13": "### Technical Summary\n\n#### Purpose\nThe `section.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/events/` directory is responsible for managing and dispatching events within the XCore kernel. It provides a structured way to handle various types of events, including their propagation, cancellation, and metadata.\n\n#### Key Components\n1. **Event Class (`Event`)**:\n - Represents an event with attributes such as `name`, `payload`, `source`, `data`, `propagate`, `cancelled`.\n - Methods like `stop()` and `cancel()` allow for controlling the event's lifecycle.\n - The `metadata` attribute is a legacy feature that can be used to store additional information about the event.\n\n2. **Handler Entry Class (`_HandlerEntry`)**:\n - Stores details about each handler function, including the handler itself, whether it's asynchronous, priority, once execution flag, and name/pattern.\n - This class helps in organizing and managing event handlers efficiently.\n\n3. **Hook Result Class (`HookResult`)**:\n - Represents the outcome of a hook operation, including the hook name, event name, result, error, execution time, cancellation status, and skipping status.\n - The `success` property checks if the hook was successful based on the presence of an error and absence of cancellation or skipping.\n\n4. **Hook Info Class (`HookInfo`)**:\n - Stores information about each hook function, including the function itself, whether it's asynchronous, priority, once execution flag, timeout, and creation time.\n - This class is used to manage and organize hooks in a structured manner.\n\n#### Dependencies\n- The file imports `dataclasses`, `enum`, and `typing` from Python's standard library.\n- It relies on the `__future__` module for annotations.\n\n#### Interactions\n- The file interacts with other parts of the XCore kernel through methods like `stop()` and `cancel()` in the `Event` class, which are used to control event lifecycle.\n- Hooks are managed using the `_HandlerEntry` class, which is called by the `HookInfo` class to execute hooks based on their priority and conditions.\n\nThis file serves as a central hub for managing events within the XCore kernel, ensuring that all events are handled correctly and efficiently.", - "/home/eliezer/devs/xcore/xcore/kernel/observability/__init__.py:bbb8460f002efc66f907d33a25de59d2700ffaf60ae1a1ecddbd019a8ca469f9": "### Technical Summary: Observability Module in XCore Kernel\n\n#### Purpose\nThe `observability` module in the XCore kernel is responsible for providing a comprehensive set of tools and utilities to monitor, log, and analyze system performance. It includes functionalities such as health checks, logging configuration, metric collection, tracing, and span management.\n\n#### Key Components\n- **HealthChecker**: A class that periodically checks the overall health status of the system.\n- **HealthStatus**: An enumeration representing different health states (e.g., healthy, warning, critical).\n- **configure_logging**: A function to configure the logging framework used by the XCore kernel.\n- **get_logger**: A function to retrieve a logger instance for specific modules or components.\n- **MetricsRegistry**: A class that manages and stores metrics collected from various sources.\n- **Counter**: A metric type used to track counts of events.\n- **Gauge**: A metric type used to track instantaneous values.\n- **Histogram**: A metric type used to track distributions of data.\n- **Tracer**: A class for tracing the execution flow of functions.\n- **Span**: A class representing a single operation within a trace.\n- **noop_tracer**: A simple tracer that does nothing, useful for testing or development environments.\n\n#### Dependencies\nThe `observability` module imports several internal modules and external libraries:\n- `health`: Contains the `HealthChecker` and `HealthStatus` classes.\n- `logging`: Provides logging functionality.\n- `metrics`: Manages metric collections.\n- `tracing`: Includes the `Tracer`, `Span`, and `noop_tracer` classes.\n\n#### Interactions\nThe `observability` module interacts with other parts of the XCore kernel through various functions:\n- It is called by the main application to initialize logging and metrics collection.\n- It provides utilities for tracing function execution, which can be used in unit tests or debugging scenarios.\n- The module is imported by other modules that need to monitor system performance or interact with external services.\n\nThis module forms a critical component of the XCore kernel's observability framework, enabling comprehensive monitoring and diagnostics of the system.", - "/home/eliezer/devs/xcore/xcore/kernel/observability/logging.py:e76d50c261fd6514e9490b045a94732019e2e1c0e6d45bb7211eddb0bec93525": "### Technical Summary\n\n**Purpose**: This file configures and manages the logging system for the Xcore project. It sets up basic console output and a rotating log file, which can be configured through the `LoggingConfig` class.\n\n**Key Components**:\n- **configure_logging(cfg: \"LoggingConfig\")**: Configures the logging level, formatter, and handlers based on the provided configuration.\n - **level**: Sets the logging level to the specified value (e.g., INFO).\n - **root**: Sets the root logger's level to the configured level.\n - **handler**: Adds a console handler that outputs logs to the console with the specified format.\n - **fh**: Adds a rotating file handler that writes logs to a file, with maximum size and backup count controlled by the configuration.\n\n- **get_logger(name: str) -> logging.Logger**: Returns a logger for the specified module. If the module name does not start with \"xcore\", it prepends \"xcore.\" to the module name.\n - **name**: The name of the module for which the logger is created.\n\n**Dependencies**:\n- `logging`: The standard Python library for logging.\n- `logging.handlers`: Handlers for different types of log output (console, file).\n- `pathlib.Path`: For handling file paths.\n- `typing`: For type hints and annotations.\n\n**Interactions**:\n- This file interacts with the rest of the codebase through the `LoggingConfig` class to configure logging settings. It also calls the `get_logger` function to obtain loggers for different parts of the system, which are then used throughout the application to log messages.", - "/home/eliezer/devs/xcore/xcore/kernel/observability/metrics.py:a3d618d805c9c16b1b36640f6fc9dfd24817e738ad8e3a383f61d7e9710d1dbe": "### Technical Summary\n\n**Purpose**: This file provides a lightweight metrics registry that can be used to track and report various performance metrics within a software system. It supports both simple counters and gauges, as well as histograms to measure distributions of values.\n\n**Key Components**:\n- **Counter**: A class representing a counter metric, which increments by a specified amount each time it is called.\n- **Gauge**: A class representing a gauge metric, which can be set to any value and read at any time.\n- **Histogram**: A class representing a histogram metric, which tracks the distribution of values across a predefined set of buckets.\n\n**Dependencies**:\n- The file imports no external libraries beyond Python's standard library.\n\n**Interactions**:\n- The `MetricsRegistry` class is designed to be used by other parts of the system to register and manage metrics. It provides methods to create counters, gauges, and histograms, as well as a method to snapshot the current state of the registry.\n- Each metric type (counter, gauge, histogram) has its own set of methods for interacting with it, such as `inc`, `set`, `observe`, and `value`.\n- The `snapshot` method allows other parts of the system to retrieve a comprehensive view of all metrics currently registered in the registry.", - "/home/eliezer/devs/xcore/xcore/kernel/observability/tracing.py:1e85a458a132b1dfbd9b199e28bf76aa13e9e5595d0e687b9530eae52c3bd3a2": "### Technical Summary: Tracing Module\n\n#### Purpose\nThe `tracing.py` file provides an interface for tracing within the XCore system. It includes classes and functions to manage spans, create spans with attributes, and export spans as JSON.\n\n#### Key Components\n1. **Span Class**:\n - Represents a single trace span.\n - Attributes: Stores key-value pairs that can be attached to each span.\n - Status: Indicates the status of the span (e.g., \"ok\", \"error\").\n - Methods: `set_attribute`, `set_status`, `end`, and `duration_ms`.\n\n2. **Tracer Class**:\n - Manages a list of spans.\n - Provides a context manager to create spans with attributes.\n - Exports the list of spans as JSON.\n\n3. **noop_tracer Function**:\n - Returns a noop tracer that does not perform any tracing operations.\n\n#### Dependencies\n- `uuid` for generating unique identifiers.\n- `time` for measuring durations.\n- `dataclasses` for defining data classes.\n- `typing` for type hints.\n\n#### Interactions\n- The `Tracer` class is used to create spans and manage a list of spans.\n- Spans are created within a context manager, which ensures that they are properly ended when the block exits.\n- The `noop_tracer` function provides a simple way to disable tracing without modifying the core logic.\n\nThis module is essential for monitoring and debugging the XCore system by providing a structured way to track the flow of operations.", - "/home/eliezer/devs/xcore/xcore/kernel/observability/health.py:2e7d86f0a42bbed7bd25a17681625d586988302d30a03c4c78d427c24044097c": "### Technical Summary\n\n**Purpose**: This file is designed to manage health checks within the XCore kernel. It provides a robust system for monitoring and reporting the status of various components in the system.\n\n**Key Components**:\n1. **HealthStatus Enum**: Defines three possible health statuses: `HEALTHY`, `DEGRADED`, and `UNHEALTHY`.\n2. **CheckResult Class**: Represents the result of a single health check, including details such as name, status, message, duration in milliseconds, and additional details.\n3. **HealthChecker Class**:\n - Registers functions to be called when an event is emitted.\n - Executes all registered checks asynchronously within a specified timeout period.\n - Reports the overall health status of the system based on the results of the checks.\n\n**Dependencies**:\n- `asyncio`: For asynchronous operations and timeouts.\n- `inspect`: To introspect function metadata.\n- `time`: For measuring execution time.\n- `dataclasses`: For defining data classes with default values.\n- `enum`: For defining enumerations for health statuses.\n- `typing`: For type annotations.\n\n**Interactions**:\n- The `HealthChecker` class is initialized and used to register functions that need to be checked. These functions are executed asynchronously, and their results are collected in a list of `CheckResult` objects.\n- The `run_all` method runs all registered checks within the specified timeout period and aggregates the results into an overall health status report.\n\nThis file plays a crucial role in ensuring the robustness and reliability of the XCore kernel by providing a centralized mechanism for monitoring and reporting the health of its components.", - "/home/eliezer/devs/xcore/xcore/kernel/permissions/__init__.py:5a61a16db18eb37e60ecc098a3e3a1f8b67a7faef51dd0bb1331376bfe1ca63f": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/permissions/__init__.py`\n\n#### Purpose\nThis file serves as the entry point for permission management in the XCore kernel. It provides a centralized location to define and manage permissions, policies, and validators used throughout the system.\n\n#### Key Components\n1. **PermissionEngine**: Manages the execution of permission checks based on defined rules.\n2. **Policy**: Represents a set of conditions that determine whether an action is allowed or denied.\n3. **PolicyEffect**: Specifies the outcome of a policy (e.g., allow, deny).\n4. **PolicySet**: A collection of policies that can be applied to different contexts.\n\n#### Dependencies\n- Internal modules: `engine`, `policies`, `validator`\n- External libraries: None\n\n#### Interactions\n- The `PermissionEngine` is called by other parts of the system to perform permission checks.\n- It interacts with the `Policy` and `PolicySet` classes to determine if an action is allowed or denied based on the defined policies.\n- The `PermissionValidator` class is used to validate permissions before they are applied.", - "/home/eliezer/devs/xcore/xcore/kernel/permissions/engine.py:9d90592f4caf5230212a0902c47db87d07d34a20998cb6001dcad3d620b3d3d4": "### Technical Summary: Permission Evaluation Engine\n\n#### Purpose\nThe `PermissionEngine` is a central component responsible for evaluating permissions across different plugins. It loads policy sets from manifests at startup and responds to authorization requests on every plugin call. The engine emits audit events (allow/deny) to track permission decisions.\n\n#### Key Components\n- **PolicySet**: Represents a collection of policies for a specific plugin.\n- **PermissionDenied**: An exception raised when a permission check fails.\n- **PermissionEngine**:\n - Initializes with an optional event emitter and a maximum audit log length.\n - Loads policy sets from manifests.\n - Grants all permissions to a plugin.\n - Checks permissions and raises `PermissionDenied` if not allowed.\n - Allows plugins to verify their permissions without raising exceptions.\n - Logs permission evaluations and can retrieve the audit log.\n\n#### Dependencies\n- **PolicySet**: An internal module for managing policy sets.\n- **logging**: For logging permission evaluation events.\n- **collections.deque**: For efficient handling of audit logs.\n\n#### Interactions\n- The `PermissionEngine` interacts with plugins through calls to `check`, `allows`, and `audit_log`.\n- It uses a cache to store evaluated policies for faster lookups.\n- Events are emitted to notify other parts of the system about permission decisions.", - "/home/eliezer/devs/xcore/xcore/kernel/permissions/schema.json:033a6457a2b082b5b9a11273efcbf10490ac3cd3801c19ed95737ca16a8518df": "### Technical Summary: xcore Plugin Permissions Schema\n\n#### Purpose\nThis file defines a JSON schema for plugin permissions, which is used in the `plugin.yaml` configuration file. It specifies rules for accessing resources within the xcore system.\n\n#### Key Components\n- **Resource**: A glob pattern that matches the resource to be accessed.\n - Example: `\"db.*\"` (matches any database resource)\n - Example: `\"cache.get\"` (matches a specific cache operation)\n\n- **Actions**: A list of verbs allowed for accessing the resource.\n - Example: `[\"read\", \"write\"]` (allows read and write operations)\n - Example: `[\"*\"]` (allows all actions)\n\n- **Effect**: The default effect of the rule, which determines whether it allows or denies access.\n - Example: `\"allow\"` (first match wins)\n - Example: `\"deny\"` (no match means deny)\n\n#### Dependencies\nThis file imports no external libraries.\n\n#### Interactions\nThe schema is used to validate and enforce permissions in the xcore system. It ensures that plugin configurations adhere to predefined rules, preventing unauthorized access to sensitive data or resources.", - "/home/eliezer/devs/xcore/xcore/kernel/permissions/validator.py:44c27116c7ae73aebfbc3488472eb101a88e23ebe513ea2dd4b9504027629eac": "### Technical Summary\n\n**Purpose**: This file validates the `permissions:` block in a manifest plugin. It ensures that the permissions are correctly defined and adhere to predefined rules.\n\n**Key Components**:\n- **PermissionValidationError**: A custom exception raised when a permission is invalid.\n- **VALID_EFFECTS**: A set of allowed effects for permissions, such as \"allow\" or \"deny\".\n- **REQUIRED_KEYS**: A set of required keys in the `permissions` block, such as \"resource\".\n\n**Dependencies**:\n- None\n\n**Interactions**:\n- The file imports no external libraries.\n- It calls into other modules within the same package.\n- Data is produced by the `PermissionValidator` class and consumed by the rest of the codebase.", - "/home/eliezer/devs/xcore/xcore/kernel/permissions/policies.py:a3c781d1fa8e1f73c6212bdce8e577c2fca6a86e0f7f35c57d95993e6dc6a398": "### Technical Summary: Plugin Access Policy Template\n\n#### Purpose\nThe `permissions` file in the `/home/eliezer/devs/xcore/xcore/kernel/permissions/policies.py` file is designed to manage access policies for plugins within a software system. Each plugin declares a `permissions` block in its manifest, specifying which resources and actions are allowed or denied.\n\n#### Key Components\n- **Policy Class (`Policy`)**:\n - Represents a single policy rule.\n - Attributes: `resource`, `actions`, and `effect`.\n - Methods: `matches(resource, action)` to check if the rule matches a given resource and action.\n - Pre-calculated fields for performance optimization.\n\n- **Policy Set Class (`PolicySet`)**:\n - Manages a collection of policies for a specific plugin.\n - Attributes: `plugin_name` and `policies`.\n - Methods: `evaluate(resource, action)`, `allows(resource, action)`, `to_list()`, and `__repr__()`.\n - Allows for easy evaluation of access rules based on resource and action.\n\n#### Dependencies\n- **fnmatch**: For pattern matching.\n- **re**: For regular expression compilation.\n\n#### Interactions\n- The file imports the necessary modules at the top.\n- It defines a class structure to represent policies and policy sets, ensuring efficient handling of permissions.\n- The `PolicySet` class provides methods for evaluating access rules based on resource and action, adhering to the fail-closed principle.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/ipc.py:599e5dc9eb7279f8642b84d4cd00f17aa9082a6b97b0fdecbf707a344febe6c0": "### Technical Summary: IPC Channel in xcore Kernel\n\n#### Purpose\nThe `ipc.py` file in the xcore kernel is responsible for facilitating inter-process communication (IPC) between the core and a subprocess sandboxed within the same process. It ensures thread safety through an asyncio lock to prevent concurrent access to shared resources.\n\n#### Key Components\n1. **IPCError**: A base exception class for IPC-related errors.\n2. **IPCTimeoutError**: An exception raised when the subprocess does not respond within the specified timeout.\n3. **IPCProcessDead**: An exception raised when the subprocess has died unexpectedly.\n4. **IPCResponse**: A dataclass representing the response from the subprocess, including success status and raw output.\n\n#### Dependencies\n- `asyncio`: For asynchronous I/O operations.\n- `json`: For handling JSON data.\n- `logging`: For logging IPC-related events.\n- `dataclasses`: For defining data classes.\n\n#### Interactions\n- The `IPCChannel` class manages the communication with the subprocess. It uses an asyncio lock to ensure that only one request can be processed at a time, preventing race conditions.\n- The `call` method sends a JSON-formatted action and payload to the subprocess and waits for a response. If the subprocess does not respond within the specified timeout, it raises an `IPCTimeoutError`.\n- The `_send_recv` method handles the actual communication with the subprocess by writing the request to stdin and reading the response from stdout.\n- The `_is_dead` method checks if the subprocess has died unexpectedly.\n- The `close` method ensures that all resources are properly closed, including closing the stdin pipe.\n\nThis file plays a crucial role in maintaining the integrity of the sandboxed environment within the xcore kernel.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/isolation.py:637c3a1a30907c71eaedd47d928c888ae929093425b45f6dc5426001afa06f8b": "### Technical Summary: Isolation of Disk and Memory Resources for Subprocesses\n\n#### Purpose\nThis file is designed to manage disk and memory quotas for sandboxed subprocesses in the XCore system. It ensures that each plugin sandboxed does not exceed a predefined quota, preventing resource exhaustion and potential security issues.\n\n#### Key Components\n1. **DiskQuotaExceeded**: An exception raised when the disk usage of a plugin exceeds its allocated quota.\n2. **DiskWatcher**: A class responsible for monitoring the disk usage of a plugin sandboxed. It calculates the current size in bytes and checks if it exceeds the maximum allowed size.\n3. **MemoryLimiter**: A static method that applies the `RLIMIT_AS` limit to a subprocess, ensuring that it does not exceed the specified memory quota.\n\n#### Dependencies\n- The file imports `logging` for logging purposes and `pathlib.Path` for handling file paths.\n- It relies on internal modules like `sys` and `resource`.\n\n#### Interactions\n- **DiskWatcher**: This class is called by the sandboxed subprocess to check its disk usage. If the quota is exceeded, it raises a `DiskQuotaExceeded` exception.\n- **MemoryLimiter**: This method is called within the sandboxed subprocess to apply the `RLIMIT_AS` limit. It sets the resource limit to the specified maximum memory quota.\n\nThis file plays a crucial role in maintaining the integrity and performance of sandboxed processes, ensuring that they do not consume excessive resources.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/process_manager.py:795cf3b46803e6393d0d9c4513bc07b13e8503df79d2677ffe5e7bbb38f225d7": "### Technical Summary\n\n**Purpose**: The `process_manager.py` file is responsible for managing the lifecycle of a subprocess plugin within an XCore system. It ensures that the plugin runs smoothly by handling restarts, monitoring its health, and ensuring it does not exceed predefined resource limits.\n\n**Key Components**:\n- **SandboxConfig**: A class to define configuration parameters such as timeout, maximum restarts, and restart delay.\n- **ProcessState**: An enumeration to represent different states of the process (stopped, starting, running, restarting, failed).\n- **SandboxProcessManager**: The main class that encapsulates the logic for managing the subprocess. It initializes the process, handles startup checks, manages health monitoring, and provides methods to interact with the plugin.\n\n**Dependencies**:\n- `asyncio`: For asynchronous I/O operations.\n- `contextlib`: For context management.\n- `logging`: For logging messages.\n- `os`: For interacting with the operating system.\n- `sys`: For accessing system-specific parameters.\n- `time`: For time-related functions.\n- `dataclasses`: For defining data classes.\n- `enum`: For defining enumerations.\n- `pathlib`: For handling file paths.\n- `xcore.ipc`: For inter-process communication (IPC).\n- `xcore.isolation`: For managing disk quotas and watchers.\n\n**Interactions**:\n- The `start()` method initializes the subprocess, performs a ping check, and starts monitoring the process.\n- The `call(action, payload)` method allows calling methods on the plugin through IPC.\n- The `_watch_loop()` method continuously monitors the process for health issues and restarts it if necessary.\n- The `_health_loop(interval, timeout)` method periodically checks the plugin's health and handles failures gracefully.\n\nThis file is crucial for maintaining the stability and reliability of the XCore system by ensuring that plugins run smoothly and efficiently.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/process_manager.py:c7cdc1bb73eed7f6b6065aac6585080cb81d114f66ba79afab784ddd462c82bc": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/sandbox/process_manager.py`\n\n#### Purpose:\nThis file is responsible for managing the lifecycle of a sandboxed process within the XCore kernel. It handles spawning, running, and stopping the process, as well as monitoring its health.\n\n#### Key Components:\n1. **Process Management**:\n - `_ping_check()`: Checks if the process is still alive by sending a ping request.\n - `stop()`: Stops the process and cleans up resources.\n - `_kill()`: Terminates the process forcefully if it does not terminate within the specified timeout.\n\n2. **Health Monitoring**:\n - `_health_loop(hc.interval_seconds, hc.timeout_seconds)`: Runs a health check at regular intervals to ensure the process is still functioning properly.\n\n3. **Status Reporting**:\n - `status()`: Returns a dictionary containing information about the process's current state and status.\n\n#### Dependencies:\n- Internal modules: `asyncio`, `time`, `logging`\n- External libraries: None\n\n#### Interactions:\n- The file interacts with other parts of the codebase through methods like `_ping_check()`, `stop()`, and `status()`.\n- It depends on the `manifest` object for configuration details.\n- It uses the `channel` object to communicate with other components of the system.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/limits.py:6537955cf91044c8216726417cf7e58ca9b30ab18f090ed18fdca4441ef7fd63": "### Technical Summary for `limits.py`\n\n#### Purpose\nThe file `/home/eliezer/devs/xcore/xcore/kernel/sandbox/limits.py` is a rate limiting plugin designed to manage the number of calls made by plugins within a specified time frame. It ensures that each plugin does not exceed its allocated quota, preventing abuse and maintaining system stability.\n\n#### Key Components\n1. **RateLimitExceeded**: An exception raised when the quota for a plugin is exceeded.\n2. **RateLimitConfig**: A dataclass containing configuration parameters such as the maximum number of calls (`calls`) and the period in seconds (`period_seconds`).\n3. **RateLimiter**: A class responsible for checking the rate limit of a specific plugin. It uses a deque to keep track of timestamps and ensures that no more than `calls` are made within the specified `period_seconds`.\n4. **RateLimiterRegistry**: A class managing multiple rate limiters, allowing plugins to register their configurations and check their limits.\n\n#### Dependencies\n- The file imports `time`, `collections`, and `dataclasses`.\n\n#### Interactions\n- The `check` method in `RateLimiter` synchronizes all operations by checking the timestamps in a deque. It raises a `RateLimitExceeded` if the quota is exceeded.\n- The `stats` method provides statistics about the current state of the rate limit, including the number of calls within the last period and the remaining quota.\n\nThis plugin ensures that each plugin operates within its allocated limits, preventing any potential issues related to excessive load on the system.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/worker.py:d4bd0ae7d046ff078ef73383a76f008593e0a93ea4281f33e3e7d779e36adbce": "### Technical Summary\n\n**Purpose**: The `worker.py` file is a subprocess sandboxed designed to isolate and secure the execution of plugins. It reads JSON commands from stdin, processes them, and writes responses to stdout. The file applies memory limits and filesystem policies to restrict access to sensitive resources.\n\n**Key Components**:\n- **Memory Limiting**: The `_apply_memory_limit` function sets a maximum memory limit for the subprocess using `resource.setrlimit`.\n- **Filesystem Guard**: The `FilesystemGuard` class manages access to files within the sandbox. It intercepts calls to `builtins.open`, `io.open`, and `pathlib.Path.open` to enforce a whitelist of allowed paths and blacklist of denied paths.\n- **Security Hooks**: The `install` method sets up security hooks for various file operations, such as `os.open`, `ctypes.CDLL`, and `importlib.import_module`. These hooks log blocked attempts and prevent unauthorized access.\n\n**Dependencies**:\n- The file imports several modules including `asyncio`, `builtins`, `contextlib`, `importlib.machinery`, `importlib.util`, `json`, `logging`, `os`, `sys`, `dataclasses`, and `pathlib`.\n\n**Interactions**:\n- The `worker.py` subprocess communicates with the main process through stdin and stdout.\n- It reads JSON commands from stdin, processes them, and writes responses to stdout.\n- The sandbox applies memory limits and filesystem policies to restrict access to sensitive resources.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/worker.py:2665b606f7c936764b37f2c00f1239f46d90f345b62e5fb3dbf4cc6f3dff92bb": "### Purpose\n\nThe `worker.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/sandbox/worker.py` directory is designed to provide a sandboxed environment for running code within a Python application. This file includes various functionalities such as file operations, dynamic imports, and ctypes manipulation to ensure that only allowed modules are imported and executed.\n\n### Key Components\n\n1. **File Operations**:\n - `_guarded_op`: A decorator that wraps the `open`, `remove`, `unlink`, `rmdir`, `mkdir`, `makedirs`, `rename`, `replace`, `listdir`, `scandir`, `stat`, `lstat`, `chmod` functions to prevent unauthorized file operations.\n - `_GuardedFileIO`: A custom implementation of the `io.FileIO` class that checks if the operation is allowed based on the current guard state.\n\n2. **Dynamic Imports**:\n - `_guarded_import`: A function that wraps the `__import__` function to block imports from forbidden modules and log any attempts.\n - `_blocked_exec`, `_blocked_eval`, `_blocked_compile`: Functions that wrap the `exec`, `eval`, and `compile` functions, respectively, to prevent code execution.\n\n3. **Importlib Post-Loading**:\n - `_guarded_import_module`, `_guarded_spec_from_file`, `_guarded_find_spec`: Functions that wrap the `importlib.import_module`, `spec_from_file_location`, and `find_spec` functions to block imports from forbidden modules and log any attempts.\n - `_blocked_ctypes_api`: A decorator that wraps the ctypes API calls to prevent unauthorized access.\n\n4. **ctypes Blockage**:\n - The file includes a section that blocks all ctypes API calls, effectively preventing the use of native libraries outside the sandbox.\n\n### Dependencies\n\n- `builtins`\n- `io`\n- `os`\n- `sys`\n\n### Interactions\n\n1. **File Operations**:\n - The `_guarded_op` decorator ensures that only allowed file operations are performed.\n - The `_GuardedFileIO` class provides a secure way to handle file I/O within the sandbox.\n\n2. **Dynamic Imports**:\n - The `_guarded_import` function prevents unauthorized imports from forbidden modules.\n - The `_blocked_exec`, `_blocked_eval`, and `_blocked_compile` functions prevent code execution.\n\n3. **Importlib Post-Loading**:\n - The `_guarded_import_module`, `_guarded_spec_from_file`, and `_guarded_find_spec` functions ensure that only allowed modules are imported.\n - The `_blocked_ctypes_api` decorator prevents unauthorized access to the ctypes API calls.\n\n4. **ctypes Blockage**:\n - The file includes a section that blocks all ctypes API calls, effectively preventing the use of native libraries outside the sandbox.\n\n### Notes\n\n- The `worker.py` file is designed to be used in a sandboxed environment where only certain modules and functionalities are allowed.\n- The `uninstall` method restores the original builtins after usage, allowing for testing purposes.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/worker.py:54955dd5db81d5af00ec06dd2b1d414e6b17a9944731ac999675cfd725d7035a": "### Technical Summary\n\n#### Purpose\nThe `worker.py` file in the `/home/eliezer/devs/xcore/xcore/kernel/sandbox/` directory is responsible for managing and loading plugins within a sandbox environment. It ensures that each plugin has a unique namespace to avoid conflicts and provides a clean separation of concerns.\n\n#### Key Components\n- **Plugin Import Hook**: Manages the import process by registering itself in `sys.meta_path`. This hook translates module names from the format `xcore_plugin_.` to their corresponding files within the source directory.\n- **Package Resolution**: The `_spec_for` method resolves the relative path of a module or package within the source directory. It checks for both `.py` and `__init__.py` files to determine the correct module location.\n- **Module Loading**: The `load_module` method loads the plugin module, ensuring that it is isolated from the global namespace. It uses the `_PluginImportHook` to manage the import process.\n- **Installation/Uninstallation**: The `install` and `uninstall` methods handle the registration and removal of the hook from `sys.meta_path`, respectively.\n\n#### Dependencies\nThe file imports several internal modules and external libraries:\n- `importlib`\n- `hashlib`\n- `os.path`\n- `logging`\n\n#### Interactions\n- **Cycle of Life**: The plugin is installed by adding the hook to `sys.meta_path` and then loading it. It ensures that all modules within the plugin are isolated and do not interfere with each other.\n- **Entry Point Resolution**: The entry point for the plugin is resolved from the manifest file, which contains details about the plugin's entry point and source directory.\n\nThis setup helps in maintaining a clean and modular environment for plugins, ensuring that they can be easily managed and updated without affecting the rest of the system.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/worker.py:d72bccb124740217bc9921de0d355a99d989c482b8ff8862b3b47bab07f5d7b5": "### Technical Summary\n\n#### 1. Purpose\nThe `worker.py` file is a critical component of the XCore kernel, responsible for managing and executing plugins in a sandboxed environment. It reads plugin manifests, installs filesystem guards to enforce access policies, loads plugins into isolated namespaces, and handles communication with the main process through an IPC protocol.\n\n#### 2. Key Components\n- **_load_manifest(plugin_dir: Path) -> _PluginManifest**: Parses plugin YAML or JSON files and returns a `_PluginManifest` object containing entry points and filesystem policies.\n- **_extracted_from__load_manifest_20(fname, manifest_path, manifest)**: Extracts data from the parsed manifest file and populates the `_PluginManifest` object.\n- **_send(transport, data: dict) -> None**: Sends JSON-formatted messages over a transport channel.\n- **_run(plugin_dir: Path) -> None**: Loads plugins, installs filesystem guards, handles IPC communication, and manages plugin lifecycle events.\n\n#### 3. Dependencies\n- The file imports `json` for parsing JSON files and `logging` for logging messages.\n- It relies on the `asyncio` library for asynchronous I/O operations.\n- It uses the `pathlib.Path` class to handle file paths.\n\n#### 4. Interactions\n- **Plugin Loading**: Reads plugin manifests, installs filesystem guards, and loads plugins into isolated namespaces.\n- **IPC Communication**: Handles communication with the main process through an IPC protocol using JSON messages.\n- **Error Handling**: Logs errors related to filesystem policies and JSON parsing, providing feedback without crashing the worker.\n\nThis file is a critical part of the XCore kernel, ensuring that plugins are executed securely within a sandboxed environment.", - "/home/eliezer/devs/xcore/xcore/kernel/sandbox/__init__.py:dc46ae19d86ebda2737a8105270ad590b4e732d97a28c81189fa31044553537a": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/sandbox/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for the sandbox module in the XCore kernel. It contains the main classes and functions responsible for managing processes within a sandbox environment, including IPC communication, isolation mechanisms, rate limiting, and disk quota checks.\n\n#### Key Components:\n1. **IPCChannel**: Manages inter-process communication channels between different components of the sandbox.\n2. **IPCResponse**: Represents the response received from an IPC channel.\n3. **IPCTimeoutError**: Exception raised when a timeout occurs during IPC operations.\n4. **IPCProcessDead**: Exception raised when a process in the sandbox is terminated unexpectedly.\n5. **IPCError**: Base class for all IPC-related errors.\n6. **DiskQuotaExceeded**: Exception raised when disk quota limits are exceeded.\n7. **DiskWatcher**: Watches disk usage and triggers actions when quotas are reached.\n8. **MemoryLimiter**: Limits the memory usage of processes in the sandbox.\n9. **RateLimiter**: Manages rate limiting for different operations within the sandbox.\n10. **RateLimiterRegistry**: Registry to manage multiple rate limiters.\n11. **RateLimitExceeded**: Exception raised when a rate limit is exceeded.\n12. **SandboxConfig**: Configuration class for the sandbox environment.\n13. **SandboxProcessManager**: Manages the lifecycle of processes within the sandbox.\n\n#### Dependencies:\n- Internal modules: `ipc`, `isolation`, `limits`, `process_manager`\n- External libraries: None\n\n#### Interactions:\n- The `__init__.py` file imports and exports several classes and functions from other modules within the sandbox package.\n- It defines a list of all exported components, which can be used by other parts of the system to interact with the sandbox functionalities.", - "/home/eliezer/devs/xcore/xcore/kernel/security/hashing.py:17bc4379c042bd8fe84d938dce8eb32cc3d1e83f60d05d59323397bd9dfb38b1": "### Technical Summary\n\n**Purpose**: This file provides cryptographic utilities for hashing and signing data in the XCore kernel. It includes functions to hash files, directories, and generate HMAC-SHA256 signatures.\n\n**Key Components**:\n- **__should_ignore(path: Path, root: Path)**: Determines if a file or directory should be ignored based on predefined criteria.\n- **hash_file(path: Path, algorithm: str = \"sha256\")**: Computes the hash of a single file using the specified algorithm (default is SHA256).\n- **hash_dir(directory: Path, algorithm: str = \"sha256\")**: Generates a deterministic hash for all files in a directory, preserving the order of files.\n- **hmac_sign(data: bytes, secret: bytes) -> str**: Computes an HMAC-SHA256 signature on raw data using a given secret key.\n- **hmac_verify(data: bytes, secret: bytes, digest: str) -> bool**: Verifies the integrity of an HMAC-SHA256 signature against expected values.\n\n**Dependencies**:\n- `fnmatch`: For pattern matching.\n- `hashlib`: For hashing functions.\n- `hmac`: For generating HMAC-SHA256 signatures.\n- `pathlib`: For handling file paths and directory traversal.\n\n**Interactions**:\n- The file is called by higher-level modules in the XCore kernel to perform cryptographic operations such as hashing files, directories, and signing data. It interacts with other parts of the system through these functions.", - "/home/eliezer/devs/xcore/xcore/kernel/security/__init__.py:7073406c29b19aed134d2113ebc3eddbd1a71788404c1d8ee8caa50f9b73e058": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/security/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for security-related functionalities within the XCore kernel. It provides a set of tools and utilities to manage, verify, and hash files and directories.\n\n#### Key Components:\n- **hashing**: Functions for hashing files and directories.\n - `hash_file`: Computes the SHA-256 hash of a single file.\n - `hash_dir`: Computes the SHA-256 hash of an entire directory.\n- **section**: Class to represent scan results from security checks.\n - `ScanResult`: Holds information about the security status of a section or file.\n- **signature**: Functions for managing and verifying plugins.\n - `SignatureError`: Exception raised when a plugin signature is invalid.\n - `is_signed`: Checks if a plugin is signed.\n - `sign_plugin`: Signs a plugin using a private key.\n - `verify_plugin`: Verifies the signature of a plugin using a public key.\n- **validation**: Classes for validating plugins and manifests.\n - `ASTScanner`: Scans an AST (Abstract Syntax Tree) to identify security vulnerabilities.\n - `ManifestValidator`: Validates a manifest file against predefined rules.\n\n#### Dependencies:\nThis file imports or relies on internal modules such as `hashing`, `section`, `signature`, and `validation`. It also depends on external libraries like `pycryptodome` for cryptographic operations.\n\n#### Interactions:\n- **Called by**: The main entry point of the XCore kernel, where security-related functions are invoked.\n- **Calls into**: Other modules within the same package or external libraries as needed.\n- **Data produced or consumed**: The file provides hash values and scan results, which can be used for further analysis or validation.", - "/home/eliezer/devs/xcore/xcore/kernel/security/section.py:78aa13f7ce53b72568e0f61b648dc64d7b740eb9802a79735eaf6379e309054a": "### Technical Summary: Section.py\n\n#### Purpose\nThe `section.py` file is a critical component of the XCore kernel security module. It serves as a manifest for plugins, defining essential details such as name, version, execution mode, and dependencies. The file also includes functions to scan and validate imports, ensuring that only allowed modules are imported by plugins.\n\n#### Key Components\n- **ScanResult Class**: A dataclass used to store the results of scanning imports. It includes fields for whether the scan was passed, errors, warnings, and a list of scanned items.\n - `passed`: Boolean indicating if the scan was successful.\n - `errors`: List of error messages encountered during the scan.\n - `warnings`: List of warning messages.\n - `scanned`: List of imported modules that were successfully scanned.\n\n- **_SimpleManifest Class**: A class responsible for managing manifest data. It initializes with various attributes such as name, version, execution mode, author, description, and dependencies. The constructor also sets default values for resources and runtime settings.\n - `name`: The name of the plugin.\n - `version`: The version of the plugin.\n - `execution_mode`: The execution mode of the plugin.\n - `author`: The author of the plugin.\n - `description`: A brief description of the plugin.\n - `framework_version`: The required framework version for the plugin.\n - `entry_point`: The entry point file for the plugin.\n - `allowed_imports`: List of allowed imports by the plugin.\n - `env`: Environment variables for the plugin.\n - `requires`: List of dependencies, which can be either strings or instances of `PluginDependency`.\n - `plugin_dir`: Directory where the plugin is located.\n - `extra`: Additional configuration options.\n\n#### Dependencies\n- The file imports several internal modules and external libraries:\n - `dataclasses`\n - `xcore.sdk.plugin_base`\n\n#### Interactions\n- The `_SimpleManifest` class interacts with other parts of the codebase through methods like `add_error`, `add_warning`, and `__str__`.\n- The `ScanResult` class is used to track the results of scanning imports, which are then passed back to higher-level components for further processing.\n\nThis file plays a crucial role in ensuring that plugins are secure and adhere to the specified requirements, enhancing the overall security and reliability of the XCore kernel.", - "/home/eliezer/devs/xcore/xcore/kernel/security/signature.py:7d34a27b492ca4a2e976c0a4e938d8ff0b41743f1db1188bda94a714e6bd9e26": "### Technical Summary\n\n**Purpose**: This file, located at `/home/eliezer/devs/xcore/xcore/kernel/security/signature.py`, serves as a critical component of the XCore kernel's security system. Its primary function is to manage and verify the integrity of plugins by computing and storing their HMAC-SHA256 signatures.\n\n**Key Components**:\n1. **SignatureError**: A custom exception class used to handle errors related to signature issues.\n2. **_should_ignore**: A helper function that determines whether a file should be ignored during the signing process based on predefined criteria.\n3. **_compute_hmac**: A function that computes the HMAC-SHA256 digest of a plugin, including its manifest and source files.\n4. **sign_plugin**: A function that generates a signature for a given plugin by computing its HMAC and writing it to a `.sig` file within the plugin's directory.\n5. **verify_plugin**: A function that verifies the integrity of a plugin by comparing its computed signature with the stored one.\n\n**Dependencies**:\n- `hashlib`: For hashing algorithms.\n- `hmac`: For generating HMAC-SHA256 signatures.\n- `json`: For handling JSON data.\n- `logging`: For logging messages.\n- `pathlib`: For file path operations.\n\n**Interactions**:\n- The `sign_plugin` function is called by the plugin manager to generate a signature for a new or updated plugin.\n- The `verify_plugin` function is used by the plugin manager to ensure that a plugin has not been tampered with after it has been signed.\n- The `is_signed` function checks if a plugin has a valid signature.\n\nThis file plays a crucial role in maintaining the integrity and security of plugins within the XCore kernel, ensuring that only trusted and authentic plugins are loaded into the system.", - "/home/eliezer/devs/xcore/xcore/kernel/security/setup.py:50b97c87a948c16d144583cfafdfc3cede0b5d668e8a808c27b1dbb9e11e2c1a": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/security/setup.py`\n\n#### Purpose:\nThis file is responsible for building the `scanner_core` extension, which is a C++ scanner used in the XCore project. The extension is designed to be imported directly from `validation.py`, facilitating seamless integration into the system.\n\n#### Key Components:\n1. **Pybind11Extension**: This class is used to define and build the C++ extension module.\n2. **build_ext**: A command-line utility provided by setuptools that compiles the C++ code into a shared library (`scanner_core.so`).\n3. **ext**: An instance of `Pybind11Extension` specifying the source file (`scanner_core.cpp`) and compiler flags.\n\n#### Dependencies:\n- The extension relies on the `pybind11` package for interfacing with Python.\n- It imports the `std::filesystem` header, which is part of C++20 and requires a specific compiler flag (`-march=native`).\n\n#### Interactions:\n- The `setup.py` script is used to build the extension module. When executed with `python setup.py build_ext --inplace`, it compiles the C++ code into a shared library that can be imported directly from Python.\n- The compiled library is placed next to `validation.py`, allowing for direct imports without additional configuration.\n\nThis setup ensures that the `scanner_core` extension is built and ready to be used in the XCore project, enhancing its functionality and integration with other components.", - "/home/eliezer/devs/xcore/xcore/kernel/security/scanner_core.cpp:38f66a664a61d6ceb81390f4124cd5b8aa4eb8433b54e53f23c861f13dfd4ec3": "### Technical Summary\n\n**Purpose**: The provided source file `/home/eliezer/devs/xcore/xcore/kernel/security/scanner_core.cpp` is an extension for the XCore project that handles the scanning of AST (Abstract Syntax Trees) of plugins. It includes functionalities to extract imports from Python code, manage forbidden and allowed modules, and perform parallel scans of directories.\n\n**Key Components**:\n1. **ImportClassifier**: A class responsible for managing forbidden and allowed modules. It uses regular expressions to identify import statements and checks them against predefined rules.\n2. **extract_imports**: A function that tokenizes the source code line-by-line, extracting imports without parsing the entire AST. This is done using a simple regex pattern.\n3. **root_of**: A helper function that returns the root of a module name by removing any dots from it.\n\n**Dependencies**:\n- `pybind11`: For interfacing with Python from C++.\n- `std::atomic`, `std::filesystem`, `std::fstream`, `std::regex`, `std::string`, `std::thread`, `std::unordered_set`, and `std::vector`.\n\n**Interactions**:\n- The `ImportClassifier` class is used to filter imports based on predefined rules.\n- The `extract_imports` function processes the source code to extract import statements.\n- The `root_of` helper function simplifies module names by removing dots.\n- The `scan_file` method scans a single Python file, checking for forbidden and allowed modules.\n- The `scan_directory` method performs parallel scans of directories using multiple threads.\n\nThis file is crucial for maintaining the security of XCore plugins by ensuring that only authorized imports are used.", - "/home/eliezer/devs/xcore/xcore/kernel/security/scanner_core.cpp:c1fe0fd46c8a0d4384297add7cbc257bdd37216fb5876d1af31b95b5c592c727": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/kernel/security/scanner_core.cpp`\n\n#### 1. Purpose\nThis file implements a multithreaded import scanner for plugins in the XCore framework. It is responsible for classifying and filtering imports based on predefined rules.\n\n#### 2. Key Components\n- **`FileResult` Class**: Represents the result of scanning a single Python file, including details about errors, warnings, and whether the file passed the classification.\n- **`ImportClassifier` Class**: Manages the import classification logic, including checking for forbidden modules, allowed exact matches, and prefix matches. It also provides methods to scan individual files and directories.\n\n#### 3. Dependencies\n- The file imports `std::unordered_set`, `std::vector`, and `pybind11`.\n- It relies on the `hardware_concurrency()` function from `pybind11` for determining the number of threads to use.\n\n#### 4. Interactions\n- **File Scanning**: The `scan_file` method processes a single Python file, returning a `FileResult`. This method is called by the `scan_directory` method when scanning directories.\n- **Directory Scanning**: The `scan_directory` method recursively scans all `.py` files in a directory and its subdirectories. It uses multiple threads to perform this task efficiently.\n\nThis file serves as the core component of the XCore framework's import classification system, ensuring that plugins are correctly identified and managed based on predefined criteria.", - "/home/eliezer/devs/xcore/xcore/kernel/security/validation.py:d5feb17d5aa80f61ed4ad0f158727dfa1044e3f9608b8de63d0c5c3ed0af9bf7": "### Purpose\n\nThe `validation.py` file is responsible for validating and parsing plugin manifest files in the XCore project. It also handles the scanning of AST (Abstract Syntax Trees) of plugins using both C++ and Python.\n\n### Key Components\n\n- **ManifestValidator**: This class loads, validates, and parses a plugin manifest file. It checks compatibility with the framework version and injects environment variables from an optional `.env` file.\n- **_build_manifest**: This function constructs a `PluginManifest` object based on the parsed manifest data.\n- **_parse_allowed_imports**: This helper function separates the list of allowed imports into exact modules, wildcard prefixes, and skipped entries. It filters out symbols that resemble class or symbol names to avoid false positives.\n\n### Dependencies\n\n- The file imports various libraries such as `ast`, `json`, `os`, `re`, `dataclasses`, `pathlib`, `xcore.sdk.plugin_base`, and `xcore`.\n- It relies on the `scanner_core` extension for C++ scanning if available, otherwise falls back to Python parsing.\n\n### Interactions\n\n- The `ManifestValidator` class interacts with the rest of the codebase through methods like `_read_raw` to load and parse manifest files.\n- It uses the `ASTScanner` class to orchestrate Python and C++ AST scanning, handling multithreading for C++ scanning if available.", - "/home/eliezer/devs/xcore/xcore/kernel/security/validation.py:f2e768ea92860e19fb4ad6c8f7926600639b955bda689cc98815bb3129d13a19": "### Technical Summary\n\n**Purpose**: The `validation.py` file is responsible for scanning a plugin directory and verifying its imports against predefined rules. It uses Python's AST (Abstract Syntax Tree) to parse the source code of each `.py` file in the plugin directory.\n\n**Key Components**:\n- **Initialization**: The class initializes with optional extra forbidden and allowed modules.\n- **Scan Function**: `scan()` method scans the plugin directory, identifies local modules, and constructs an AST scanner. It then scans imports for builtins and attributes, checking against predefined rules.\n- **Fallback Python Scanning**: If no C++ classifier is available, it falls back to scanning Python files using the AST.\n\n**Dependencies**:\n- The file imports `ast`, `os`, `pathlib`, and possibly `_CppClassifier` if C++ support is enabled.\n\n**Interactions**:\n- The class interacts with the rest of the codebase through methods like `scan()`, which orchestrates the scanning process.\n- It communicates errors and warnings to the caller, indicating issues found in the plugin's imports.", - "/home/eliezer/devs/xcore/xcore/kernel/security/validation.py:d23e76c9992ab3643574c2317d9986b325dd257b8dd351acec7c6c9b3aff0da9": "### Technical Summary: Validation Module\n\n#### Purpose\nThe `validation.py` file is responsible for validating the attributes of nodes in an abstract syntax tree (AST) during the parsing phase of a software project. It ensures that certain attributes are not used, which could potentially lead to security vulnerabilities or other issues.\n\n#### Key Components\n1. **Function: validate_attributes**\n - This function takes an AST node and a list of forbidden attribute names.\n - It checks if the attribute name is in the `FORBIDDEN_ATTRIBUTES` list.\n - If it is, it adds an error message to the `result` object.\n\n2. **Class: AttributeValidator**\n - This class encapsulates the validation logic for attributes.\n - It has a method `validate(self, node, forbidden)`, which calls `validate_attributes` with the appropriate parameters.\n\n#### Dependencies\n- The file imports no external libraries beyond Python's standard library.\n\n#### Interactions\n- This file is called by other parts of the codebase during the parsing phase.\n- It interacts with the `result` object to report any errors found during validation.", - "/home/eliezer/devs/xcore/xcore/cli/__init__.py:b8f25f227787ae4afdc5117ad3e933128727727197b6a5125313e3245edc8f0c": "### Technical Summary\n\n**Purpose**: The `/home/eliezer/devs/xcore/xcore/cli/__init__.py` file serves as the entry point for the CLI (Command Line Interface) of the `xcore` project. It provides a set of commands to manage plugins, facilitating the integration and configuration of various components within the system.\n\n**Key Components**:\n- **Main Classes**: \n - `CliManager`: Manages the execution of CLI commands.\n - `PluginManager`: Handles the registration and management of plugins.\n \n- **Functions**:\n - `main()`: The entry point for the CLI application, parsing command-line arguments and invoking appropriate handlers.\n - `register_plugin(plugin_name)`: Registers a new plugin with the system.\n - `unregister_plugin(plugin_name)`: Unregisters an existing plugin from the system.\n\n- **Dependencies**: \n - `xcore.plugin`: The core module for managing plugins within the xcore project.\n - `argparse`: For parsing command-line arguments.\n \n- **Interactions**:\n - The CLI interacts with the `CliManager` to execute commands like `install`, `uninstall`, and `list`.\n - It calls into the `PluginManager` to register or unregister plugins, which in turn interact with the `xcore.plugin` module to manage plugin functionality.\n\nThis file is crucial for enabling users to effectively manage plugins within the xcore project, enhancing its flexibility and scalability.", - "/home/eliezer/devs/xcore/xcore/cli/marketplace_cmd.py:4b244b8f0265b6871a221ef8458b0c2ea59d0e658e6f34a824473b4e3936c46a": "### Technical Summary: marketplace_cmd.py\n\n#### Purpose\nThe `marketplace_cmd.py` file is a command-line interface (CLI) handler for the XCore Marketplace feature. It provides various commands to list, search, show details, and rate plugins.\n\n#### Key Components\n- **Main Classes**:\n - `MarketplaceClient`: Handles interactions with the marketplace API.\n - `ConfigLoader`: Loads configuration settings from a file or environment variables.\n\n- **Functions**:\n - `_load_config(args)`: Loads the configuration based on command-line arguments.\n - `_get_client(args)`: Initializes the `MarketplaceClient` and configuration object.\n - `handle_marketplace(args)`: Dispatches the appropriate handler for each subcommand.\n - `_mkt_list(args)`, `_mkt_trending(args)`, `_mkt_search(args)`, `_mkt_show(args)`, `_mkt_rate(args)`: Handlers for listing, trending, searching, showing details, and rating plugins, respectively.\n\n- **Dependencies**:\n - `rich.console.Console` and `rich.markup.Markup` for rich text formatting.\n - `rich.table.Table` for creating tables in the CLI output.\n - `xcore.configurations.loader.ConfigLoader` for loading configuration settings.\n - `xcore.marketplace.MarketplaceClient` for interacting with the marketplace API.\n\n- **Interactions**:\n - The file connects to the rest of the codebase through the `handle_marketplace` function, which dispatches commands based on user input. It interacts with the `MarketplaceClient` to fetch and display information about plugins.", - "/home/eliezer/devs/xcore/xcore/cli/marketplace_cmd.py:dd378427997f08b5efca200d027c935cc77d1c999712d4e0f0623626c572677c": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/cli/marketplace_cmd.py`\n\n#### Purpose:\nThis file provides a function `rating` that converts a numerical rating from 0 to 5 into an ASCII representation of stars with markup for Rich text formatting.\n\n#### Key Components:\n- **Function**: `rating`\n - **Description**: Converts a given rating (as a string or float) into an ASCII representation of stars using the Rich library.\n - **Parameters**:\n - `rating`: A string representing the rating, which can be empty or contain non-numeric characters. If empty, it defaults to 0.0.\n - **Return**: A string containing the formatted stars.\n\n#### Dependencies:\n- **Imports**:\n - `float`\n - `max`\n - `min`\n - `ValueError`\n - `TypeError`\n\n#### Interactions:\n- **Calls into**:\n - The function is called by other parts of the codebase to format ratings in a user-friendly manner.\n- **Data produced or consumed**:\n - The formatted stars are used to display rating information in the CLI interface.\n\nThis file serves as a utility function for converting numerical ratings into visually appealing ASCII representations, enhancing the readability and presentation of data in the xcore CLI application.", - "/home/eliezer/devs/xcore/xcore/cli/main.py:584670b326990a7f794f36a6f679df1047b9f2aa92c3248c2cb059788b3dec22": "### Technical Summary: xcore CLI Main Module\n\n#### Purpose\nThe `main.py` file serves as the entry point for the Command Line Interface (CLI) of the xcore framework. It provides a set of commands to manage plugins, sandbox runtime, marketplace, and services.\n\n#### Key Components\n- **Main Function (`main()`)**:\n - Parses command-line arguments using `argparse`.\n - Defines subparsers for different functionalities such as plugin management, sandbox, marketplace, and services.\n - Handles each subcommand with corresponding functions from respective modules.\n\n- **Plugin Management**:\n - Subcommands like `list`, `health`, `load`, `reload`, `install`, `remove`, `info`, `sign`, `verify`, and `validate` are defined under the `plugin` group.\n - Each command is handled by a corresponding function in the respective module (`plugin_cmd.py`).\n\n- **Sandbox Runtime**:\n - Subcommands like `run`, `limits`, `network`, and `fs` are defined under the `sandbox` group.\n - Each command is handled by a corresponding function in the respective module (`sandbox_cmd.py`).\n\n- **Marketplace**:\n - Subcommands like `list`, `trending`, `search`, `show`, and `rate` are defined under the `marketplace` group.\n - Each command is handled by a corresponding function in the respective module (`marketplace_cmd.py`).\n\n- **Services Status**:\n - Subcommand `status` provides the status of all services, which can be output as JSON.\n\n#### Dependencies\n- The file imports several modules and functions from other parts of the xcore framework.\n- It relies on external libraries such as `argparse`, `asyncio`, and possibly others depending on specific functionalities.\n\n#### Interactions\n- The CLI interacts with the rest of the codebase through subcommands, which are defined in separate modules (`plugin_cmd.py`, `sandbox_cmd.py`, etc.).\n- Each command is responsible for executing a specific task within the xcore framework, such as managing plugins, running sandboxes, accessing the marketplace, and monitoring services.\n\nThis file serves as the central hub for interacting with the xcore CLI, providing a comprehensive set of commands to manage various aspects of the framework.", - "/home/eliezer/devs/xcore/xcore/cli/plugin_cmd.py:a441d0bad8c8757366136dd61ff0577035fd4e088f3f9831e13b1ff53eefb083": "### Technical Summary\n\n**Purpose**: The `plugin_cmd.py` file is a command-line interface (CLI) handler for managing plugins in the XCore software project. It provides various subcommands to list, health check, install, reload, sign, verify, and validate plugins.\n\n**Key Components**:\n- **Main Classes and Functions**:\n - `_validate_plugin_name`: Validates the plugin name against a regular expression.\n - `_ensure_safe_scheme`: Ensures that the URL used for installing plugins is secure (HTTP/HTTPS).\n - `_load_config`: Loads the configuration settings from the specified file or defaults to `xcore.configurations.loader.ConfigLoader`.\n - `handle_plugin`: Dispatches the appropriate handler based on the subcommand provided.\n - `_plugin_list`: Lists all available plugins in the specified directory, including their versions and modes.\n - `_plugin_health`: Checks the health of each plugin by validating its manifest and performing signature and AST scans.\n - `_plugin_install`: Installs a plugin from a Git repository or URL. It also handles signing the plugin after installation.\n - `_install_from_git`: Clones a Git repository into the specified directory.\n - `_install_from_zip`: Downloads a ZIP file and extracts it to the specified directory.\n - `_auto_sign`: Automatically signs the installed plugin using the XCore marketplace client.\n\n**Dependencies**:\n- `json`, `re`, `shutil`, `sys`, `pathlib`\n- `urllib.parse`\n- `rich.console`, `rich.markup`, `rich.panel`, `rich.prompt`\n- `xcore.configurations.loader.ConfigLoader`\n- `xcore.kernel.security.signature.SignatureValidator`\n- `xcore.kernel.security.validation.ASTScanner`\n- `xcore.marketplace.MarketplaceClient`\n\n**Interactions**:\n- The CLI interacts with the rest of the codebase through the `handle_plugin` function, which dispatches subcommands to specific handlers.\n- Handlers like `_plugin_list`, `_plugin_health`, and `_install_from_git` interact with the filesystem and external services (like Git and the XCore marketplace) to perform their respective tasks.", - "/home/eliezer/devs/xcore/xcore/cli/plugin_cmd.py:d5501512bc1770b5ee7a0b6ad4464fd03330a228e7090e2335f0cd0eb51748cd": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/cli/plugin_cmd.py`\n\n#### Purpose\nThis file is responsible for managing plugins in the XCore system. It provides commands to install, remove, and verify plugins from the marketplace.\n\n#### Key Components\n- **`nicate()`**: Handles the basic git clone operation and prints an error message if the command fails.\n- **`_install_from_zip(name: str, url: str, dest: Path) -> None`:** Downloads a plugin from a URL and extracts it to the specified destination. It handles errors during the download process.\n- **`_install_from_marketplace(client, name: str, dest: Path, cfg) -> None`:** Searches for a plugin on the marketplace using the provided client and downloads it based on the source type (zip or git). It handles errors during the installation process.\n- **`_auto_sign(plugin_dir: Path, cfg) -> None`:** Signs a plugin after installation with a secret key defined in the configuration. It includes validation to ensure the manifest is valid and signs the plugin if successful.\n\n#### Dependencies\n- `asyncio`\n- `io`\n- `urllib.request`\n- `zipfile`\n- `shutil`\n\n#### Interactions\n- **Called by:** Various parts of the XCore system, including commands like `xcore install`, `xcore remove`, and `xcore info`.\n- **Calls into:** Other modules within the XCore system, such as `xcore.kernel.security.signature` for signing plugins.\n- **Data produced or consumed:** The plugin directory structure is modified based on the installation process. The manifest of the installed plugin is validated and signed if necessary.\n\nThis file serves as a central point for managing plugins in the XCore system, ensuring they are properly installed, verified, and managed according to the defined specifications.", - "/home/eliezer/devs/xcore/xcore/cli/plugin_cmd.py:8fe63293bb722bedb65add5156df9dbc652e4f35f4ed61fe5cb13ae5de5e356b": "### Technical Summary\n\n#### Purpose\nThe provided Python script is a command-line interface (CLI) tool for managing plugins in an XCore system. It includes functions to sign, verify, and load plugins, as well as perform IPC calls to the xCore server.\n\n#### Key Components\n1. **Sign Plugin Function**:\n - `sign_plugin(manifest, key)`: Signs a plugin manifest using a provided key.\n - Outputs the signed signature.\n\n2. **Verify Plugin Function**:\n - `_plugin_verify(args)`: Verifies the signature of a plugin using the provided key.\n - Prints success or error messages based on the verification result.\n\n3. **IPC Call Function**:\n - `_ipc_call(args, action: str, method: str = \"POST\")`: Calls an IPC endpoint on the xCore server with specified parameters.\n - Handles HTTP errors and URLError exceptions gracefully.\n\n4. **Service Management Functions**:\n - `handle_services(args)`: Retrieves and displays the status of services using a ServiceContainer.\n - `handle_health(args)`: Executes a global health check on all services, displaying the results in a table format.\n\n#### Dependencies\n- The script imports several modules from the xCore kernel, including `ManifestValidator`, `SignatureError`, `verify_plugin`, `ServiceContainer`, and `console`.\n- It relies on external libraries such as `urllib.request` for HTTP requests and `json` for JSON handling.\n\n#### Interactions\n1. **Sign Plugin**:\n - Takes a plugin manifest and a key, signs the manifest using the provided key.\n - Outputs the signed signature.\n\n2. **Verify Plugin**:\n - Takes a plugin manifest and a key, verifies the signature of the manifest.\n - Prints success or error messages based on the verification result.\n\n3. **IPC Call**:\n - Calls an IPC endpoint on the xCore server with specified parameters.\n - Handles HTTP errors and URLError exceptions gracefully.\n\n4. **Service Management**:\n - Retrieves and displays the status of services using a ServiceContainer.\n - Executes a global health check on all services, displaying the results in a table format.", - "/home/eliezer/devs/xcore/xcore/cli/sandbox_cmd.py:8ad25e1d81bbd07ab422381a7fa05a0aac7bd77f1ffa8d2a2ec547c6044b0663": "### Technical Summary\n\n#### Purpose\nThe `sandbox_cmd.py` file is responsible for handling command-line commands related to sandboxing plugins within the Xcore system. It provides functionalities such as running a plugin in a sandboxed environment, displaying resource limits, and inspecting network policies.\n\n#### Key Components\n- **Main Classes**:\n - `SandboxCmd`: The main class that orchestrates the execution of sandbox-related commands.\n - `_sandbox_run`, `_sandbox_limits`, `_sandbox_network`: Handlers for specific sandbox subcommands.\n\n- **Functions**:\n - `_load_config`: Loads configuration settings from a specified file or defaults.\n - `_load_manifest`: Validates and loads the manifest file for a given plugin.\n - `handle_sandbox`: Dispatches commands to their respective handlers based on the provided arguments.\n\n- **Dependencies**:\n - `xcore.configurations.loader.ConfigLoader`: Handles loading configuration files.\n - `xcore.kernel.security.validation.ManifestValidator`: Validates the manifest against predefined rules.\n - `xcore.kernel.sandbox.process_manager.SandboxConfig`: Configures sandbox settings.\n - `xcore.kernel.sandbox.ipc.IPCChannel`: Manages inter-process communication for sandbox management.\n\n- **Interactions**:\n - The file interacts with other parts of the Xcore system through methods like `_load_config`, `_load_manifest`, and `handle_sandbox`.\n - It communicates with the sandbox manager (`SandboxProcessManager`) to start, stop, and manage sandboxed processes.\n - It uses the AST scanner (`ASTScanner`) to analyze the plugin's code for network imports.\n\n#### Summary\nThis file is a critical component of the Xcore system, responsible for managing sandboxed environments for plugins. It provides commands for running, inspecting resource limits, and monitoring network policies, ensuring that plugins operate within secure and controlled environments.", - "/home/eliezer/devs/xcore/xcore/cli/sandbox_cmd.py:3ac574cb44a93dc42b2b847a67d8f96fac73bced06e55e4cfdefec42cd927cbe": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/cli/sandbox_cmd.py`\n\n#### 1. Purpose\nThis file is responsible for displaying and validating the network policy of a plugin within the XCore system. It provides information about allowed and blocked imports, as well as notes on isolation mechanisms.\n\n#### 2. Key Components\n- **Network Policy Display**:\n - Reads configuration settings from `_load_config`.\n - Checks if the plugin directory exists.\n - Loads the manifest from the plugin directory.\n - Constructs a table to display allowed and denied network paths.\n - Prints the table with appropriate styling.\n\n- **Filesystem Policy Display**:\n - Similar to the network policy, but focuses on filesystem policies.\n - Reads configuration settings from `_load_config`.\n - Checks if the plugin directory exists.\n - Loads the manifest from the plugin directory.\n - Constructs a table to display allowed and denied filesystem paths.\n - Prints the table with appropriate styling.\n\n#### 3. Dependencies\n- **Internal Modules**:\n - `network`: Contains functions for displaying network policies.\n - `fs`: Contains functions for displaying filesystem policies.\n - `console.print`: For printing messages to the console.\n - `Group`, `Table`, and `Confirm` from `rich`: For creating styled tables and prompts.\n\n- **External Libraries**:\n - `pathlib.Path`: For handling file paths.\n - `sys.exit`: For exiting the program with an error code.\n - `error_console.print`: For printing error messages to the console.\n - `create_confirm.ask`: For asking the user if a directory should be created.\n\n#### 4. Interactions\n- **Plugin Directory Existence**:\n - Checks if the plugin directory exists before proceeding with policy checks.\n\n- **Manifest Loading**:\n - Loads the manifest from the plugin directory to access configuration settings and policies.\n\n- **Table Construction**:\n - Constructs a table using `rich` to display allowed and denied paths in a visually appealing manner.\n\n- **Directory Creation**:\n - Creates the `data/` directory if it does not exist, prompting the user for confirmation.", - "/home/eliezer/devs/xcore/xcore/cli/validate_cmd.py:fea28d6a4a8668c09efcb420259be2855b3486f31b671dbca527ad792af6d2ce": "### Technical Summary: validate_cmd.py\n\n**Purpose**: This file provides a comprehensive validation process for plugins, ensuring they meet specific criteria such as manifest format, AST structure, and signature verification. The plugin is validated based on its execution mode (trusted or untrusted) and requires a secret key if the plugin is trusted.\n\n**Key Components**:\n- **ManifestValidator**: Responsible for loading and validating the plugin's manifest file.\n- **ASTScanner**: Scans the plugin's source code to ensure it adheres to the specified schema and imports.\n- **SignatureVerification**: Verifies the plugin's signature using a secret key if the plugin is trusted.\n\n**Dependencies**:\n- `xcore.kernel.api.contract`: Contains classes for contract validation.\n- `xcore.kernel.security.validation`: Provides functions for manifest validation and AST scanning.\n- `xcore.kernel.security.signature`: Handles signature verification for trusted plugins.\n\n**Interactions**:\n- The file reads a plugin's path from the command line argument.\n- It loads and validates the manifest, scans the AST, and verifies the signature if necessary.\n- The results are printed to the console, indicating whether the validation was successful or not.", - "/home/eliezer/devs/xcore/xcore/configurations/helper.py:8778a5944b5cc01b4840e7af96222f5df695c77e710b42f38dc1da24cb04181b": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/configurations/helper.py`\n\n#### Purpose:\nThis file provides a utility function to resolve environment variables within YAML configuration files. It ensures that any placeholders like `${VAR}` are replaced with their corresponding values from the system's environment.\n\n#### Key Components:\n1. **Import Statements**:\n - `from __future__ import annotations`: Enables type hints.\n - `import logging`: For logging purposes.\n - `import os`: To interact with the operating system.\n - `import re`: For regular expressions for pattern matching.\n - `from typing import Any`: For type hinting lists and dictionaries.\n\n2. **Global Variables**:\n - `_ENV_PATTERN`: A compiled regex pattern to match environment variable placeholders in strings.\n\n3. **Function: `_resolve`**\n - This function takes a value (string, dictionary, or list) as input.\n - If the value is a string, it replaces all occurrences of `${VAR}` with their corresponding environment variables using `os.environ`.\n - If the value is a dictionary, it recursively applies `_resolve` to each key-value pair.\n - If the value is a list, it applies `_resolve` to each item in the list.\n\n4. **Dependency**:\n - This file imports `logging` and `os`, which are essential for logging and interacting with the operating system, respectively.\n\n5. **Interactions**:\n - The function `_resolve` is called by other parts of the codebase when parsing YAML configuration files to ensure that environment variables are correctly resolved.\n - It ensures that the application runs smoothly by providing a consistent interface for accessing environment variables across different parts of the system.", - "/home/eliezer/devs/xcore/xcore/configurations/sections.py:3bfdfeef27e7a9a1e6caf9b5982f1b2e3bea6152f453a65bd0fe7f89ead524ae": "### Technical Summary\n\n#### 1. Purpose\nThis file contains configuration settings for various components of the Xcore application, including databases, cache, scheduler, services, plugins, logging, metrics, tracing, observability, security, and marketplace.\n\n#### 2. Key Components\n- **AppConfig**: Contains general application settings such as name, environment, debug mode, secret key, plugin prefix, and server key.\n- **DatabaseConfig**: Configures database connections with details like type, URL, pool size, max overflow, echo mode, and optional MongoDB or Redis configurations.\n- **CacheConfig**: Manages caching options including backend (memory or Redis), TTL, maximum size, and URL.\n- **SchedulerConfig**: Sets up a scheduler with enabled status, backend (memory, Redis, database), timezone, and job definitions.\n- **ServicesConfig**: Configures services like databases, cache, scheduler, and extensions.\n- **PluginConfig**: Manages plugin settings including directory, secret key, strict trust, interval, entry point, and snapshot configuration.\n- **LoggingConfig**: Sets up logging options with level, format, file path, maximum bytes, and backup count.\n- **MetricsConfig**: Configures metrics collection with enabled status, backend (memory, Prometheus, statsd), and prefix.\n- **TracingConfig**: Enables tracing with optional backend (noop, opentelemetry, jaeger) and service name.\n- **ObservabilityConfig**: Combines logging, metrics, and tracing configurations.\n- **SecurityConfig**: Defines allowed and forbidden imports, rate limit default settings.\n- **MarketplaceConfig**: Configures the marketplace client with URL, API key, timeout, cache TTL.\n\n#### 3. Dependencies\nThis file imports several internal modules and external libraries:\n- `dataclasses` for defining data classes.\n- `typing` for type annotations.\n- `os` for interacting with the operating system.\n- `json` for handling JSON data.\n- `requests` for making HTTP requests (if needed).\n\n#### 4. Interactions\nThis file interacts with other parts of the codebase through methods and functions:\n- **AppConfig**: Used to initialize the application configuration.\n- **DatabaseConfig**: Configured in the database service.\n- **CacheConfig**: Used by various services and plugins.\n- **SchedulerConfig**: Manages scheduled tasks.\n- **ServicesConfig**: Manages services like databases, cache, scheduler, and extensions.\n- **PluginConfig**: Configures plugins with settings such as directory, secret key, interval, entry point, and snapshot configuration.\n- **LoggingConfig**: Used for logging messages throughout the application.\n- **MetricsConfig**: Collects metrics using the specified backend.\n- **TracingConfig**: Enables tracing with optional backend.\n- **ObservabilityConfig**: Combines logging, metrics, and tracing configurations.\n- **SecurityConfig**: Defines security rules for imports and rate limiting.\n- **MarketplaceConfig**: Configures the marketplace client with URL, API key, timeout, cache TTL.\n\nThis file serves as a centralized configuration repository for the Xcore application, ensuring consistency across different parts of the codebase.", - "/home/eliezer/devs/xcore/xcore/configurations/__init__.py:25a2b971b62efaeb9435f3aa8cd8cea6e152800d0d1da08cfa4dbcc353c54fc5": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/configurations/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for configuration management in the XCore project. It defines classes and functions responsible for loading, parsing, and managing various configuration settings.\n\n#### Key Components:\n- **ConfigLoader**: A class that handles the loading of configuration files from different sources (e.g., environment variables, YAML files).\n - Description: Loads configuration data from specified locations and parses it into a structured format.\n- **XcoreConfig**: The main configuration object that encapsulates all settings related to the XCore application.\n - Description: Manages global configurations such as database connection details, server settings, and more.\n- **AppConfig**: A subclass of `XcoreConfig` specifically tailored for application-specific configurations.\n - Description: Manages configurations specific to the application, such as API endpoints, logging levels, and authentication settings.\n- **PluginConfig**: A class that handles configuration for plugins used in the XCore system.\n - Description: Manages plugin-specific configurations, including dependencies, settings, and initialization logic.\n- **ServicesConfig**: A subclass of `XcoreConfig` designed for service-related configurations.\n - Description: Manages configurations related to services, such as API endpoints, data handling, and security measures.\n- **DatabaseConfig**: A class that handles database configuration settings.\n - Description: Manages database connection details, authentication methods, and other database-specific configurations.\n- **CacheConfig**: A class that manages cache configuration settings.\n - Description: Manages caching strategies, storage locations, and expiration times.\n- **SchedulerConfig**: A class that handles scheduling-related configurations.\n - Description: Manages scheduled tasks, cron expressions, and job execution logic.\n- **ObservabilityConfig**: A class that handles observability-related configurations.\n - Description: Manages logging levels, metrics collection, and monitoring tools.\n- **SecurityConfig**: A class that manages security configuration settings.\n - Description: Manages authentication methods, encryption keys, and other security-related configurations.\n\n#### Dependencies:\nThis file imports several internal modules and external libraries:\n- `from .loader import ConfigLoader, XcoreConfig`\n- `from .sections import (AppConfig, CacheConfig, DatabaseConfig,\n ObservabilityConfig, PluginConfig, SchedulerConfig,\n SecurityConfig, ServicesConfig)`\n\n#### Interactions:\n- **Calls into**: This file is called by other parts of the codebase to load and manage configuration settings.\n- **Data produced or consumed**: The `XcoreConfig` object provides a structured interface for accessing all configuration settings. It also interacts with other classes like `AppConfig`, `PluginConfig`, etc., to retrieve specific configurations as needed.\n\nThis file is crucial for ensuring that the XCore application runs smoothly by providing a centralized and consistent way to manage its various configurations.", - "/home/eliezer/devs/xcore/xcore/configurations/loader.py:a03f147aabbeb6ca65e9662b2dbd8614ea5901b50c0631256fb9a1890512d719": "### Technical Summary\n\n**Purpose**: The `loader.py` file in the `/home/eliezer/devs/xcore/xcore/configurations/` directory is responsible for loading and parsing an xcore configuration file (`xcore.yaml`) into a structured dataclass object. This file is crucial for configuring various aspects of the xcore application, such as database settings, cache configurations, logging, observability, and more.\n\n**Key Components**:\n- **ConfigLoader Class**: The main class that handles the loading process.\n - `_read` method: Reads the configuration file from specified paths or defaults to `integation.yaml`.\n - `_load_dotenv`: Loads environment variables from a `.env` file if present.\n - `_apply_env_overrides`: Applies environment variable overrides to the raw configuration data.\n - `_parse`: Parses the raw configuration into an instance of `XcoreConfig`.\n\n- **XcoreConfig Class**: A dataclass that represents the parsed configuration.\n - `app`: An instance of `AppConfig`.\n - `plugins`: An instance of `PluginConfig`.\n - `services`: An instance of `ServicesConfig`.\n - `observability`: An instance of `ObservabilityConfig`.\n - `security`: An instance of `SecurityConfig`.\n - `marketplace`: An instance of `MarketplaceConfig`.\n\n- **Helper Classes**:\n - `_resolve`: A helper function to resolve environment variables in the configuration.\n - `sections`: A module containing classes for different sections of the configuration.\n\n**Dependencies**:\n- The file imports `yaml` and `json` for parsing YAML and JSON files, respectively.\n- It uses `os` for accessing environment variables and `pathlib` for handling file paths.\n- It relies on `dotenv` for loading environment variables from a `.env` file if present.\n\n**Interactions**:\n- The `ConfigLoader` class is called by the main application to load the configuration file.\n- The loaded configuration is then parsed into an instance of `XcoreConfig`, which can be used throughout the application to access and configure various aspects of the xcore system.", - "/home/eliezer/devs/xcore/xcore/configurations/loader.py:759b202b1170e0d502f3fe1b92f7a1b4aa1118d2f8e0a6764d05932c6def2e4d": "### Technical Summary: `xcore/configurations/loader.py`\n\n#### Purpose\nThis file is responsible for loading and managing configuration settings for the XCore system. It provides methods to parse different types of configurations such as service, security, and marketplace.\n\n#### Key Components\n1. **ConfigLoader Class**:\n - **Purpose**: Loads and parses configuration files.\n - **Methods**:\n - `load(path: str | Path | None = None) -> XcoreConfig`: Loads the configuration from a file or defaults to a predefined path.\n - `_parse_service(d: dict) -> ServiceConfig`: Parses service-specific configurations.\n - `_parse_security(d: dict) -> SecurityConfig`: Parses security-related configurations.\n - `_parse_marketplace(d: dict) -> MarketplaceConfig`: Parses marketplace-related configurations.\n\n2. **XcoreConfig Class**:\n - **Purpose**: Represents the main configuration object for the XCore system.\n - **Attributes**:\n - `service_name`, `endpoint`: Service-specific configurations.\n - `allowed_imports`, `forbidden_imports`: Security-related configurations.\n - `rate_limit_default`: Rate limit settings.\n - `url`, `api_key`, `timeout`, `cache_ttl`: Marketplace-related configurations.\n\n3. **Singleton Global**:\n - **Purpose**: Manages a single instance of the `XcoreConfig` object.\n - **Methods**:\n - `get_config(path: str | Path | None = None) -> XcoreConfig`: Retrieves the current configuration or loads it if not already set.\n - `reload_config(path: str | Path | None = None) -> XcoreConfig`: Reloads the configuration from a file.\n\n#### Dependencies\n- **Internal Modules**: None.\n- **External Libraries**: None.\n\n#### Interactions\n- **Calls into**: The `XcoreConfig` object is used by other parts of the system to access and manage configuration settings.\n- **Data Produced or Consumed**: Configuration data is parsed and stored in the `XcoreConfig` object, which is then used throughout the application.", - "/home/eliezer/devs/xcore/xcore/marketplace/__init__.py:3284c63444f4e83806dbd6948cf2e8d562acafafacb8120e22d2b1f30bf6ccbe": "### Technical Summary for `/home/eliezer/devs/xcore/xcore/marketplace/__init__.py`\n\n#### Purpose\nThis file serves as the entry point for the marketplace module in the XCore project. It initializes the `MarketplaceClient`, which is responsible for interacting with external marketplaces to facilitate transactions and product listings.\n\n#### Key Components\n1. **MarketplaceClient**:\n - **Description**: This class encapsulates the functionality to communicate with various marketplaces, handling tasks such as listing products, placing orders, and retrieving order status.\n - **Dependencies**: It imports necessary modules like `requests` for HTTP requests and `json` for JSON data parsing.\n\n2. **__all__**:\n - **Description**: This list specifies the public API of the module. In this case, it includes only one class: `MarketplaceClient`.\n\n#### Dependencies\n- **Internal Modules**: None.\n- **External Libraries**: `requests`, `json`.\n\n#### Interactions\n- **Called by**: The `MarketplaceClient` is instantiated and used throughout the application to handle marketplace-related operations.\n- **Calls into**: It interacts with external marketplaces through HTTP requests, parsing JSON responses, and handling errors.\n- **Data Produced or Consumed**:\n - **Produced**: The `MarketplaceClient` produces data such as product listings and order details.\n - **Consumed**: It consumes data from external marketplaces for further processing in the application.", - "/home/eliezer/devs/xcore/xcore/marketplace/client.py:165b6b6ba0a434442e541460013258e2d5fc62146b8692097c0548ef4cdd5972": "### Technical Summary: Marketplace Client\n\n#### Purpose\nThe `marketplace/client.py` file is a client HTTP implementation designed to interact with the marketplace xcore API. It provides a generic interface for fetching various data related to plugins, including listing, trending, searching, retrieving details, rating, and managing versions.\n\n#### Key Components\n- **MarketplaceError**: A custom exception class used to handle errors specific to the marketplace operations.\n- **MarketplaceClient**: The main class that encapsulates the functionality of interacting with the marketplace API. It reads configuration from `xcore.yaml`, supports caching for improved performance, and handles HTTP requests using `urllib`.\n\n#### Dependencies\nThe file imports several modules:\n- `json` for JSON handling.\n- `logging` for logging purposes.\n- `time` for timing operations.\n- `pathlib.Path` for file path manipulation.\n- `typing.Any` for type hinting.\n- `urllib.error.HTTPError` and `urllib.error.URLError` for error handling in HTTP requests.\n- `urllib.parse.urlencode`, `urlparse`, and `Request` from `urllib.request` for URL operations.\n\n#### Interactions\nThe client interacts with the marketplace API through methods like:\n- `list_plugins`: Retrieves a list of plugins, optionally paginated.\n- `trending`: Returns the top trending plugins.\n- `search`: Searches for plugins based on query parameters.\n- `get_plugin`: Fetches detailed information about a specific plugin.\n- `get_versions`: Lists all available versions of a plugin.\n- `rate_plugin`: Rates a plugin with a score between 1 and 5.\n\nThe client uses caching to store responses from the API, which helps in reducing the number of network requests and improving performance. The cache is stored locally in JSON files under the user's home directory.\n\n#### Usage\nTo use the `MarketplaceClient`, you need to configure it with the necessary settings in `xcore.yaml` and then create an instance of the class. You can then call methods like `list_plugins`, `search`, or `get_plugin` to interact with the marketplace API.", - "/home/eliezer/devs/xcore/xcore/registry/__init__.py:b987f46412b1bcf148f792147dbfe77c92f0a3e22431bea64a65ceab4b96b8cc": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/registry/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for the `xcore` project's registry module. It defines classes and functions that manage plugins, dependencies, and version constraints.\n\n#### Key Components:\n1. **PluginRegistry**:\n - A class responsible for managing a collection of plugins.\n - Methods to add, remove, and retrieve plugins based on their names or types.\n\n2. **DependencyResolver**:\n - A class used to resolve dependencies between plugins.\n - Methods to find the appropriate plugin to satisfy a given dependency constraint.\n\n3. **VersionConstraint**:\n - A class for representing version constraints.\n - Methods to compare versions and check if one satisfies another.\n\n4. **satisfies**:\n - A function that checks if one version satisfies another version constraint.\n\n#### Dependencies:\n- This file imports `PluginRegistry`, `DependencyResolver`, `VersionConstraint`, and `satisfies` from the respective modules within the same directory (`registry/index.py`, `registry/resolver.py`, `registry/versioning.py`, respectively).\n\n#### Interactions:\n- The `__init__.py` file is imported by other parts of the codebase to access these components.\n- It defines the `__all__` list, which specifies the public API available from this module.\n\nThis file forms a central hub for managing plugins and dependencies in the `xcore` project, ensuring that all components can interact seamlessly.", - "/home/eliezer/devs/xcore/xcore/registry/resolver.py:d820b2f12f1a26d507fec2534f4963e27e2b4314c632f88aaa5beef547120f06": "### Technical Summary: Dependency Resolver in xcore/registry/resolver.py\n\n#### Purpose:\nThe `resolver.py` file is responsible for resolving dependencies and performing a topological sort on a plugin graph. It ensures that plugins are loaded in the correct order to avoid circular dependencies.\n\n#### Key Components:\n1. **CircularDependencyError**: Raised when a circular dependency is detected during the resolution process.\n2. **MissingDependencyError**: Raised when a required dependency is missing from the system.\n3. **DependencyResolver**:\n - Adds plugins with their dependencies to a graph.\n - Removes plugins from the graph.\n - Resolves the graph in topological order, raising an exception if circular dependencies are detected.\n\n#### Dependencies:\n- `collections.deque` for efficient queue operations.\n- No external libraries required.\n\n#### Interactions:\n- The `DependencyResolver` class is initialized and used to add plugins with their dependencies.\n- Plugins can be added or removed from the graph using the `add` and `remove` methods.\n- The `resolve` method performs a topological sort on the plugin graph, raising an exception if circular dependencies are detected.\n- The `waves` method returns vagues of parallel loading, where each wave can be loaded in parallel.\n\nThis file is crucial for managing the order in which plugins are loaded in a system to prevent conflicts and ensure proper functionality.", - "/home/eliezer/devs/xcore/xcore/registry/versioning.py:564b2e06a45d2a0b1be3ea081a1b5d0e9255328e19515f69362db35a89f7b14b": "### Technical Summary: Versioning Constraints in `versioning.py`\n\n#### Purpose\nThe file `/home/eliezer/devs/xcore/xcore/registry/versioning.py` is designed to manage version constraints for a registry system. It provides a class `VersionConstraint` that represents a version number and a function `satisfies` to check if one version satisfies a given constraint.\n\n#### Key Components\n1. **Class: VersionConstraint**\n - **Purpose**: Represents a version number with major, minor, and optional patch components.\n - **Methods**:\n - `parse(v: str) -> VersionConstraint`: Parses a string representation of a version into a `VersionConstraint` object.\n - `__str__() -> str`: Returns the string representation of the version constraint.\n\n2. **Function: satisfies(version_str: str, constraint_expr: str) -> bool**\n - **Purpose**: Checks if a given version satisfies a specified constraint expressed as a string.\n - **Parameters**:\n - `version_str`: A string representing the version to be checked.\n - `constraint_expr`: A string representing the constraint in the format ` `, where `` is an operator (`>=`, `<=`, `>`, `<`, `==`, `!=`) and `` is a version number.\n - **Returns**: `True` if the version satisfies the constraint, otherwise `False`.\n\n#### Dependencies\n- The file imports no external libraries.\n\n#### Interactions\n- This file interacts with other parts of the codebase through calls to `VersionConstraint.parse()` and `satisfies()`, which are used in various parts of the registry system to enforce versioning rules.", - "/home/eliezer/devs/xcore/xcore/registry/index.py:5d805e3f1c9700d509abfa9687512800ef176c3706eb2a46f0a5a959fd73a6d1": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/registry/index.py`\n\n#### Purpose\nThis file serves as the central registry for plugins in the XCore system. It manages a collection of plugins with metadata such as version, execution mode, dependencies, and descriptions. The registry also supports service management, allowing plugins to export services that can be accessed by other plugins.\n\n#### Key Components\n- **PluginRegistry Class**: Manages the registration, unregistration, and retrieval of plugins.\n - `register(name: str, handler: Any, metadata: dict | None = None)`: Registers a plugin with its handler and optional metadata.\n - `unregister(name: str)`: Unregisters a plugin by name.\n - `register_service(plugin_name: str, service_name: str, service_obj: Any, metadata: dict | None = None, scope: str = \"public\")`: Registers an exported service by a plugin.\n - `register_core_service(name: str, obj: Any, metadata: dict | None = None)`: Registers a core service with default protection.\n\n- **get_service(service_name: str, requester: str | None = None)`: Retrieves a service with optional scope checking.\n- **list_services()**: Returns a list of all services registered in the registry.\n- **has(name: str) -> bool**: Checks if a plugin is registered by name.\n- **get_info(name: str) -> dict[str, Any]**: Retrieves metadata for a specific plugin.\n- **all_plugins() -> list[dict[str, Any]]**: Returns a list of all plugins in the registry.\n- **all_names() -> list[str]**: Returns a list of all plugin names.\n- **dependents_of(plugin_name: str) -> list[str]**: Returns a list of plugins that depend on a specific plugin.\n- **required_by(plugin_name: str) -> list[str]**: Alias for `dependents_of`.\n- **plugins_by_mode(mode: str) -> list[str]**: Returns a list of plugins by their execution mode.\n- **search(query: str) -> list[dict]**: Searches for plugins based on name, description, or author (case-insensitive).\n- **summary() -> dict**: Provides a summary of the registry's contents.\n\n#### Dependencies\nThis file imports `logging` and uses type hints (`TYPE_CHECKING`) for better code readability and static type checking.\n\n#### Interactions\nThe registry interacts with other parts of the system through methods like `register`, `unregister`, and `get_service`. It also provides metadata retrieval and service management functionalities.", - "/home/eliezer/devs/xcore/xcore/sdk/manifest_schema.json:323ef9370765cd908cc05b41d9284395ccf2a514adf32203cd38dfabe091ccde": "### Technical Summary: xcore v2 Plugin Manifest Schema\n\n#### Purpose\nThe `manifest_schema.json` file serves as the schema for validating plugin configuration files in the xcore v2 framework. It defines a set of rules and constraints that ensure plugins adhere to a standardized format, facilitating interoperability and consistency across different environments.\n\n#### Key Components\n- **Name**: A unique identifier for the plugin.\n- **Version**: The version number of the plugin.\n- **Author**: The name of the developer or organization responsible for creating the plugin.\n- **Description**: A brief description of what the plugin does.\n- **Framework Version**: Specifies the minimum required xcore framework version.\n- **Entry Point**: The entry point script that will be executed when the plugin is loaded.\n- **Execution Mode**: Determines how the plugin executes (trusted, sandboxed, legacy).\n- **Requires**: Lists other plugins that this plugin depends on.\n- **Allowed Imports**: Defines Python packages that are allowed to be imported by the plugin.\n- **Permissions**: Specifies access controls for resources within the plugin environment.\n- **Env**: Environment variables that can be injected into the plugin.\n- **Env Configuration**: Configures how environment variables are handled (inject, file).\n- **Resources**: Limits on resource usage such as timeout, memory, and disk space.\n- **Runtime**: Defines health checks and retry policies for plugin execution.\n- **Filesystem**: Specifies allowed and denied paths in the filesystem.\n\n#### Dependencies\nThe `manifest_schema.json` file imports no external libraries beyond those required by JSON Schema itself. It relies on the xcore framework's core functionalities to validate the schema against the provided data.\n\n#### Interactions\nThis file interacts with other parts of the codebase through various mechanisms:\n- **Validation**: The file is used to validate plugin configuration files against a predefined schema.\n- **Configuration Loading**: Plugins use this schema to load their configurations from files or environment variables.\n- **Execution**: The validated configuration is passed to the plugin's entry point script for execution.\n\nThis schema ensures that plugins are consistent and secure, facilitating smooth integration within the xcore framework.", - "/home/eliezer/devs/xcore/xcore/sdk/plugin_base.py:32f0e639068920a3fa5e3e8b63d804cc87ec9296d560a2587dd3f98933da99ca": "### Technical Summary\n\n**Purpose**: This file defines a rich, typed representation of a plugin manifest in the XCore SDK. The manifest is parsed by `ManifestValidator` and replaces the simpler `_SimpleManifest` for more comprehensive use cases.\n\n**Key Components**:\n- **RateLimitConfig**: Configuration for rate limiting requests.\n- **ResourceConfig**: Configuration for resource limits such as timeout, memory, disk space, and rate limit.\n- **HealthCheckConfig**: Configuration for health checks.\n- **RetryConfig**: Maximum number of retries for the plugin.\n- **RuntimeConfig**: Runtime-specific configurations like health check and retry settings.\n- **FilesystemConfig**: Configuration for file system access restrictions.\n- **PluginDependency**: Represents a dependency on another plugin with version constraints.\n- **VersionConstraint**: Parses and evaluates version constraints for plugins.\n- **PluginManifest**: The main class representing the complete and typed manifest of a plugin.\n\n**Dependencies**:\n- `dataclasses`: For defining data classes.\n- `pathlib`: For handling file paths.\n- `typing`: For type annotations.\n- `..kernel.api.contract`: For execution mode definitions.\n\n**Interactions**:\n- This file imports `PluginDependency` from the same module to define dependencies on other plugins.\n- It calls into `VersionConstraint` to parse and evaluate version constraints for plugins.\n- The manifest is parsed by `ManifestValidator`, which uses this file to validate and process the manifest data.", - "/home/eliezer/devs/xcore/xcore/sdk/plugin_base.py:a2c980f03c46ceb3ab1c7f0f30ada4d0a40df5b9f00085a222e6556673be7de9": "### Technical Summary: Plugin Manifest\n\n#### Purpose\nThe `plugin_base.py` file serves as the foundation for defining and managing plugins within a software system. It encapsulates essential configuration parameters such as permissions, environment variables, resource limits, runtime settings, filesystem restrictions, and extra data.\n\n#### Key Components\n1. **PluginManifest Class**:\n - **Purpose**: Manages the metadata of a plugin.\n - **Key Attributes**:\n - `name`: The unique identifier for the plugin.\n - `version`: The version number of the plugin.\n - `execution_mode`: The mode in which the plugin operates (e.g., development, production).\n - `permissions`: A list of permissions required by the plugin.\n - `env`: An environment dictionary containing configuration settings.\n - `resources`: A `ResourceConfig` object defining resource limits for the plugin.\n - `runtime`: A `RuntimeConfig` object specifying runtime parameters like health checks and retries.\n - `filesystem`: A `FilesystemConfig` object defining file system restrictions.\n - `extra`: Additional data specific to the plugin.\n\n2. **__init__ Method**:\n - **Purpose**: Initializes a new instance of `PluginManifest`.\n - **Parameters**:\n - `raw`: A dictionary containing raw configuration data from an external source.\n - `resolved_env`: An environment dictionary with resolved values for variables.\n - **Description**: Parses the raw configuration, resolves environment variables, and constructs the `ResourceConfig`, `RuntimeConfig`, and `FilesystemConfig` objects.\n\n3. **__repr__ Method**:\n - **Purpose**: Provides a string representation of the `PluginManifest`.\n - **Description**: Returns a formatted string that includes the plugin's name, version, execution mode, and other metadata.\n\n#### Dependencies\n- The file imports no external libraries.\n- It relies on internal modules like `ResourceConfig`, `RuntimeConfig`, `FilesystemConfig`, and `HealthCheckConfig`.\n\n#### Interactions\n- This file is called by other parts of the codebase to configure plugins dynamically based on configuration files or user inputs.\n- Plugins can interact with each other through methods provided by these classes, such as setting up health checks or handling retries.", - "/home/eliezer/devs/xcore/xcore/sdk/routers.py:3310bb8a39b33adf47c420d037b2b708dca65654784e576dc12166e7229d7555": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/sdk/routers.py`\n\n#### Purpose:\nThis file defines a set of decorators for FastAPI routers, providing a standardized way to create routes with various attributes such as path, method, tags, summary, status code, response model, dependencies, permissions, and scopes.\n\n#### Key Components:\n1. **RouterRegistry Class**:\n - This class contains methods to register routes using the `router` decorator.\n - It provides methods for each HTTP verb (`get`, `post`, `put`, `delete`, `patch`) that return a decorated function.\n\n2. **Decorator Function**:\n - The `router` decorator takes several parameters such as path, method, tags, summary, status code, response model, dependencies, permissions, and scopes.\n - It returns a new function that sets the route attributes on the input function (`fn`) and wraps it in a router.\n\n3. **Route Instance Method**:\n - The `route_instance` method is used to create a route instance from an existing function decorated with `router`.\n - It takes a function as an argument and returns a new function that sets the route attributes on the input function (`fn`) and wraps it in a router.\n\n#### Dependencies:\n- This file imports `APIRouter` from `fastapi`.\n\n#### Interactions:\n- The `RouterRegistry` class is used to register routes, which are then used by FastAPI applications.\n- The `router` decorator is used to create routes with specific attributes, such as path and method, tags, summary, status code, response model, dependencies, permissions, and scopes.\n- The `route_instance` method allows for creating route instances from existing functions decorated with `router`, which can be useful in scenarios where the route definition needs to be reused or modified.", - "/home/eliezer/devs/xcore/xcore/sdk/decorators.py:6a30f5511faf044113cbea1d57c973d3ee5a889a27c8e6f86877b4ac2558484f": "### Technical Summary\n\n#### Purpose\nThe `decorators.py` file in the `/home/eliezer/devs/xcore/xcore/sdk/decorators.py` directory is a collection of utility decorators designed to enhance the functionality and security of plugins within an xCore v2 system. These decorators include actions, trusted methods, sandboxed methods, service requirements, payload validation, route definitions, and automatic router generation.\n\n#### Key Components\n1. **Actions**: Decorators for defining asynchronous methods that can be triggered by specific actions. Each action is associated with a unique name.\n2. **Trusted Methods**: Decorator to mark methods as trusted, meaning they should only be executed in trusted environments.\n3. **Sandboxed Methods**: Decorator to mark methods as compatible with sandboxed environments.\n4. **Service Requirements**: Decorator to ensure that required services are available before executing a method.\n5. **Payload Validation**: Decorator to validate incoming payloads against Pydantic models, returning an error response if validation fails.\n6. **Route Definitions**: Decorator to define HTTP routes using FastAPI, automatically mounting them on the app when the plugin is loaded.\n\n#### Dependencies\n- The file imports `functools`, `inspect`, and `logging` for utility functions.\n- It also imports `typing` for type annotations and `pydantic` for data validation.\n\n#### Interactions\n- **FastAPI**: The decorators integrate with FastAPI to define routes, handle requests, and manage dependencies.\n- **RBAC**: Decorators can be used to enforce role-based access control (RBAC) by checking required permissions.\n- **OAuth2 Scopes**: Decorators can be used to specify OAuth2 scopes for secure API calls.\n\n#### Summary\nThis file provides a comprehensive set of decorators that enhance the functionality and security of plugins in an xCore v2 system. It includes utilities for defining actions, trusted methods, sandboxed methods, service requirements, payload validation, route definitions, and automatic router generation. The decorators are designed to be flexible and can be combined with other mixins like `AutoDispatchMixin` to provide a robust framework for plugin development.", - "/home/eliezer/devs/xcore/xcore/sdk/decorators.py:ddd47cbd26be57165b2e0b283c1d2c97207f3dc0608102fbfedd5b26451015c9": "### Technical Summary: Decorators Module\n\n#### Purpose\nThe `decorators.py` file is designed to provide a set of decorators for enhancing the functionality of an application. These decorators are used to define actions that can be called by other parts of the system, allowing for modular and reusable code.\n\n#### Key Components\n1. **Action Decorator**:\n - **Purpose**: This decorator marks methods as actions that can be invoked through a specific action name.\n - **Usage**:\n ```python\n @action(\"greet\")\n async def greet(self, payload: dict) -> dict:\n return ok(msg=\"hello\")\n ```\n - **Description**: The `@action` decorator takes an action name as an argument and applies it to the decorated method. This allows for easy registration of actions that can be called by other parts of the system.\n\n2. **Handle Method**:\n - **Purpose**: This method is responsible for handling incoming requests based on the specified action name.\n - **Usage**:\n ```python\n async def handle(self, action_name: str, payload: dict) -> dict:\n from ..kernel.api.contract import error\n\n for attr_name in dir(self):\n method = getattr(self, attr_name, None)\n if (\n callable(method)\n and getattr(method, \"_xcore_action\", None) == action_name\n ):\n return await method(payload)\n\n available = [\n getattr(getattr(self, a), \"_xcore_action\")\n for a in dir(self)\n if callable(getattr(self, a, None))\n and hasattr(getattr(self, a), \"_xcore_action\")\n ]\n return error(\n f\"Action '{action_name}' inconnue. Disponibles : {available}\",\n \"unknown_action\",\n )\n ```\n - **Description**: The `handle` method iterates through all methods of the class and checks if they are callable and have an `_xcore_action` attribute set to the specified action name. If a match is found, it calls the corresponding method with the provided payload. If no matching action is found, it returns an error message indicating that the action is unknown.\n\n#### Dependencies\n- **Internal Modules**:\n - `..kernel.api.contract`: Contains utility functions for handling errors and responses.\n- **External Libraries**: None\n\n#### Interactions\n- **Called by**: Other parts of the system can call methods decorated with the `@action` decorator to invoke specific actions.\n- **Calls into**: The `handle` method is called by other parts of the system to process incoming requests based on the specified action name.\n- **Data Produced or Consumed**:\n - The `greet` and `bye` methods produce responses, while the `handle` method consumes incoming payloads and returns appropriate responses.", - "/home/eliezer/devs/xcore/xcore/sdk/__init__.py:7b6720e9786b742859207931f52b9ae58aba391b1785724197266bc697aeff61": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/sdk/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for the xCore SDK, providing a comprehensive set of utilities and classes essential for developing plugins. It includes foundational components such as `TrustedBase`, `PluginManifest`, and decorators to facilitate plugin development.\n\n#### Key Components:\n- **TrustedBase**: A base class for trusted plugins, ensuring they adhere to certain security standards.\n- **BasePlugin**: The main interface for all plugins, defining the contract for interacting with the xCore kernel.\n- **ok** and **error**: Simple functions used to return success or failure responses from plugins.\n- **ExecutionMode**: Enumerates different execution modes available in xCore.\n- **PluginManifest**: Represents the metadata of a plugin, including its name, version, and dependencies.\n- **ResourceConfig**: Configuration for resources managed by plugins.\n- **RuntimeConfig**: Configuration for the runtime environment of plugins.\n- **action**, **sandboxed**, **trusted**: Decorators used to control access and execution modes within plugins.\n- **require_service**, **validate_payload**: Functions used to enforce service requirements and payload validation in plugins.\n- **route**: A decorator for defining routes in plugin routers.\n- **RoutedPlugin**: A base class for plugins that can be routed through a router registry.\n- **AutoDispatchMixin**: A mixin for automatically dispatching actions based on the plugin's configuration.\n- **BaseAsyncRepository** and **BaseSyncRepository**: Interfaces for asynchronous and synchronous repositories, respectively.\n- **RBACChecker**, **require_permission**, and **require_role**: Functions used to enforce role-based access control in plugins.\n\n#### Dependencies:\nThis file imports several internal modules and external libraries:\n- `..kernel.api.contract`: Contains the contract definitions for plugins and the xCore kernel.\n- `..kernel.api.rbac`: Provides role-based access control functionality.\n- `./adapter.asyncsql`, `./adapter.syncsql`: Implementations of asynchronous and synchronous repositories, respectively.\n- `./decorators`, `./plugin_base`, `./routers`: Various utility modules and classes used throughout the SDK.\n\n#### Interactions:\nThe SDK interacts with other parts of the codebase through various mechanisms:\n- Plugins can import and use functions and classes from this file to interact with the xCore kernel.\n- The SDK provides decorators and utilities that plugins can use to control access, execution modes, and routing.\n- The SDK includes interfaces for asynchronous and synchronous repositories, which plugins can implement to manage resources efficiently.", - "/home/eliezer/devs/xcore/xcore/sdk/adapter/asyncsql.py:dfa1a03cbdff65635613e1f4fe1bddcfdfc41665ab32306c52ba3e76df3e7907": "### Technical Summary\n\n**Purpose**: This file provides an asynchronous repository for interacting with a database using SQLAlchemy. It encapsulates common CRUD operations such as retrieving, creating, updating, and deleting records.\n\n**Key Components**:\n- **BaseAsyncRepository**: An abstract base class that defines the interface for all repositories.\n- **T**: A type variable representing the model class associated with this repository.\n- **model**: The SQLAlchemy model class used by the repository.\n- **session**: An asynchronous session object provided by SQLAlchemy to interact with the database.\n\n**Dependencies**:\n- `abc`: For abstract base classes.\n- `Generic`, `List`, `Optional`, and `TypeVar`: For type annotations.\n- `sqlalchemy`: For database operations.\n- `asyncio`: For asynchronous programming.\n\n**Interactions**:\n- The repository interacts with the database through an asynchronous session object (`session`).\n- It provides methods to perform CRUD operations such as `get_by_id`, `get_all`, `create`, `update`, `delete`, and `update_c9`.\n- These methods handle database queries, data manipulation, and result handling using SQLAlchemy's ORM capabilities.", - "/home/eliezer/devs/xcore/xcore/sdk/adapter/syncsql.py:05308a21a3110477fa1186290fb0240cc635ce5b92dbe2347fed9bf4bfb5cabd": "### Technical Summary: SyncSQL Repository\n\n#### Purpose\nThe `SyncSQLRepository` class is designed to manage database interactions for a specific model using SQLAlchemy. It provides methods to perform CRUD operations (Create, Read, Update, Delete) on the specified model.\n\n#### Key Components\n- **BaseSyncRepository**: An abstract base class that defines common methods for all repositories.\n - **model**: The SQLAlchemy model associated with this repository.\n - **session**: A SQLAlchemy session object used for database transactions.\n\n- **get_by_id**: Retrieves a record by its ID from the database.\n- **get_all**: Fetches all records of the specified model from the database.\n- **create**: Adds a new record to the database and commits the transaction.\n- **update**: Updates an existing record in the database based on its ID and provided data.\n- **delete**: Deletes a record from the database by its ID.\n- **get_by_name**: Retrieves a record by its name from the database.\n\n#### Dependencies\n- SQLAlchemy: The ORM used for interacting with the database.\n- `abc`: For abstract base classes.\n- `typing`: For type annotations.\n\n#### Interactions\n- This repository is called by other parts of the codebase to perform CRUD operations on the specified model. It interacts with the database through the provided session object, which is managed by SQLAlchemy.", - "/home/eliezer/devs/xcore/xcore/services/__init__.py:54b0e5f41df36749c7444d62d04486c8b01cd0aa43657ce9dafb098fe1fbd618": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/services/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for the integration layer of xcore v2 services. It initializes, orchestrates, and exposes all services within the system.\n\n#### Key Components:\n1. **ServiceContainer**:\n - Initializes, orchestrates, and exposes all services.\n - Injects services into plugins via `PluginContext.services`.\n\n2. **BaseService**:\n - Base class for all services in xcore v2.\n - Defines common methods and properties for service management.\n\n3. **ServiceStatus**:\n - Enum representing the status of a service (e.g., running, stopped).\n\n#### Dependencies:\n- This file imports or relies on internal modules (`base.py`, `container.py`) and external libraries (not specified in the given snippet).\n\n#### Interactions:\n- The `ServiceContainer` class is responsible for managing all services.\n- It initializes the container with configuration settings from `config.services`.\n- Services are injected into plugins through `PluginContext.services`.\n- The `ServiceContainer` exposes services to other parts of the codebase, allowing them to interact with the services using the `container.get()` method.\n\n#### Usage:\nTo use the `ServiceContainer`, you can follow these steps:\n1. Import the necessary modules and classes.\n2. Create an instance of `ServiceContainer` with configuration settings.\n3. Initialize the container using `await container.init()`.\n4. Access services using `container.get(\"service_name\")`.\n5. Shutdown the container using `await container.shutdown()`.\n\nThis file provides a structured way to manage and expose services in xcore v2, ensuring that all services are properly initialized, managed, and interacted with by other parts of the codebase.", - "/home/eliezer/devs/xcore/xcore/services/base.py:a0515be064bec30b52dbef9166746eb8d2f77955ed618ad4afb299af084bebe1": "### Technical Summary\n\n**Purpose**: The `base.py` file serves as a common interface for all services within the xcore system. It provides a standardized way to manage and interact with these services, ensuring consistency across different components of the application.\n\n**Key Components**:\n1. **ServiceStatus Enum**: Defines the possible states a service can be in (uninitialized, initializing, ready, degraded, failed, stopped).\n2. **BaseService ABC**: An abstract base class for all services that must implement methods to initialize, shutdown, and check health.\n3. **MyService Class**: A concrete implementation of `BaseService` that demonstrates how to use the service interface. It includes methods for initializing, shutting down, checking health, and providing a status report.\n\n**Dependencies**:\n- The file imports `abc`, `enum`, and `typing`.\n- It uses type hints (`TYPE_CHECKING`) for better code readability and static type checking.\n\n**Interactions**:\n- The `BaseService` class is designed to be called by other parts of the system, passing a `ServiceContainer` object.\n- The `BaseServiceProvider` abstract base class provides a method to initialize services within a container, encapsulating the initialization logic for multiple services.", - "/home/eliezer/devs/xcore/xcore/services/container.py:b0d2876791f57da4f3d6e70c06089e0a803d3fde4863b56c20e5641ea1c3a48d": "### Purpose\n\nThe `container.py` file in the XCore project serves as a central service container that manages various services such as databases, caches, schedulers, and extensions. It handles dependency injection, lifecycle management, and type safety for accessing these services.\n\n### Key Components\n\n1. **DatabaseServiceProvider**:\n - Initializes the database manager with configurations from `ServicesConfig`.\n - Registers the database adapter in the container.\n - Logs a message indicating the databases available.\n\n2. **CacheServiceProvider**:\n - Initializes the cache service with configuration from `ServicesConfig`.\n - Registers the cache service in the container.\n - Logs a message indicating the backend of the cache.\n\n3. **SchedulerServiceProvider**:\n - Initializes the scheduler service with configuration from `ServicesConfig`.\n - Registers the scheduler service in the container.\n - Logs a message indicating that the scheduler is ready.\n\n4. **ExtensionServiceProvider**:\n - Initializes the extension loader with configurations from `ServicesConfig`.\n - Registers the extensions in the container.\n - Logs a message indicating the extensions available.\n\n5. **ServiceContainer**:\n - Manages a dictionary of services and raw objects.\n - Provides methods to register services, lazy providers, and access them by name.\n - Handles type inference for known service names using `overload`.\n - Raises a KeyError if a service is not found.\n\n### Dependencies\n\n- The file imports necessary modules such as `asyncio`, `logging`, and `typing`.\n- It uses the `TypeVar` and `Literal` types from `typing_extensions` for type hints.\n- It relies on the `BaseServiceProvider` class for managing services.\n\n### Interactions\n\n- **Initialization**:\n - The `init` method initializes all registered providers in the order specified (`database \u2192 cache \u2192 scheduler \u2192 extensions`).\n - It logs a success message indicating that services have been initialized.\n\n- **Shutdown**:\n - The shutdown process reverses the initialization order (`extensions \u2192 scheduler \u2192 cache \u2192 database`).\n\n- **Accessing Services**:\n - The `get` method retrieves a service by name, handling known types and providing type hints for custom connections.\n - It raises a KeyError if the service is not found.\n\n### Usage\n\nTo use the `ServiceContainer`, you can create an instance with your configuration and call the `init` method. After initialization, you can access services using their names, which are typed according to the configurations in `xcore.yaml`.\n\n```python\nfrom xcore.services.container import ServiceContainer\nfrom xcore.configurations.sections import ServicesConfig\n\nconfig = ServicesConfig()\ncontainer = ServiceContainer(config)\nawait container.init()\n\ndb = container.get(\"db\") # type: AsyncSQLAdapter\ncache = container.get(\"cache\") # type: CacheService\nscheduler = container.get(\"scheduler\") # type: SchedulerService\n```\n\nThis setup ensures that all services are properly managed and can be accessed with clear type hints, enhancing code readability and maintainability.", - "/home/eliezer/devs/xcore/xcore/services/container.py:1a2b8fba116129fea25bae9d5ef9bbb6085259d454bb12cada75fb002759d5fa": "### Technical Summary\n\n#### Purpose\nThe `container.py` file is a service container for managing and initializing various services within the XCore system. It provides methods to retrieve, create, and manage different types of services such as analytics and MongoDB adapters.\n\n#### Key Components\n- **get_as(name, type_)**: Retrieves a service by its name and ensures it matches the specified type.\n - Example usage: `analytics = container.get_as(\"analytics\", AsyncSQLAdapter)`\n- **get_or_none(name)**: Returns `None` if the service is not found, otherwise returns the service instance.\n - Example usage: `svc = container.get_or_none(\"mongo\")`\n- **has(name)**: Checks if a service with the given name exists in the container.\n - Example usage: `if container.has(\"analytics\"):`\n- **as_dict()**: Returns a reference to the internal dictionary containing all services, shared with plugins.\n - Example usage: `services = container.as_dict()`\n\n#### Dependencies\nThe file imports:\n- `asyncio` for asynchronous operations.\n- `logger` for logging service status and errors.\n- `AsyncSQLAdapter`, `MongoDBAdapter` (assuming these are external classes).\n\n#### Interactions\n- **shutdown()**: Stops all services in the container in reverse order, handling timeouts and exceptions gracefully.\n - Example usage: `await container.shutdown()`\n- **health()**: Checks the health of each service and returns a dictionary with results.\n - Example usage: `results = await container.health()`\n\nThis file is crucial for managing the lifecycle and status of services within the XCore system, ensuring that all necessary components are properly initialized and managed.", - "/home/eliezer/devs/xcore/xcore/services/cache/__init__.py:df8a6fd071a4122c6ea9171400a55a251e92d8fb34ffa999ed70870e9865b863": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/services/cache/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for the cache service in the XCore project. It defines the main classes and functions that handle caching operations, including memory and Redis backends.\n\n#### Key Components:\n1. **CacheService**: This class is responsible for managing the overall cache functionality. It provides methods to interact with different cache backends.\n2. **MemoryBackend**: A concrete implementation of a cache backend using in-memory storage. It stores data temporarily until it expires or is explicitly cleared.\n3. **RedisCacheBackend**: Another concrete implementation of a cache backend using Redis as the underlying storage mechanism. It supports more advanced features like expiration times and key prefixes.\n\n#### Dependencies:\n- The file imports `MemoryBackend` and `RedisCacheBackend` from the respective modules within the same directory.\n- It also imports `CacheService` from the same module.\n\n#### Interactions:\n- **Calls into**: The `CacheService` class is called by other parts of the system to perform cache operations such as setting, getting, and deleting items.\n- **Data produced or consumed**: The `CacheService` interacts with both memory and Redis backends to store and retrieve data. It also handles expiration times for cached items.\n\nThis file provides a clear structure for managing caching in the XCore project, ensuring that different cache implementations can be easily swapped out without affecting the rest of the system.", - "/home/eliezer/devs/xcore/xcore/services/cache/service.py:d0eb964350e88cf825219d3643196150983066da0ae09aa274e2bf8615bb699f": "### Technical Summary\n\n**Purpose**: The `service.py` file serves as a facade for managing a unified cache system in the XCore project. It provides an interface that plugins do not need to know about the specific backend being used (either Redis or memory). The service ensures consistency across different backends by providing a uniform API.\n\n**Key Components**:\n- **CacheService**: A class that encapsulates the logic for interacting with the cache. It initializes the appropriate backend based on configuration and provides methods for setting, getting, deleting, checking existence, clearing, and listing keys.\n- **RedisCacheBackend**: A concrete implementation of the `BaseService` interface using Redis as the backend.\n- **MemoryBackend**: Another concrete implementation that uses in-memory storage.\n\n**Dependencies**:\n- The file imports necessary modules such as `logging`, `typing`, and `asyncio`.\n- It relies on external libraries like `redis` for Redis support.\n\n**Interactions**:\n- The `CacheService` class interacts with the backend through methods like `get`, `set`, `delete`, `exists`, `clear`, `keys`, `mget`, `mset`, `shutdown`, and `health_check`.\n- These interactions are handled internally by the respective backends (`RedisCacheBackend` or `MemoryBackend`).\n\n**Cycle of Life**:\n- The service starts in the `INITIALIZING` state, initializes the backend based on configuration, and transitions to the `READY` state once initialized.\n- It handles shutdown gracefully by disconnecting from the backend if necessary.\n- The health check method verifies the connection status of the backend.\n\nThis file serves as a central point for managing cache operations in the XCore project, ensuring consistency across different storage options.", - "/home/eliezer/devs/xcore/xcore/services/cache/backends/__init__.py:ffa16495bf38a36b65e21aedfdd8923b3a91fa27f221e1778226c36d123c9099": "### Technical Summary: Cache Backend API\n\n#### Purpose\nThis file provides an API for managing different types of cache backends in a software project. It allows developers to easily switch between memory and Redis caching mechanisms.\n\n#### Key Components\n- **`MemoryBackend`**: Manages data in memory, suitable for development environments or small-scale applications.\n- **`RedisCacheBackend`**: Uses Redis as the backend storage system, ideal for production environments where high availability and scalability are required.\n\n#### Dependencies\nThis file imports `MemoryBackend` and `RedisCacheBackend` from internal modules within the same package. It does not rely on external libraries beyond Python's standard library.\n\n#### Interactions\n- **Calls into**: The API is called by other parts of the codebase to instantiate and use cache backends.\n- **Data produced or consumed**: The API manages data stored in memory or Redis, facilitating operations like setting, getting, and deleting items from the cache.", - "/home/eliezer/devs/xcore/xcore/services/cache/backends/memory.py:7b552579d99748f936db1f3e7d3c2469f8b61df70f73727acdc85b04ac79c25e": "### Technical Summary: Memory Backend Cache\n\n#### Purpose\nThe `MemoryBackend` class is designed to provide a simple in-memory cache with Least Recently Used (LRU) eviction policy and Time To Live (TTL) functionality. It ensures that the cache does not grow indefinitely by automatically removing entries that have expired or are least recently used.\n\n#### Key Components\n- **_Entry Class**: Represents an entry in the cache, storing the value and its expiration time.\n- **MemoryBackend Class**: The main class responsible for managing the cache operations:\n - `__init__`: Initializes the cache with TTL and maximum size.\n - `get(key)`: Retrieves a value from the cache. If the key does not exist or has expired, it returns `None`.\n - `set(key, value, ttl=None)`: Sets a value in the cache with an optional TTL. If no TTL is provided, it uses the default TTL.\n - `delete(key)`: Deletes a key from the cache.\n - `exists(key)`: Checks if a key exists in the cache.\n - `clear()`: Clears all entries from the cache.\n - `mget(keys)`: Retrieves multiple keys at once. Returns a dictionary of values or `None` for missing keys.\n - `mset(mapping, ttl=None)`: Sets multiple key-value pairs at once. If no TTL is provided, it uses the default TTL.\n - `keys(pattern=None)`: Returns all keys in the cache that match a given pattern (if any).\n - `ttl(key)`: Retrieves the remaining time to live for a specific key.\n - `ping()`: A placeholder method indicating that the backend is operational.\n - `stats()`: Provides statistics about the cache, including size, hits, misses, and hit rate.\n\n#### Dependencies\n- None\n\n#### Interactions\n- The `MemoryBackend` class interacts with other parts of the system through asynchronous methods (`async def`) to ensure non-blocking operations. It uses an ordered dictionary to maintain the LRU order of entries and a simple counter for hits and misses to track cache performance.", - "/home/eliezer/devs/xcore/xcore/services/cache/backends/redis.py:291ed17f198be4e59dbc911da6f7765157fd318f1fc5df933a72492c3d9cbb5b": "### Technical Summary: Redis Cache Backend for CacheService\n\n#### Purpose\nThe `redis.py` file serves as a backend cache for the `CacheService`. It provides JSON serialization support for all Python types, allowing for efficient storage and retrieval of data in a Redis database.\n\n#### Key Components\n1. **RedisCacheBackend Class**:\n - Initializes with a Redis URL and an optional TTL (time to live) for keys.\n - Connects to the Redis server using `aioredis`.\n - Disconnects from the Redis server when done.\n - Provides methods to get, set, mget, mset, delete, exists, clear, keys, ttl, ping, and stats.\n\n2. **Dependencies**:\n - Imports `json` for JSON serialization/deserialization.\n - Imports `logging` for logging purposes.\n - Imports `typing` for type hints.\n - Imports `aioredis.asyncio` for asynchronous Redis operations.\n\n3. **Interactions**\n - The file interacts with the Redis server through methods like `connect`, `disconnect`, `get`, `set`, `mget`, `mset`, `delete`, `exists`, `clear`, `keys`, `ttl`, `ping`, and `stats`.\n\n#### Usage\nTo use this backend, you can create an instance of `RedisCacheBackend` with the Redis URL and optional TTL. You can then call methods like `connect()` to establish a connection, `get(key)` to retrieve data by key, `set(key, value)` to store data, and so on.\n\n#### Example Usage\n```python\nbackend = RedisCacheBackend(url=\"redis://localhost:6379\", ttl=300)\nawait backend.connect()\nawait backend.set(\"key\", {\"data\": 1})\nvalue = await backend.get(\"key\")\n```\n\nThis setup allows for efficient caching of data in a Redis database, leveraging JSON serialization to handle various Python types.", - "/home/eliezer/devs/xcore/xcore/services/database/__init__.py:5f9e16e84959f639ef2fb9a8f878c6814586945820b41fdac43301680bda13ba": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/services/database/__init__.py`\n\n#### Purpose:\nThis file serves as the entry point for database-related services within the `xcore` project. It provides a centralized location to manage different types of database adapters and their interactions with the system.\n\n#### Key Components:\n1. **DatabaseManager**: A class responsible for managing the overall database operations, including initialization, configuration, and data persistence.\n2. **SQLAdapter**: An adapter that interacts with SQL databases using SQLAlchemy.\n3. **AsyncSQLAdapter**: An asynchronous version of `SQLAdapter` optimized for handling high-performance applications.\n4. **MongoDBAdapter**: An adapter that connects to MongoDB databases using PyMongo.\n5. **RedisAdapter**: An adapter that communicates with Redis databases using the redis-py library.\n\n#### Dependencies:\n- The file imports several internal modules and external libraries:\n - `asyncio` for asynchronous operations.\n - `sqlalchemy` for SQL database interactions.\n - `pymongo` for MongoDB interactions.\n - `redis-py` for Redis interactions.\n\n#### Interactions:\n- **Initialization**: The `DatabaseManager` class initializes the database connections and sets up the necessary configurations.\n- **Data Persistence**: It handles data insertion, retrieval, and updates across different databases.\n- **Asynchronous Operations**: The `AsyncSQLAdapter` allows for efficient asynchronous database operations, suitable for high-load applications.\n- **Integration with Other Services**: The adapters are integrated into other services within the system to ensure seamless data management.\n\nThis file serves as a central hub for managing various types of database interactions, ensuring that all database-related functionalities are organized and easily accessible.", - "/home/eliezer/devs/xcore/xcore/services/database/manager.py:53cbcda22a638612a2c3166e1f9eaee5b0610e0494ee880b2ff83ea0f26f7078": "### Technical Summary\n\n**Purpose**: The `manager.py` file is responsible for managing multiple types of databases within an application. It dynamically selects the appropriate adapter based on the configuration settings and provides methods to connect, disconnect, and perform health checks on these databases.\n\n**Key Components**:\n- **DatabaseManager Class**: Extends `BaseService` from a base module. Manages a dictionary of database adapters.\n- **init Method**: Initializes the manager by connecting to each configured database using the `_build_adapter` method. Logs successful connections and errors.\n- **_build_adapter Method**: Creates an instance of the appropriate adapter class based on the configuration type.\n- **shutdown Method**: Disconnects all databases and clears the adapter dictionary, setting the service status to `STOPPED`.\n- **health_check Method**: Checks the health of each database by attempting a ping operation. Logs successful connections and errors.\n- **status Method**: Returns a dictionary containing the name, current status, and URLs of connected databases.\n\n**Dependencies**:\n- The file imports necessary modules such as `logging`, `typing`, and `asyncio`.\n- It relies on an external configuration module (`configurations.sections`) for database configurations.\n\n**Interactions**:\n- The manager interacts with the rest of the codebase through methods like `init`, `shutdown`, and `health_check`. It also provides a method to retrieve the current status of all databases.", - "/home/eliezer/devs/xcore/xcore/services/database/migrations.py:b90903ea6e35d9ce0d25fdb83b0c3db7baa7d5fc5a14db4beabf6641ce092f9a": "### Technical Summary: Database Migrations in Xcore Services\n\n#### Purpose\nThe `migrations.py` file serves as a wrapper for Alembic, a database migration tool. It provides a convenient interface to manage schema changes in the Xcore services project.\n\n#### Key Components\n- **MigrationError**: An exception class used to handle errors during migration operations.\n- **MigrationRunner**: A class responsible for running migrations on the database. It handles both synchronous and asynchronous operations based on the database URL.\n\n#### Dependencies\n- **alembic**: The core library for Alembic, which is required for managing database schema changes.\n- **sqlalchemy.ext.asyncio**: For handling asynchronous database connections if necessary.\n\n#### Interactions\n- **Upgrade**: The `upgrade` method applies all pending migrations to the database. It supports both synchronous and asynchronous execution.\n- **Downgrade**: The `downgrade` method reverses the last migration applied to the database. It also supports asynchronous execution.\n- **Revison**: The `revison` method generates a new migration script based on provided parameters. It supports asynchronous execution.\n- **Status**: The `status` method provides information about the current state of migrations, including the list of applied and pending revisions.\n\n#### Usage\nIn a Trusted plugin, the `MigrationRunner` class is used to manage database migrations. It initializes with the database URL and migration directory, then provides methods to upgrade, downgrade, generate revisions, and check the status of migrations. This setup ensures that database schema changes are managed efficiently and securely within the Xcore services project.", - "/home/eliezer/devs/xcore/xcore/services/database/adapters/__init__.py:f18fb51865459cc64e053813316b69750c8452485dcd3bf1fe9126475b46a90a": "### Technical Summary\n\n**Purpose**: This file serves as a central hub for managing database adapters within the xcore v2 project. It provides a unified interface for interacting with various types of databases, ensuring consistency and abstraction across different data storage solutions.\n\n**Key Components**:\n- **DatabaseAdapterBase**: A base class that defines the common interface for all database adapters.\n - **__init__**: Initializes the adapter with necessary parameters such as connection details.\n - **connect**: Establishes a connection to the database.\n - **disconnect**: Closes the database connection.\n - **execute_query**: Executes SQL queries and returns results.\n\n- **MySQLAdapter**: A concrete implementation of `DatabaseAdapterBase` for MySQL databases.\n - **__init__**: Initializes with specific MySQL connection details.\n - **execute_query**: Implements a method to execute SQL queries using the MySQL client library.\n\n- **PostgreSQLAdapter**: Another concrete implementation of `DatabaseAdapterBase` for PostgreSQL databases.\n - **__init__**: Initializes with specific PostgreSQL connection details.\n - **execute_query**: Implements a method to execute SQL queries using the psycopg2 library.\n\n**Dependencies**:\n- The file imports `DatabaseAdapterBase` from the same directory.\n- It relies on external libraries such as `mysqlclient` for MySQL and `psycopg2` for PostgreSQL.\n\n**Interactions**:\n- The `__init__.py` file is called by other modules in the project to instantiate database adapters.\n- Adapters are used throughout the system to interact with different databases, ensuring that all database operations are handled uniformly.", - "/home/eliezer/devs/xcore/xcore/services/database/adapters/mongodb.py:8e8440672c45dd9831075a224d3747d2d96cc1d18197badba3b0ef281c12d8f2": "### Technical Summary: MongoDB Adapter via Motor\n\n#### Purpose\nThe `mongodb.py` file serves as an asynchronous MongoDB adapter using the Motor library. It provides a high-level interface for interacting with MongoDB databases in Python.\n\n#### Key Components\n1. **MongoDBAdapter Class**:\n - Initializes the MongoDB connection parameters.\n - Manages the client and database connections.\n - Provides methods to interact with collections and databases.\n\n2. **connect() Method**:\n - Establishes a connection to the MongoDB server using Motor's `AsyncIOMotorClient`.\n - Sets up the maximum number of connections and server selection timeout.\n - Verifies the connection by sending a ping command.\n\n3. **disconnect() Method**:\n - Closes the MongoDB client and database connections if they are open.\n - Ensures proper cleanup to prevent resource leaks.\n\n4. **collection() Method**:\n - Returns a collection object from the current database.\n - Throws an error if the database is not initialized.\n\n5. **database() Method**:\n - Returns the current database object.\n - Throws an error if the database is not initialized.\n\n6. **ping() Method**:\n - Sends a ping command to the MongoDB server and returns the result.\n - Throws an exception if the connection fails.\n\n#### Dependencies\n- Motor: The asynchronous MongoDB client library used for interacting with MongoDB databases.\n- Configurations Section: A configuration section that holds database connection details such as URL, database name, and maximum connections.\n\n#### Interactions\n- **Initialization**: The adapter is initialized with a name and a `DatabaseConfig` object.\n- **Connection**: The `connect()` method establishes the connection to the MongoDB server.\n- **Disconnection**: The `disconnect()` method closes the client and database connections.\n- **Collection Access**: The `collection()` method returns a collection object for further operations.\n- **Database Access**: The `database()` method returns the current database object.\n- **Ping Check**: The `ping()` method verifies the connection to the MongoDB server.\n\nThis adapter provides a robust and asynchronous interface for interacting with MongoDB databases in Python, making it suitable for high-performance applications.", - "/home/eliezer/devs/xcore/xcore/services/database/adapters/redis.py:fde4b70c0074efc1f3b70962024a5f226df68d9a2d1c852fcb03070b5a811c4e": "### Technical Summary: Redis Adapter for Asynchronous Redis Operations in XCore Services\n\n#### Purpose\nThe `redis.py` file serves as an asynchronous adapter for interacting with Redis databases. It provides a high-level interface to perform common Redis operations such as setting, getting, deleting, and handling hash data.\n\n#### Key Components\n- **RedisAdapter Class**: This class encapsulates the functionality of connecting to Redis, performing operations, and managing connections.\n - `__init__`: Initializes the adapter with a name and database configuration.\n - `connect()`: Establishes an asynchronous connection to Redis using `aioredis`.\n - `disconnect()`: Closes the Redis connection if it is open.\n - `get(key)`, `set(key, value, ex=None)`, `delete(*keys)`, `exists(key)`, `hget(name, key)`, `hset(name, mapping)`, `hgetall(name)`: Methods for interacting with Redis keys and hash data.\n- **client Property**: Allows direct access to the underlying `aioredis.Redis` client instance.\n\n#### Dependencies\nThe file imports `redis.asyncio` from `aioredis` which is used for asynchronous Redis operations. It also relies on the `DatabaseConfig` class from the `xcore.configurations.sections` module, which contains configuration settings for the database connection.\n\n#### Interactions\n- The adapter connects to Redis when initialized.\n- It can be disconnected using the `disconnect()` method.\n- Operations like setting and getting data are asynchronous, making it suitable for high-performance applications.\n- The adapter handles exceptions gracefully and logs information about its status.", - "/home/eliezer/devs/xcore/xcore/services/database/adapters/sql.py:978863c8c91b02b2e7ab331f81a385baf6bee0203874942a0d4c56b8c4e4dc43": "### Technical Summary: SQLAdapter\n\n#### Purpose\nThe `SQLAdapter` class is designed to provide a synchronous interface for interacting with databases using SQLAlchemy. It allows developers to execute SQL queries and manage database sessions efficiently.\n\n#### Key Components\n- **Initialization**: The `__init__` method initializes the adapter with the database name, configuration settings, and engine details.\n- **Connection Management**:\n - `connect()`: Establishes a connection to the database using SQLAlchemy's `create_engine`.\n - `disconnect()`: Closes the database connection.\n- **Session Management**:\n - `session()`: Provides a context manager for managing database sessions. It automatically commits changes and handles exceptions, ensuring data integrity.\n- **Query Execution**:\n - `execute(sql: str, params: dict | None = None)`: Executes SQL queries with optional parameters. It returns the result of the query.\n - `ping()`: Tests the connection to the database and returns a tuple indicating whether the test was successful and any error message.\n\n#### Dependencies\n- **SQLAlchemy**: The adapter relies on SQLAlchemy for database operations, which must be installed via `pip install sqlalchemy`.\n\n#### Interactions\n- **Database Connection**: The adapter connects to the database using the provided configuration settings.\n- **Session Management**: It manages database sessions using SQLAlchemy's ORM, ensuring that transactions are handled correctly and resources are properly released.\n- **Query Execution**: The adapter allows developers to execute SQL queries with optional parameters, returning the results of the query.\n- **Connection Testing**: The `ping()` method tests the connection to the database and provides feedback on its status.", - "/home/eliezer/devs/xcore/xcore/services/database/adapters/async_sql.py:c03459b0d79eb646170cb410769c7589555147a64cbc4ca75488895cb8844720": "### Technical Summary: AsyncSQLAdapter\n\n#### Purpose\nThe `AsyncSQLAdapter` class provides an asynchronous interface to interact with a database using SQLAlchemy. It allows developers to execute SQL queries, manage sessions, and handle transactions in an asynchronous manner.\n\n#### Key Components\n- **Initialization**: The adapter is initialized with the name of the database and configuration settings.\n- **Connection Management**:\n - `connect()`: Establishes a connection to the database using SQLAlchemy's async engine.\n - `disconnect()`: Closes the database connection.\n- **Session Handling**:\n - `session()`: Provides an asynchronous context manager for managing database sessions. It automatically commits changes and handles exceptions.\n- **Query Execution**:\n - `execute(sql: str, params: dict | None = None)`: Executes a SQL query with optional parameters.\n- **Ping Functionality**:\n - `ping()`: Checks the connection to the database and returns a tuple indicating whether the connection is active and any error message.\n\n#### Dependencies\nThe adapter depends on SQLAlchemy for its functionality. It requires the `sqlalchemy[asyncio]` package, which can be installed using pip:\n```sh\npip install sqlalchemy[asyncio]\n```\n\n#### Interactions\n- The adapter interacts with the rest of the codebase through methods like `connect()`, `disconnect()`, and `session()`. These methods are used to manage database connections and sessions.\n- The adapter also allows executing SQL queries using the `execute()` method, which takes a SQL statement and optional parameters.\n\nThis class provides a robust and asynchronous interface for interacting with databases in Python applications.", - "/home/eliezer/devs/xcore/xcore/services/extensions/__init__.py:2f519c7b9f7fa9fe092ba47dfc11f05f323076232b305c5659d009c8371b2dc9": "### Technical Summary: `/home/eliezer/devs/xcore/xcore/services/extensions/__init__.py`\n\n#### Purpose\nThis file serves as the entry point for extension management in the XCore system. It provides a centralized location to load and manage various extensions, facilitating the integration of third-party functionality into the core application.\n\n#### Key Components\n1. **ExtensionLoader Class**:\n - **Description**: This class is responsible for loading and initializing all available extensions.\n - **Usage**: Extensions are typically loaded by this class during the initialization phase of the XCore system.\n\n2. **__all__ List**:\n - **Description**: The `__all__` list specifies which modules and functions should be imported when this file is used as a module in other parts of the codebase.\n - **Usage**: This ensures that only necessary components are exposed to external users, enhancing encapsulation.\n\n#### Dependencies\n1. **Internal Modules**:\n - **Description**: The `ExtensionLoader` class relies on internal modules such as `xcore.services.extensions.loader`, which handles the loading logic for extensions.\n - **Usage**: These modules provide the core functionality required by the `ExtensionLoader`.\n\n2. **External Libraries**:\n - **Description**: No external libraries are explicitly imported or relied upon in this file.\n - **Usage**: The focus is on internal implementation details and system integration.\n\n#### Interactions\n1. **Called By**:\n - **Description**: This file is called by the main entry point of the XCore application to initialize extension management.\n - **Usage**: It ensures that all extensions are loaded before any other parts of the system start running.\n\n2. **Calls Into**:\n - **Description**: The `ExtensionLoader` class calls into internal modules and external services as needed during its initialization process.\n - **Usage**: This allows for seamless integration with other components of the XCore system.\n\n3. **Data Produced or Consumed**:\n - **Description**: The `ExtensionLoader` class does not produce any data directly but consumes it by loading extensions, which are then used throughout the application.\n - **Usage**: This ensures that all necessary functionality is available for use within the XCore system.", - "/home/eliezer/devs/xcore/xcore/services/extensions/loader.py:7f4a81f2869b3fe7ce19c76f684d057165ef051496fb6248233785bc819a6087": "### Technical Summary\n\n**Purpose**: The `loader.py` file in the `/home/eliezer/devs/xcore/xcore/services/extensions/` directory is responsible for loading and managing external services defined in the `xcore.yaml` configuration. It allows developers to declare custom services that inherit from a base class or expose specific methods like `init()`, `shutdown()`, `health_check()`, and `status()`.\n\n**Key Components**:\n- **ExtensionLoader Class**: Inherits from `BaseService`. Manages the loading, initialization, shutdown, health check, and status of extensions.\n- **load Method**: Imports a module based on the provided path and class name. It also handles configuration settings for each service.\n- **init Method**: Initializes all loaded services. It logs success or failure for each extension.\n- **shutdown Method**: Shuts down all loaded services. It logs any errors that occur during shutdown.\n- **health_check Method**: Checks the health of all loaded services and returns a tuple indicating whether all extensions are healthy and their status messages.\n\n**Dependencies**:\n- The file imports `importlib` for dynamic module loading and `logging` for logging purposes.\n- It relies on the `BaseService` class from the same directory, which provides common functionality for service management.\n\n**Interactions**:\n- The `ExtensionLoader` class is called by the main application to load and manage services defined in the configuration file. It interacts with other parts of the codebase through methods like `init()`, `shutdown()`, and `health_check()`.\n\nThis file plays a crucial role in extending the functionality of xcore by allowing developers to integrate third-party services seamlessly into their applications.", - "/home/eliezer/devs/xcore/xcore/services/scheduler/__init__.py:a9b8cda273322bd5623b8f9ccd01e3decfbbba3bff8516066ef408dd686377cb": "### Technical Summary of `/home/eliezer/devs/xcore/xcore/services/scheduler/__init__.py`\n\n#### Purpose\nThis file serves as the entry point for the scheduler service within the XCore project. It defines the main class `SchedulerService` which is responsible for managing and executing scheduled tasks.\n\n#### Key Components\n- **Main Class**: `SchedulerService`\n - This class encapsulates all functionalities related to scheduling tasks.\n - It provides methods for adding, removing, and executing scheduled jobs.\n - The class interacts with other components like task queues and database services.\n\n#### Dependencies\n- **Internal Modules**:\n - `service`: Contains the implementation of the `SchedulerService`.\n- **External Libraries**:\n - None\n\n#### Interactions\n- **Called by**: Other parts of the XCore system that need to manage scheduled tasks.\n- **Calls into**: The `SchedulerService` class provides methods for interacting with task queues and database services.\n- **Data Produced or Consumed**: The `SchedulerService` manages a queue of scheduled jobs, which are then processed by other components. It also interacts with a database to store and retrieve job details.\n\nThis file is crucial for orchestrating the execution of tasks in a timely manner within the XCore system.", - "/home/eliezer/devs/xcore/xcore/services/scheduler/service.py:2cd739a019b675930bca98d913224c1d83ea12ab5e9eba24350358ab596c93ff": "### Technical Summary\n\n**Purpose**: The `service.py` file in the `/home/eliezer/devs/xcore/xcore/services/scheduler/` directory is responsible for managing a task scheduler using APScheduler. This scheduler supports cron, interval, and date triggers, with options to store jobs in memory or Redis.\n\n**Key components**:\n- **SchedulerService**: The main class that initializes the scheduler, manages job scheduling, and handles dependencies.\n- **MemoryJobStore**: Manages jobs stored in memory for simplicity.\n- **RedisJobStore**: Manages jobs stored in a Redis database if configured.\n- **AsyncIOScheduler**: Asynchronous scheduler using asyncio.\n\n**Dependencies**:\n- `apscheduler`: Required for the task scheduler functionality.\n- `redis` (if enabled): For storing job data in Redis.\n- `configurations.sections`: Configuration settings related to the scheduler.\n\n**Interactions**:\n- The scheduler is initialized with a configuration file that specifies job details such as cron expressions, trigger types, and job IDs.\n- Jobs are added using decorators or directly through the `add_job` method.\n- The scheduler can be started, stopped, paused, resumed, and queried for jobs.\n- Health checks provide information about the scheduler's status and running state.\n\nThis file is crucial for managing background tasks in a Python application, ensuring that critical operations are executed at specified intervals or on specific dates." -} diff --git a/docgen/composer.py b/docgen/composer.py index c06f868d..025c07c6 100644 --- a/docgen/composer.py +++ b/docgen/composer.py @@ -8,13 +8,17 @@ def compose_file_doc(path, filename, summary, cfg): prompt = f""" You are a senior software architect writing official developer documentation. -Write a clean, well-structured Markdown documentation page for the following source file. -This page will be published in the project's `docs/` directory. +Write a clean, well-structured Markdown documentation page for the +following source file. This page will be published in the project's +`docs/` directory. --- STYLE GUIDELINES --- -- Write in clear, flowing prose. Use bullet lists only for discrete enumerable items (e.g. parameters, config keys). -- Use a confident, technical tone. The reader is a developer joining the project. -- Use Markdown headings (## and ###), backticks for code references (`ClassName`, `function_name()`), and short paragraphs. +- Write in clear, flowing prose. Use bullet lists only for discrete + enumerable items (e.g. parameters, config keys). +- Use a confident, technical tone. The reader is a developer joining + the project. +- Use Markdown headings (## and ###), backticks for code references + (`ClassName`, `function_name()`), and short paragraphs. - Do not pad sections. If a section has little to say, keep it brief. - Never repeat the filename in the body — it will appear as the page title. @@ -24,16 +28,20 @@ def compose_file_doc(path, filename, summary, cfg): What this file does and why it exists. 2–3 sentences max. ## Responsibilities -The specific tasks this file handles within the system. Write in prose, not a bullet list. +The specific tasks this file handles within the system. Write in prose, +not a bullet list. ## Key Components -For each important class or function, write a short paragraph: what it does, its signature (if relevant), and any notable behavior or edge cases. +For each important class or function, write a short paragraph: what it does, +its signature (if relevant), and any notable behavior or edge cases. ## Dependencies -What this file imports and relies on — internal modules and external libraries. Briefly explain why each dependency is needed. +What this file imports and relies on — internal modules and external libraries. +Briefly explain why each dependency is needed. ## How It Fits In -How this file connects to the rest of the codebase: who calls it, what it produces, and where its output goes. +How this file connects to the rest of the codebase: who calls it, what it +produces, and where its output goes. --- FILE SUMMARY --- File: {path} @@ -48,11 +56,13 @@ def compose_module_index(module_name, file_docs, child_modules, cfg): Génère un README.md pour un module. Gère les deux cas : - module feuille : a des fichiers directs, pas de sous-modules - - module intermédiaire : a des sous-modules (et éventuellement des fichiers directs) + - module intermédiaire : a des sous-modules (et éventuellement des + fichiers directs) module_name : ex "linting" ou "core/utils" file_docs : dict filename → { summary, doc_path } (fichiers directs) - child_modules : dict child_module_path → description courte (sous-modules directs) + child_modules : dict child_module_path → description courte (sous-modules + directs) """ # Section fichiers directs if file_docs: @@ -68,7 +78,8 @@ def compose_module_index(module_name, file_docs, child_modules, cfg): if child_modules: # Extraire uniquement le dernier segment pour le lien relatif sub_section = "### Sub-modules\n" + "\n".join( - f"- [`{child.split('/')[-1]}/`](./{child.split('/')[-1]}/README.md) — {desc}" + f"- [`{child.split('/')[-1]}/`](./{child.split('/')[-1]}/README.md) " + f"— {desc}" for child, desc in child_modules.items() ) else: @@ -76,17 +87,21 @@ def compose_module_index(module_name, file_docs, child_modules, cfg): content_block = "\n\n".join(filter(None, [files_section, sub_section])) - prompt = f"""You are writing the index page for a Python module's documentation. + prompt = f"""You are writing the index page for a Python module's +documentation. Module: `{module_name}` Write a concise README.md in Markdown for this module. -It will serve as the entry point when a developer opens the `docs/{module_name}/` folder. +It will serve as the entry point when a developer opens the +`docs/{module_name}/` folder. --- STYLE GUIDELINES --- -- Start with 2–4 sentences of prose describing what this module is responsible for. Be specific. -- Then reproduce the "Files" and "Sub-modules" sections below exactly as provided — do not rewrite them, - just insert them after your prose overview. They already contain the correct Markdown links. +- Start with 2–4 sentences of prose describing what this module is + responsible for. Be specific. +- Then reproduce the "Files" and "Sub-modules" sections below exactly as + provided — do not rewrite them, just insert them after your prose overview. + They already contain the correct Markdown links. - Use backticks for module and file names. - Do not add extra sections. @@ -99,8 +114,10 @@ def compose_module_index(module_name, file_docs, child_modules, cfg): def compose_root_index(modules_summary, root_files, cfg): """ Génère le README.md racine de docs/. - modules_summary : dict module_name → description courte (modules de premier niveau) - root_files : dict filename → { summary } (fichiers à la racine du repo, hors module) + modules_summary : dict module_name → description courte (modules de + premier niveau) + root_files : dict filename → { summary } (fichiers à la racine du + repo, hors module) """ modules_list = "\n".join( f"- [`{mod}/`](./{mod}/README.md) — {desc}" @@ -120,14 +137,18 @@ def compose_root_index(modules_summary, root_files, cfg): f"### Root-level files\n{root_files_list}" if root_files_list else "" ) - prompt = f"""You are writing the top-level documentation index for a software project. + prompt = f"""You are writing the top-level documentation index for a +software project. -Write a root README.md for the `docs/` folder. This is the first page a developer reads. +Write a root README.md for the `docs/` folder. This is the first page a +developer reads. --- STYLE GUIDELINES --- - Start with a short, specific project overview (3–4 sentences). No filler. -- Then reproduce the modules list and root files section below exactly as provided — do not rewrite the links. -- Close with one short paragraph explaining how the documentation is organized and how to navigate it. +- Then reproduce the modules list and root files section below exactly as + provided — do not rewrite the links. +- Close with one short paragraph explaining how the documentation is + organized and how to navigate it. --- MODULES --- {modules_list} diff --git a/docgen/config.yaml b/docgen/config.yaml index ffda6524..6929dc00 100644 --- a/docgen/config.yaml +++ b/docgen/config.yaml @@ -10,7 +10,7 @@ cache: model: base_url: http://localhost:11434/v1 api_key: lm-studio - model_name: qwen2.5-coder:1.5b-instruct + model_name: aleshribar3/deepseek-r1-tool-calling:1.5b temperature: 0.1 generation: diff --git a/docgen/pipeline.py b/docgen/pipeline.py index cdd5c89d..2659fcff 100644 --- a/docgen/pipeline.py +++ b/docgen/pipeline.py @@ -31,7 +31,8 @@ def main(): chunks = scan_repo(cfg) if not chunks: print( - "No files found to process. Check repo_path and include_extensions in config." + "No files found to process. Check repo_path and " + "include_extensions in config." ) return diff --git a/docgen/summarizer.py b/docgen/summarizer.py index 9b082f04..b9a1bfc3 100644 --- a/docgen/summarizer.py +++ b/docgen/summarizer.py @@ -78,16 +78,23 @@ def summarize_chunk(path, content, cfg=None): print(f"[PROCESSING] {path}") prompt = f"""You are documenting a software project for other developers. -Analyze the following source file chunk and produce a concise technical summary. +Analyze the following source file chunk and produce a concise technical +summary. -Write in clear, professional English. Use plain prose — avoid filler phrases like "this file contains" or "it is responsible for". -Go straight to the point. Be specific: name the actual classes, functions, and modules involved. +Write in clear, professional English. Use plain prose — avoid filler phrases +like "this file contains" or "it is responsible for". +Go straight to the point. Be specific: name the actual classes, functions, +and modules involved. Cover these aspects in order: -1. **Purpose** — What problem does this file solve? What is its role in the system? -2. **Key components** — List the main classes and functions with a one-line description of each. -3. **Dependencies** — What does this file import or rely on (internal modules, external libraries)? -4. **Interactions** — How does this file connect to the rest of the codebase (called by, calls into, data it produces or consumes)? +1. **Purpose** — What problem does this file solve? What is its role in the + system? +2. **Key components** — List the main classes and functions with a one-line + description of each. +3. **Dependencies** — What does this file import or rely on (internal + modules, external libraries)? +4. **Interactions** — How does this file connect to the rest of the + codebase (called by, calls into, data it produces or consumes)? Keep the summary under 200 words. Do not repeat the file path in your answer. diff --git a/integration.yaml b/integration.yaml index 89781214..9984ae73 100644 --- a/integration.yaml +++ b/integration.yaml @@ -18,7 +18,7 @@ plugins: secret_key: "12345" # true = refuse tout plugin Trusted non signé - strict_trusted: true + strict_trusted: false # Intervalle du watcher de rechargement à chaud (secondes) # Mettre à 0 pour désactiver en prod si tu gères les reloads via API diff --git a/scripts/benchmarks.py b/scripts/benchmarks.py index ff192c87..a63b01f0 100644 --- a/scripts/benchmarks.py +++ b/scripts/benchmarks.py @@ -207,9 +207,7 @@ def _make_plugin_dir( src_dir = plugin_dir / "src" src_dir.mkdir(parents=True, exist_ok=True) - (plugin_dir / "plugin.yaml").write_text( - textwrap.dedent( - f""" + (plugin_dir / "plugin.yaml").write_text(textwrap.dedent(f""" name: {name} version: 1.0.0 execution_mode: {mode} @@ -231,13 +229,9 @@ def _make_plugin_dir( rate_limit: calls: 100000 period_seconds: 60 - """ - ).strip() - ) + """).strip()) - (src_dir / "main.py").write_text( - textwrap.dedent( - f""" + (src_dir / "main.py").write_text(textwrap.dedent(f""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): @@ -261,9 +255,7 @@ async def on_load(self): async def on_unload(self): pass {extra_code} - """ - ).strip() - ) + """).strip()) return plugin_dir @@ -271,9 +263,7 @@ async def on_unload(self): def _make_xcore_config(plugins_dir: Path) -> str: """Crée un fichier de config minimal et retourne son chemin.""" cfg_file = plugins_dir.parent / "xcore_bench.yaml" - cfg_file.write_text( - textwrap.dedent( - f""" + cfg_file.write_text(textwrap.dedent(f""" app: name: my-app env: development @@ -409,9 +399,7 @@ def _make_xcore_config(plugins_dir: Path) -> str: calls: 200 period_seconds: 60 - """ - ).strip() - ) + """).strip()) return str(cfg_file) diff --git a/tests/benchmarks/cache_batch_perf.py b/tests/benchmarks/cache_batch_perf.py index d473e062..51dcecb2 100644 --- a/tests/benchmarks/cache_batch_perf.py +++ b/tests/benchmarks/cache_batch_perf.py @@ -109,7 +109,8 @@ async def __aexit__(self, *args): await backend.set(k, v) end = time.perf_counter() print( - f"Sequential SET (100 keys, {LATENCY*1000}ms latency): {(end-start)*1000:.2f}ms" + f"Sequential SET (100 keys, {LATENCY*1000}ms latency): " + f"{(end-start)*1000:.2f}ms" ) # MSET (Optimized) @@ -117,7 +118,8 @@ async def __aexit__(self, *args): await backend.mset(values) end = time.perf_counter() print( - f"Optimized MSET (Pipeline) (100 keys, {LATENCY*1000}ms latency): {(end-start)*1000:.2f}ms" + f"Optimized MSET (Pipeline) (100 keys, {LATENCY*1000}ms latency): " + f"{(end-start)*1000:.2f}ms" ) # 2. GET Benchmark @@ -127,7 +129,8 @@ async def __aexit__(self, *args): await backend.get(k) end = time.perf_counter() print( - f"Sequential GET (100 keys, {LATENCY*1000}ms latency): {(end-start)*1000:.2f}ms" + f"Sequential GET (100 keys, {LATENCY*1000}ms latency): " + f"{(end-start)*1000:.2f}ms" ) # MGET (Optimized) @@ -135,7 +138,8 @@ async def __aexit__(self, *args): await backend.mget(keys) end = time.perf_counter() print( - f"Optimized MGET (Native) (100 keys, {LATENCY*1000}ms latency): {(end-start)*1000:.2f}ms" + f"Optimized MGET (Native) (100 keys, {LATENCY*1000}ms latency): " + f"{(end-start)*1000:.2f}ms" ) diff --git a/tests/benchmarks/test_kernel_benchmarks.py b/tests/benchmarks/test_kernel_benchmarks.py index f9f94c4a..0f7073c3 100644 --- a/tests/benchmarks/test_kernel_benchmarks.py +++ b/tests/benchmarks/test_kernel_benchmarks.py @@ -1,7 +1,7 @@ import pytest from xcore.kernel.permissions.engine import PermissionEngine -from xcore.kernel.permissions.policies import Policy, PolicyEffect +from xcore.kernel.permissions.policies import Policy @pytest.mark.benchmark(group="policy-matching") diff --git a/tests/benchmarks/test_permission_bench.py b/tests/benchmarks/test_permission_bench.py index 09b9cbce..d45b80d9 100644 --- a/tests/benchmarks/test_permission_bench.py +++ b/tests/benchmarks/test_permission_bench.py @@ -69,9 +69,9 @@ def check(self, plugin_name, resource, action): def allows(self, plugin_name: str, resource: str, action: str) -> bool: try: self.check(plugin_name, resource, action) - # This is a bit simplified compared to original but should show the overhead of _evaluate + # Simplified version to show the overhead of _evaluate return True - except: + except Exception: return False diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py index 042dd0ea..29cd34c3 100644 --- a/tests/fixtures/__init__.py +++ b/tests/fixtures/__init__.py @@ -2,7 +2,6 @@ Test fixtures and utilities. """ -import os import tempfile from pathlib import Path @@ -19,30 +18,26 @@ def sample_plugin_dir(): plugin_dir.mkdir() # Create plugin.yaml - (plugin_dir / "plugin.yaml").write_text( - """ + (plugin_dir / "plugin.yaml").write_text(""" name: sample_plugin version: 1.0.0 author: Test execution_mode: trusted entry_point: src/main.py -""" - ) +""") # Create src directory src_dir = plugin_dir / "src" src_dir.mkdir() # Create main.py - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.sdk import TrustedBase, ok class Plugin(TrustedBase): async def handle(self, action, payload): return ok(message="Hello from sample plugin") -""" - ) +""") yield plugin_dir diff --git a/tests/integration/test_plugin_lifecycle.py b/tests/integration/test_plugin_lifecycle.py index 1ae2b53c..1e49ef3d 100644 --- a/tests/integration/test_plugin_lifecycle.py +++ b/tests/integration/test_plugin_lifecycle.py @@ -19,8 +19,7 @@ async def xcore_app(self): with tempfile.TemporaryDirectory() as tmp: # Create minimal config config_path = Path(tmp) / "test.yaml" - config_path.write_text( - """ + config_path.write_text(""" app: name: test-app secret_key: test-secret-key-for-testing-min32chars @@ -35,8 +34,7 @@ async def xcore_app(self): cache: backend: memory ttl: 300 -""" - ) +""") app = Xcore(config_path=str(config_path)) await app.boot() diff --git a/tests/integration/test_xcore.py b/tests/integration/test_xcore.py index ff5cb2eb..dbb69945 100644 --- a/tests/integration/test_xcore.py +++ b/tests/integration/test_xcore.py @@ -109,27 +109,23 @@ def config_with_plugins(self, tmp_path): src_dir.mkdir() # plugin.yaml - (test_plugin / "plugin.yaml").write_text( - """ + (test_plugin / "plugin.yaml").write_text(""" name: test_plugin version: 1.0.0 execution_mode: trusted permissions: - resource: "*" actions: ["*"] -""" - ) +""") # main.py - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.sdk import TrustedBase, ok class Plugin(TrustedBase): async def handle(self, action, payload): return ok(message="pong") -""" - ) +""") config_content = f""" app: diff --git a/tests/unit/kernel/test_dynamic_middleware.py b/tests/unit/kernel/test_dynamic_middleware.py index 75f73bb0..7374e9f4 100644 --- a/tests/unit/kernel/test_dynamic_middleware.py +++ b/tests/unit/kernel/test_dynamic_middleware.py @@ -2,7 +2,6 @@ import pytest -from xcore.kernel.runtime.loader import PluginLoader from xcore.kernel.runtime.supervisor import Middleware, PluginSupervisor diff --git a/tests/unit/kernel/test_filesystem_guard_enhanced.py b/tests/unit/kernel/test_filesystem_guard_enhanced.py index 969eb6d4..fb4031f8 100644 --- a/tests/unit/kernel/test_filesystem_guard_enhanced.py +++ b/tests/unit/kernel/test_filesystem_guard_enhanced.py @@ -1,4 +1,3 @@ -import builtins from unittest.mock import MagicMock import pytest @@ -20,13 +19,10 @@ def guard(self, plugin_dir): return FilesystemGuard(plugin_dir, ["data/"], ["src/"]) def test_os_patches(self, guard, plugin_dir): - # Setup the guard (normally done via install(), but we want controlled test) - # We need to reach into the local scope of install() to test the logic - # OR we just test it via a mock since the logic is now part of the class or global - - # Actually _guarded_op is defined INSIDE install() in the current implementation. - # This makes it hard to test in isolation without running install(). - # Let's verify if I can test it by running install() on a Mock object instead of global builtins. + # Setup the guard (normally done via install()) + # Hard to test in isolation without running install(). + # Verify if I can test it by running install() on a Mock object + # instead of global builtins. MagicMock() MagicMock() diff --git a/tests/unit/kernel/test_hooks.py b/tests/unit/kernel/test_hooks.py index 37205208..af9a39f3 100644 --- a/tests/unit/kernel/test_hooks.py +++ b/tests/unit/kernel/test_hooks.py @@ -6,7 +6,7 @@ import pytest -from xcore.kernel.events.hooks import HookError, HookManager, HookTimeoutError +from xcore.kernel.events.hooks import HookManager from xcore.kernel.events.section import Event diff --git a/tests/unit/kernel/test_lifecycle.py b/tests/unit/kernel/test_lifecycle.py index f66e90c4..4315825d 100644 --- a/tests/unit/kernel/test_lifecycle.py +++ b/tests/unit/kernel/test_lifecycle.py @@ -8,7 +8,7 @@ import pytest -from xcore.kernel.api.contract import BasePlugin, ExecutionMode +from xcore.kernel.api.contract import BasePlugin from xcore.kernel.runtime.lifecycle import LifecycleManager, LoadError from xcore.kernel.runtime.state_machine import PluginState from xcore.sdk.plugin_base import PluginManifest @@ -155,13 +155,11 @@ async def test_load_invalid_plugin_contract(self, lifecycle_manager, tmp_path): """Test load raises error when plugin doesn't implement BasePlugin.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" class Plugin: def __init__(self): pass -""" - ) +""") with pytest.raises(LoadError) as exc_info: await lifecycle_manager.load() @@ -173,8 +171,7 @@ async def test_load_success(self, lifecycle_manager, tmp_path): """Test successful plugin load.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): @@ -183,8 +180,7 @@ async def handle(self, action, payload): async def on_load(self): self.loaded = True -""" - ) +""") await lifecycle_manager.load() @@ -198,8 +194,7 @@ async def test_load_calls_on_load(self, lifecycle_manager, tmp_path): """Test that on_load hook is called.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): @@ -211,8 +206,7 @@ async def handle(self, action, payload): async def on_load(self): self.on_load_called = True -""" - ) +""") await lifecycle_manager.load() assert lifecycle_manager._instance.on_load_called is True @@ -222,15 +216,13 @@ async def test_call_action(self, lifecycle_manager, tmp_path): """Test calling an action on the plugin.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): async def handle(self, action, payload): return {"status": "ok", "action": action} -""" - ) +""") await lifecycle_manager.load() result = await lifecycle_manager.call("test_action", {"key": "value"}) @@ -251,8 +243,7 @@ async def test_call_timeout(self, lifecycle_manager, tmp_path): """Test call handles timeout.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" import asyncio from xcore.kernel.api.contract import BasePlugin @@ -260,8 +251,7 @@ class Plugin(BasePlugin): async def handle(self, action, payload): await asyncio.sleep(10) # Longer than timeout return {"status": "ok"} -""" - ) +""") lifecycle_manager.manifest.resources.timeout_seconds = 0.1 await lifecycle_manager.load() @@ -275,8 +265,7 @@ async def test_concurrent_calls(self, lifecycle_manager, tmp_path): """Test that multiple calls can be made concurrently.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" import asyncio from xcore.kernel.api.contract import BasePlugin @@ -284,8 +273,7 @@ class Plugin(BasePlugin): async def handle(self, action, payload): await asyncio.sleep(0.1) return {"status": "ok", "action": action} -""" - ) +""") lifecycle_manager.manifest.resources.timeout_seconds = 1 await lifecycle_manager.load() @@ -303,8 +291,7 @@ async def test_reload(self, lifecycle_manager, tmp_path): """Test plugin reload.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): @@ -313,8 +300,7 @@ async def handle(self, action, payload): async def on_reload(self): self.reloaded = True -""" - ) +""") await lifecycle_manager.load() first_instance = lifecycle_manager._instance @@ -329,8 +315,7 @@ async def test_unload(self, lifecycle_manager, tmp_path): """Test plugin unload.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): @@ -339,8 +324,7 @@ async def handle(self, action, payload): async def on_unload(self): self.unloaded = True -""" - ) +""") await lifecycle_manager.load() await lifecycle_manager.unload() @@ -353,8 +337,7 @@ async def test_collect_router(self, lifecycle_manager, tmp_path): """Test router collection.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin from unittest.mock import MagicMock @@ -366,8 +349,7 @@ def get_router(self): router = MagicMock() router.routes = [1, 2, 3] return router -""" - ) +""") await lifecycle_manager.load() assert lifecycle_manager.plugin_router is not None @@ -387,15 +369,13 @@ async def test_status_loaded(self, lifecycle_manager, tmp_path): """Test status when plugin is loaded.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): async def handle(self, action, payload): return {"status": "ok"} -""" - ) +""") await lifecycle_manager.load() status = lifecycle_manager.status() @@ -507,15 +487,13 @@ async def test_call_non_dict_result(self, lifecycle_manager, tmp_path): """Test call handles non-dict result.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): async def handle(self, action, payload): return "string_result" # Not a dict -""" - ) +""") await lifecycle_manager.load() result = await lifecycle_manager.call("action", {}) @@ -548,15 +526,13 @@ async def test_unload_cleans_modules(self, lifecycle_manager, tmp_path): """Test unload cleans sys.modules.""" src_dir = tmp_path / "src" src_dir.mkdir() - (src_dir / "main.py").write_text( - """ + (src_dir / "main.py").write_text(""" from xcore.kernel.api.contract import BasePlugin class Plugin(BasePlugin): async def handle(self, action, payload): return {"status": "ok"} -""" - ) +""") await lifecycle_manager.load() module_name = f"xcore_plugin_{lifecycle_manager.manifest.name}" diff --git a/tests/unit/kernel/test_permissions.py b/tests/unit/kernel/test_permissions.py index 2048c549..2d582fcb 100644 --- a/tests/unit/kernel/test_permissions.py +++ b/tests/unit/kernel/test_permissions.py @@ -1,7 +1,6 @@ import pytest from xcore.kernel.permissions.engine import PermissionDenied, PermissionEngine -from xcore.kernel.permissions.policies import PolicyEffect class TestPermissionEngine: diff --git a/tests/unit/kernel/test_sandbox_worker.py b/tests/unit/kernel/test_sandbox_worker.py index b20a27d3..6c86d59d 100644 --- a/tests/unit/kernel/test_sandbox_worker.py +++ b/tests/unit/kernel/test_sandbox_worker.py @@ -2,7 +2,6 @@ Tests for sandbox worker components. """ -import builtins import os import sys from pathlib import Path diff --git a/tests/unit/kernel/test_supervisor_new.py b/tests/unit/kernel/test_supervisor_new.py index 12cd7b02..d9f19929 100644 --- a/tests/unit/kernel/test_supervisor_new.py +++ b/tests/unit/kernel/test_supervisor_new.py @@ -2,7 +2,6 @@ import pytest -from xcore.kernel.runtime.middlewares.middleware import Middleware from xcore.kernel.runtime.middlewares.retry import RetryMiddleware from xcore.kernel.runtime.supervisor import PluginSupervisor diff --git a/tests/unit/plugins/test_base.py b/tests/unit/plugins/test_base.py index df865294..815cb6ca 100644 --- a/tests/unit/plugins/test_base.py +++ b/tests/unit/plugins/test_base.py @@ -2,8 +2,6 @@ Tests for plugin base classes and SDK. """ -import pytest - from xcore.kernel.api.contract import ExecutionMode from xcore.sdk.plugin_base import ( PluginManifest, diff --git a/tests/unit/plugins/test_decorators.py b/tests/unit/plugins/test_decorators.py index ca5b352c..ada7b25d 100644 --- a/tests/unit/plugins/test_decorators.py +++ b/tests/unit/plugins/test_decorators.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock import pytest -from pydantic import BaseModel, ValidationError +from pydantic import BaseModel from xcore.sdk.decorators import ( AutoDispatchMixin, @@ -284,7 +284,6 @@ class TestRoutedPlugin: async def test_routerin_returns_router(self): """Test RouterIn returns APIRouter.""" pytest.importorskip("fastapi") - from fastapi import APIRouter class TestPlugin(RoutedPlugin): @route("/ping", method="GET") diff --git a/tests/unit/security/test_ast_scanner.py b/tests/unit/security/test_ast_scanner.py index 3b278338..980d5561 100644 --- a/tests/unit/security/test_ast_scanner.py +++ b/tests/unit/security/test_ast_scanner.py @@ -274,8 +274,8 @@ def test_scan_file_read_error(self, tmp_path): scanner = ASTScanner() - # Mock file read to raise exception. On Python 3.12, Path.read_text is read-only on instances. - # Patching it via its string path is more robust. + # Mock file read to raise exception. On Python 3.12, Path.read_text is + # read-only on instances. Patching it via its string path is more robust. with patch( "xcore.kernel.security.validation.Path.read_text", side_effect=IOError("Permission denied"), diff --git a/tests/unit/security/test_sentinel_fixes.py b/tests/unit/security/test_sentinel_fixes.py index 4f3f9873..50b79fd6 100644 --- a/tests/unit/security/test_sentinel_fixes.py +++ b/tests/unit/security/test_sentinel_fixes.py @@ -1,5 +1,3 @@ -import pytest - from xcore.kernel.security.validation import ASTScanner diff --git a/tests/unit/security/test_signature_bypass.py b/tests/unit/security/test_signature_bypass.py index 43ed6c7c..4a987258 100644 --- a/tests/unit/security/test_signature_bypass.py +++ b/tests/unit/security/test_signature_bypass.py @@ -53,7 +53,8 @@ def test_signature_bypass_outside_src(tmp_path): # The signature verification SHOULD fail, but currently it will PASS # because it only hashes the 'src/' directory. - # After the fix, verify_plugin must raise SignatureError when app/main.py is modified. + # After the fix, verify_plugin must raise SignatureError when app/main.py + # is modified. with pytest.raises(SignatureError): verify_plugin(manifest, secret_key) diff --git a/tests/unit/test_configuration.py b/tests/unit/test_configuration.py index 3a61e582..aca1e3d2 100644 --- a/tests/unit/test_configuration.py +++ b/tests/unit/test_configuration.py @@ -4,9 +4,6 @@ import os -import pytest -import yaml - from xcore.configurations.loader import ConfigLoader from xcore.configurations.sections import AppConfig, PluginConfig, ServicesConfig diff --git a/xcore/__init__.py b/xcore/__init__.py index bc3b54c6..d3e22a2c 100644 --- a/xcore/__init__.py +++ b/xcore/__init__.py @@ -235,13 +235,17 @@ def _attach_router( key=f"{middleware['name']}_{key}", value=value ) self._logger.info( - f"{middleware['name']}📦 état {middleware['name']}_{key} mis à jour" + f"{middleware['name']}📦 état {middleware['name']}_{key} " + "mis à jour" ) app.openapi_schema = None # force la regen du schéma OpenAPI def _validate_secret_keys(self) -> None: - """Bloque le démarrage en production si les clés secrètes sont celles par défaut.""" + """ + Bloque le démarrage en production si les clés secrètes sont celles + par défaut. + """ if self._config.app.env != "production": return default_key = b"change-me-in-production" diff --git a/xcore/cli/marketplace_cmd.py b/xcore/cli/marketplace_cmd.py index 6e1d4c38..7f05ea49 100644 --- a/xcore/cli/marketplace_cmd.py +++ b/xcore/cli/marketplace_cmd.py @@ -190,13 +190,19 @@ async def _mkt_show(args) -> None: sys.exit(1) info = [ - f"[bold cyan]Auteur :[/][magenta] {escape(str(plugin.get('author', '?')))}[/]", - f"[bold cyan]Description :[/] {escape(str(plugin.get('description', '?')))}", - f"[bold cyan]Mode :[/][yellow] {escape(str(plugin.get('execution_mode', 'legacy')))}[/]", - f"[bold cyan]Licence :[/][green] {escape(str(plugin.get('license', '?')))}[/]", - f"[bold cyan]Note :[/] {_stars(plugin.get('rating', 0))} ({plugin.get('rating_count', 0)} votes)", + f"[bold cyan]Auteur :[/][magenta] " + f"{escape(str(plugin.get('author', '?')))}[/]", + f"[bold cyan]Description :[/] " + f"{escape(str(plugin.get('description', '?')))}", + f"[bold cyan]Mode :[/][yellow] " + f"{escape(str(plugin.get('execution_mode', 'legacy')))}[/]", + f"[bold cyan]Licence :[/][green] " + f"{escape(str(plugin.get('license', '?')))}[/]", + f"[bold cyan]Note :[/] {_stars(plugin.get('rating', 0))} " + f"({plugin.get('rating_count', 0)} votes)", f"[bold cyan]Téléch. :[/][bold] {plugin.get('downloads', 0):,}[/]", - f"[bold cyan]Dépôt :[/][blue] {escape(str(plugin.get('repository', '?')))}[/]", + f"[bold cyan]Dépôt :[/][blue] " + f"{escape(str(plugin.get('repository', '?')))}[/]", ] if plugin.get("requires"): info.append( @@ -208,10 +214,18 @@ async def _mkt_show(args) -> None: content += "\n\n[bold white]Versions disponibles :[/]\n" for v in versions[:5]: tag = " [bold green]← latest[/]" if v.get("latest") else "" - content += f" {escape(str(v.get('version', '?'))):12} {escape(str(v.get('released_at', '?')))}{tag}\n" + ver_str = escape(str(v.get("version", "?"))) + rel_at = escape(str(v.get("released_at", "?"))) + content += f" {ver_str:12} {rel_at}{tag}\n" - content += f"\n[italic grey70]Pour installer :[/]\n [bold]xcore plugin install {escape(name)}[/]" - title = f"[bold green]📦 {escape(plugin.get('name', name))} v{escape(str(plugin.get('version', '?')))}[/]" + content += ( + f"\n[italic grey70]Pour installer :[/]\n" + f" [bold]xcore plugin install {escape(name)}[/]" + ) + title = ( + f"[bold green]📦 {escape(plugin.get('name', name))} " + f"v{escape(str(plugin.get('version', '?')))}[/]" + ) console.print(Panel(content, title=title, expand=False, border_style="cyan")) diff --git a/xcore/cli/plugin_cmd.py b/xcore/cli/plugin_cmd.py index 2e4f5fd3..3de1cbd8 100644 --- a/xcore/cli/plugin_cmd.py +++ b/xcore/cli/plugin_cmd.py @@ -19,8 +19,9 @@ console = Console() -# Pattern pour valider le nom d'un plugin : alphanumérique, tirets et underscores uniquement. -# Cela empêche les tentatives de traversal (..) ou de chemins absolus. +# Pattern pour valider le nom d'un plugin : alphanumérique, tirets et +# underscores uniquement. Cela empêche les tentatives de traversal (..) +# ou de chemins absolus. PLUGIN_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+$") @@ -66,9 +67,11 @@ async def handle_plugin(args) -> None: if handler: await handler(args) else: - print( - "Usage : xcore plugin " + usage = ( + "Usage : xcore plugin " ) + print(usage) # ── list ────────────────────────────────────────────────────── @@ -211,7 +214,8 @@ async def _plugin_install(args) -> None: f"[bold red]❌ Erreur :[/] Plugin '{name}' déjà installé dans {dest}" ) console.print( - f" Pour mettre à jour : xcore plugin remove {name} && xcore plugin install {name}" + f" Pour mettre à jour : xcore plugin remove {name} && " + f"xcore plugin install {name}" ) sys.exit(1) @@ -220,7 +224,7 @@ async def _plugin_install(args) -> None: elif source == "zip" or (url and (url.endswith(".zip") or url.startswith("http"))): if not url: - console.print(f"[bold red]❌ Erreur :[/] --url requis pour --source zip") + console.print("[bold red]❌ Erreur :[/] --url requis pour --source zip") sys.exit(1) await _install_from_zip(name, url, dest) @@ -315,7 +319,8 @@ async def _install_from_marketplace(client, name: str, dest: Path, cfg) -> None: source_type = plugin.get("source_type", "zip") print( - f"📦 Plugin trouvé : v{plugin.get('version', '?')} — {plugin.get('description', '')}" + f"📦 Plugin trouvé : v{plugin.get('version', '?')} — " + f"{plugin.get('description', '')}" ) if source_type == "git": @@ -407,11 +412,14 @@ async def _plugin_info(args) -> None: # Construction du contenu du panel info = [ f"[bold cyan]Auteur :[/][magenta] {escape(str(manifest.author))}[/]", - f"[bold cyan]Description :[/] {escape(str(manifest.description))}", - f"[bold cyan]Mode :[/][yellow] {escape(str(manifest.execution_mode.value))}[/]", - f"[bold cyan]Framework :[/][green] {escape(str(manifest.framework_version))}[/]", - f"[bold cyan]Entry point :[/][blue] {escape(str(manifest.entry_point))}[/]", - f"[bold cyan]Signé :[/] {'✅ oui' if is_signed(manifest) else '⚠️ non'}", + f"[bold cyan]Description :[/] " f"{escape(str(manifest.description))}", + f"[bold cyan]Mode :[/][yellow] " + f"{escape(str(manifest.execution_mode.value))}[/]", + f"[bold cyan]Framework :[/][green] " + f"{escape(str(manifest.framework_version))}[/]", + f"[bold cyan]Entry point :[/][blue] " f"{escape(str(manifest.entry_point))}[/]", + f"[bold cyan]Signé :[/] " + f"{'✅ oui' if is_signed(manifest) else '⚠️ non'}", ] if manifest.requires: @@ -431,7 +439,8 @@ async def _plugin_info(args) -> None: info.append(f" [cyan]mémoire max :[/][magenta] {r.max_memory_mb}MB[/]") info.append(f" [cyan]disque max :[/][magenta] {r.max_disk_mb}MB[/]") info.append( - f" [cyan]rate limit :[/][magenta] {r.rate_limit.calls} appels / {r.rate_limit.period_seconds}s[/]" + f" [cyan]rate limit :[/][magenta] {r.rate_limit.calls} appels " + f"/ {r.rate_limit.period_seconds}s[/]" ) # Permissions @@ -463,7 +472,8 @@ async def _plugin_validate(args) -> None: v = ManifestValidator() manifest = v.load_and_validate(path) console.print( - f"✅ Manifeste valide : {manifest.name} v{manifest.version} [{manifest.execution_mode.value}]" + f"✅ Manifeste valide : {manifest.name} v{manifest.version} " + f"[{manifest.execution_mode.value}]" ) except Exception as e: console.print(f"[bold red]❌ Manifeste invalide :[/] {e}") @@ -584,7 +594,8 @@ def _do_request(): except URLError: console.print( - f"[bold red]❌ Erreur :[/] Impossible de joindre le serveur xcore sur {host}:{port}.\n" + f"[bold red]❌ Erreur :[/] Impossible de joindre le serveur " + f"xcore sur {host}:{port}.\n" f" Vérifiez que le serveur est démarré.", ) sys.exit(1) diff --git a/xcore/cli/sandbox_cmd.py b/xcore/cli/sandbox_cmd.py index 9e352505..cfe7f04a 100644 --- a/xcore/cli/sandbox_cmd.py +++ b/xcore/cli/sandbox_cmd.py @@ -77,8 +77,10 @@ async def _sandbox_run(args) -> None: ) info = [ - f"[bold cyan]Mémoire max :[/][magenta] {manifest.resources.max_memory_mb}MB[/]", - f"[bold cyan]Timeout :[/][magenta] {manifest.resources.timeout_seconds}s[/]", + f"[bold cyan]Mémoire max :[/][magenta] " + f"{manifest.resources.max_memory_mb}MB[/]", + f"[bold cyan]Timeout :[/][magenta] " + f"{manifest.resources.timeout_seconds}s[/]", ] title = f"[bold green]🚀 Lancement sandbox : {escape(name)}[/]" console.print(Panel(Group(*info), title=title, expand=False, border_style="cyan")) @@ -98,23 +100,21 @@ async def _sandbox_run(args) -> None: status = mgr.status() # Ping de confirmation - from xcore.kernel.sandbox.ipc import IPCChannel - resp = await mgr._channel.call("ping", {}) if resp.success: - console.print(f"✅ [bold green]Sandbox opérationnelle[/]") + console.print("✅ [bold green]Sandbox opérationnelle[/]") else: - console.print( - f"⚠️ [yellow]Sandbox démarrée mais ping échoué : {escape(str(resp.data))}[/]" - ) + msg = escape(str(resp.data)) + console.print(f"⚠️ [yellow]Sandbox démarrée mais ping échoué : {msg}[/]") table = Table(box=None, show_header=False, padding=(0, 2)) table.add_row("[bold cyan]PID :[/]", f"[magenta]{status['pid']}[/]") table.add_row("[bold cyan]État :[/]", f"[yellow]{status['state']}[/]") table.add_row( "[bold cyan]Disque:[/]", - f"[magenta]{status['disk']['used_mb']}MB / {status['disk']['max_mb']}MB[/]", + f"[magenta]{status['disk']['used_mb']}MB / " + f"{status['disk']['max_mb']}MB[/]", ) console.print(table) @@ -153,12 +153,14 @@ async def _sandbox_limits(args) -> None: rt = manifest.runtime info = [ - f"[bold cyan]Mémoire max :[/][magenta] {r.max_memory_mb} MB[/]", - f"[bold cyan]Disque max :[/][magenta] {r.max_disk_mb} MB[/]", - f"[bold cyan]Timeout appel :[/][magenta] {r.timeout_seconds} s[/]", - f"[bold cyan]Rate limit :[/][magenta] {r.rate_limit.calls} appels / {r.rate_limit.period_seconds}s[/]", + f"[bold cyan]Mémoire max :[/][magenta] " f"{r.max_memory_mb} MB[/]", + f"[bold cyan]Disque max :[/][magenta] " f"{r.max_disk_mb} MB[/]", + f"[bold cyan]Timeout appel :[/][magenta] " f"{r.timeout_seconds} s[/]", + f"[bold cyan]Rate limit :[/][magenta] " + f"{r.rate_limit.calls} appels / {r.rate_limit.period_seconds}s[/]", "\n[bold white]Runtime :[/]", - f" [cyan]Health check :[/][yellow] {'activé' if rt.health_check.enabled else 'désactivé'}[/]", + f" [cyan]Health check :[/][yellow] " + f"{'activé' if rt.health_check.enabled else 'désactivé'}[/]", ] if rt.health_check.enabled: @@ -181,7 +183,9 @@ async def _sandbox_limits(args) -> None: symbol = "✅" if stats["ok"] else "❌" info.append("\n[bold white]État actuel :[/]") info.append( - f" [cyan]Disque utilisé :[/][magenta] {stats['used_mb']}MB / {stats['max_mb']}MB ({stats['used_pct']}%) {symbol}[/]" + f" [cyan]Disque utilisé :[/][magenta] " + f"{stats['used_mb']}MB / {stats['max_mb']}MB " + f"({stats['used_pct']}%) {symbol}[/]" ) content = Group(*info) @@ -301,7 +305,9 @@ async def _sandbox_fs(args) -> None: for p in fs.allowed_paths: abs_path = plugin_dir / p status = ( - "[green]✅ existe[/]" if abs_path.exists() else "[yellow]⚠️ manquant[/]" + "[green]✅ existe[/]" + if abs_path.exists() + else "[yellow]⚠️ manquant[/]" ) table.add_row(escape(str(p)), status) info.append(table) @@ -324,8 +330,9 @@ async def _sandbox_fs(args) -> None: data_dir = plugin_dir / "data" if not data_dir.exists(): console.print("") + rel_path = escape(str(data_dir.relative_to(plugin_dir.parent))) create = Confirm.ask( - f"[yellow]⚠️ Le dossier {escape(str(data_dir.relative_to(plugin_dir.parent)))} n'existe pas. Créer ?[/]", + f"[yellow]⚠️ Le dossier {rel_path} n'existe pas. Créer ?[/]", default=False, ) if create: diff --git a/xcore/cli/validate_cmd.py b/xcore/cli/validate_cmd.py index 2c2bee25..462ddebd 100644 --- a/xcore/cli/validate_cmd.py +++ b/xcore/cli/validate_cmd.py @@ -37,8 +37,9 @@ def validate_full( try: validator = ManifestValidator() manifest = validator.load_and_validate(path) - print( - f"✅ Manifeste : {manifest.name} v{manifest.version} [{manifest.execution_mode.value}]" + console.print( + f"✅ Manifeste : {manifest.name} v{manifest.version} " + f"[{manifest.execution_mode.value}]" ) except Exception as e: print(f"❌ Manifeste : {e}", file=sys.stderr) @@ -52,7 +53,7 @@ def validate_full( if result.passed: print(f"✅ Scan AST : {len(result.scanned)} fichier(s) analysé(s)") else: - print(f"❌ Scan AST :") + print("❌ Scan AST :") for err in result.errors: print(f" {err}", file=sys.stderr) ok = False @@ -65,7 +66,7 @@ def validate_full( try: verify_plugin(manifest, secret_key) - print(f"✅ Signature : valide") + print("✅ Signature : valide") except SignatureError as e: if strict: print(f"❌ Signature : {e}", file=sys.stderr) diff --git a/xcore/configurations/loader.py b/xcore/configurations/loader.py index 46c30eb7..70f8ef4f 100644 --- a/xcore/configurations/loader.py +++ b/xcore/configurations/loader.py @@ -46,10 +46,10 @@ class ConfigLoader: """ DEFAULT_PATHS = [ - Path("integation.yaml"), - Path("integation.yml"), - Path("integation.json"), - Path("config/integation.yaml"), + Path("integration.yaml"), + Path("integration.json"), + Path("config/integration.json"), + Path("config/integration.yaml"), ] @classmethod diff --git a/xcore/kernel/api/contract.py b/xcore/kernel/api/contract.py index 1c0fc154..b1fc4cac 100644 --- a/xcore/kernel/api/contract.py +++ b/xcore/kernel/api/contract.py @@ -55,6 +55,8 @@ class BasePlugin(Protocol): async def handle(self, action: str, payload: dict) -> dict """ + _config: dict + async def handle(self, action: str, payload: dict) -> dict: ... # Hooks optionnels diff --git a/xcore/kernel/api/proto.py b/xcore/kernel/api/proto.py index fba84e4a..621d1436 100644 --- a/xcore/kernel/api/proto.py +++ b/xcore/kernel/api/proto.py @@ -63,7 +63,8 @@ def register(self, name: str) -> Callable: ... -class PluginRegistry(Protocol): ... +class PluginRegistry(Protocol): + """Registry for plugins.""" @dataclass diff --git a/xcore/kernel/events/hooks.py b/xcore/kernel/events/hooks.py index 67601a18..dc56ffe4 100644 --- a/xcore/kernel/events/hooks.py +++ b/xcore/kernel/events/hooks.py @@ -12,7 +12,7 @@ import time from typing import Any, Callable, Dict, List, Optional, Tuple -from .section import Event, HookInfo, HookResult, InterceptorResult +from .section import Event, HookInfo, HookResult logger = logging.getLogger("xcore.events.hooks") diff --git a/xcore/kernel/runtime/lifecycle.py b/xcore/kernel/runtime/lifecycle.py index 15350b81..46a1b782 100644 --- a/xcore/kernel/runtime/lifecycle.py +++ b/xcore/kernel/runtime/lifecycle.py @@ -144,9 +144,10 @@ async def _do_load(self) -> None: cls = self._module.Plugin self._instance = self._instantiate(cls) - if not isinstance(self._instance, BasePlugin): + if not hasattr(self._instance, "handle"): raise LoadError( - "the plugin not respect contrat BasePlugin (missing method async handle(action, payload))" + "the plugin not respect contrat BasePlugin" + " (missing method async handle(action, payload))" ) # Injection du contexte riche diff --git a/xcore/kernel/runtime/loader.py b/xcore/kernel/runtime/loader.py index 8f91a20f..8f70a533 100644 --- a/xcore/kernel/runtime/loader.py +++ b/xcore/kernel/runtime/loader.py @@ -16,7 +16,6 @@ from typing import TYPE_CHECKING, Any if TYPE_CHECKING: - from ...configurations.sections import PluginConfig from ..context import KernelContext from ...kernel.security.validation import ManifestValidator @@ -343,7 +342,5 @@ def collect_app_state(self) -> list[Any]: and handler.plugin_middlewares is not None ): middlewares.append(handler.plugin_middlewares) - try: - return middlewares - except: - return middlewares + + return middlewares diff --git a/xcore/kernel/sandbox/process_manager.py b/xcore/kernel/sandbox/process_manager.py index d07f612a..4064e502 100644 --- a/xcore/kernel/sandbox/process_manager.py +++ b/xcore/kernel/sandbox/process_manager.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from ..runtime.loader import PluginLoader -from .ipc import IPCChannel, IPCProcessDead, IPCResponse +from .ipc import IPCChannel, IPCProcessDead from .isolation import DiskQuotaExceeded, DiskWatcher logger = logging.getLogger("xcore.sandbox.process_manager") diff --git a/xcore/kernel/sandbox/worker.py b/xcore/kernel/sandbox/worker.py index 9ed5aa5c..687db67e 100644 --- a/xcore/kernel/sandbox/worker.py +++ b/xcore/kernel/sandbox/worker.py @@ -192,21 +192,37 @@ def _block(label: str, *args) -> None: # ── Couche 1 : Filesystem ───────────────────────────────────────────── def _guarded_op(func, label): - sig = inspect.signature(func) - pnames = {"path", "file", "src", "dst", "target", "name", "self"} + try: + sig = inspect.signature(func) + pnames = {"path", "file", "src", "dst", "target", "name", "self"} + except (ValueError, TypeError): + # Builtin C sans signature introspectable (ex: os.chmod, os.stat…) + # Fallback : on considère le 1er argument positionnel comme le chemin + sig = None + pnames = None def wrapper(*args, **kwargs): if guard._in_guard: return func(*args, **kwargs) - try: - bound = sig.bind_partial(*args, **kwargs).arguments - paths = [ - v - for k, v in bound.items() - if k in pnames and isinstance(v, (str, os.PathLike)) - ] - except Exception: - paths = [] + + if sig is not None: + try: + bound = sig.bind_partial(*args, **kwargs).arguments + paths = [ + v + for k, v in bound.items() + if k in pnames and isinstance(v, (str, os.PathLike)) + ] + except Exception: + paths = [] + else: + # Fallback builtin : 1er arg positionnel = le chemin + paths = ( + [args[0]] + if args and isinstance(args[0], (str, os.PathLike)) + else [] + ) + guard._in_guard = True try: for p in paths: @@ -576,6 +592,7 @@ class _PluginManifest: entry_point: str = "src/main.py" allowed_paths: list = field(default_factory=lambda: ["data/"]) denied_paths: list = field(default_factory=lambda: ["src/"]) + configuration: dict = field(default_factory=dict) def _load_manifest(plugin_dir: Path) -> _PluginManifest: @@ -594,7 +611,7 @@ def _load_manifest(plugin_dir: Path) -> _PluginManifest: return manifest -def _extracted_from__load_manifest_20(fname, manifest_path, manifest): +def _extracted_from__load_manifest_20(fname, manifest_path, manifest: _PluginManifest): if fname.endswith(".yaml"): import yaml @@ -615,6 +632,9 @@ def _extracted_from__load_manifest_20(fname, manifest_path, manifest): if dp := fs.get("denied_paths"): manifest.denied_paths = dp + if cp := raw.get("configuration", {}): + manifest.configuration = cp + logger.debug( f"Manifeste chargé : entry_point={manifest.entry_point!r}, " f"allowed={manifest.allowed_paths}, denied={manifest.denied_paths}" @@ -657,6 +677,7 @@ async def _run(plugin_dir: Path) -> None: finally: guard._in_guard = False # à partir d'ici : code plugin, restrictions actives + plugin._config = manifest.configuration if hasattr(plugin, "on_load"): await plugin.on_load() diff --git a/xcore/kernel/security/setup.py b/xcore/kernel/security/setup.py index ebd3bc09..fc6fcb1e 100644 --- a/xcore/kernel/security/setup.py +++ b/xcore/kernel/security/setup.py @@ -9,7 +9,6 @@ `from .scanner_core import ImportClassifier` fonctionne directement. """ -import setuptools from pybind11.setup_helpers import Pybind11Extension, build_ext from setuptools import setup diff --git a/xcore/sdk/routers.py b/xcore/sdk/routers.py index 98b2c5e9..1d65e06b 100644 --- a/xcore/sdk/routers.py +++ b/xcore/sdk/routers.py @@ -1,7 +1,5 @@ from typing import Callable -from fastapi import APIRouter - class RouterRegistry: """ diff --git a/xcore_bench_report.json b/xcore_bench_report.json deleted file mode 100644 index de74e37f..00000000 --- a/xcore_bench_report.json +++ /dev/null @@ -1,461 +0,0 @@ -{ - "meta": { - "xcore_version": "2.1.2", - "python_version": "3.14.4", - "platform": "linux", - "timestamp": "2026-04-29T11:02:58.798418", - "cpu_count": 8, - "total_duration_s": 3.172987825999371, - "system_info": { - "cpu_count": 8, - "cpu_freq_mhz": 1379.54425, - "total_ram_gb": 15.3, - "available_ram_gb": 8.4 - } - }, - "results": [ - { - "name": "single_plugin_load", - "category": "plugin_lifecycle", - "iterations": 20, - "total_ms": 23.769449999235803, - "mean_ms": 1.1884724999617902, - "median_ms": 1.1223724995943485, - "p95_ms": 2.5641230004112003, - "p99_ms": 2.5641230004112003, - "min_ms": 0.9731579993967898, - "max_ms": 2.5641230004112003, - "std_ms": 0.3313133053575544, - "throughput_ops_sec": 841.4161876123767, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "20 runs" - }, - { - "name": "single_plugin_unload", - "category": "plugin_lifecycle", - "iterations": 20, - "total_ms": 5.08798499686236, - "mean_ms": 0.254399249843118, - "median_ms": 0.24472649874951458, - "p95_ms": 0.3115250001428649, - "p99_ms": 0.3115250001428649, - "min_ms": 0.2223270003014477, - "max_ms": 0.3115250001428649, - "std_ms": 0.024043957390132698, - "throughput_ops_sec": 3930.829201016419, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "20 runs" - }, - { - "name": "plugin_reload", - "category": "plugin_lifecycle", - "iterations": 20, - "total_ms": 12.287289991945727, - "mean_ms": 0.6143644995972863, - "median_ms": 0.6017319992679404, - "p95_ms": 0.736632999178255, - "p99_ms": 0.736632999178255, - "min_ms": 0.5194500008656178, - "max_ms": 0.736632999178255, - "std_ms": 0.055637530881803024, - "throughput_ops_sec": 1627.6982160517027, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "batch_load_5_plugins", - "category": "plugin_lifecycle", - "iterations": 5, - "total_ms": 334.2003189991374, - "mean_ms": 66.84006379982748, - "median_ms": 66.84006379982748, - "p95_ms": 100.26009569974121, - "p99_ms": 133.68012759965495, - "min_ms": 0, - "max_ms": 334.2003189991374, - "std_ms": 0, - "throughput_ops_sec": 14.961086856451821, - "memory_delta_mb": 8.98046875, - "errors": 4, - "notes": "1/5 loaded, 1.80MB/plugin" - }, - { - "name": "batch_load_20_plugins", - "category": "plugin_lifecycle", - "iterations": 20, - "total_ms": 98.60400199977448, - "mean_ms": 4.930200099988724, - "median_ms": 4.930200099988724, - "p95_ms": 7.395300149983086, - "p99_ms": 9.860400199977448, - "min_ms": 0, - "max_ms": 98.60400199977448, - "std_ms": 0, - "throughput_ops_sec": 202.83152401913406, - "memory_delta_mb": 0.0078125, - "errors": 19, - "notes": "1/20 loaded, 0.00MB/plugin" - }, - { - "name": "batch_load_50_plugins", - "category": "plugin_lifecycle", - "iterations": 50, - "total_ms": 217.12198100067326, - "mean_ms": 4.342439620013465, - "median_ms": 4.342439620013465, - "p95_ms": 6.513659430020198, - "p99_ms": 8.68487924002693, - "min_ms": 0, - "max_ms": 217.12198100067326, - "std_ms": 0, - "throughput_ops_sec": 230.28529755283026, - "memory_delta_mb": 0.0078125, - "errors": 49, - "notes": "1/50 loaded, 0.00MB/plugin" - }, - { - "name": "sequential_call_ping", - "category": "plugin_calls", - "iterations": 300, - "total_ms": 0.43731200457841624, - "mean_ms": 0.0014577066819280542, - "median_ms": 0.0013984999895910732, - "p95_ms": 0.0015459991118405014, - "p99_ms": 0.003385999661986716, - "min_ms": 0.0013400003808783367, - "max_ms": 0.00393899972550571, - "std_ms": 0.0002761582529130064, - "throughput_ops_sec": 686009.0664312092, - "memory_delta_mb": 0.0, - "errors": 300, - "notes": "single plugin, 300 calls" - }, - { - "name": "sequential_call_echo_payload", - "category": "plugin_calls", - "iterations": 300, - "total_ms": 0.4002499863418052, - "mean_ms": 0.0013341666211393506, - "median_ms": 0.0013040007615927607, - "p95_ms": 0.0014170000213198364, - "p99_ms": 0.002333999873371795, - "min_ms": 0.001186999725177884, - "max_ms": 0.0084509993030224, - "std_ms": 0.0004493578761466993, - "throughput_ops_sec": 749531.5683628937, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "concurrent_10_calls", - "category": "plugin_calls", - "iterations": 10, - "total_ms": 0.1259989985555876, - "mean_ms": 0.01259989985555876, - "median_ms": 0.01259989985555876, - "p95_ms": 0.01637986981222639, - "p99_ms": 0.01889984978333814, - "min_ms": 0, - "max_ms": 0.1259989985555876, - "std_ms": 0, - "throughput_ops_sec": 79365.71016148395, - "memory_delta_mb": 0.0, - "errors": 10, - "notes": "asyncio.gather(10)" - }, - { - "name": "concurrent_50_calls", - "category": "plugin_calls", - "iterations": 50, - "total_ms": 0.9103359989239834, - "mean_ms": 0.01820671997847967, - "median_ms": 0.01820671997847967, - "p95_ms": 0.02366873597202357, - "p99_ms": 0.027310079967719503, - "min_ms": 0, - "max_ms": 0.9103359989239834, - "std_ms": 0, - "throughput_ops_sec": 54924.77509304253, - "memory_delta_mb": 0.0, - "errors": 50, - "notes": "asyncio.gather(50)" - }, - { - "name": "concurrent_100_calls", - "category": "plugin_calls", - "iterations": 100, - "total_ms": 0.977535000856733, - "mean_ms": 0.00977535000856733, - "median_ms": 0.00977535000856733, - "p95_ms": 0.012707955011137528, - "p99_ms": 0.014663025012850994, - "min_ms": 0, - "max_ms": 0.977535000856733, - "std_ms": 0, - "throughput_ops_sec": 102298.12734312104, - "memory_delta_mb": 0.0, - "errors": 100, - "notes": "asyncio.gather(100)" - }, - { - "name": "routing_5_plugins", - "category": "plugin_calls", - "iterations": 200, - "total_ms": 36.704412994367885, - "mean_ms": 0.18352206497183943, - "median_ms": 0.053088499953446444, - "p95_ms": 0.09035499897436239, - "p99_ms": 1.3090060001559323, - "min_ms": 0.04803100091521628, - "max_ms": 23.589220998474048, - "std_ms": 1.6658224108825137, - "throughput_ops_sec": 5448.936072910062, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "1 loaded, 200 calls round-robin" - }, - { - "name": "routing_20_plugins", - "category": "plugin_calls", - "iterations": 200, - "total_ms": 27.830518991322606, - "mean_ms": 0.13915259495661303, - "median_ms": 0.04957249984727241, - "p95_ms": 0.05526799941435456, - "p99_ms": 0.15645399980712682, - "min_ms": 0.04550499943434261, - "max_ms": 17.677613999694586, - "std_ms": 1.2464368919166002, - "throughput_ops_sec": 7186.3553842585125, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "1 loaded, 200 calls round-robin" - }, - { - "name": "pipeline_0_middlewares", - "category": "middleware", - "iterations": 2000, - "total_ms": 6.2837549648975255, - "mean_ms": 0.0031418774824487627, - "median_ms": 0.0030020000849617645, - "p95_ms": 0.003402001311769709, - "p99_ms": 0.005285000952426344, - "min_ms": 0.0028329995984677225, - "max_ms": 0.027694000891642645, - "std_ms": 0.0007802001839578725, - "throughput_ops_sec": 318281.02960291284, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "pipeline_4_middlewares", - "category": "middleware", - "iterations": 2000, - "total_ms": 15.405727997858776, - "mean_ms": 0.007702863998929388, - "median_ms": 0.00762699892220553, - "p95_ms": 0.007886999810580164, - "p99_ms": 0.008286000593216158, - "min_ms": 0.007045999154797755, - "max_ms": 0.038139998650876805, - "std_ms": 0.0009654246622238234, - "throughput_ops_sec": 129821.84290661095, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_no_handlers", - "category": "events", - "iterations": 2000, - "total_ms": 5.895346959732706, - "mean_ms": 0.002947673479866353, - "median_ms": 0.002868000592570752, - "p95_ms": 0.0030080009310040623, - "p99_ms": 0.0050319995352765545, - "min_ms": 0.002712999048526399, - "max_ms": 0.043355999878258444, - "std_ms": 0.001064872533143774, - "throughput_ops_sec": 339250.6011369142, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_1_handler", - "category": "events", - "iterations": 2000, - "total_ms": 60.01824601298722, - "mean_ms": 0.03000912300649361, - "median_ms": 0.02952399881905876, - "p95_ms": 0.03320500036352314, - "p99_ms": 0.041909999708877876, - "min_ms": 0.02584400135674514, - "max_ms": 0.2899190003518015, - "std_ms": 0.006676347765717948, - "throughput_ops_sec": 33323.199741079145, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_emit_10_handlers", - "category": "events", - "iterations": 2000, - "total_ms": 188.12697701469006, - "mean_ms": 0.09406348850734503, - "median_ms": 0.09339999996882398, - "p95_ms": 0.10070899952552281, - "p99_ms": 0.14355000166688114, - "min_ms": 0.08609399992565159, - "max_ms": 0.22089699996286072, - "std_ms": 0.009094239149095826, - "throughput_ops_sec": 10631.11751295418, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "eventbus_wildcard_matching", - "category": "events", - "iterations": 2000, - "total_ms": 61.01844501426967, - "mean_ms": 0.030509222507134837, - "median_ms": 0.030687499929626938, - "p95_ms": 0.03206899964425247, - "p99_ms": 0.03860600008920301, - "min_ms": 0.02817599852278363, - "max_ms": 0.11208199975953903, - "std_ms": 0.002674307538655587, - "throughput_ops_sec": 32776.97423348437, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "hookmanager_5_priority_hooks", - "category": "events", - "iterations": 1000, - "total_ms": 583.6400079806481, - "mean_ms": 0.5836400079806481, - "median_ms": 0.5261955002424656, - "p95_ms": 0.8773120007390389, - "p99_ms": 1.2226449998706812, - "min_ms": 0.4424439994181739, - "max_ms": 1.6500950005138293, - "std_ms": 0.15156558065797768, - "throughput_ops_sec": 1713.384939904869, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "permission_check_cold", - "category": "permissions", - "iterations": 30000, - "total_ms": 95.54461987681862, - "mean_ms": 0.0031848206625606206, - "median_ms": 0.0024439996195724234, - "p95_ms": 0.004006000381195918, - "p99_ms": 0.005276000592857599, - "min_ms": 0.0021680007193936035, - "max_ms": 16.837430999657954, - "std_ms": 0.09720053431247311, - "throughput_ops_sec": 313989.4223105147, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "permission_check_cached", - "category": "permissions", - "iterations": 30000, - "total_ms": 47.549882936436916, - "mean_ms": 0.0015849960978812304, - "median_ms": 0.0014399993233382702, - "p95_ms": 0.002587999915704131, - "p99_ms": 0.0039810001908335835, - "min_ms": 0.0012749987945426255, - "max_ms": 0.18682699919736478, - "std_ms": 0.0013853130015427815, - "throughput_ops_sec": 630916.3797543517, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_set_single", - "category": "cache", - "iterations": 3000, - "total_ms": 9.143716904873145, - "mean_ms": 0.003047905634957715, - "median_ms": 0.0027790010790340602, - "p95_ms": 0.003654000465758145, - "p99_ms": 0.0054299998737405986, - "min_ms": 0.0024029995984165, - "max_ms": 0.1521260001027258, - "std_ms": 0.0034273297951717763, - "throughput_ops_sec": 328094.147184407, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_get_hot", - "category": "cache", - "iterations": 3000, - "total_ms": 4.200314024274121, - "mean_ms": 0.0014001046747580403, - "median_ms": 0.0013295002645463683, - "p95_ms": 0.0017040001694113016, - "p99_ms": 0.0024310011212946847, - "min_ms": 0.0011490010365378112, - "max_ms": 0.019130999135086313, - "std_ms": 0.000579013570229349, - "throughput_ops_sec": 714232.3127896244, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_mset_100_keys", - "category": "cache", - "iterations": 300, - "total_ms": 31.199731001834152, - "mean_ms": 0.10399910333944717, - "median_ms": 0.09965949993784307, - "p95_ms": 0.12172499918960966, - "p99_ms": 0.14522600031341426, - "min_ms": 0.09780799882719293, - "max_ms": 0.15260500003932975, - "std_ms": 0.008374501325396673, - "throughput_ops_sec": 9615.467517407884, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - }, - { - "name": "cache_mget_100_keys", - "category": "cache", - "iterations": 300, - "total_ms": 13.054071996521088, - "mean_ms": 0.04351357332173696, - "median_ms": 0.04144000013184268, - "p95_ms": 0.05062099990027491, - "p99_ms": 0.07507800000894349, - "min_ms": 0.04022000030090567, - "max_ms": 0.08977200013760012, - "std_ms": 0.0059871690475594725, - "throughput_ops_sec": 22981.33487236397, - "memory_delta_mb": 0.0, - "errors": 0, - "notes": "" - } - ], - "capacity": {} -}