File size: 8,648 Bytes
c8fa89c
 
c0f4adf
8b7e088
b350371
760155b
b9b7087
eef89e3
094008d
c8fa89c
024ef47
c8fa89c
c0f4adf
06e9d76
c0f4adf
06e9d76
094008d
 
 
c0f4adf
06e9d76
c0f4adf
06e9d76
 
 
c0f4adf
 
 
 
 
 
06e9d76
 
c0f4adf
 
 
06e9d76
 
 
c0f4adf
06e9d76
c0f4adf
094008d
06e9d76
094008d
 
64ad029
c0f4adf
 
094008d
c0f4adf
 
b652405
16e19a3
06e9d76
b652405
 
8a082d7
b652405
06e9d76
b652405
06e9d76
c0f4adf
06e9d76
bca8f87
b652405
 
 
 
c0f4adf
 
 
 
 
 
b652405
c0f4adf
b652405
c0f4adf
 
b652405
 
 
 
2a78f31
094008d
b652405
094008d
 
64ad029
905c230
64ad029
21e8595
024ef47
 
09d65a8
 
 
 
 
 
 
 
c0f4adf
09d65a8
 
 
 
c0f4adf
09d65a8
 
 
06e9d76
 
c0f4adf
09d65a8
 
 
 
 
 
06e9d76
09d65a8
c8fa89c
024ef47
57dab07
024ef47
 
 
68cb555
024ef47
 
760155b
c0f4adf
 
760155b
 
024ef47
c0f4adf
024ef47
 
b652405
 
 
 
 
024ef47
 
c0f4adf
024ef47
 
 
b652405
024ef47
c8fa89c
760155b
c0f4adf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import gradio as gr
import pandas as pd
from typing import Any
import json

from cognitive_mapping_probe.orchestrator_seismograph import run_seismic_analysis
from cognitive_mapping_probe.auto_experiment import run_auto_suite, get_curated_experiments
from cognitive_mapping_probe.prompts import RESONANCE_PROMPTS
from cognitive_mapping_probe.utils import dbg, cleanup_memory

theme = gr.themes.Soft(primary_hue="indigo", secondary_hue="blue").set(body_background_fill="#f0f4f9", block_background_fill="white")

def run_single_analysis_display(*args: Any, progress: gr.Progress = gr.Progress()) -> Any:
    """
    Wrapper für den 'Manual Single Run'-Tab, mit polyrhythmischer Analyse und korrigierten Plots.
    """
    try:
        results = run_seismic_analysis(*args, progress_callback=progress)
        stats, deltas = results.get("stats", {}), results.get("state_deltas", [])

        df_time = pd.DataFrame({"Internal Step": range(len(deltas)), "State Change (Delta)": deltas})

        spectrum_data = []
        if "power_spectrum" in results:
            spectrum = results["power_spectrum"]
            # KORREKTUR: Verwende den konsistenten Schlüssel 'frequencies'
            if spectrum and "frequencies" in spectrum and "power" in spectrum:
                for freq, power in zip(spectrum["frequencies"], spectrum["power"]):
                    if freq > 0.001:
                        period = 1 / freq if freq > 0 else float('inf')
                        spectrum_data.append({"Period (Steps/Cycle)": period, "Power": power})
        df_freq = pd.DataFrame(spectrum_data)

        periods_list = stats.get('dominant_periods_steps')
        periods_str = ", ".join(map(str, periods_list)) if periods_list else "N/A"

        stats_md = f"""### Statistical Signature
- **Mean Delta:** {stats.get('mean_delta', 0):.4f}
- **Std Dev Delta:** {stats.get('std_delta', 0):.4f}
- **Dominant Periods:** {periods_str} Steps/Cycle
- **Spectral Entropy:** {stats.get('spectral_entropy', 0):.4f}"""

        serializable_results = json.dumps(results, indent=2, default=str)
        return f"{results.get('verdict', 'Error')}\n\n{stats_md}", df_time, df_freq, serializable_results
    finally:
        cleanup_memory()

def run_auto_suite_display(model_id: str, num_steps: int, seed: int, experiment_name: str, progress: gr.Progress = gr.Progress()) -> Any:
    """Wrapper für den 'Automated Suite'-Tab, der nun alle Plot-Typen korrekt handhabt."""
    try:
        summary_df, plot_df, all_results = run_auto_suite(model_id, num_steps, seed, experiment_name, progress)

        dataframe_component = gr.DataFrame(label="Comparative Signature (incl. Signal Metrics)", value=summary_df, wrap=True, row_count=(len(summary_df), "dynamic"))

        plot_params_time = {
            "title": "Comparative Cognitive Dynamics (Time Domain)",
            "color_legend_position": "bottom", "show_label": True, "height": 300, "interactive": True
        }
        if experiment_name == "Mechanistic Probe (Attention Entropies)":
            plot_params_time.update({"x": "Step", "y": "Value", "color": "Metric", "color_legend_title": "Metric"})
        else:
            plot_params_time.update({"x": "Step", "y": "Delta", "color": "Experiment", "color_legend_title": "Experiment Runs"})

        time_domain_plot = gr.LinePlot(value=plot_df, **plot_params_time)

        spectrum_data = []
        for label, result in all_results.items():
            if "power_spectrum" in result:
                spectrum = result["power_spectrum"]
                if spectrum and "frequencies" in spectrum and "power" in spectrum:
                    for freq, power in zip(spectrum["frequencies"], spectrum["power"]):
                        if freq > 0.001:
                            period = 1 / freq if freq > 0 else float('inf')
                            spectrum_data.append({"Period (Steps/Cycle)": period, "Power": power, "Experiment": label})

        spectrum_df = pd.DataFrame(spectrum_data)

        spectrum_plot_params = {
            "x": "Period (Steps/Cycle)", "y": "Power", "color": "Experiment",
            "title": "Cognitive Frequency Fingerprint (Period Domain)", "height": 300,
            "color_legend_position": "bottom", "show_label": True, "interactive": True,
            "color_legend_title": "Experiment Runs",
        }
        frequency_domain_plot = gr.LinePlot(value=spectrum_df, **spectrum_plot_params)

        serializable_results = json.dumps(all_results, indent=2, default=str)
        return dataframe_component, time_domain_plot, frequency_domain_plot, serializable_results
    finally:
        cleanup_memory()

with gr.Blocks(theme=theme, title="Cognitive Seismograph 2.3") as demo:
    gr.Markdown("# 🧠 Cognitive Seismograph 2.3: Advanced Experiment Suite")

    with gr.Tabs():
        with gr.TabItem("🔬 Manual Single Run"):
            gr.Markdown("Run a single experiment with manual parameters to explore specific hypotheses.")
            with gr.Row(variant='panel'):
                with gr.Column(scale=1):
                    gr.Markdown("### 1. General Parameters")
                    manual_model_id = gr.Textbox(value="google/gemma-3-1b-it", label="Model ID")
                    manual_prompt_type = gr.Radio(choices=list(RESONANCE_PROMPTS.keys()), value="resonance_prompt", label="Prompt Type")
                    manual_seed = gr.Slider(1, 1000, 42, step=1, label="Seed")
                    manual_num_steps = gr.Slider(50, 1000, 300, step=10, label="Number of Internal Steps")

                    gr.Markdown("### 2. Modulation Parameters")
                    manual_concept = gr.Textbox(label="Concept to Inject", placeholder="e.g., 'calmness'")
                    manual_strength = gr.Slider(0.0, 5.0, 1.5, step=0.1, label="Injection Strength")
                    manual_run_btn = gr.Button("Run Single Analysis", variant="primary")

                with gr.Column(scale=2):
                    gr.Markdown("### Single Run Results")
                    manual_verdict = gr.Markdown("Analysis results will appear here.")
                    with gr.Row():
                        manual_time_plot = gr.LinePlot(x="Internal Step", y="State Change (Delta)", title="Time Domain")
                        manual_freq_plot = gr.LinePlot(x="Period (Steps/Cycle)", y="Power", title="Frequency Domain (Period)")
                    with gr.Accordion("Raw JSON Output", open=False):
                        manual_raw_json = gr.JSON()

            manual_run_btn.click(
                fn=run_single_analysis_display,
                inputs=[manual_model_id, manual_prompt_type, manual_seed, manual_num_steps, manual_concept, manual_strength],
                outputs=[manual_verdict, manual_time_plot, manual_freq_plot, manual_raw_json]
            )

        with gr.TabItem("🚀 Automated Suite"):
            gr.Markdown("Run a predefined, curated suite of experiments and visualize the results comparatively.")
            with gr.Row(variant='panel'):
                with gr.Column(scale=1):
                    gr.Markdown("### Auto-Experiment Parameters")
                    auto_model_id = gr.Textbox(value="google/gemma-3-1b-it", label="Model ID")
                    auto_num_steps = gr.Slider(50, 1000, 300, step=10, label="Steps per Run")
                    auto_seed = gr.Slider(1, 1000, 42, step=1, label="Seed")
                    auto_experiment_name = gr.Dropdown(
                        choices=list(get_curated_experiments().keys()),
                        value="Causal Verification & Crisis Dynamics",
                        label="Curated Experiment Protocol"
                    )
                    auto_run_btn = gr.Button("Run Curated Auto-Experiment", variant="primary")

                with gr.Column(scale=2):
                    gr.Markdown("### Suite Results Summary")
                    auto_summary_df = gr.DataFrame(label="Comparative Signature (incl. Signal Metrics)", wrap=True)
                    with gr.Row():
                        auto_time_plot_output = gr.LinePlot()
                        auto_freq_plot_output = gr.LinePlot()

                    with gr.Accordion("Raw JSON for all runs", open=False):
                        auto_raw_json = gr.JSON()

            auto_run_btn.click(
                fn=run_auto_suite_display,
                inputs=[auto_model_id, auto_num_steps, auto_seed, auto_experiment_name],
                outputs=[auto_summary_df, auto_time_plot_output, auto_freq_plot_output, auto_raw_json]
            )

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)