admina-framework 0.9.2__tar.gz → 0.9.3__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.
Files changed (114) hide show
  1. {admina_framework-0.9.2/admina_framework.egg-info → admina_framework-0.9.3}/PKG-INFO +25 -24
  2. {admina_framework-0.9.2 → admina_framework-0.9.3}/README.md +24 -23
  3. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/__init__.py +1 -1
  4. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/main.py +132 -17
  5. {admina_framework-0.9.2 → admina_framework-0.9.3/admina_framework.egg-info}/PKG-INFO +25 -24
  6. {admina_framework-0.9.2 → admina_framework-0.9.3}/pyproject.toml +1 -1
  7. {admina_framework-0.9.2 → admina_framework-0.9.3}/LICENSE +0 -0
  8. {admina_framework-0.9.2 → admina_framework-0.9.3}/NOTICE +0 -0
  9. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/__init__.py +0 -0
  10. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/commands/__init__.py +0 -0
  11. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/admina.yaml.j2 +0 -0
  12. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/docker-compose.yml.j2 +0 -0
  13. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/env.j2 +0 -0
  14. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/main.py.j2 +0 -0
  15. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/plugin.py.j2 +0 -0
  16. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/plugin_pyproject.toml.j2 +0 -0
  17. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/plugin_readme.md.j2 +0 -0
  18. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/cli/templates/plugin_test.py.j2 +0 -0
  19. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/core/__init__.py +0 -0
  20. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/core/config.py +0 -0
  21. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/core/event_bus.py +0 -0
  22. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/core/secrets.py +0 -0
  23. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/core/types.py +0 -0
  24. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/dashboard/__init__.py +0 -0
  25. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/dashboard/static/heimdall.png +0 -0
  26. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/dashboard/static/index.html +0 -0
  27. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/dashboard/static/vendor/alpinejs.min.js +0 -0
  28. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/__init__.py +0 -0
  29. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/agent_security/__init__.py +0 -0
  30. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/agent_security/firewall.py +0 -0
  31. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/agent_security/loop_breaker.py +0 -0
  32. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/ai_infra/__init__.py +0 -0
  33. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/ai_infra/llm_engine.py +0 -0
  34. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/ai_infra/rag.py +0 -0
  35. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/ai_infra/webui.py +0 -0
  36. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/__init__.py +0 -0
  37. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/cross_regulation.py +0 -0
  38. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/eu_ai_act.py +0 -0
  39. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/forensic.py +0 -0
  40. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/gdpr.py +0 -0
  41. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/nis2.py +0 -0
  42. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/oisg.py +0 -0
  43. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/compliance/otel.py +0 -0
  44. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/data_sovereignty/__init__.py +0 -0
  45. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/data_sovereignty/classification.py +0 -0
  46. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/data_sovereignty/pii.py +0 -0
  47. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/domains/data_sovereignty/residency.py +0 -0
  48. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/__init__.py +0 -0
  49. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/_engines.py +0 -0
  50. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/cheshirecat/__init__.py +0 -0
  51. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/cheshirecat/admina-plugin/admina_governance.py +0 -0
  52. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/crewai/__init__.py +0 -0
  53. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/crewai/callbacks.py +0 -0
  54. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/langchain/__init__.py +0 -0
  55. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/langchain/callbacks.py +0 -0
  56. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/n8n/__init__.py +0 -0
  57. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/integrations/openclaw/__init__.py +0 -0
  58. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/__init__.py +0 -0
  59. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/base.py +0 -0
  60. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/__init__.py +0 -0
  61. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/adapters/__init__.py +0 -0
  62. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/adapters/ollama.py +0 -0
  63. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/adapters/openai.py +0 -0
  64. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/alerts/__init__.py +0 -0
  65. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/alerts/log.py +0 -0
  66. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/alerts/webhook.py +0 -0
  67. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/auth/__init__.py +0 -0
  68. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/auth/apikey.py +0 -0
  69. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/compliance/__init__.py +0 -0
  70. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/compliance/eu_ai_act.py +0 -0
  71. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/connectors/__init__.py +0 -0
  72. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/connectors/chromadb.py +0 -0
  73. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/connectors/filesystem.py +0 -0
  74. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/forensic/__init__.py +0 -0
  75. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/forensic/filesystem.py +0 -0
  76. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/forensic/minio.py +0 -0
  77. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/guards/__init__.py +0 -0
  78. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/guards/guardrailsai_guard.py +0 -0
  79. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/pii/__init__.py +0 -0
  80. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/pii/spacy_regex.py +0 -0
  81. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/transports/__init__.py +0 -0
  82. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/transports/http_rest.py +0 -0
  83. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/builtin/transports/mcp.py +0 -0
  84. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/plugins/registry.py +0 -0
  85. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/__init__.py +0 -0
  86. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/api/__init__.py +0 -0
  87. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/api/dashboard.py +0 -0
  88. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/api/integration.py +0 -0
  89. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/config.py +0 -0
  90. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/engine_bridge.py +0 -0
  91. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/governance.py +0 -0
  92. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/main.py +0 -0
  93. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/multi_upstream.py +0 -0
  94. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/proxy/state.py +0 -0
  95. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/py.typed +0 -0
  96. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/__init__.py +0 -0
  97. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/_compat.py +0 -0
  98. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/compliance_kit.py +0 -0
  99. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/governed_agent.py +0 -0
  100. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/governed_data.py +0 -0
  101. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina/sdk/governed_model.py +0 -0
  102. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina_framework.egg-info/SOURCES.txt +0 -0
  103. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina_framework.egg-info/dependency_links.txt +0 -0
  104. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina_framework.egg-info/entry_points.txt +0 -0
  105. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina_framework.egg-info/requires.txt +0 -0
  106. {admina_framework-0.9.2 → admina_framework-0.9.3}/admina_framework.egg-info/top_level.txt +0 -0
  107. {admina_framework-0.9.2 → admina_framework-0.9.3}/setup.cfg +0 -0
  108. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_benchmark_14us.py +0 -0
  109. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_core_config.py +0 -0
  110. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_domains.py +0 -0
  111. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_governance_pipeline.py +0 -0
  112. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_mcp_transport.py +0 -0
  113. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_proxy_security.py +0 -0
  114. {admina_framework-0.9.2 → admina_framework-0.9.3}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: admina-framework
3
- Version: 0.9.2
3
+ Version: 0.9.3
4
4
  Summary: Admina — governed AI development framework
5
5
  Author-email: Stefano Noferi <info@admina.org>
6
6
  Maintainer-email: Stefano Noferi <info@admina.org>
@@ -120,20 +120,22 @@ report = kit.gap_analysis(risk_category="high", current_compliance={...})
120
120
  ### Install from PyPI
121
121
 
122
122
  ```bash
123
- # SDK only (lightweight, pure Python)
124
- pip install admina-framework
125
-
126
- # Proxy + infrastructure deps
123
+ # Recommended for new users: SDK + proxy + dashboard.
124
+ # Lets you run `admina dev` and see the dashboard out of the box.
127
125
  pip install "admina-framework[proxy]"
128
126
 
129
- # Everything (proxy + NLP + telemetry)
127
+ # Everything (proxy + NLP + telemetry). Use this if you also want
128
+ # spaCy-based NER for PII detection or OpenTelemetry export.
130
129
  pip install "admina-framework[full]"
130
+ python -m spacy download en_core_web_sm # for [full] only
131
131
 
132
- # After [nlp] / [full] install: download the spaCy NER model
133
- python -m spacy download en_core_web_sm
134
-
135
- # Optional: Rust-accelerated engine (auto-detected at runtime)
132
+ # Optional: Rust-accelerated engine (auto-detected at runtime).
136
133
  pip install admina-core
134
+
135
+ # Advanced: SDK only (no proxy, no dashboard, no `admina dev`).
136
+ # Use this when embedding the SDK into another service and you don't
137
+ # need the local dev server.
138
+ pip install admina-framework
137
139
  ```
138
140
 
139
141
  > The PyPI distribution name is `admina-framework`; the Python import
@@ -151,28 +153,27 @@ pip install admina-core
151
153
  git clone https://github.com/admina-org/admina.git
152
154
  cd admina
153
155
 
154
- # Option 1: SDK only (lightweight)
155
- pip install -e .
156
- python -c "from admina import GovernedModel; print('SDK ready')"
157
-
158
- # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
159
- # and pull a model first: ollama pull llama3.1:8b
160
-
161
- # Option 2: Proxy + infra deps
156
+ # Recommended: proxy + dashboard + infra deps (enables `admina dev`)
162
157
  pip install -e ".[proxy]"
163
158
 
164
- # Option 3: Everything (proxy + NLP + telemetry)
159
+ # Everything (proxy + NLP + telemetry)
165
160
  pip install -e ".[full]"
166
161
 
167
- # Option 4: Full stack (proxy + dashboard + infra via Docker)
162
+ # CLI workflow
163
+ admina init my-project # Scaffold a governed AI project
164
+ cd my-project # admina dev runs from the project directory
165
+ admina dev # Start the local proxy + dashboard
166
+
167
+ # Full stack via Docker (no [proxy] extra required)
168
168
  ./scripts/bootstrap-secrets.sh # Auto-generate .env with random credentials
169
169
  docker compose up --build # Credentials printed at bootstrap
170
170
 
171
- # Option 5: CLI
171
+ # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
172
+ # and pull a model first: ollama pull llama3.1:8b
173
+
174
+ # Advanced: SDK only (no proxy, no dashboard)
172
175
  pip install -e .
173
- admina init my-project # Scaffold a governed AI project
174
- cd my-project # admina dev runs from the project directory
175
- admina dev # Start local dev stack
176
+ python -c "from admina import GovernedModel; print('SDK ready')"
176
177
  ```
177
178
 
178
179
  Dashboard: [http://localhost:3000](http://localhost:3000) | API docs: [http://localhost:8080/docs](http://localhost:8080/docs)
@@ -62,20 +62,22 @@ report = kit.gap_analysis(risk_category="high", current_compliance={...})
62
62
  ### Install from PyPI
63
63
 
64
64
  ```bash
65
- # SDK only (lightweight, pure Python)
66
- pip install admina-framework
67
-
68
- # Proxy + infrastructure deps
65
+ # Recommended for new users: SDK + proxy + dashboard.
66
+ # Lets you run `admina dev` and see the dashboard out of the box.
69
67
  pip install "admina-framework[proxy]"
70
68
 
71
- # Everything (proxy + NLP + telemetry)
69
+ # Everything (proxy + NLP + telemetry). Use this if you also want
70
+ # spaCy-based NER for PII detection or OpenTelemetry export.
72
71
  pip install "admina-framework[full]"
72
+ python -m spacy download en_core_web_sm # for [full] only
73
73
 
74
- # After [nlp] / [full] install: download the spaCy NER model
75
- python -m spacy download en_core_web_sm
76
-
77
- # Optional: Rust-accelerated engine (auto-detected at runtime)
74
+ # Optional: Rust-accelerated engine (auto-detected at runtime).
78
75
  pip install admina-core
76
+
77
+ # Advanced: SDK only (no proxy, no dashboard, no `admina dev`).
78
+ # Use this when embedding the SDK into another service and you don't
79
+ # need the local dev server.
80
+ pip install admina-framework
79
81
  ```
80
82
 
81
83
  > The PyPI distribution name is `admina-framework`; the Python import
@@ -93,28 +95,27 @@ pip install admina-core
93
95
  git clone https://github.com/admina-org/admina.git
94
96
  cd admina
95
97
 
96
- # Option 1: SDK only (lightweight)
97
- pip install -e .
98
- python -c "from admina import GovernedModel; print('SDK ready')"
99
-
100
- # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
101
- # and pull a model first: ollama pull llama3.1:8b
102
-
103
- # Option 2: Proxy + infra deps
98
+ # Recommended: proxy + dashboard + infra deps (enables `admina dev`)
104
99
  pip install -e ".[proxy]"
105
100
 
106
- # Option 3: Everything (proxy + NLP + telemetry)
101
+ # Everything (proxy + NLP + telemetry)
107
102
  pip install -e ".[full]"
108
103
 
109
- # Option 4: Full stack (proxy + dashboard + infra via Docker)
104
+ # CLI workflow
105
+ admina init my-project # Scaffold a governed AI project
106
+ cd my-project # admina dev runs from the project directory
107
+ admina dev # Start the local proxy + dashboard
108
+
109
+ # Full stack via Docker (no [proxy] extra required)
110
110
  ./scripts/bootstrap-secrets.sh # Auto-generate .env with random credentials
111
111
  docker compose up --build # Credentials printed at bootstrap
112
112
 
113
- # Option 5: CLI
113
+ # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
114
+ # and pull a model first: ollama pull llama3.1:8b
115
+
116
+ # Advanced: SDK only (no proxy, no dashboard)
114
117
  pip install -e .
115
- admina init my-project # Scaffold a governed AI project
116
- cd my-project # admina dev runs from the project directory
117
- admina dev # Start local dev stack
118
+ python -c "from admina import GovernedModel; print('SDK ready')"
118
119
  ```
119
120
 
120
121
  Dashboard: [http://localhost:3000](http://localhost:3000) | API docs: [http://localhost:8080/docs](http://localhost:8080/docs)
@@ -23,7 +23,7 @@ from __future__ import annotations
23
23
 
24
24
  from admina.sdk import ComplianceKit, GovernedAgent, GovernedData, GovernedModel
25
25
 
26
- __version__ = "0.9.2"
26
+ __version__ = "0.9.3"
27
27
 
28
28
  __all__ = [
29
29
  "__version__",
@@ -262,20 +262,61 @@ def init(
262
262
  else:
263
263
  click.echo(" ⚠ docker compose pull failed (you can run it later)")
264
264
 
265
- # 5. Print next steps
266
- click.echo(f"""
267
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
268
- Project ready!
265
+ # 5. Print next steps — tailored to what the user actually has installed.
266
+ click.echo(_format_next_steps(project_name))
269
267
 
270
- Next steps:
271
- cd {project_name}
272
- admina dev # local mode (no Docker): proxy + dashboard on :3000
273
- admina dev --stack # full Docker stack (proxy, redis, clickhouse, minio, grafana)
274
- python main.py # run example (works without admina dev)
275
268
 
276
- Docs: https://admina.org/docs
277
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
278
- """)
269
+ def _format_next_steps(project_name: str) -> str:
270
+ """Build the post-init "Next steps" message based on detected extras.
271
+
272
+ Honest output: only suggest commands that will work with the user's
273
+ current install. Missing prerequisites are surfaced explicitly with
274
+ the exact upgrade command.
275
+ """
276
+ proxy_ok = _proxy_extra_installed()
277
+ docker_ok = shutil.which("docker") is not None
278
+
279
+ lines: list[str] = [
280
+ "",
281
+ " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
282
+ " Project ready!",
283
+ "",
284
+ " Next steps:",
285
+ f" cd {project_name}",
286
+ " python main.py # SDK example — works with any install",
287
+ ]
288
+ if proxy_ok:
289
+ lines.append(" admina dev # local proxy + dashboard on :3000")
290
+ else:
291
+ lines.extend(
292
+ [
293
+ "",
294
+ " To run the local proxy + dashboard (admina dev), install the [proxy] extra:",
295
+ " pip install 'admina-framework[proxy]' --upgrade",
296
+ ]
297
+ )
298
+ if docker_ok:
299
+ lines.append(
300
+ " admina dev --stack # full Docker stack "
301
+ "(proxy + redis + clickhouse + minio + grafana)"
302
+ )
303
+ else:
304
+ lines.extend(
305
+ [
306
+ "",
307
+ " To run the full Docker stack (admina dev --stack), install Docker:",
308
+ " https://docs.docker.com/get-docker/",
309
+ ]
310
+ )
311
+ lines.extend(
312
+ [
313
+ "",
314
+ " Docs: https://admina.org/docs",
315
+ " ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
316
+ "",
317
+ ]
318
+ )
319
+ return "\n".join(lines)
279
320
 
280
321
 
281
322
  # ── admina dev helpers ─────────────────────────────────────
@@ -482,6 +523,46 @@ def _list_local_ipv4() -> list[str]:
482
523
  return sorted(ips, key=lambda ip: (ip != "127.0.0.1", ip))
483
524
 
484
525
 
526
+ def _proxy_extra_installed() -> bool:
527
+ """True if uvicorn + fastapi (the [proxy] extra) are importable."""
528
+ try:
529
+ import fastapi # noqa: F401
530
+ import uvicorn # noqa: F401
531
+ except ImportError:
532
+ return False
533
+ return True
534
+
535
+
536
+ def _require_proxy_extra_for_local_dev() -> None:
537
+ """Exit cleanly with an actionable message when [proxy] is missing.
538
+
539
+ Local-mode `admina dev` shells out to uvicorn, which lives only in the
540
+ [proxy] extra. Without an early check, the user sees a cryptic
541
+ `No module named uvicorn` from python -m uvicorn.
542
+ """
543
+ if _proxy_extra_installed():
544
+ return
545
+ click.echo("", err=True)
546
+ click.echo(" admina dev (local mode) requires the [proxy] extra.", err=True)
547
+ click.echo(" Install one of:", err=True)
548
+ click.echo(
549
+ " pip install 'admina-framework[proxy]' --upgrade",
550
+ err=True,
551
+ )
552
+ click.echo(
553
+ " pip install 'admina-framework[full]' --upgrade # adds NLP + telemetry",
554
+ err=True,
555
+ )
556
+ click.echo("", err=True)
557
+ click.echo(
558
+ " Or run the full Docker stack (no [proxy] extra required):",
559
+ err=True,
560
+ )
561
+ click.echo(" admina dev --stack", err=True)
562
+ click.echo("", err=True)
563
+ raise SystemExit(1)
564
+
565
+
485
566
  def _run_local(
486
567
  project_dir: Path,
487
568
  vault: SecretVault,
@@ -491,6 +572,8 @@ def _run_local(
491
572
  host: str,
492
573
  ) -> None:
493
574
  """Run proxy + dashboard as a single uvicorn process (no Docker)."""
575
+ _require_proxy_extra_for_local_dev()
576
+
494
577
  # Auto-detect free port: if preferred is taken (Docker Desktop, Grafana,
495
578
  # another node dev server on :3000…), fall back to the next free port.
496
579
  try:
@@ -1032,6 +1115,8 @@ def doctor() -> None:
1032
1115
  issues.append(f"Missing: pip install {pkg_name}")
1033
1116
 
1034
1117
  # ── Optional extras ──────────────────────────────────────
1118
+ # Each group lists (import_name, pypi_name) tuples. numpy + scikit-learn
1119
+ # are part of [proxy] (LoopBreaker requires them), not [nlp].
1035
1120
  click.echo("\n Optional extras:")
1036
1121
  extras = {
1037
1122
  "proxy": [
@@ -1042,16 +1127,17 @@ def doctor() -> None:
1042
1127
  ("redis", "redis"),
1043
1128
  ("minio", "minio"),
1044
1129
  ("clickhouse_connect", "clickhouse-connect"),
1130
+ ("numpy", "numpy"),
1131
+ ("sklearn", "scikit-learn"),
1045
1132
  ],
1046
1133
  "nlp": [
1047
1134
  ("spacy", "spacy"),
1048
- ("sklearn", "scikit-learn"),
1049
- ("numpy", "numpy"),
1050
1135
  ],
1051
1136
  "telemetry": [
1052
1137
  ("opentelemetry", "opentelemetry-api"),
1053
1138
  ],
1054
1139
  }
1140
+ extras_status: dict[str, str] = {}
1055
1141
  for group, mods in extras.items():
1056
1142
  present = 0
1057
1143
  for mod_name, _ in mods:
@@ -1062,12 +1148,25 @@ def doctor() -> None:
1062
1148
  pass
1063
1149
  if present == len(mods):
1064
1150
  click.echo(f" [{group}]{' ' * (16 - len(group))} {ok_mark} ({present}/{len(mods)})")
1151
+ extras_status[group] = "ok"
1065
1152
  elif present > 0:
1066
1153
  click.echo(
1067
1154
  f" [{group}]{' ' * (16 - len(group))} {warn_mark} ({present}/{len(mods)})"
1068
1155
  )
1156
+ extras_status[group] = "partial"
1069
1157
  else:
1070
1158
  click.echo(f" [{group}]{' ' * (16 - len(group))} -- not installed")
1159
+ extras_status[group] = "missing"
1160
+
1161
+ if extras_status.get("proxy") != "ok":
1162
+ click.echo(
1163
+ f" {warn_mark} admina dev (local mode) needs the [proxy] extra — "
1164
+ "pip install 'admina-framework[proxy]' --upgrade"
1165
+ )
1166
+ issues.append(
1167
+ "admina dev (local mode) requires the [proxy] extra — "
1168
+ "run: pip install 'admina-framework[proxy]' --upgrade"
1169
+ )
1071
1170
 
1072
1171
  # ── spaCy NER model ──────────────────────────────────────
1073
1172
  click.echo("\n NLP engine:")
@@ -1078,12 +1177,28 @@ def doctor() -> None:
1078
1177
  spacy.load("en_core_web_sm")
1079
1178
  click.echo(f" en_core_web_sm {ok_mark}")
1080
1179
  except OSError:
1180
+ # PII still works in regex-only mode without the spaCy model, so
1181
+ # this is a soft warning rather than a blocking issue.
1081
1182
  click.echo(
1082
- f" en_core_web_sm {warn_mark} (run: python -m spacy download en_core_web_sm)"
1183
+ f" en_core_web_sm {warn_mark} not loadable "
1184
+ "(PII falls back to regex-only — install for NER coverage)"
1185
+ )
1186
+ # The model is not on PyPI — it ships as a direct wheel URL
1187
+ # from explosion/spacy-models on GitHub. `python -m spacy
1188
+ # download` is the canonical command but needs pip in the
1189
+ # venv; for uv venvs (which omit pip) point at the wheel URL.
1190
+ model_ver = "3.8.0" # matches spacy>=3.8,<4 pinned in [nlp]
1191
+ wheel_url = (
1192
+ "https://github.com/explosion/spacy-models/releases/download/"
1193
+ f"en_core_web_sm-{model_ver}/en_core_web_sm-{model_ver}-py3-none-any.whl"
1083
1194
  )
1084
- issues.append("spaCy model not installed PII uses regex-only mode")
1195
+ click.echo(f" Install with: {sys.executable} -m spacy download en_core_web_sm")
1196
+ click.echo(f" For uv venvs: uv pip install {wheel_url}")
1085
1197
  except ImportError:
1086
- click.echo(" spacy -- not installed (PII disabled)")
1198
+ click.echo(
1199
+ " spacy -- not installed "
1200
+ "(PII falls back to regex-only — install [nlp] extra for NER)"
1201
+ )
1087
1202
 
1088
1203
  # ── Rust engine ──────────────────────────────────────────
1089
1204
  click.echo("\n Governance engine:")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: admina-framework
3
- Version: 0.9.2
3
+ Version: 0.9.3
4
4
  Summary: Admina — governed AI development framework
5
5
  Author-email: Stefano Noferi <info@admina.org>
6
6
  Maintainer-email: Stefano Noferi <info@admina.org>
@@ -120,20 +120,22 @@ report = kit.gap_analysis(risk_category="high", current_compliance={...})
120
120
  ### Install from PyPI
121
121
 
122
122
  ```bash
123
- # SDK only (lightweight, pure Python)
124
- pip install admina-framework
125
-
126
- # Proxy + infrastructure deps
123
+ # Recommended for new users: SDK + proxy + dashboard.
124
+ # Lets you run `admina dev` and see the dashboard out of the box.
127
125
  pip install "admina-framework[proxy]"
128
126
 
129
- # Everything (proxy + NLP + telemetry)
127
+ # Everything (proxy + NLP + telemetry). Use this if you also want
128
+ # spaCy-based NER for PII detection or OpenTelemetry export.
130
129
  pip install "admina-framework[full]"
130
+ python -m spacy download en_core_web_sm # for [full] only
131
131
 
132
- # After [nlp] / [full] install: download the spaCy NER model
133
- python -m spacy download en_core_web_sm
134
-
135
- # Optional: Rust-accelerated engine (auto-detected at runtime)
132
+ # Optional: Rust-accelerated engine (auto-detected at runtime).
136
133
  pip install admina-core
134
+
135
+ # Advanced: SDK only (no proxy, no dashboard, no `admina dev`).
136
+ # Use this when embedding the SDK into another service and you don't
137
+ # need the local dev server.
138
+ pip install admina-framework
137
139
  ```
138
140
 
139
141
  > The PyPI distribution name is `admina-framework`; the Python import
@@ -151,28 +153,27 @@ pip install admina-core
151
153
  git clone https://github.com/admina-org/admina.git
152
154
  cd admina
153
155
 
154
- # Option 1: SDK only (lightweight)
155
- pip install -e .
156
- python -c "from admina import GovernedModel; print('SDK ready')"
157
-
158
- # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
159
- # and pull a model first: ollama pull llama3.1:8b
160
-
161
- # Option 2: Proxy + infra deps
156
+ # Recommended: proxy + dashboard + infra deps (enables `admina dev`)
162
157
  pip install -e ".[proxy]"
163
158
 
164
- # Option 3: Everything (proxy + NLP + telemetry)
159
+ # Everything (proxy + NLP + telemetry)
165
160
  pip install -e ".[full]"
166
161
 
167
- # Option 4: Full stack (proxy + dashboard + infra via Docker)
162
+ # CLI workflow
163
+ admina init my-project # Scaffold a governed AI project
164
+ cd my-project # admina dev runs from the project directory
165
+ admina dev # Start the local proxy + dashboard
166
+
167
+ # Full stack via Docker (no [proxy] extra required)
168
168
  ./scripts/bootstrap-secrets.sh # Auto-generate .env with random credentials
169
169
  docker compose up --build # Credentials printed at bootstrap
170
170
 
171
- # Option 5: CLI
171
+ # Note: To use the OllamaAdapter, install Ollama (https://ollama.ai)
172
+ # and pull a model first: ollama pull llama3.1:8b
173
+
174
+ # Advanced: SDK only (no proxy, no dashboard)
172
175
  pip install -e .
173
- admina init my-project # Scaffold a governed AI project
174
- cd my-project # admina dev runs from the project directory
175
- admina dev # Start local dev stack
176
+ python -c "from admina import GovernedModel; print('SDK ready')"
176
177
  ```
177
178
 
178
179
  Dashboard: [http://localhost:3000](http://localhost:3000) | API docs: [http://localhost:8080/docs](http://localhost:8080/docs)
@@ -19,7 +19,7 @@ build-backend = "setuptools.build_meta"
19
19
 
20
20
  [project]
21
21
  name = "admina-framework"
22
- version = "0.9.2"
22
+ version = "0.9.3"
23
23
  description = "Admina — governed AI development framework"
24
24
  readme = "README.md"
25
25
  requires-python = ">=3.11"