coredipper commited on
Commit
a6d733f
Β·
verified Β·
1 Parent(s): ebb40cc

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +22 -6
  2. __pycache__/app.cpython-314.pyc +0 -0
  3. app.py +416 -0
  4. requirements.txt +2 -0
README.md CHANGED
@@ -1,12 +1,28 @@
1
  ---
2
- title: Operon Morphogen
3
- emoji: 🐨
4
- colorFrom: purple
5
- colorTo: green
6
  sdk: gradio
7
- sdk_version: 6.5.1
8
  app_file: app.py
9
  pinned: false
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Operon Morphogen Gradients
3
+ emoji: πŸ§ͺ
4
+ colorFrom: yellow
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: "6.5.1"
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
+ short_description: Gradient-based agent coordination without central control
12
  ---
13
 
14
+ # πŸ§ͺ Morphogen Gradients
15
+
16
+ Explore **gradient-based coordination** where agents adapt behavior based on local chemical signals β€” no central controller needed.
17
+
18
+ ## Features
19
+
20
+ - **Tab 1 β€” Manual Gradient**: Set 6 morphogen values and see strategy hints, context injection, and phenotype adaptation
21
+ - **Tab 2 β€” Orchestrator Simulation**: Watch gradients evolve step-by-step as the orchestrator reacts to successes and failures
22
+ - **7 presets**: Easy task, crisis mode, exploration, budget crunch, smooth sailing, cascading failures, recovery arc
23
+
24
+ ## How It Works
25
+
26
+ The `MorphogenGradient` holds 6 signal types (complexity, confidence, budget, error_rate, urgency, risk). The `GradientOrchestrator` adjusts these signals after each step result, producing strategy hints and phenotype parameters that shape agent behavior.
27
+
28
+ [GitHub](https://github.com/coredipper/operon) | [PyPI](https://pypi.org/project/operon-ai/)
__pycache__/app.cpython-314.pyc ADDED
Binary file (20.2 kB). View file
 
app.py ADDED
@@ -0,0 +1,416 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Operon Morphogen Gradients -- Interactive Gradio Demo
3
+ =====================================================
4
+
5
+ Two-tab demo: manually set gradient values to see strategy hints and
6
+ phenotype adaptation, or simulate multi-step orchestration and watch
7
+ gradients evolve.
8
+
9
+ Run locally:
10
+ pip install gradio
11
+ python space-morphogen/app.py
12
+
13
+ Deploy to HuggingFace Spaces:
14
+ Copy this directory to a new HF Space with sdk=gradio.
15
+ """
16
+
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ import gradio as gr
21
+
22
+ # Allow importing operon_ai from the repo root when running locally
23
+ _repo_root = Path(__file__).resolve().parent.parent
24
+ if str(_repo_root) not in sys.path:
25
+ sys.path.insert(0, str(_repo_root))
26
+
27
+ from operon_ai import (
28
+ MorphogenType,
29
+ MorphogenGradient,
30
+ GradientOrchestrator,
31
+ )
32
+
33
+ # ── Morphogen type ordering ───────────────────────────────────────────────
34
+
35
+ MORPHOGEN_ORDER = [
36
+ MorphogenType.COMPLEXITY,
37
+ MorphogenType.CONFIDENCE,
38
+ MorphogenType.BUDGET,
39
+ MorphogenType.ERROR_RATE,
40
+ MorphogenType.URGENCY,
41
+ MorphogenType.RISK,
42
+ ]
43
+
44
+ MORPHOGEN_COLORS = {
45
+ MorphogenType.COMPLEXITY: "#8b5cf6",
46
+ MorphogenType.CONFIDENCE: "#22c55e",
47
+ MorphogenType.BUDGET: "#3b82f6",
48
+ MorphogenType.ERROR_RATE: "#ef4444",
49
+ MorphogenType.URGENCY: "#f97316",
50
+ MorphogenType.RISK: "#eab308",
51
+ }
52
+
53
+ # ── Tab 1: Manual Gradient Presets ─────────────────────────────────────────
54
+
55
+ MANUAL_PRESETS: dict[str, dict] = {
56
+ "(custom)": {
57
+ "description": "Set your own gradient values.",
58
+ "values": {m: 0.5 for m in MORPHOGEN_ORDER},
59
+ },
60
+ "Easy task, high confidence": {
61
+ "description": "Low complexity, high budget, high confidence β€” smooth sailing.",
62
+ "values": {
63
+ MorphogenType.COMPLEXITY: 0.2,
64
+ MorphogenType.CONFIDENCE: 0.9,
65
+ MorphogenType.BUDGET: 0.8,
66
+ MorphogenType.ERROR_RATE: 0.05,
67
+ MorphogenType.URGENCY: 0.3,
68
+ MorphogenType.RISK: 0.1,
69
+ },
70
+ },
71
+ "Crisis mode": {
72
+ "description": "Everything bad β€” high complexity, errors, urgency, risk, low budget/confidence.",
73
+ "values": {
74
+ MorphogenType.COMPLEXITY: 0.95,
75
+ MorphogenType.CONFIDENCE: 0.1,
76
+ MorphogenType.BUDGET: 0.05,
77
+ MorphogenType.ERROR_RATE: 0.85,
78
+ MorphogenType.URGENCY: 0.95,
79
+ MorphogenType.RISK: 0.9,
80
+ },
81
+ },
82
+ "Exploration phase": {
83
+ "description": "Balanced values β€” moderate complexity, decent budget, exploring.",
84
+ "values": {
85
+ MorphogenType.COMPLEXITY: 0.5,
86
+ MorphogenType.CONFIDENCE: 0.5,
87
+ MorphogenType.BUDGET: 0.6,
88
+ MorphogenType.ERROR_RATE: 0.2,
89
+ MorphogenType.URGENCY: 0.4,
90
+ MorphogenType.RISK: 0.3,
91
+ },
92
+ },
93
+ "Budget crunch": {
94
+ "description": "High complexity but near-zero budget β€” forces capability reduction.",
95
+ "values": {
96
+ MorphogenType.COMPLEXITY: 0.8,
97
+ MorphogenType.CONFIDENCE: 0.4,
98
+ MorphogenType.BUDGET: 0.05,
99
+ MorphogenType.ERROR_RATE: 0.3,
100
+ MorphogenType.URGENCY: 0.7,
101
+ MorphogenType.RISK: 0.5,
102
+ },
103
+ },
104
+ }
105
+
106
+
107
+ def _load_manual_preset(name: str) -> tuple[float, float, float, float, float, float]:
108
+ p = MANUAL_PRESETS.get(name, MANUAL_PRESETS["(custom)"])
109
+ v = p["values"]
110
+ return tuple(v[m] for m in MORPHOGEN_ORDER)
111
+
112
+
113
+ # ── Tab 2: Orchestrator Simulation Presets ─────────────────────────────────
114
+
115
+ ORCH_PRESETS: dict[str, dict] = {
116
+ "(custom)": {
117
+ "description": "Enter steps as 'success:tokens' or 'fail:tokens' per line.",
118
+ "steps": "",
119
+ "budget": 2000,
120
+ },
121
+ "Smooth sailing": {
122
+ "description": "8 consecutive successes β€” confidence rises, error rate drops.",
123
+ "steps": "success:200\nsuccess:180\nsuccess:190\nsuccess:210\nsuccess:170\nsuccess:200\nsuccess:195\nsuccess:185",
124
+ "budget": 2000,
125
+ },
126
+ "Cascading failures": {
127
+ "description": "3 successes then 5 failures β€” watch confidence collapse and error rate spike.",
128
+ "steps": "success:200\nsuccess:180\nsuccess:190\nfail:250\nfail:200\nfail:300\nfail:150\nfail:200",
129
+ "budget": 2000,
130
+ },
131
+ "Recovery arc": {
132
+ "description": "Alternating fail-success β€” gradients oscillate as system recovers.",
133
+ "steps": "fail:200\nsuccess:180\nfail:250\nsuccess:150\nfail:300\nsuccess:200\nsuccess:170\nsuccess:160",
134
+ "budget": 2000,
135
+ },
136
+ }
137
+
138
+
139
+ def _load_orch_preset(name: str) -> tuple[str, int]:
140
+ p = ORCH_PRESETS.get(name, ORCH_PRESETS["(custom)"])
141
+ return p["steps"], p["budget"]
142
+
143
+
144
+ # ── Gradient visualization helper ─────────��───────────────────────────────
145
+
146
+
147
+ def _render_gradient_bars(gradient: MorphogenGradient) -> str:
148
+ """Render horizontal bars for all 6 morphogen values."""
149
+ rows = []
150
+ for m in MORPHOGEN_ORDER:
151
+ val = gradient.get(m)
152
+ color = MORPHOGEN_COLORS[m]
153
+ pct = max(0, min(100, val * 100))
154
+ level = gradient.get_level(m)
155
+ rows.append(
156
+ f'<div style="margin:4px 0">'
157
+ f'<div style="display:flex;align-items:center;gap:8px">'
158
+ f'<span style="width:100px;font-size:0.85em;font-weight:600">{m.value}</span>'
159
+ f'<div style="flex:1;background:#e5e7eb;border-radius:4px;height:20px;position:relative">'
160
+ f'<div style="width:{pct}%;background:{color};height:100%;border-radius:4px;'
161
+ f'transition:width 0.3s"></div></div>'
162
+ f'<span style="width:60px;text-align:right;font-size:0.85em;color:#666">'
163
+ f'{val:.2f}</span>'
164
+ f'<span style="width:60px;font-size:0.75em;color:{color}">{level}</span>'
165
+ f'</div></div>'
166
+ )
167
+ return '<div style="padding:8px">' + "".join(rows) + "</div>"
168
+
169
+
170
+ # ── Tab 1: Manual gradient ────────────────────────────────────────────────
171
+
172
+
173
+ def run_manual_gradient(
174
+ preset_name: str,
175
+ complexity: float,
176
+ confidence: float,
177
+ budget: float,
178
+ error_rate: float,
179
+ urgency: float,
180
+ risk: float,
181
+ ) -> tuple[str, str, str, str]:
182
+ """Set gradient values and return analysis.
183
+
184
+ Returns (gradient_html, hints_md, context_md, phenotype_md).
185
+ """
186
+ gradient = MorphogenGradient()
187
+ values = [complexity, confidence, budget, error_rate, urgency, risk]
188
+ for m, v in zip(MORPHOGEN_ORDER, values):
189
+ gradient.set(m, v)
190
+
191
+ orchestrator = GradientOrchestrator(gradient=gradient, silent=True)
192
+
193
+ # Gradient bars
194
+ gradient_html = _render_gradient_bars(gradient)
195
+
196
+ # Strategy hints
197
+ hints = gradient.get_strategy_hints()
198
+ if hints:
199
+ hints_md = "### Strategy Hints\n\n" + "\n".join(f"- {h}" for h in hints)
200
+ else:
201
+ hints_md = "### Strategy Hints\n\n*No specific hints at these levels.*"
202
+
203
+ # Context injection
204
+ ctx = gradient.get_context_injection()
205
+ context_md = f"### Context Injection\n\n```\n{ctx}\n```" if ctx else "### Context Injection\n\n*Empty context.*"
206
+
207
+ # Phenotype + coordination signals
208
+ phenotype = orchestrator.get_phenotype_params()
209
+ recruit = orchestrator.should_recruit_help()
210
+ reduce = orchestrator.should_reduce_capabilities()
211
+
212
+ pheno_lines = ["### Phenotype Parameters\n", "| Parameter | Value |", "| :--- | :--- |"]
213
+ for k, v in phenotype.items():
214
+ pheno_lines.append(f"| {k} | {v} |")
215
+
216
+ pheno_lines.append("\n### Coordination Signals\n")
217
+ pheno_lines.append(f"| Signal | Value |")
218
+ pheno_lines.append(f"| :--- | :--- |")
219
+
220
+ recruit_color = "#ef4444" if recruit else "#22c55e"
221
+ recruit_label = "YES β€” requesting help" if recruit else "No"
222
+ pheno_lines.append(
223
+ f'| Should recruit help | <span style="color:{recruit_color}">{recruit_label}</span> |'
224
+ )
225
+
226
+ reduce_color = "#f97316" if reduce else "#22c55e"
227
+ reduce_label = "YES β€” reducing capabilities" if reduce else "No"
228
+ pheno_lines.append(
229
+ f'| Should reduce capabilities | <span style="color:{reduce_color}">{reduce_label}</span> |'
230
+ )
231
+
232
+ phenotype_md = "\n".join(pheno_lines)
233
+
234
+ return gradient_html, hints_md, context_md, phenotype_md
235
+
236
+
237
+ # ── Tab 2: Orchestrator simulation ────────────────────────────────────────
238
+
239
+
240
+ def run_orchestrator(
241
+ preset_name: str,
242
+ steps_text: str,
243
+ total_budget: int,
244
+ ) -> tuple[str, str, str]:
245
+ """Run step-by-step orchestrator simulation.
246
+
247
+ Returns (final_gradient_html, timeline_md, final_phenotype_md).
248
+ """
249
+ # Parse steps
250
+ steps = []
251
+ for line in steps_text.strip().split("\n"):
252
+ line = line.strip()
253
+ if not line:
254
+ continue
255
+ parts = line.split(":")
256
+ if len(parts) != 2:
257
+ continue
258
+ success = parts[0].strip().lower() == "success"
259
+ try:
260
+ tokens = int(parts[1].strip())
261
+ except ValueError:
262
+ tokens = 100
263
+ steps.append((success, tokens))
264
+
265
+ if not steps:
266
+ return "<p>Enter steps as 'success:200' or 'fail:150', one per line.</p>", "", ""
267
+
268
+ orchestrator = GradientOrchestrator(silent=True)
269
+ timeline_rows = [
270
+ "| Step | Result | Tokens | Complexity | Confidence | Budget | Error Rate | Urgency | Risk |",
271
+ "| ---: | :--- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |",
272
+ ]
273
+
274
+ for i, (success, tokens) in enumerate(steps, 1):
275
+ orchestrator.report_step_result(
276
+ success=success,
277
+ tokens_used=tokens,
278
+ total_budget=int(total_budget),
279
+ )
280
+
281
+ g = orchestrator.gradient
282
+ result_icon = "βœ“" if success else "βœ—"
283
+ result_color = "#22c55e" if success else "#ef4444"
284
+
285
+ timeline_rows.append(
286
+ f'| {i} | <span style="color:{result_color}">{result_icon}</span> '
287
+ f"| {tokens} "
288
+ f"| {g.get(MorphogenType.COMPLEXITY):.2f} "
289
+ f"| {g.get(MorphogenType.CONFIDENCE):.2f} "
290
+ f"| {g.get(MorphogenType.BUDGET):.2f} "
291
+ f"| {g.get(MorphogenType.ERROR_RATE):.2f} "
292
+ f"| {g.get(MorphogenType.URGENCY):.2f} "
293
+ f"| {g.get(MorphogenType.RISK):.2f} |"
294
+ )
295
+
296
+ timeline_md = "\n".join(timeline_rows)
297
+
298
+ # Final gradient
299
+ final_gradient_html = _render_gradient_bars(orchestrator.gradient)
300
+
301
+ # Final phenotype
302
+ phenotype = orchestrator.get_phenotype_params()
303
+ recruit = orchestrator.should_recruit_help()
304
+ reduce = orchestrator.should_reduce_capabilities()
305
+
306
+ pheno_lines = ["### Final Phenotype\n", "| Parameter | Value |", "| :--- | :--- |"]
307
+ for k, v in phenotype.items():
308
+ pheno_lines.append(f"| {k} | {v} |")
309
+
310
+ pheno_lines.append(f"\n**Recruit help**: {'YES' if recruit else 'No'} | "
311
+ f"**Reduce capabilities**: {'YES' if reduce else 'No'}")
312
+
313
+ final_phenotype_md = "\n".join(pheno_lines)
314
+
315
+ return final_gradient_html, timeline_md, final_phenotype_md
316
+
317
+
318
+ # ── Gradio UI ──────────────────────────────────────────────────────────────
319
+
320
+
321
+ def build_app() -> gr.Blocks:
322
+ with gr.Blocks(title="Morphogen Gradients") as app:
323
+ gr.Markdown(
324
+ "# πŸ§ͺ Morphogen Gradients\n"
325
+ "Explore **gradient-based coordination** where agents adapt "
326
+ "behavior based on local chemical signals."
327
+ )
328
+
329
+ with gr.Tabs():
330
+ # ── Tab 1: Manual Gradient ────────────────────────────────
331
+ with gr.TabItem("Manual Gradient"):
332
+ with gr.Row():
333
+ manual_preset_dd = gr.Dropdown(
334
+ choices=list(MANUAL_PRESETS.keys()),
335
+ value="Easy task, high confidence",
336
+ label="Preset",
337
+ scale=2,
338
+ )
339
+ manual_btn = gr.Button("Analyze Gradient", variant="primary", scale=1)
340
+
341
+ with gr.Row():
342
+ complexity_sl = gr.Slider(0, 1, value=0.2, step=0.05, label="Complexity")
343
+ confidence_sl = gr.Slider(0, 1, value=0.9, step=0.05, label="Confidence")
344
+ budget_sl = gr.Slider(0, 1, value=0.8, step=0.05, label="Budget")
345
+
346
+ with gr.Row():
347
+ error_sl = gr.Slider(0, 1, value=0.05, step=0.05, label="Error Rate")
348
+ urgency_sl = gr.Slider(0, 1, value=0.3, step=0.05, label="Urgency")
349
+ risk_sl = gr.Slider(0, 1, value=0.1, step=0.05, label="Risk")
350
+
351
+ gradient_html = gr.HTML(label="Gradient Bars")
352
+
353
+ with gr.Row():
354
+ with gr.Column():
355
+ hints_md = gr.Markdown(label="Strategy Hints")
356
+ with gr.Column():
357
+ context_md = gr.Markdown(label="Context Injection")
358
+
359
+ phenotype_md = gr.Markdown(label="Phenotype & Signals")
360
+
361
+ manual_preset_dd.change(
362
+ fn=_load_manual_preset,
363
+ inputs=[manual_preset_dd],
364
+ outputs=[complexity_sl, confidence_sl, budget_sl, error_sl, urgency_sl, risk_sl],
365
+ )
366
+
367
+ manual_btn.click(
368
+ fn=run_manual_gradient,
369
+ inputs=[manual_preset_dd, complexity_sl, confidence_sl, budget_sl, error_sl, urgency_sl, risk_sl],
370
+ outputs=[gradient_html, hints_md, context_md, phenotype_md],
371
+ )
372
+
373
+ # ── Tab 2: Orchestrator Simulation ────────────────────────
374
+ with gr.TabItem("Orchestrator Simulation"):
375
+ with gr.Row():
376
+ orch_preset_dd = gr.Dropdown(
377
+ choices=list(ORCH_PRESETS.keys()),
378
+ value="Smooth sailing",
379
+ label="Preset",
380
+ scale=2,
381
+ )
382
+ orch_btn = gr.Button("Run Simulation", variant="primary", scale=1)
383
+
384
+ steps_tb = gr.Textbox(
385
+ lines=8,
386
+ label="Steps (one per line: 'success:tokens' or 'fail:tokens')",
387
+ placeholder="success:200\nfail:150\nsuccess:180\n…",
388
+ )
389
+ budget_orch_sl = gr.Slider(100, 5000, value=2000, step=100, label="Total budget (tokens)")
390
+
391
+ orch_gradient_html = gr.HTML(label="Final Gradient")
392
+
393
+ with gr.Row():
394
+ with gr.Column(scale=2):
395
+ orch_timeline_md = gr.Markdown(label="Step Timeline")
396
+ with gr.Column(scale=1):
397
+ orch_phenotype_md = gr.Markdown(label="Final Phenotype")
398
+
399
+ orch_preset_dd.change(
400
+ fn=_load_orch_preset,
401
+ inputs=[orch_preset_dd],
402
+ outputs=[steps_tb, budget_orch_sl],
403
+ )
404
+
405
+ orch_btn.click(
406
+ fn=run_orchestrator,
407
+ inputs=[orch_preset_dd, steps_tb, budget_orch_sl],
408
+ outputs=[orch_gradient_html, orch_timeline_md, orch_phenotype_md],
409
+ )
410
+
411
+ return app
412
+
413
+
414
+ if __name__ == "__main__":
415
+ app = build_app()
416
+ app.launch(theme=gr.themes.Soft())
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio>=4.0
2
+ operon-ai