mcp-souschef 2.8.0__py3-none-any.whl → 3.2.0__py3-none-any.whl
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.
- {mcp_souschef-2.8.0.dist-info → mcp_souschef-3.2.0.dist-info}/METADATA +159 -384
- mcp_souschef-3.2.0.dist-info/RECORD +47 -0
- {mcp_souschef-2.8.0.dist-info → mcp_souschef-3.2.0.dist-info}/WHEEL +1 -1
- souschef/__init__.py +31 -7
- souschef/assessment.py +1451 -105
- souschef/ci/common.py +126 -0
- souschef/ci/github_actions.py +3 -92
- souschef/ci/gitlab_ci.py +2 -52
- souschef/ci/jenkins_pipeline.py +2 -59
- souschef/cli.py +149 -16
- souschef/converters/playbook.py +378 -138
- souschef/converters/resource.py +12 -11
- souschef/converters/template.py +177 -0
- souschef/core/__init__.py +6 -1
- souschef/core/metrics.py +313 -0
- souschef/core/path_utils.py +233 -19
- souschef/core/validation.py +53 -0
- souschef/deployment.py +71 -12
- souschef/generators/__init__.py +13 -0
- souschef/generators/repo.py +695 -0
- souschef/parsers/attributes.py +1 -1
- souschef/parsers/habitat.py +1 -1
- souschef/parsers/inspec.py +25 -2
- souschef/parsers/metadata.py +5 -3
- souschef/parsers/recipe.py +1 -1
- souschef/parsers/resource.py +1 -1
- souschef/parsers/template.py +1 -1
- souschef/server.py +1039 -121
- souschef/ui/app.py +486 -374
- souschef/ui/pages/ai_settings.py +74 -8
- souschef/ui/pages/cookbook_analysis.py +3216 -373
- souschef/ui/pages/validation_reports.py +274 -0
- mcp_souschef-2.8.0.dist-info/RECORD +0 -42
- souschef/converters/cookbook_specific.py.backup +0 -109
- {mcp_souschef-2.8.0.dist-info → mcp_souschef-3.2.0.dist-info}/entry_points.txt +0 -0
- {mcp_souschef-2.8.0.dist-info → mcp_souschef-3.2.0.dist-info}/licenses/LICENSE +0 -0
souschef/ui/pages/ai_settings.py
CHANGED
|
@@ -5,7 +5,9 @@ Configure and validate AI provider settings for the SousChef MCP server.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
+
import os
|
|
8
9
|
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
9
11
|
from urllib.parse import urlparse, urlunparse
|
|
10
12
|
|
|
11
13
|
import streamlit as st
|
|
@@ -171,10 +173,15 @@ def _render_validation_section(
|
|
|
171
173
|
st.subheader("Configuration Validation")
|
|
172
174
|
col1, col2 = st.columns([1, 1])
|
|
173
175
|
with col1:
|
|
174
|
-
if st.button(
|
|
176
|
+
if st.button(
|
|
177
|
+
"Validate Configuration",
|
|
178
|
+
type="primary",
|
|
179
|
+
width="stretch",
|
|
180
|
+
key="validate_ai_config",
|
|
181
|
+
):
|
|
175
182
|
validate_ai_configuration(provider, api_key, model, base_url, project_id)
|
|
176
183
|
with col2:
|
|
177
|
-
if st.button("Save Settings", width="stretch"):
|
|
184
|
+
if st.button("Save Settings", width="stretch", key="save_ai_settings"):
|
|
178
185
|
save_ai_settings(
|
|
179
186
|
provider, api_key, model, base_url, temperature, max_tokens, project_id
|
|
180
187
|
)
|
|
@@ -182,6 +189,17 @@ def _render_validation_section(
|
|
|
182
189
|
|
|
183
190
|
def show_ai_settings_page():
|
|
184
191
|
"""Show the AI settings configuration page."""
|
|
192
|
+
# Add back to dashboard button
|
|
193
|
+
col1, col2 = st.columns([1, 4])
|
|
194
|
+
with col1:
|
|
195
|
+
if st.button(
|
|
196
|
+
"← Back to Dashboard",
|
|
197
|
+
help="Return to main dashboard",
|
|
198
|
+
key="back_to_dashboard_from_ai",
|
|
199
|
+
):
|
|
200
|
+
st.session_state.current_page = "Dashboard"
|
|
201
|
+
st.rerun()
|
|
202
|
+
|
|
185
203
|
st.markdown("""
|
|
186
204
|
Configure your AI provider settings for the SousChef MCP server.
|
|
187
205
|
These settings determine which AI model will be used for Chef to Ansible
|
|
@@ -481,17 +499,65 @@ def display_current_settings():
|
|
|
481
499
|
st.info("No AI configuration found. Please configure your settings above.")
|
|
482
500
|
|
|
483
501
|
|
|
484
|
-
def load_ai_settings():
|
|
502
|
+
def load_ai_settings() -> dict[str, Any]:
|
|
503
|
+
"""Load AI settings from file, session state, or environment variables."""
|
|
504
|
+
file_config = _load_ai_settings_from_file()
|
|
505
|
+
if file_config:
|
|
506
|
+
return file_config
|
|
507
|
+
|
|
508
|
+
session_config = st.session_state.get("ai_config", {})
|
|
509
|
+
if isinstance(session_config, dict) and session_config:
|
|
510
|
+
return session_config
|
|
511
|
+
|
|
512
|
+
env_config = _load_ai_settings_from_env()
|
|
513
|
+
if env_config:
|
|
514
|
+
return env_config
|
|
515
|
+
|
|
516
|
+
return {}
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def _load_ai_settings_from_env() -> dict[str, str | float | int]:
|
|
520
|
+
"""Load AI settings from environment variables."""
|
|
521
|
+
from contextlib import suppress
|
|
522
|
+
|
|
523
|
+
env_config: dict[str, str | float | int] = {}
|
|
524
|
+
env_mappings = {
|
|
525
|
+
"SOUSCHEF_AI_PROVIDER": "provider",
|
|
526
|
+
"SOUSCHEF_AI_MODEL": "model",
|
|
527
|
+
"SOUSCHEF_AI_API_KEY": "api_key",
|
|
528
|
+
"SOUSCHEF_AI_BASE_URL": "base_url",
|
|
529
|
+
"SOUSCHEF_AI_PROJECT_ID": "project_id",
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
# Handle string values
|
|
533
|
+
for env_var, config_key in env_mappings.items():
|
|
534
|
+
env_value = os.environ.get(env_var)
|
|
535
|
+
if env_value:
|
|
536
|
+
env_config[config_key] = env_value
|
|
537
|
+
|
|
538
|
+
# Handle numeric values with error suppression
|
|
539
|
+
temp_value = os.environ.get("SOUSCHEF_AI_TEMPERATURE")
|
|
540
|
+
if temp_value:
|
|
541
|
+
with suppress(ValueError):
|
|
542
|
+
env_config["temperature"] = float(temp_value)
|
|
543
|
+
|
|
544
|
+
tokens_value = os.environ.get("SOUSCHEF_AI_MAX_TOKENS")
|
|
545
|
+
if tokens_value:
|
|
546
|
+
with suppress(ValueError):
|
|
547
|
+
env_config["max_tokens"] = int(tokens_value)
|
|
548
|
+
|
|
549
|
+
return env_config
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def _load_ai_settings_from_file() -> dict[str, Any]:
|
|
485
553
|
"""Load AI settings from configuration file."""
|
|
486
554
|
try:
|
|
487
|
-
# Use /tmp/.souschef for container compatibility (tmpfs is writable)
|
|
488
555
|
config_file = Path("/tmp/.souschef/ai_config.json")
|
|
489
556
|
if config_file.exists():
|
|
490
557
|
with config_file.open() as f:
|
|
491
|
-
|
|
558
|
+
result = json.load(f)
|
|
559
|
+
return result if isinstance(result, dict) else {}
|
|
492
560
|
except Exception as e:
|
|
493
|
-
# Failed to load config from file; fall back to session state/defaults
|
|
494
561
|
st.warning(f"Unable to load saved AI settings: {e}")
|
|
495
562
|
|
|
496
|
-
|
|
497
|
-
return st.session_state.get("ai_config", {})
|
|
563
|
+
return {}
|