cognia-ai 3.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognia_ai-3.2.0/PKG-INFO +161 -0
- cognia_ai-3.2.0/README.md +126 -0
- cognia_ai-3.2.0/app/__init__.py +0 -0
- cognia_ai-3.2.0/app/main.py +53 -0
- cognia_ai-3.2.0/app/routes/__init__.py +0 -0
- cognia_ai-3.2.0/app/routes/chat.py +101 -0
- cognia_ai-3.2.0/app/routes/status.py +68 -0
- cognia_ai-3.2.0/app/routes/user_data.py +119 -0
- cognia_ai-3.2.0/cognia/__init__.py +1 -0
- cognia_ai-3.2.0/cognia/__main__.py +302 -0
- cognia_ai-3.2.0/cognia/attention.py +97 -0
- cognia_ai-3.2.0/cognia/cli.py +1019 -0
- cognia_ai-3.2.0/cognia/cognia.py +1819 -0
- cognia_ai-3.2.0/cognia/compression.py +158 -0
- cognia_ai-3.2.0/cognia/config.py +115 -0
- cognia_ai-3.2.0/cognia/consolidation_engine.py +894 -0
- cognia_ai-3.2.0/cognia/database.py +266 -0
- cognia_ai-3.2.0/cognia/first_run.py +395 -0
- cognia_ai-3.2.0/cognia/goal_and_pattern_engine.py +920 -0
- cognia_ai-3.2.0/cognia/ingest.py +161 -0
- cognia_ai-3.2.0/cognia/knowledge/__init__.py +4 -0
- cognia_ai-3.2.0/cognia/knowledge/goals.py +114 -0
- cognia_ai-3.2.0/cognia/knowledge/graph.py +218 -0
- cognia_ai-3.2.0/cognia/knowledge/inference.py +173 -0
- cognia_ai-3.2.0/cognia/knowledge/temporal.py +115 -0
- cognia_ai-3.2.0/cognia/language_engine.py +1017 -0
- cognia_ai-3.2.0/cognia/learning/__init__.py +1 -0
- cognia_ai-3.2.0/cognia/learning/style_engine.py +163 -0
- cognia_ai-3.2.0/cognia/memory/__init__.py +5 -0
- cognia_ai-3.2.0/cognia/memory/adapter_store.py +80 -0
- cognia_ai-3.2.0/cognia/memory/chat.py +103 -0
- cognia_ai-3.2.0/cognia/memory/emotion_wheel.py +223 -0
- cognia_ai-3.2.0/cognia/memory/episodic.py +319 -0
- cognia_ai-3.2.0/cognia/memory/episodic_fast.py +304 -0
- cognia_ai-3.2.0/cognia/memory/forgetting.py +163 -0
- cognia_ai-3.2.0/cognia/memory/narrative.py +199 -0
- cognia_ai-3.2.0/cognia/memory/personal_index.py +184 -0
- cognia_ai-3.2.0/cognia/memory/semantic.py +261 -0
- cognia_ai-3.2.0/cognia/memory/working.py +69 -0
- cognia_ai-3.2.0/cognia/memory_response_engine.py +174 -0
- cognia_ai-3.2.0/cognia/migrations/__init__.py +3 -0
- cognia_ai-3.2.0/cognia/migrations/runner.py +149 -0
- cognia_ai-3.2.0/cognia/program_creator/__init__.py +1 -0
- cognia_ai-3.2.0/cognia/program_creator/evaluator.py +295 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/cellular_automata_simulator/program.py +53 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/decent_dilemma/program.py +67 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/euclidean_empire/program.py +92 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/fractal_pattern_renderer/program.py +72 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/franzs_treasure_hunt/program.py +44 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/permutation_patterns/program.py +105 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/reaction_diffusion_simulator/program.py +96 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/royal_favors/program.py +39 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/stem_encryptor/program.py +36 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/story_spinner/program.py +61 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/untitled_automated_poetry_generator_based_on_user/program.py +23 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/untitled_procedural_story_generator_with_built_in/program.py +29 -0
- cognia_ai-3.2.0/cognia/program_creator/generated_programs/untitled_word_frequency_analyzer/program.py +61 -0
- cognia_ai-3.2.0/cognia/program_creator/generator.py +270 -0
- cognia_ai-3.2.0/cognia/program_creator/program_creator.py +263 -0
- cognia_ai-3.2.0/cognia/program_creator/sandbox_runner.py +229 -0
- cognia_ai-3.2.0/cognia/program_creator/storage.py +296 -0
- cognia_ai-3.2.0/cognia/reasoning/__init__.py +4 -0
- cognia_ai-3.2.0/cognia/reasoning/contradiction.py +91 -0
- cognia_ai-3.2.0/cognia/reasoning/hypothesis.py +180 -0
- cognia_ai-3.2.0/cognia/reasoning/metacognition.py +169 -0
- cognia_ai-3.2.0/cognia/reasoning/world_model.py +43 -0
- cognia_ai-3.2.0/cognia/research_engine/__init__.py +49 -0
- cognia_ai-3.2.0/cognia/research_engine/github_scraper.py +153 -0
- cognia_ai-3.2.0/cognia/research_engine/knowledge_integrator.py +345 -0
- cognia_ai-3.2.0/cognia/research_engine/research_orchestrator.py +257 -0
- cognia_ai-3.2.0/cognia/research_engine/researcher.py +223 -0
- cognia_ai-3.2.0/cognia/scale_manager.py +241 -0
- cognia_ai-3.2.0/cognia/user_profile.py +510 -0
- cognia_ai-3.2.0/cognia/ux/__init__.py +3 -0
- cognia_ai-3.2.0/cognia/ux/messages.py +44 -0
- cognia_ai-3.2.0/cognia/vectors.py +77 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/PKG-INFO +161 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/SOURCES.txt +134 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/dependency_links.txt +1 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/entry_points.txt +4 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/requires.txt +17 -0
- cognia_ai-3.2.0/cognia_ai.egg-info/top_level.txt +6 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/biplist/__init__.py +977 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/dmgbuild/badge.py +143 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/dmgbuild/colors.py +494 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/dmgbuild/core.py +290 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/ds_store/__init__.py +3 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/ds_store/buddy.py +478 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/ds_store/store.py +1251 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/mac_alias/__init__.py +27 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/mac_alias/alias.py +662 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/mac_alias/bookmark.py +672 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/mac_alias/osx.py +970 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/dmg-builder/vendor/mac_alias/utils.py +18 -0
- cognia_ai-3.2.0/cognia_desktop/node_modules/shell-quote/print.py +3 -0
- cognia_ai-3.2.0/coordinator/__init__.py +1 -0
- cognia_ai-3.2.0/coordinator/app.py +782 -0
- cognia_ai-3.2.0/coordinator/contributor.py +208 -0
- cognia_ai-3.2.0/coordinator/federated_store.py +333 -0
- cognia_ai-3.2.0/coordinator/rate_limiter.py +56 -0
- cognia_ai-3.2.0/coordinator/registry.py +336 -0
- cognia_ai-3.2.0/coordinator/relay.py +232 -0
- cognia_ai-3.2.0/coordinator/run.py +13 -0
- cognia_ai-3.2.0/node/__init__.py +1 -0
- cognia_ai-3.2.0/node/client.py +315 -0
- cognia_ai-3.2.0/node/downloader.py +645 -0
- cognia_ai-3.2.0/node/inference_pipeline.py +443 -0
- cognia_ai-3.2.0/node/local_adapter.py +254 -0
- cognia_ai-3.2.0/node/main.py +234 -0
- cognia_ai-3.2.0/node/qwen2_ops.py +156 -0
- cognia_ai-3.2.0/node/rank_expansion.py +78 -0
- cognia_ai-3.2.0/node/relay_client.py +354 -0
- cognia_ai-3.2.0/node/shard_engine.py +431 -0
- cognia_ai-3.2.0/pyproject.toml +54 -0
- cognia_ai-3.2.0/setup.cfg +4 -0
- cognia_ai-3.2.0/shattering/__init__.py +29 -0
- cognia_ai-3.2.0/shattering/distillation/__init__.py +27 -0
- cognia_ai-3.2.0/shattering/distillation/data_generator.py +179 -0
- cognia_ai-3.2.0/shattering/distillation/losses.py +141 -0
- cognia_ai-3.2.0/shattering/distillation/trainer.py +208 -0
- cognia_ai-3.2.0/shattering/dynamic_precision.py +192 -0
- cognia_ai-3.2.0/shattering/fragment_manager.py +275 -0
- cognia_ai-3.2.0/shattering/manifest.py +139 -0
- cognia_ai-3.2.0/shattering/mla.py +267 -0
- cognia_ai-3.2.0/shattering/model_constants.py +101 -0
- cognia_ai-3.2.0/shattering/moe_layer.py +564 -0
- cognia_ai-3.2.0/shattering/orchestrator.py +447 -0
- cognia_ai-3.2.0/shattering/quantization.py +173 -0
- cognia_ai-3.2.0/shattering/recursive_context.py +106 -0
- cognia_ai-3.2.0/shattering/router.py +145 -0
- cognia_ai-3.2.0/tests/test_consolidation.py +538 -0
- cognia_ai-3.2.0/tests/test_fase2.py +500 -0
- cognia_ai-3.2.0/tests/test_fase3.py +356 -0
- cognia_ai-3.2.0/tests/test_phase12.py +202 -0
- cognia_ai-3.2.0/tests/test_phase9_security.py +210 -0
- cognia_ai-3.2.0/tests/test_shattering.py +470 -0
cognia_ai-3.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cognia-ai
|
|
3
|
+
Version: 3.2.0
|
|
4
|
+
Summary: Local cognitive AI with episodic memory, distributed inference, and swarm learning
|
|
5
|
+
Author: Acua124298042
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/tomascomenta-blip/cognia_v2
|
|
8
|
+
Project-URL: Repository, https://github.com/tomascomenta-blip/cognia_v2
|
|
9
|
+
Keywords: ai,llm,distributed,memory,cognia
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: fastapi>=0.111.0
|
|
19
|
+
Requires-Dist: uvicorn[standard]>=0.29.0
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: flask>=2.3.0
|
|
22
|
+
Requires-Dist: requests>=2.31.0
|
|
23
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
24
|
+
Requires-Dist: pdfplumber>=0.10.0
|
|
25
|
+
Requires-Dist: numpy
|
|
26
|
+
Requires-Dist: sentence-transformers>=2.2.0
|
|
27
|
+
Requires-Dist: networkx>=3.0
|
|
28
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
29
|
+
Requires-Dist: websockets>=12.0
|
|
30
|
+
Requires-Dist: cryptography>=41.0.0
|
|
31
|
+
Requires-Dist: slowapi>=0.1.9
|
|
32
|
+
Requires-Dist: sse-starlette>=1.6
|
|
33
|
+
Requires-Dist: rich>=13.0
|
|
34
|
+
Requires-Dist: prompt_toolkit>=3.0
|
|
35
|
+
|
|
36
|
+
# Cognia v3 — Arquitectura Cognitiva Simbolico-Neural
|
|
37
|
+
|
|
38
|
+
> IA local, ligera, sin APIs externas. Corre en CPU. Objetivo: 2-5W de consumo.
|
|
39
|
+
> Ahora con inferencia distribuida real (SRDN) y soporte Qwen2.5-Coder.
|
|
40
|
+
|
|
41
|
+
**Stack:** Python 3.11+ · SQLite · Qwen2.5-Coder (INT4) · sentence-transformers · numpy · FastAPI · Electron
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Estado del proyecto (Mayo 2026)
|
|
46
|
+
|
|
47
|
+
| Fase | Estado | Descripcion |
|
|
48
|
+
|------|--------|-------------|
|
|
49
|
+
| **Fase 1-6 — Estabilizacion y Core** | COMPLETADA | Base limpia, NarrativeThread, MeshNode, Seguridad, Escalado. |
|
|
50
|
+
| **Fase 7 — Shattering (SRDN)** | COMPLETADA | LOGOS/TECHNE/RHETOR sub-models, MoE, NPQ, RST, MLA. |
|
|
51
|
+
| **Fase 8 — Commercial Release** | COMPLETADA | Instaladores, UX, Cifrado por defecto, Documentacion completa. |
|
|
52
|
+
| **Fase 9-12 — Hardening y UX** | COMPLETADA | Proteccion SQLi/XSS/SSRF, Consentimiento de privacidad, Auto-update. |
|
|
53
|
+
| **Fase 13 — Real Distributed Inference** | COMPLETADA | Inferencia real con Qwen2.5-Coder-3B INT4, auto-sharding. |
|
|
54
|
+
|
|
55
|
+
Ver [ROADMAP.md](ROADMAP.md) para el detalle tecnico de cada fase.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Que hace Cognia
|
|
60
|
+
|
|
61
|
+
Cognia es una arquitectura cognitiva que aprende, razona y recuerda localmente. A diferencia de un simple chatbot, gestiona un ciclo de vida cognitivo completo incluyendo consolidacion de memoria durante el "sueño" y razonamiento distribuido entre multiples dispositivos.
|
|
62
|
+
|
|
63
|
+
### Arquitectura Shattering (SRDN)
|
|
64
|
+
|
|
65
|
+
Cognia v3 introduce **Sparse-Recursive Distillation Network**, permitiendo correr modelos de 3B+ parametros en dispositivos con poca RAM (Android, PCs antiguos) mediante:
|
|
66
|
+
- **Auto-sharding:** El modelo se divide en fragmentos (shards) que pueden ejecutarse en distintos nodos de una red local.
|
|
67
|
+
- **Cuantizacion INT4:** Pesos comprimidos un 75% sin perdida critica de precision, operados puramente en numpy.
|
|
68
|
+
- **Inferencia hibrida:** Combina Ollama (para razonamiento general) con el motor nativo de Cognia (para tareas especializadas).
|
|
69
|
+
|
|
70
|
+
### Modulos Principales
|
|
71
|
+
|
|
72
|
+
| Modulo | Funcion |
|
|
73
|
+
|--------|---------|
|
|
74
|
+
| `KnowledgeGraph` | Memoria semantica estructurada y jerarquica. |
|
|
75
|
+
| `InferenceEngine` | Razonamiento transitivo y herencia de propiedades. |
|
|
76
|
+
| `ShatteringOrchestrator` | Gestion de inferencia distribuida y ruteo MoE. |
|
|
77
|
+
| `ConsolidationEngine` | Ciclo de sueño: purga, refuerzo y olvido de memorias. |
|
|
78
|
+
| `SecureStorage` | Cifrado AES-256-GCM de memorias episodicas. |
|
|
79
|
+
| `CogniaMeshNode` | Red P2P para sincronizacion de conocimiento via CRDT. |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Descarga e Instalacion
|
|
84
|
+
|
|
85
|
+
### Instaladores rapidos
|
|
86
|
+
|
|
87
|
+
Recomendado para la mayoria de los usuarios. Descarga el repositorio y ejecuta:
|
|
88
|
+
|
|
89
|
+
**Windows (PowerShell):**
|
|
90
|
+
```powershell
|
|
91
|
+
.\install.ps1
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Linux / macOS (Bash):**
|
|
95
|
+
```bash
|
|
96
|
+
bash install.sh
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Desktop App (Electron)
|
|
100
|
+
|
|
101
|
+
Para una experiencia visual, puedes construir el instalador de escritorio:
|
|
102
|
+
```bash
|
|
103
|
+
cd cognia_desktop
|
|
104
|
+
npm install
|
|
105
|
+
npm run build:win # o build:linux / build:mac
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Uso — Comandos Principales
|
|
111
|
+
|
|
112
|
+
### Cognicion y Memoria
|
|
113
|
+
- `aprender <texto> | <etiqueta>`: Enseñar un concepto nuevo.
|
|
114
|
+
- `observar <texto>`: Guardar una observacion sin procesar.
|
|
115
|
+
- `dormir`: Iniciar ciclo de consolidacion y limpieza (sueño).
|
|
116
|
+
- `yo`: Ver estado interno de la memoria y perfil cognitivo.
|
|
117
|
+
- `narrativa <texto>`: Recuperar hilos de episodios relacionados.
|
|
118
|
+
|
|
119
|
+
### Sistema y Red
|
|
120
|
+
- `doctor`: Diagnostico completo del sistema y dependencias.
|
|
121
|
+
- `update`: Actualizar Cognia, dependencias y migraciones de DB.
|
|
122
|
+
- `seguridad`: Gestionar cifrado y llaves de acceso.
|
|
123
|
+
- `grafo <concepto>`: Visualizar el grafo de conocimiento local.
|
|
124
|
+
- `inferir <concepto>`: Ejecutar razonamiento transitivo sobre un tema.
|
|
125
|
+
|
|
126
|
+
### Inferencia Distribuida (Qwen2.5)
|
|
127
|
+
```bash
|
|
128
|
+
# Convertir pesos de HuggingFace a shards de Cognia
|
|
129
|
+
python scripts/convert_hf_to_shards.py --hf-dir /path/to/qwen --out-dir model_shards/qwen-q4
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Seguridad y Privacidad
|
|
135
|
+
|
|
136
|
+
- **Local-First:** Tus datos nunca salen de tu maquina a menos que conectes nodos en red mesh de forma explicita.
|
|
137
|
+
- **Cifrado en reposo:** Memorias episodicas cifradas con AES-256-GCM.
|
|
138
|
+
- **Proteccion Anti-Injection:** Filtros estructurales en prompts y consultas SQL parametrizadas.
|
|
139
|
+
- **Privacidad Diferencial:** Ruido estadistico aplicado en sincronizaciones de red para proteger la identidad.
|
|
140
|
+
|
|
141
|
+
Ver [docs/PRIVACY.md](docs/PRIVACY.md) y [docs/SECURITY.md](docs/SECURITY.md) para mas detalles.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Documentacion
|
|
146
|
+
|
|
147
|
+
| Documento | Contenido |
|
|
148
|
+
|-----------|-----------|
|
|
149
|
+
| [docs/INSTALL.md](docs/INSTALL.md) | Guia detallada de instalacion y configuracion. |
|
|
150
|
+
| [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Solucion a problemas comunes y diagnostico. |
|
|
151
|
+
| [docs/PRIVACY.md](docs/PRIVACY.md) | Detalles sobre el manejo de datos y privacidad. |
|
|
152
|
+
| [ROADMAP.md](ROADMAP.md) | Plan de desarrollo y estado de las fases. |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Para Colaborar
|
|
157
|
+
|
|
158
|
+
Lee el [ROADMAP.md](ROADMAP.md) para entender la direccion actual. Cognia prioriza la eficiencia (CPU-only), la privacidad y la estabilidad. No se aceptan dependencias pesadas (PyTorch/Tensorflow) en el motor de inferencia principal.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
© 2026 Cognia Project. Distribuido bajo licencia MIT.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Cognia v3 — Arquitectura Cognitiva Simbolico-Neural
|
|
2
|
+
|
|
3
|
+
> IA local, ligera, sin APIs externas. Corre en CPU. Objetivo: 2-5W de consumo.
|
|
4
|
+
> Ahora con inferencia distribuida real (SRDN) y soporte Qwen2.5-Coder.
|
|
5
|
+
|
|
6
|
+
**Stack:** Python 3.11+ · SQLite · Qwen2.5-Coder (INT4) · sentence-transformers · numpy · FastAPI · Electron
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Estado del proyecto (Mayo 2026)
|
|
11
|
+
|
|
12
|
+
| Fase | Estado | Descripcion |
|
|
13
|
+
|------|--------|-------------|
|
|
14
|
+
| **Fase 1-6 — Estabilizacion y Core** | COMPLETADA | Base limpia, NarrativeThread, MeshNode, Seguridad, Escalado. |
|
|
15
|
+
| **Fase 7 — Shattering (SRDN)** | COMPLETADA | LOGOS/TECHNE/RHETOR sub-models, MoE, NPQ, RST, MLA. |
|
|
16
|
+
| **Fase 8 — Commercial Release** | COMPLETADA | Instaladores, UX, Cifrado por defecto, Documentacion completa. |
|
|
17
|
+
| **Fase 9-12 — Hardening y UX** | COMPLETADA | Proteccion SQLi/XSS/SSRF, Consentimiento de privacidad, Auto-update. |
|
|
18
|
+
| **Fase 13 — Real Distributed Inference** | COMPLETADA | Inferencia real con Qwen2.5-Coder-3B INT4, auto-sharding. |
|
|
19
|
+
|
|
20
|
+
Ver [ROADMAP.md](ROADMAP.md) para el detalle tecnico de cada fase.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Que hace Cognia
|
|
25
|
+
|
|
26
|
+
Cognia es una arquitectura cognitiva que aprende, razona y recuerda localmente. A diferencia de un simple chatbot, gestiona un ciclo de vida cognitivo completo incluyendo consolidacion de memoria durante el "sueño" y razonamiento distribuido entre multiples dispositivos.
|
|
27
|
+
|
|
28
|
+
### Arquitectura Shattering (SRDN)
|
|
29
|
+
|
|
30
|
+
Cognia v3 introduce **Sparse-Recursive Distillation Network**, permitiendo correr modelos de 3B+ parametros en dispositivos con poca RAM (Android, PCs antiguos) mediante:
|
|
31
|
+
- **Auto-sharding:** El modelo se divide en fragmentos (shards) que pueden ejecutarse en distintos nodos de una red local.
|
|
32
|
+
- **Cuantizacion INT4:** Pesos comprimidos un 75% sin perdida critica de precision, operados puramente en numpy.
|
|
33
|
+
- **Inferencia hibrida:** Combina Ollama (para razonamiento general) con el motor nativo de Cognia (para tareas especializadas).
|
|
34
|
+
|
|
35
|
+
### Modulos Principales
|
|
36
|
+
|
|
37
|
+
| Modulo | Funcion |
|
|
38
|
+
|--------|---------|
|
|
39
|
+
| `KnowledgeGraph` | Memoria semantica estructurada y jerarquica. |
|
|
40
|
+
| `InferenceEngine` | Razonamiento transitivo y herencia de propiedades. |
|
|
41
|
+
| `ShatteringOrchestrator` | Gestion de inferencia distribuida y ruteo MoE. |
|
|
42
|
+
| `ConsolidationEngine` | Ciclo de sueño: purga, refuerzo y olvido de memorias. |
|
|
43
|
+
| `SecureStorage` | Cifrado AES-256-GCM de memorias episodicas. |
|
|
44
|
+
| `CogniaMeshNode` | Red P2P para sincronizacion de conocimiento via CRDT. |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Descarga e Instalacion
|
|
49
|
+
|
|
50
|
+
### Instaladores rapidos
|
|
51
|
+
|
|
52
|
+
Recomendado para la mayoria de los usuarios. Descarga el repositorio y ejecuta:
|
|
53
|
+
|
|
54
|
+
**Windows (PowerShell):**
|
|
55
|
+
```powershell
|
|
56
|
+
.\install.ps1
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Linux / macOS (Bash):**
|
|
60
|
+
```bash
|
|
61
|
+
bash install.sh
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Desktop App (Electron)
|
|
65
|
+
|
|
66
|
+
Para una experiencia visual, puedes construir el instalador de escritorio:
|
|
67
|
+
```bash
|
|
68
|
+
cd cognia_desktop
|
|
69
|
+
npm install
|
|
70
|
+
npm run build:win # o build:linux / build:mac
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Uso — Comandos Principales
|
|
76
|
+
|
|
77
|
+
### Cognicion y Memoria
|
|
78
|
+
- `aprender <texto> | <etiqueta>`: Enseñar un concepto nuevo.
|
|
79
|
+
- `observar <texto>`: Guardar una observacion sin procesar.
|
|
80
|
+
- `dormir`: Iniciar ciclo de consolidacion y limpieza (sueño).
|
|
81
|
+
- `yo`: Ver estado interno de la memoria y perfil cognitivo.
|
|
82
|
+
- `narrativa <texto>`: Recuperar hilos de episodios relacionados.
|
|
83
|
+
|
|
84
|
+
### Sistema y Red
|
|
85
|
+
- `doctor`: Diagnostico completo del sistema y dependencias.
|
|
86
|
+
- `update`: Actualizar Cognia, dependencias y migraciones de DB.
|
|
87
|
+
- `seguridad`: Gestionar cifrado y llaves de acceso.
|
|
88
|
+
- `grafo <concepto>`: Visualizar el grafo de conocimiento local.
|
|
89
|
+
- `inferir <concepto>`: Ejecutar razonamiento transitivo sobre un tema.
|
|
90
|
+
|
|
91
|
+
### Inferencia Distribuida (Qwen2.5)
|
|
92
|
+
```bash
|
|
93
|
+
# Convertir pesos de HuggingFace a shards de Cognia
|
|
94
|
+
python scripts/convert_hf_to_shards.py --hf-dir /path/to/qwen --out-dir model_shards/qwen-q4
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Seguridad y Privacidad
|
|
100
|
+
|
|
101
|
+
- **Local-First:** Tus datos nunca salen de tu maquina a menos que conectes nodos en red mesh de forma explicita.
|
|
102
|
+
- **Cifrado en reposo:** Memorias episodicas cifradas con AES-256-GCM.
|
|
103
|
+
- **Proteccion Anti-Injection:** Filtros estructurales en prompts y consultas SQL parametrizadas.
|
|
104
|
+
- **Privacidad Diferencial:** Ruido estadistico aplicado en sincronizaciones de red para proteger la identidad.
|
|
105
|
+
|
|
106
|
+
Ver [docs/PRIVACY.md](docs/PRIVACY.md) y [docs/SECURITY.md](docs/SECURITY.md) para mas detalles.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Documentacion
|
|
111
|
+
|
|
112
|
+
| Documento | Contenido |
|
|
113
|
+
|-----------|-----------|
|
|
114
|
+
| [docs/INSTALL.md](docs/INSTALL.md) | Guia detallada de instalacion y configuracion. |
|
|
115
|
+
| [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Solucion a problemas comunes y diagnostico. |
|
|
116
|
+
| [docs/PRIVACY.md](docs/PRIVACY.md) | Detalles sobre el manejo de datos y privacidad. |
|
|
117
|
+
| [ROADMAP.md](ROADMAP.md) | Plan de desarrollo y estado de las fases. |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Para Colaborar
|
|
122
|
+
|
|
123
|
+
Lee el [ROADMAP.md](ROADMAP.md) para entender la direccion actual. Cognia prioriza la eficiencia (CPU-only), la privacidad y la estabilidad. No se aceptan dependencias pesadas (PyTorch/Tensorflow) en el motor de inferencia principal.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
© 2026 Cognia Project. Distribuido bajo licencia MIT.
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
app/main.py
|
|
3
|
+
===========
|
|
4
|
+
Punto de entrada FastAPI para Cognia v3 - Fase 7A
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
# Asegurar que el root del repo esté en el path para que Cognia importe bien
|
|
11
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
12
|
+
sys.path.insert(0, ROOT)
|
|
13
|
+
|
|
14
|
+
from fastapi import FastAPI
|
|
15
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
16
|
+
from fastapi.staticfiles import StaticFiles
|
|
17
|
+
from fastapi.responses import FileResponse
|
|
18
|
+
|
|
19
|
+
from app.routes.chat import router as chat_router
|
|
20
|
+
from app.routes.status import router as status_router
|
|
21
|
+
from app.routes.user_data import router as user_data_router
|
|
22
|
+
|
|
23
|
+
app = FastAPI(
|
|
24
|
+
title="Cognia v3 API",
|
|
25
|
+
description="API REST para el sistema de IA Cognia v3",
|
|
26
|
+
version="7.0.0",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
app.add_middleware(
|
|
30
|
+
CORSMiddleware,
|
|
31
|
+
allow_origins=["http://localhost:3000", "http://localhost:8765"],
|
|
32
|
+
allow_methods=["*"],
|
|
33
|
+
allow_headers=["*"],
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
app.include_router(chat_router, prefix="/api")
|
|
37
|
+
app.include_router(status_router, prefix="/api")
|
|
38
|
+
app.include_router(user_data_router, prefix="/api")
|
|
39
|
+
|
|
40
|
+
# Servir frontend estático
|
|
41
|
+
static_dir = os.path.join(os.path.dirname(__file__), "static")
|
|
42
|
+
if os.path.isdir(static_dir):
|
|
43
|
+
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
|
44
|
+
|
|
45
|
+
@app.get("/", include_in_schema=False)
|
|
46
|
+
def index():
|
|
47
|
+
return FileResponse(os.path.join(static_dir, "index.html"))
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
from prometheus_fastapi_instrumentator import Instrumentator
|
|
51
|
+
Instrumentator().instrument(app).expose(app)
|
|
52
|
+
except ImportError:
|
|
53
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
app/routes/chat.py
|
|
3
|
+
==================
|
|
4
|
+
Endpoint POST /api/chat con fallback simbolico cuando Ollama no esta disponible.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
|
10
|
+
|
|
11
|
+
from fastapi import APIRouter
|
|
12
|
+
from pydantic import BaseModel
|
|
13
|
+
|
|
14
|
+
router = APIRouter()
|
|
15
|
+
|
|
16
|
+
_cognia = None
|
|
17
|
+
|
|
18
|
+
def get_cognia():
|
|
19
|
+
global _cognia
|
|
20
|
+
if _cognia is None:
|
|
21
|
+
from cognia.cognia import Cognia
|
|
22
|
+
_cognia = Cognia()
|
|
23
|
+
return _cognia
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ChatRequest(BaseModel):
|
|
27
|
+
input: str
|
|
28
|
+
|
|
29
|
+
class ChatResponse(BaseModel):
|
|
30
|
+
response: str
|
|
31
|
+
stage: str = ""
|
|
32
|
+
error: str = ""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _respuesta_sin_ollama(ai, pregunta: str) -> dict:
|
|
36
|
+
"""
|
|
37
|
+
Respuesta usando solo memoria interna de Cognia, sin LLM.
|
|
38
|
+
Fuerza al LanguageEngine a usar Stage 2 (simbolico) o Stage 5 (fallback)
|
|
39
|
+
apuntando Ollama a un puerto cerrado para que falle rapido.
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
from language_engine import get_language_engine
|
|
43
|
+
engine = get_language_engine(ai)
|
|
44
|
+
original_url = engine.ollama_url
|
|
45
|
+
engine.ollama_url = "http://127.0.0.1:1"
|
|
46
|
+
try:
|
|
47
|
+
result = engine.respond(cognia_instance=ai, question=pregunta)
|
|
48
|
+
return {"response": result.response, "stage": result.stage_used}
|
|
49
|
+
finally:
|
|
50
|
+
engine.ollama_url = original_url
|
|
51
|
+
except Exception:
|
|
52
|
+
try:
|
|
53
|
+
resp = ai.process(pregunta)
|
|
54
|
+
return {"response": resp or "Mensaje recibido.", "stage": "process"}
|
|
55
|
+
except Exception:
|
|
56
|
+
return {
|
|
57
|
+
"response": (
|
|
58
|
+
"Cognia recibio tu mensaje. "
|
|
59
|
+
"El modelo de lenguaje (Ollama) no esta disponible en este servidor. "
|
|
60
|
+
"Puedes usar comandos como 'yo', 'conceptos', 'dormir' para interactuar "
|
|
61
|
+
"con la memoria interna de Cognia."
|
|
62
|
+
),
|
|
63
|
+
"stage": "no_llm",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@router.post("/chat", response_model=ChatResponse)
|
|
68
|
+
def chat(req: ChatRequest):
|
|
69
|
+
if not req.input.strip():
|
|
70
|
+
return ChatResponse(response="", error="Mensaje vacio.")
|
|
71
|
+
try:
|
|
72
|
+
ai = get_cognia()
|
|
73
|
+
try:
|
|
74
|
+
from respuestas_articuladas import responder_articulado
|
|
75
|
+
resultado = responder_articulado(ai, req.input.strip())
|
|
76
|
+
except Exception as e:
|
|
77
|
+
resultado = {"error": str(e)}
|
|
78
|
+
|
|
79
|
+
if "error" in resultado:
|
|
80
|
+
err = str(resultado["error"])
|
|
81
|
+
ollama_error = any(x in err.lower() for x in [
|
|
82
|
+
"ollama", "connection refused", "urlerror", "urlopen", "errno 111"
|
|
83
|
+
])
|
|
84
|
+
if ollama_error:
|
|
85
|
+
fallback = _respuesta_sin_ollama(ai, req.input.strip())
|
|
86
|
+
return ChatResponse(
|
|
87
|
+
response=fallback["response"],
|
|
88
|
+
stage=fallback.get("stage", "fallback"),
|
|
89
|
+
)
|
|
90
|
+
return ChatResponse(response="", error=err)
|
|
91
|
+
|
|
92
|
+
stage = (
|
|
93
|
+
resultado.get("stage")
|
|
94
|
+
or resultado.get("language_engine", {}).get("stage", "")
|
|
95
|
+
)
|
|
96
|
+
return ChatResponse(
|
|
97
|
+
response=resultado.get("response", ""),
|
|
98
|
+
stage=stage,
|
|
99
|
+
)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
return ChatResponse(response="", error=str(e))
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
app/routes/status.py
|
|
3
|
+
=====================
|
|
4
|
+
Endpoints GET /api/health, /api/status, /api/conceptos
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
|
10
|
+
|
|
11
|
+
from fastapi import APIRouter
|
|
12
|
+
from app.routes.chat import get_cognia
|
|
13
|
+
|
|
14
|
+
router = APIRouter()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@router.get("/health")
|
|
18
|
+
def health():
|
|
19
|
+
return {"status": "ok", "service": "cognia-v3"}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@router.get("/status")
|
|
23
|
+
def status():
|
|
24
|
+
try:
|
|
25
|
+
ai = get_cognia()
|
|
26
|
+
result = {
|
|
27
|
+
"status": "ok",
|
|
28
|
+
"episodios": 0,
|
|
29
|
+
"conceptos": 0,
|
|
30
|
+
"escala": {},
|
|
31
|
+
"usuarios": [],
|
|
32
|
+
}
|
|
33
|
+
# Episodios
|
|
34
|
+
try:
|
|
35
|
+
from storage.db_pool import db_connect_pooled as db_connect
|
|
36
|
+
with db_connect(ai.db) as conn:
|
|
37
|
+
cur = conn.execute("SELECT COUNT(*) FROM episodic_memory")
|
|
38
|
+
result["episodios"] = cur.fetchone()[0]
|
|
39
|
+
cur2 = conn.execute("SELECT COUNT(DISTINCT label) FROM episodic_memory")
|
|
40
|
+
result["conceptos"] = cur2.fetchone()[0]
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
# Escala
|
|
44
|
+
try:
|
|
45
|
+
from cognia.scale_manager import get_scale_manager
|
|
46
|
+
st = get_scale_manager().status()
|
|
47
|
+
result["escala"] = {
|
|
48
|
+
"nivel": st.get("level"),
|
|
49
|
+
"nombre": st.get("name"),
|
|
50
|
+
"modelo": st.get("model"),
|
|
51
|
+
"ram_gb": st.get("ram_gb"),
|
|
52
|
+
}
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
return result
|
|
56
|
+
except Exception as e:
|
|
57
|
+
return {"status": "error", "detail": str(e)}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@router.get("/conceptos")
|
|
61
|
+
def conceptos():
|
|
62
|
+
try:
|
|
63
|
+
ai = get_cognia()
|
|
64
|
+
lista = ai.list_concepts()
|
|
65
|
+
# list_concepts() devuelve string; si hay un metodo mejor lo usamos
|
|
66
|
+
return {"conceptos": lista}
|
|
67
|
+
except Exception as e:
|
|
68
|
+
return {"error": str(e)}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
app/routes/user_data.py
|
|
3
|
+
=======================
|
|
4
|
+
GDPR-aligned user data endpoints:
|
|
5
|
+
GET /api/user/data/export — export all personal episodic memory as JSON
|
|
6
|
+
DELETE /api/user/data — soft-delete all episodic memory (right to erasure)
|
|
7
|
+
|
|
8
|
+
Authentication: X-Admin-Key header must match COGNIA_ADMIN_KEY env var.
|
|
9
|
+
If COGNIA_ADMIN_KEY is not set, both endpoints return 503 (fail-safe).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
|
15
|
+
|
|
16
|
+
from fastapi import APIRouter, HTTPException, Header
|
|
17
|
+
from typing import Optional
|
|
18
|
+
|
|
19
|
+
router = APIRouter()
|
|
20
|
+
|
|
21
|
+
_ADMIN_KEY = os.environ.get("COGNIA_ADMIN_KEY", "")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _require_admin_key(x_admin_key: Optional[str] = Header(None)) -> None:
|
|
25
|
+
if not _ADMIN_KEY:
|
|
26
|
+
raise HTTPException(
|
|
27
|
+
status_code=503,
|
|
28
|
+
detail="User data endpoints are not configured. Set COGNIA_ADMIN_KEY.",
|
|
29
|
+
)
|
|
30
|
+
if x_admin_key != _ADMIN_KEY:
|
|
31
|
+
raise HTTPException(status_code=403, detail="Invalid admin key.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_db_path() -> str:
|
|
35
|
+
try:
|
|
36
|
+
from cognia.config import DB_PATH
|
|
37
|
+
return DB_PATH
|
|
38
|
+
except ImportError:
|
|
39
|
+
return "cognia_memory.db"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@router.get("/user/data/export")
|
|
43
|
+
def export_user_data(x_admin_key: Optional[str] = Header(None)):
|
|
44
|
+
"""
|
|
45
|
+
Export all non-forgotten episodic memory rows as JSON.
|
|
46
|
+
Intended for privacy/GDPR data access requests.
|
|
47
|
+
"""
|
|
48
|
+
_require_admin_key(x_admin_key)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
from cognia.database import db_connect
|
|
52
|
+
conn = db_connect(_get_db_path())
|
|
53
|
+
rows = conn.execute(
|
|
54
|
+
"""
|
|
55
|
+
SELECT id, timestamp, observation, label, confidence,
|
|
56
|
+
emotion_label, context_tags, notes
|
|
57
|
+
FROM episodic_memory
|
|
58
|
+
WHERE forgotten = 0
|
|
59
|
+
ORDER BY timestamp DESC
|
|
60
|
+
"""
|
|
61
|
+
).fetchall()
|
|
62
|
+
conn.close()
|
|
63
|
+
except Exception:
|
|
64
|
+
raise HTTPException(
|
|
65
|
+
status_code=503,
|
|
66
|
+
detail="Could not read user data. Please try again.",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
records = [
|
|
70
|
+
{
|
|
71
|
+
"id": r[0],
|
|
72
|
+
"timestamp": r[1],
|
|
73
|
+
"observation": r[2],
|
|
74
|
+
"label": r[3],
|
|
75
|
+
"confidence": r[4],
|
|
76
|
+
"emotion": r[5],
|
|
77
|
+
"context_tags": r[6],
|
|
78
|
+
"notes": r[7],
|
|
79
|
+
}
|
|
80
|
+
for r in rows
|
|
81
|
+
]
|
|
82
|
+
return {"count": len(records), "records": records}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@router.delete("/user/data")
|
|
86
|
+
def delete_user_data(x_admin_key: Optional[str] = Header(None)):
|
|
87
|
+
"""
|
|
88
|
+
Soft-delete all episodic memory (sets forgotten=1).
|
|
89
|
+
Irreversible via API. Right to erasure (GDPR Art. 17).
|
|
90
|
+
|
|
91
|
+
WARNING: Cognia is single-user. This endpoint deletes ALL stored memory
|
|
92
|
+
regardless of which user created it. There is no per-user scoping.
|
|
93
|
+
"""
|
|
94
|
+
_require_admin_key(x_admin_key)
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
from cognia.database import db_connect
|
|
98
|
+
conn = db_connect(_get_db_path())
|
|
99
|
+
result = conn.execute(
|
|
100
|
+
"UPDATE episodic_memory SET forgotten=1 WHERE forgotten=0"
|
|
101
|
+
)
|
|
102
|
+
deleted = result.rowcount
|
|
103
|
+
conn.commit()
|
|
104
|
+
conn.close()
|
|
105
|
+
except Exception:
|
|
106
|
+
raise HTTPException(
|
|
107
|
+
status_code=503,
|
|
108
|
+
detail="Could not delete user data. Please try again.",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
"deleted": deleted,
|
|
113
|
+
"status": "ok",
|
|
114
|
+
"scope": "all",
|
|
115
|
+
"warning": (
|
|
116
|
+
"Cognia is single-user. All episodic memory was deleted, "
|
|
117
|
+
"regardless of origin. There is no per-user scoping."
|
|
118
|
+
),
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .cognia import Cognia
|