jmisak commited on
Commit
f7868c9
·
verified ·
1 Parent(s): 473c3af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -117
app.py CHANGED
@@ -1,117 +1,125 @@
1
- import gradio as gr
2
- import yaml
3
- import json
4
- import os
5
- import traceback
6
- import matplotlib.pyplot as plt
7
- import numpy as np
8
-
9
- from engine.loader import load_persona
10
- from engine.drift import apply_stimuli
11
- from engine.responder import generate_response
12
- from engine.utils import safe_log
13
- from engine.logger import log_transcript
14
-
15
- # Paths
16
- persona_dir = "./personas"
17
- stimuli_path = "./stimuli/events.json"
18
- error_log_path = "./driftline_errors.log"
19
-
20
-
21
-
22
- # Load available personas
23
- def get_persona_choices():
24
- return [f for f in os.listdir(persona_dir) if f.endswith(".yml")]
25
-
26
- # Load available stimuli
27
- def get_stimuli_choices():
28
- try:
29
- with open(stimuli_path, "r") as f:
30
- events = json.load(f)
31
- return [e["event"] for e in events]
32
- except Exception as e:
33
- safe_log("Stimuli load error", str(e))
34
- return []
35
-
36
- # Generate radar chart for traits
37
- def plot_traits(state):
38
- traits = ["innovation", "openness", "risk_tolerance", "peer_influence"]
39
- values = [state.get(t, 0.0) for t in traits]
40
- angles = np.linspace(0, 2 * np.pi, len(traits), endpoint=False).tolist()
41
- values += values[:1]
42
- angles += angles[:1]
43
-
44
- fig, ax = plt.subplots(figsize=(4, 4), subplot_kw=dict(polar=True))
45
- ax.plot(angles, values, color="blue", linewidth=2)
46
- ax.fill(angles, values, color="blue", alpha=0.25)
47
- ax.set_xticks(angles[:-1])
48
- ax.set_xticklabels(traits)
49
- ax.set_yticklabels([])
50
- ax.set_title("Dynamic Trait Profile", fontsize=12)
51
- fig.tight_layout()
52
-
53
- chart_path = "./trait_chart.png"
54
- fig.savefig(chart_path)
55
- plt.close(fig)
56
- return chart_path
57
-
58
- # Main simulation function
59
- def simulate(prompt, selected_event, selected_persona_file):
60
- try:
61
- persona_path = os.path.join(persona_dir, selected_persona_file)
62
- persona = load_persona(persona_path)
63
-
64
- with open(stimuli_path, "r") as f:
65
- events = json.load(f)
66
- event = next((e for e in events if e["event"] == selected_event), None)
67
-
68
- if event:
69
- persona = apply_stimuli(persona, event)
70
-
71
- response = generate_response(prompt, persona)
72
- state_yaml = yaml.dump(persona["dynamic_state"], sort_keys=False)
73
- chart_path = plot_traits(persona["dynamic_state"])
74
-
75
- # ? Log transcript here, after response is generated
76
- from engine.logger import log_transcript
77
- transcript_path = log_transcript(persona, prompt, selected_event, response)
78
-
79
- return response, state_yaml, chart_path
80
-
81
- except Exception as e:
82
- error_msg = traceback.format_exc()
83
- safe_log("Simulation error", error_msg)
84
- return "[ERROR] Simulation failed. Check logs.", "", None
85
-
86
- # Gradio UI
87
- with gr.Blocks(title="Driftline HCP Simulator") as ui:
88
- gr.Markdown("## 🧠 Driftline: Adaptive HCP Simulation")
89
- gr.Markdown("Simulate how healthcare personas evolve in response to market stimuli.")
90
-
91
- with gr.Row():
92
- persona_selector = gr.Dropdown(label="Choose Persona", choices=get_persona_choices(), value="hcp_drift_trailblazer.yml")
93
- event_selector = gr.Dropdown(label="Market Stimulus", choices=get_stimuli_choices(), value="FDA_approval")
94
-
95
- prompt = gr.Textbox(label="Interviewer Prompt", lines=2, placeholder="Ask about a new therapy, trial data, or prescribing behavior...")
96
-
97
- with gr.Row():
98
- simulate_btn = gr.Button("Run Simulation")
99
- clear_btn = gr.Button("Clear")
100
-
101
- response_output = gr.Textbox(label="Simulated HCP Response", lines=6)
102
- state_output = gr.Textbox(label="Updated Persona State", lines=10)
103
- trait_chart = gr.Image(label="Trait Radar Chart")
104
-
105
- simulate_btn.click(
106
- fn=simulate,
107
- inputs=[prompt, event_selector, persona_selector],
108
- outputs=[response_output, state_output, trait_chart]
109
- )
110
-
111
- clear_btn.click(
112
- fn=lambda: ("", "", None),
113
- inputs=[],
114
- outputs=[response_output, state_output, trait_chart]
115
- )
116
-
117
- ui.launch(server_port=7865, share=True)
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import yaml
3
+ import json
4
+ import os
5
+ import traceback
6
+ import matplotlib.pyplot as plt
7
+ import numpy as np
8
+
9
+ from engine.loader import load_persona
10
+ from engine.drift import apply_stimuli
11
+ from engine.responder import generate_response
12
+ from engine.utils import safe_log
13
+ from engine.logger import log_transcript
14
+
15
+ # Paths
16
+ persona_dir = "./personas"
17
+ stimuli_path = "./stimuli/events.json"
18
+ error_log_path = "./driftline_errors.log"
19
+
20
+
21
+
22
+ # Load available personas
23
+ def get_persona_choices():
24
+ return [f for f in os.listdir(persona_dir) if f.endswith(".yml")]
25
+
26
+ # Load available stimuli
27
+ def get_stimuli_choices():
28
+ try:
29
+ with open(stimuli_path, "r") as f:
30
+ events = json.load(f)
31
+ return [e["event"] for e in events]
32
+ except Exception as e:
33
+ safe_log("Stimuli load error", str(e))
34
+ return []
35
+
36
+ # Generate radar chart for traits
37
+ def plot_traits(state):
38
+ traits = ["innovation", "openness", "risk_tolerance", "peer_influence"]
39
+ values = [state.get(t, 0.0) for t in traits]
40
+ angles = np.linspace(0, 2 * np.pi, len(traits), endpoint=False).tolist()
41
+ values += values[:1]
42
+ angles += angles[:1]
43
+
44
+ fig, ax = plt.subplots(figsize=(4, 4), subplot_kw=dict(polar=True))
45
+ ax.plot(angles, values, color="blue", linewidth=2)
46
+ ax.fill(angles, values, color="blue", alpha=0.25)
47
+ ax.set_xticks(angles[:-1])
48
+ ax.set_xticklabels(traits)
49
+ ax.set_yticklabels([])
50
+ ax.set_title("Dynamic Trait Profile", fontsize=12)
51
+ fig.tight_layout()
52
+
53
+ chart_path = "./trait_chart.png"
54
+ fig.savefig(chart_path)
55
+ plt.close(fig)
56
+ return chart_path
57
+
58
+ # Main simulation function
59
+ def simulate(prompt, selected_event, selected_persona_file):
60
+ try:
61
+ persona_path = os.path.join(persona_dir, selected_persona_file)
62
+ persona = load_persona(persona_path)
63
+
64
+ with open(stimuli_path, "r") as f:
65
+ events = json.load(f)
66
+ event = next((e for e in events if e["event"] == selected_event), None)
67
+
68
+ if event:
69
+ persona = apply_stimuli(persona, event)
70
+
71
+ response = generate_response(prompt, persona)
72
+ state_yaml = yaml.dump(persona["dynamic_state"], sort_keys=False)
73
+ chart_path = plot_traits(persona["dynamic_state"])
74
+
75
+ # ? Log transcript here, after response is generated
76
+ from engine.logger import log_transcript
77
+ transcript_path = log_transcript(persona, prompt, selected_event, response)
78
+
79
+ return response, state_yaml, chart_path
80
+
81
+ except Exception as e:
82
+ error_msg = traceback.format_exc()
83
+ safe_log("Simulation error", error_msg)
84
+ return "[ERROR] Simulation failed. Check logs.", "", None
85
+
86
+ # Gradio UI
87
+ with gr.Blocks(title="Driftline HCP Simulator") as ui:
88
+ gr.Markdown("## 🧠 Driftline: Adaptive HCP Simulation")
89
+ gr.Markdown("Simulate how healthcare personas evolve in response to market stimuli.")
90
+
91
+ with gr.Row():
92
+ persona_files = get_persona_choices()
93
+ default_persona = persona_files[0] if persona_files else None
94
+
95
+ persona_selector = gr.Dropdown(
96
+ label="Choose Persona",
97
+ choices=persona_files,
98
+ value=default_persona,
99
+ allow_custom_value=False
100
+ )
101
+ event_selector = gr.Dropdown(label="Market Stimulus", choices=get_stimuli_choices(), value="FDA_approval")
102
+
103
+ prompt = gr.Textbox(label="Interviewer Prompt", lines=2, placeholder="Ask about a new therapy, trial data, or prescribing behavior...")
104
+
105
+ with gr.Row():
106
+ simulate_btn = gr.Button("Run Simulation")
107
+ clear_btn = gr.Button("Clear")
108
+
109
+ response_output = gr.Textbox(label="Simulated HCP Response", lines=6)
110
+ state_output = gr.Textbox(label="Updated Persona State", lines=10)
111
+ trait_chart = gr.Image(label="Trait Radar Chart")
112
+
113
+ simulate_btn.click(
114
+ fn=simulate,
115
+ inputs=[prompt, event_selector, persona_selector],
116
+ outputs=[response_output, state_output, trait_chart]
117
+ )
118
+
119
+ clear_btn.click(
120
+ fn=lambda: ("", "", None),
121
+ inputs=[],
122
+ outputs=[response_output, state_output, trait_chart]
123
+ )
124
+
125
+ ui.launch()