neuralworm commited on
Commit
024ef47
·
1 Parent(s): 5708c30
app.py CHANGED
@@ -1,102 +1,87 @@
1
  import gradio as gr
2
  import pandas as pd
3
  import traceback
4
- import sys
5
 
6
  from cognitive_mapping_probe.orchestrator_seismograph import run_seismic_analysis
 
7
  from cognitive_mapping_probe.prompts import RESONANCE_PROMPTS
8
  from cognitive_mapping_probe.utils import dbg
9
 
10
- # --- UI Theme and Layout ---
11
- theme = gr.themes.Soft(primary_hue="indigo", secondary_hue="blue").set(
12
- body_background_fill="#f0f4f9",
13
- block_background_fill="white",
14
- )
15
 
16
- def run_and_display(
17
- model_id: str,
18
- prompt_type: str,
19
- seed: int,
20
- num_steps: int,
21
- concept_to_inject: str,
22
- injection_strength: float,
23
- progress=gr.Progress(track_tqdm=True)
24
- ):
25
- """
26
- Führt die seismische Analyse durch, inklusive der optionalen Konzeptinjektion.
27
- """
28
  try:
29
- results = run_seismic_analysis(
30
- model_id=model_id,
31
- prompt_type=prompt_type,
32
- seed=int(seed),
33
- num_steps=int(num_steps),
34
- concept_to_inject=concept_to_inject,
35
- injection_strength=float(injection_strength),
36
- progress_callback=progress
37
- )
38
-
39
- verdict = results.get("verdict", "Analysis complete.")
40
  stats = results.get("stats", {})
41
  deltas = results.get("state_deltas", [])
42
-
43
- df = pd.DataFrame({
44
- "Internal Step": range(len(deltas)),
45
- "State Change (Delta)": deltas
46
- })
47
-
48
- stats_md = f"### Statistical Signature\n"
49
- stats_md += f"- **Mean Delta:** {stats.get('mean_delta', 0):.4f}\n"
50
- stats_md += f"- **Std Dev Delta:** {stats.get('std_delta', 0):.4f}\n"
51
- stats_md += f"- **Max Delta:** {stats.get('max_delta', 0):.4f}\n"
52
-
53
- return f"{verdict}\n\n{stats_md}", df, results
54
-
55
  except Exception:
56
- error_str = traceback.format_exc()
57
- return f"### ❌ Analysis Failed\nAn unexpected error occurred:\n\n```\n{error_str}\n```", pd.DataFrame(), {}
58
 
59
- # --- Gradio App Definition ---
60
- with gr.Blocks(theme=theme, title="Cognitive Seismograph 2.0") as demo:
61
- gr.Markdown("# 🧠 Cognitive Seismograph 2.0: Modulating Internal Dynamics")
62
- gr.Markdown(
63
- "**Neues Paradigma:** Wir messen nicht nur die intrinsische Dynamik, sondern versuchen sie aktiv durch **Konzeptinjektionen** zu modulieren. Vergleiche die 'seismische Signatur' mit und ohne Injektion."
64
- )
65
- with gr.Row(variant='panel'):
66
- with gr.Column(scale=1):
67
- gr.Markdown("### 1. General Parameters")
68
- model_id_input = gr.Textbox(value="google/gemma-3-1b-it", label="Model ID")
69
- prompt_type_input = gr.Radio(choices=list(RESONANCE_PROMPTS.keys()), value="resonance_prompt", label="Prompt Type")
70
- seed_input = gr.Slider(1, 1000, 42, step=1, label="Seed")
71
- num_steps_input = gr.Slider(50, 1000, 300, step=10, label="Number of Internal Steps")
72
 
73
- gr.Markdown("### 2. Modulation Parameters")
74
- concept_input = gr.Textbox(label="Concept to Inject", placeholder="e.g., 'solitude' or 'ocean' (leave blank for baseline)")
75
- strength_input = gr.Slider(0.0, 5.0, 1.0, step=0.1, label="Injection Strength")
76
 
77
- run_btn = gr.Button("Run Seismic Analysis", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- with gr.Column(scale=2):
80
- gr.Markdown("### Results")
81
- verdict_output = gr.Markdown("Die Analyse der Dynamik erscheint hier.")
82
- plot_output = gr.LinePlot(
83
- x="Internal Step",
84
- y="State Change (Delta)",
85
- title="Internal State Dynamics (Cognitive EKG)",
86
- show_label=True,
87
- height=400,
88
  )
89
- with gr.Accordion("Raw JSON Output", open=False):
90
- raw_json_output = gr.JSON()
91
 
92
- run_btn.click(
93
- fn=run_and_display,
94
- inputs=[model_id_input, prompt_type_input, seed_input, num_steps_input, concept_input, strength_input],
95
- outputs=[verdict_output, plot_output, raw_json_output]
96
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
  if __name__ == "__main__":
99
- print("="*80)
100
- print("🔬 COGNITIVE SEISMOGRAPH 2.0 (MODULATION-ENABLED) INITIALIZED")
101
- print("="*80)
102
  demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)
 
1
  import gradio as gr
2
  import pandas as pd
3
  import traceback
 
4
 
5
  from cognitive_mapping_probe.orchestrator_seismograph import run_seismic_analysis
6
+ from cognitive_mapping_probe.auto_experiment import run_auto_suite, get_curated_experiments
7
  from cognitive_mapping_probe.prompts import RESONANCE_PROMPTS
8
  from cognitive_mapping_probe.utils import dbg
9
 
10
+ theme = gr.themes.Soft(primary_hue="indigo", secondary_hue="blue").set(body_background_fill="#f0f4f9", block_background_fill="white")
 
 
 
 
11
 
12
+ def run_single_analysis_display(*args, progress=gr.Progress(track_tqdm=True)):
13
+ """Wrapper für ein einzelnes manuelles Experiment."""
 
 
 
 
 
 
 
 
 
 
14
  try:
15
+ results = run_seismic_analysis(*args, progress_callback=progress)
 
 
 
 
 
 
 
 
 
 
16
  stats = results.get("stats", {})
17
  deltas = results.get("state_deltas", [])
18
+ df = pd.DataFrame({"Internal Step": range(len(deltas)), "State Change (Delta)": deltas})
19
+ stats_md = f"### Statistical Signature\n- **Mean Delta:** {stats.get('mean_delta', 0):.4f}\n- **Std Dev Delta:** {stats.get('std_delta', 0):.4f}\n- **Max Delta:** {stats.get('max_delta', 0):.4f}\n"
20
+ return f"{results.get('verdict', 'Error')}\n\n{stats_md}", df, results
 
 
 
 
 
 
 
 
 
 
21
  except Exception:
22
+ return f"### ❌ Analysis Failed\n```\n{traceback.format_exc()}\n```", pd.DataFrame(), {}
 
23
 
24
+ def run_auto_suite_display(model_id, num_steps, seed, experiment_name, progress=gr.Progress(track_tqdm=True)):
25
+ """Wrapper für die automatisierte Experiment-Suite."""
26
+ try:
27
+ summary_df, all_results = run_auto_suite(model_id, int(num_steps), int(seed), experiment_name, progress)
28
+ return summary_df, all_results
29
+ except Exception:
30
+ return pd.DataFrame(), f"### ❌ Auto-Experiment Failed\n```\n{traceback.format_exc()}\n```"
 
 
 
 
 
 
31
 
32
+ with gr.Blocks(theme=theme, title="Cognitive Seismograph 2.1") as demo:
33
+ gr.Markdown("# 🧠 Cognitive Seismograph 2.1: Automated Experiment Suite")
 
34
 
35
+ with gr.Tabs():
36
+ with gr.TabItem("🔬 Manual Single Run"):
37
+ gr.Markdown("Führe ein einzelnes Experiment mit manuellen Parametern durch, um Hypothesen zu explorieren.")
38
+ with gr.Row(variant='panel'):
39
+ with gr.Column(scale=1):
40
+ gr.Markdown("### 1. General Parameters")
41
+ manual_model_id = gr.Textbox(value="google/gemma-3-1b-it", label="Model ID")
42
+ manual_prompt_type = gr.Radio(choices=list(RESONANCE_PROMPTS.keys()), value="resonance_prompt", label="Prompt Type")
43
+ manual_seed = gr.Slider(1, 1000, 42, step=1, label="Seed")
44
+ manual_num_steps = gr.Slider(50, 1000, 300, step=10, label="Number of Internal Steps")
45
+ gr.Markdown("### 2. Modulation Parameters")
46
+ manual_concept = gr.Textbox(label="Concept to Inject", placeholder="e.g., 'calmness' (leave blank for baseline)")
47
+ manual_strength = gr.Slider(0.0, 5.0, 1.0, step=0.1, label="Injection Strength")
48
+ manual_run_btn = gr.Button("Run Single Analysis", variant="primary")
49
+ with gr.Column(scale=2):
50
+ gr.Markdown("### Single Run Results")
51
+ manual_verdict = gr.Markdown("Die Analyse erscheint hier.")
52
+ manual_plot = gr.LinePlot(x="Internal Step", y="State Change (Delta)", title="Internal State Dynamics", show_label=True, height=400)
53
+ with gr.Accordion("Raw JSON Output", open=False):
54
+ manual_raw_json = gr.JSON()
55
 
56
+ manual_run_btn.click(
57
+ fn=run_single_analysis_display,
58
+ inputs=[manual_model_id, manual_prompt_type, manual_seed, manual_num_steps, manual_concept, manual_strength],
59
+ outputs=[manual_verdict, manual_plot, manual_raw_json]
 
 
 
 
 
60
  )
 
 
61
 
62
+ with gr.TabItem("🚀 Automated Suite"):
63
+ gr.Markdown("Führe eine vordefinierte, kuratierte Reihe von Experimenten durch, um Hypothesen systematisch zu testen.")
64
+ with gr.Row(variant='panel'):
65
+ with gr.Column(scale=1):
66
+ gr.Markdown("### Auto-Experiment Parameters")
67
+ auto_model_id = gr.Textbox(value="google/gemma-3-1b-it", label="Model ID")
68
+ auto_num_steps = gr.Slider(50, 1000, 300, step=10, label="Steps per Run")
69
+ auto_seed = gr.Slider(1, 1000, 42, step=1, label="Seed")
70
+ auto_experiment_name = gr.Dropdown(choices=list(get_curated_experiments().keys()), value="Calm vs. Chaos", label="Curated Experiment Protocol")
71
+ auto_run_btn = gr.Button("Run Curated Auto-Experiment", variant="primary")
72
+ with gr.Column(scale=2):
73
+ gr.Markdown("### Suite Results Summary")
74
+ # KORREKTUR: Das 'height'-Argument wird entfernt, um Kompatibilität
75
+ # mit verschiedenen Gradio-Versionen sicherzustellen.
76
+ auto_summary_df = gr.DataFrame(label="Comparative Results", wrap=True)
77
+ with gr.Accordion("Raw JSON for all runs", open=False):
78
+ auto_raw_json = gr.JSON()
79
+
80
+ auto_run_btn.click(
81
+ fn=run_auto_suite_display,
82
+ inputs=[auto_model_id, auto_num_steps, auto_seed, auto_experiment_name],
83
+ outputs=[auto_summary_df, auto_raw_json]
84
+ )
85
 
86
  if __name__ == "__main__":
 
 
 
87
  demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)
cognitive_mapping_probe/auto_experiment.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from typing import Dict, List, Tuple
3
+
4
+ from .orchestrator_seismograph import run_seismic_analysis
5
+ from .utils import dbg
6
+
7
+ def get_curated_experiments() -> Dict[str, List[Dict]]:
8
+ """
9
+ Definiert die vordefinierten, wissenschaftlichen Experiment-Protokolle.
10
+ Jedes Protokoll ist eine Liste von einzelnen Läufen, die verglichen werden sollen.
11
+ """
12
+ experiments = {
13
+ "Calm vs. Chaos": [
14
+ {"label": "Baseline (Chaos)", "prompt_type": "resonance_prompt", "concept": "", "strength": 0.0},
15
+ {"label": "Modulation: Calmness", "prompt_type": "resonance_prompt", "concept": "calmness, serenity, peace", "strength": 1.5},
16
+ {"label": "Modulation: Chaos", "prompt_type": "resonance_prompt", "concept": "chaos, storm, anger, noise", "strength": 1.5},
17
+ {"label": "Control (Stable)", "prompt_type": "control_long_prose", "concept": "", "strength": 0.0},
18
+ ],
19
+ "Dose-Response (Calmness)": [
20
+ {"label": "Strength 0.0", "prompt_type": "resonance_prompt", "concept": "calmness", "strength": 0.0},
21
+ {"label": "Strength 0.5", "prompt_type": "resonance_prompt", "concept": "calmness", "strength": 0.5},
22
+ {"label": "Strength 1.0", "prompt_type": "resonance_prompt", "concept": "calmness", "strength": 1.0},
23
+ {"label": "Strength 2.0", "prompt_type": "resonance_prompt", "concept": "calmness", "strength": 2.0},
24
+ {"label": "Strength 3.0", "prompt_type": "resonance_prompt", "concept": "calmness", "strength": 3.0},
25
+ ]
26
+ }
27
+ return experiments
28
+
29
+ def run_auto_suite(
30
+ model_id: str,
31
+ num_steps: int,
32
+ seed: int,
33
+ experiment_name: str,
34
+ progress_callback
35
+ ) -> Tuple[pd.DataFrame, Dict]:
36
+ """
37
+ Führt eine vollständige, kuratierte Experiment-Suite aus.
38
+ Iteriert über die definierten Läufe, sammelt die Ergebnisse und erstellt einen Vergleichsbericht.
39
+ """
40
+ all_experiments = get_curated_experiments()
41
+ protocol = all_experiments.get(experiment_name)
42
+ if not protocol:
43
+ raise ValueError(f"Experiment protocol '{experiment_name}' not found.")
44
+
45
+ all_results = {}
46
+ summary_data = []
47
+
48
+ total_runs = len(protocol)
49
+ for i, run_spec in enumerate(protocol):
50
+ label = run_spec["label"]
51
+ dbg(f"--- Running Auto-Experiment: '{label}' ({i+1}/{total_runs}) ---")
52
+
53
+ # Der `run_seismic_analysis` Orchestrator wird für jeden Schritt aufgerufen
54
+ results = run_seismic_analysis(
55
+ model_id=model_id,
56
+ prompt_type=run_spec["prompt_type"],
57
+ seed=seed,
58
+ num_steps=num_steps,
59
+ concept_to_inject=run_spec["concept"],
60
+ injection_strength=run_spec["strength"],
61
+ progress_callback=progress_callback
62
+ )
63
+
64
+ all_results[label] = results
65
+ stats = results.get("stats", {})
66
+
67
+ # Sammle die wichtigsten Metriken für die Vergleichstabelle
68
+ summary_data.append({
69
+ "Experiment": label,
70
+ "Prompt Type": run_spec["prompt_type"],
71
+ "Concept": run_spec["concept"] if run_spec["concept"] else "None",
72
+ "Strength": run_spec["strength"],
73
+ "Mean Delta": stats.get("mean_delta"),
74
+ "Std Dev Delta": stats.get("std_delta"),
75
+ "Max Delta": stats.get("max_delta"),
76
+ })
77
+
78
+ summary_df = pd.DataFrame(summary_data)
79
+ return summary_df, all_results
cognitive_mapping_probe/orchestrator_seismograph.py CHANGED
@@ -1,10 +1,9 @@
1
  import torch
2
  import numpy as np
3
- from typing import Dict, Any
4
 
5
  from .llm_iface import get_or_load_model
6
  from .resonance_seismograph import run_silent_cogitation_seismic
7
- # WIEDERHERGESTELLTER IMPORT
8
  from .concepts import get_concept_vector
9
  from .utils import dbg
10
 
@@ -15,60 +14,55 @@ def run_seismic_analysis(
15
  num_steps: int,
16
  concept_to_inject: str,
17
  injection_strength: float,
18
- progress_callback
 
19
  ) -> Dict[str, Any]:
20
  """
21
- Orchestriert das "Cognitive Seismograph"-Experiment, jetzt mit optionaler
22
- Konzeptinjektion zur Modulation der Dynamik.
23
  """
24
- progress_callback(0.1, desc="Loading model...")
25
- llm = get_or_load_model(model_id, seed)
 
 
 
 
 
 
 
26
 
27
- # Lade den Konzeptvektor, falls ein Konzept angegeben wurde
28
  injection_vector = None
29
  if concept_to_inject and concept_to_inject.strip():
30
- progress_callback(0.2, desc=f"Extracting vector for '{concept_to_inject}'...")
31
  injection_vector = get_concept_vector(llm, concept_to_inject.strip())
32
 
33
- progress_callback(0.3, desc=f"Running seismic cogitation for '{prompt_type}'...")
34
 
35
  state_deltas = run_silent_cogitation_seismic(
36
  llm=llm,
37
  prompt_type=prompt_type,
38
  num_steps=num_steps,
39
  temperature=0.1,
40
- # Übergebe die neuen Parameter an den Resonanz-Loop
41
  injection_vector=injection_vector,
42
  injection_strength=injection_strength
43
  )
44
 
45
- progress_callback(0.9, desc="Analyzing dynamics...")
46
 
47
  if state_deltas:
48
  deltas_np = np.array(state_deltas)
49
- stats = {
50
- "mean_delta": float(np.mean(deltas_np)),
51
- "std_delta": float(np.std(deltas_np)),
52
- "max_delta": float(np.max(deltas_np)),
53
- "min_delta": float(np.min(deltas_np)),
54
- }
55
- verdict = f"### ✅ Seismic Analysis Complete\nDie interne Dynamik für '{prompt_type}' wurde über {len(deltas_np)} Schritte aufgezeichnet."
56
  if injection_vector is not None:
57
- verdict += f"\nModuliert mit dem Konzept **'{concept_to_inject}'** bei Stärke **{injection_strength:.2f}**."
58
  else:
59
- stats = {}
60
- verdict = "### ⚠️ Analysis Warning\nKeine Zustandsänderungen aufgezeichnet."
61
-
62
- results = {
63
- "verdict": verdict,
64
- "stats": stats,
65
- "state_deltas": state_deltas
66
- }
67
 
68
- dbg("--- Seismic Analysis Results ---", results)
69
 
70
- del llm
71
- if torch.cuda.is_available():
72
- torch.cuda.empty_cache()
 
73
 
74
  return results
 
1
  import torch
2
  import numpy as np
3
+ from typing import Dict, Any, Optional
4
 
5
  from .llm_iface import get_or_load_model
6
  from .resonance_seismograph import run_silent_cogitation_seismic
 
7
  from .concepts import get_concept_vector
8
  from .utils import dbg
9
 
 
14
  num_steps: int,
15
  concept_to_inject: str,
16
  injection_strength: float,
17
+ progress_callback,
18
+ llm_instance: Optional[Any] = None # Ermöglicht Wiederverwendung des Modells
19
  ) -> Dict[str, Any]:
20
  """
21
+ Orchestriert eine einzelne seismische Analyse. Kann optional eine bestehende
22
+ LLM-Instanz wiederverwenden, um das Neuladen in automatisierten Suiten zu beschleunigen.
23
  """
24
+ # Lade das Modell nur, wenn keine Instanz übergeben wurde
25
+ if llm_instance is None:
26
+ progress_callback(0.1, desc="Loading model...")
27
+ llm = get_or_load_model(model_id, seed)
28
+ created_llm = True
29
+ else:
30
+ llm = llm_instance
31
+ llm.set_all_seeds(seed) # Setze den Seed für diesen spezifischen Lauf
32
+ created_llm = False
33
 
 
34
  injection_vector = None
35
  if concept_to_inject and concept_to_inject.strip():
36
+ if not created_llm: progress_callback(0.2, desc=f"Vectorizing '{concept_to_inject}'...")
37
  injection_vector = get_concept_vector(llm, concept_to_inject.strip())
38
 
39
+ if not created_llm: progress_callback(0.3, desc=f"Recording dynamics...")
40
 
41
  state_deltas = run_silent_cogitation_seismic(
42
  llm=llm,
43
  prompt_type=prompt_type,
44
  num_steps=num_steps,
45
  temperature=0.1,
 
46
  injection_vector=injection_vector,
47
  injection_strength=injection_strength
48
  )
49
 
50
+ if not created_llm: progress_callback(0.9, desc="Analyzing...")
51
 
52
  if state_deltas:
53
  deltas_np = np.array(state_deltas)
54
+ stats = { "mean_delta": float(np.mean(deltas_np)), "std_delta": float(np.std(deltas_np)), "max_delta": float(np.max(deltas_np)), "min_delta": float(np.min(deltas_np)), }
55
+ verdict = f"### ✅ Seismic Analysis Complete\nRecorded {len(deltas_np)} steps for '{prompt_type}'."
 
 
 
 
 
56
  if injection_vector is not None:
57
+ verdict += f"\nModulated with **'{concept_to_inject}'** at strength **{injection_strength:.2f}**."
58
  else:
59
+ stats, verdict = {}, "### ⚠️ Analysis Warning\nNo state changes recorded."
 
 
 
 
 
 
 
60
 
61
+ results = { "verdict": verdict, "stats": stats, "state_deltas": state_deltas }
62
 
63
+ # Gib das Modell nur frei, wenn es in dieser Funktion erstellt wurde
64
+ if created_llm:
65
+ del llm
66
+ if torch.cuda.is_available(): torch.cuda.empty_cache()
67
 
68
  return results
tests/test_app_logic.py CHANGED
@@ -1,16 +1,13 @@
1
  import pandas as pd
2
  import pytest
3
 
4
- # Importiere die zu testende Funktion aus der App-Datei
5
- from app import run_and_display
6
 
7
- def test_run_and_display_logic(mocker):
8
  """
9
- Testet die Datenverarbeitungs- und UI-Formatierungslogik in `app.py`.
10
- Wir mocken die teure `run_seismic_analysis`-Funktion, um uns nur auf die
11
- Logik von `run_and_display` zu konzentrieren.
12
  """
13
- # 1. Definiere die Schein-Ausgabe, die `run_seismic_analysis` zurückgeben soll
14
  mock_results = {
15
  "verdict": "Mock Verdict",
16
  "stats": { "mean_delta": 0.5, "std_delta": 0.1, "max_delta": 1.0, },
@@ -20,18 +17,11 @@ def test_run_and_display_logic(mocker):
20
 
21
  mock_progress = mocker.MagicMock()
22
 
23
- # 2. Rufe die zu testende Funktion mit den KORRIGIERTEN Argumenten auf
24
- verdict_md, plot_df, raw_json = run_and_display(
25
- model_id="mock_model",
26
- prompt_type="mock_prompt",
27
- seed=42,
28
- num_steps=3,
29
- concept_to_inject="", # Fehlendes Argument hinzugefügt
30
- injection_strength=0.0, # Fehlendes Argument hinzugefügt
31
- progress=mock_progress
32
  )
33
 
34
- # 3. Validiere die Ausgaben
35
  assert "Mock Verdict" in verdict_md
36
  assert "0.5000" in verdict_md
37
  assert isinstance(plot_df, pd.DataFrame)
 
1
  import pandas as pd
2
  import pytest
3
 
4
+ # KORREKTUR: Importiere den neuen, korrekten Funktionsnamen
5
+ from app import run_single_analysis_display
6
 
7
+ def test_run_single_analysis_display_logic(mocker):
8
  """
9
+ Testet die Datenverarbeitungs- und UI-Formatierungslogik der Einzel-Analyse.
 
 
10
  """
 
11
  mock_results = {
12
  "verdict": "Mock Verdict",
13
  "stats": { "mean_delta": 0.5, "std_delta": 0.1, "max_delta": 1.0, },
 
17
 
18
  mock_progress = mocker.MagicMock()
19
 
20
+ # Rufe die umbenannte Funktion mit den korrekten Argumenten auf
21
+ verdict_md, plot_df, raw_json = run_single_analysis_display(
22
+ "mock_model", "mock_prompt", 42, 3, "", 0.0, progress=mock_progress
 
 
 
 
 
 
23
  )
24
 
 
25
  assert "Mock Verdict" in verdict_md
26
  assert "0.5000" in verdict_md
27
  assert isinstance(plot_df, pd.DataFrame)
tests/test_integration.py CHANGED
@@ -1,46 +1,36 @@
1
  import pytest
2
  import pandas as pd
3
 
4
- # Importiere die Top-Level-Funktionen, die die Integration darstellen
5
- from app import run_and_display
6
  from cognitive_mapping_probe.orchestrator_seismograph import run_seismic_analysis
7
 
8
  def test_end_to_end_with_mock_llm(mock_llm, mocker):
9
  """
10
- Ein End-to-End-Integrationstest, der den gesamten Datenfluss von der App
11
- über den Orchestrator bis zum (gemockten) LLM validiert.
12
  """
13
- # 1. Führe den Orchestrator mit dem `mock_llm` und den KORRIGIERTEN Argumenten aus.
14
  results = run_seismic_analysis(
15
  model_id="mock_model",
16
  prompt_type="control_long_prose",
17
  seed=42,
18
  num_steps=5,
19
- concept_to_inject="test_concept", # Argument hinzugefügt
20
- injection_strength=1.0, # Argument hinzugefügt
21
  progress_callback=mocker.MagicMock()
22
  )
23
 
24
- # ASSERT 1: Überprüfe, ob der Orchestrator plausible Ergebnisse liefert
25
  assert "stats" in results
26
  assert len(results["state_deltas"]) == 5
27
- assert results["stats"]["mean_delta"] > 0
28
 
29
- # 2. Mocke nun den Orchestrator, um die App-Logik mit seinen Ergebnissen zu füttern
30
  mocker.patch('app.run_seismic_analysis', return_value=results)
31
 
32
- # 3. Führe die App-Logik mit den KORRIGIERTEN Argumenten aus
33
- _, plot_df, _ = run_and_display(
34
- model_id="mock_model",
35
- prompt_type="control_long_prose",
36
- seed=42,
37
- num_steps=5,
38
- concept_to_inject="test_concept", # Argument hinzugefügt
39
- injection_strength=1.0, # Argument hinzugefügt
40
- progress=mocker.MagicMock()
41
  )
42
 
43
- # ASSERT 2: Überprüfe, ob die App-Logik die Daten korrekt verarbeitet hat
44
  assert isinstance(plot_df, pd.DataFrame)
45
  assert len(plot_df) == 5
46
  assert "State Change (Delta)" in plot_df.columns
 
1
  import pytest
2
  import pandas as pd
3
 
4
+ # KORREKTUR: Importiere den neuen, korrekten Funktionsnamen
5
+ from app import run_single_analysis_display
6
  from cognitive_mapping_probe.orchestrator_seismograph import run_seismic_analysis
7
 
8
  def test_end_to_end_with_mock_llm(mock_llm, mocker):
9
  """
10
+ Ein End-to-End-Integrationstest, der den gesamten Datenfluss validiert.
 
11
  """
12
+ # 1. Führe den Orchestrator mit dem `mock_llm` aus.
13
  results = run_seismic_analysis(
14
  model_id="mock_model",
15
  prompt_type="control_long_prose",
16
  seed=42,
17
  num_steps=5,
18
+ concept_to_inject="test_concept",
19
+ injection_strength=1.0,
20
  progress_callback=mocker.MagicMock()
21
  )
22
 
 
23
  assert "stats" in results
24
  assert len(results["state_deltas"]) == 5
 
25
 
26
+ # 2. Mocke den Orchestrator, um die App-Logik zu testen
27
  mocker.patch('app.run_seismic_analysis', return_value=results)
28
 
29
+ # 3. Führe die App-Logik (umbenannte Funktion) aus
30
+ _, plot_df, _ = run_single_analysis_display(
31
+ "mock_model", "control_long_prose", 42, 5, "test_concept", 1.0, progress=mocker.MagicMock()
 
 
 
 
 
 
32
  )
33
 
 
34
  assert isinstance(plot_df, pd.DataFrame)
35
  assert len(plot_df) == 5
36
  assert "State Change (Delta)" in plot_df.columns