aedmark commited on
Commit
21aa7e2
·
verified ·
1 Parent(s): 7450d72

Delete bone_gui.py

Browse files
Files changed (1) hide show
  1. bone_gui.py +0 -550
bone_gui.py DELETED
@@ -1,550 +0,0 @@
1
- from typing import Dict, List, Any, Tuple
2
- from bone_core import Prisma
3
- from bone_physics import ChromaScope
4
-
5
-
6
- class Projector:
7
- def __init__(self):
8
- self.width = 80
9
-
10
- @staticmethod
11
- def _extract(physics_obj: Any, field: str, sub_field: str, default: Any = 0.0):
12
- val = None
13
- if hasattr(physics_obj, sub_field):
14
- val = getattr(physics_obj, sub_field)
15
- elif isinstance(physics_obj, dict):
16
- if sub_field in physics_obj:
17
- val = physics_obj[sub_field]
18
- elif field in physics_obj and isinstance(physics_obj[field], dict):
19
- val = physics_obj[field].get(sub_field)
20
- return default if val is None else val
21
-
22
- def render(
23
- self,
24
- physics_ctx: Dict,
25
- data_ctx: Dict,
26
- mind_ctx: tuple,
27
- reality_depth: int = 1,
28
- labels: Dict = None,
29
- ) -> str:
30
- if not labels:
31
- labels = {"HP": "HP", "STM": "STM"}
32
- physics = physics_ctx.get("physics", {})
33
- status_line = self._render_vital_strip(data_ctx, mind_ctx, labels)
34
- physics_line = ""
35
- if labels.get("SHOW_PHYSICS", True):
36
- physics_line = self._render_physics_strip(
37
- physics, data_ctx.get("vectors", {})
38
- )
39
- ui_depth = data_ctx.get("ui_depth", "IDLE")
40
- vsl_line = self._render_lattice_strip(physics, depth=ui_depth)
41
- zone = self._extract(physics, "space", "zone", "UNKNOWN")
42
- lens = mind_ctx[0] if mind_ctx else "RAW"
43
- depth_map = {0: "TERM", 1: "SIM", 2: "VIL", 3: "DBG", 4: "DEEP"}
44
- depth_label = depth_map.get(reality_depth, "?")
45
- depth_marker = f"{Prisma.VIOLET}[D{reality_depth}:{depth_label}]{Prisma.RST}"
46
- context_line = (
47
- f"{Prisma.GRY} 📍 {zone:<12} 👁️ {lens:<12} {depth_marker}{Prisma.RST}"
48
- )
49
- div = f"{Prisma.GRY}{'─' * self.width}{Prisma.RST}"
50
-
51
- mid_lines = []
52
- if physics_line:
53
- mid_lines.append(physics_line)
54
- if vsl_line:
55
- mid_lines.append(" " + vsl_line)
56
- mid_section = "\n".join(mid_lines) if mid_lines else ""
57
-
58
- return f"{div}\n{status_line}\n{mid_section}\n{context_line}\n{div}"
59
-
60
- def _render_vital_strip(self, data: Dict, mind: tuple, labels: Dict) -> str:
61
- health = data.get("health", 100)
62
- stamina = data.get("stamina", 100)
63
- atp = data.get("bio", {}).get("atp") or 0
64
- dignity = data.get("dignity", 100)
65
- hp_bar = self._mini_bar(health, 100, 6, Prisma.RED)
66
- stm_bar = self._mini_bar(stamina, 100, 6, Prisma.GRN)
67
- dig_color = Prisma.VIOLET if dignity > 50 else Prisma.GRY
68
- dig_icon = "✦" if dignity > 80 else "✧"
69
- raw_role = mind[2] if mind and len(mind) > 2 else None
70
- role = str(raw_role).upper() if raw_role else "OBSERVER"
71
- role = role.replace("THE THE ", "THE ")
72
- if len(role) > 30:
73
- role = role[:27] + "..."
74
- l_hp = labels.get("HP", "HP")
75
- l_stm = labels.get("STM", "STM")
76
- role_block = f"{Prisma.WHT}♦ {role}{Prisma.RST}"
77
- return (
78
- f" {role_block:<35} "
79
- f"{l_hp} {hp_bar} "
80
- f"{l_stm} {stm_bar} "
81
- f"{dig_color}{dig_icon}{int(dignity)}%{Prisma.RST} "
82
- f"{Prisma.YEL}ATP:{int(atp)}{Prisma.RST}"
83
- )
84
-
85
- def _render_physics_strip(self, physics: Any, vectors: Dict) -> str:
86
- volt = self._extract(physics, "energy", "voltage", 0.0)
87
- drag = self._extract(physics, "space", "narrative_drag", 0.0)
88
- dom_vec = "NEUTRAL"
89
- dom_val = 0.0
90
- if vectors:
91
- dom_vec = max(vectors, key=vectors.get)
92
- dom_val = vectors[dom_vec]
93
- return (
94
- f" {Prisma.CYN}VOLT:{Prisma.RST} {volt:04.1f}v "
95
- f"{Prisma.SLATE}DRAG:{Prisma.RST} {drag:04.1f} "
96
- f"{Prisma.MAG}VEC:{Prisma.RST} {dom_vec} ({dom_val:.2f})"
97
- )
98
-
99
- @staticmethod
100
- def _render_lattice_strip(physics: Dict, depth: str = "DEEP") -> str:
101
- if depth == "IDLE" or not physics:
102
- return ""
103
-
104
- def _get_val(k1, k2, default_val):
105
- v = physics.get(k1)
106
- if v is None:
107
- v = physics.get(k2)
108
- return default_val if v is None else v
109
-
110
- E = _get_val("exhaustion", "E", 0.2)
111
- beta = _get_val("contradiction", "beta", 0.4)
112
- V = _get_val("voltage", "voltage", 30.0)
113
- F = _get_val("friction", "narrative_drag", 0.6)
114
- H = _get_val("health", "health", 100.0)
115
- P = _get_val("stamina", "stamina", 100.0)
116
- T = _get_val("trauma", "T", 0.0)
117
- psi = _get_val("psi", "psi", 0.0)
118
- chi = _get_val("chi", "chi", 0.0)
119
- valence = _get_val("valence", "valence", 0.0)
120
- core = f"{Prisma.CYN}[🧊 E:{E:.2f} β:{beta:.2f} | ⚡ V:{V:.0f} F:{F:.1f} | ❤️ H:{H:.0f} P:{P:.0f} | 🏺 T:{T:.0f}]{Prisma.RST}"
121
- deep = (
122
- f"{Prisma.VIOLET} [🌌 Ψ:{psi:.2f} Χ:{chi:.2f} ♥:{valence:.2f}]{Prisma.RST}"
123
- )
124
- if depth == "DEEP":
125
- return core + deep
126
- elif depth == "CORE":
127
- return core
128
- elif depth == "LITE":
129
- return f"{Prisma.CYN}[⚡ V:{V:.0f} | ❤️ H:{H:.0f} P:{P:.0f}]{Prisma.RST}"
130
- return ""
131
-
132
- def render_technical(self, physics: Dict, data: Dict, mind: tuple) -> str:
133
- v = self._extract(physics, "energy", "voltage", 0.0)
134
- d = self._extract(physics, "space", "narrative_drag", 0.0)
135
- vec = data.get("vectors", {})
136
- vec_str = ", ".join([f"{k}:{v:.2f}" for k, v in vec.items() if v > 0.01])
137
- return (
138
- f"{Prisma.CYN}/// KERNEL TELEMETRY ///{Prisma.RST}\n"
139
- f"PHYSICS : V={v:<6.3f} D={d:<6.3f} | LENS: {mind[0]}\n"
140
- f"VECTORS : [{vec_str}]\n"
141
- f"BIO_DUMP: {str(data.get('bio', {}))[:60]}..."
142
- )
143
-
144
- @staticmethod
145
- def _mini_bar(val, max_val, width, color):
146
- if max_val == 0:
147
- return ""
148
- ratio = max(0.0, min(1.0, val / max_val))
149
- fill = int(ratio * width)
150
- empty = width - fill
151
- return f"{color}{'█' * fill}{Prisma.GRY}{'░' * empty}{Prisma.RST}"
152
-
153
-
154
- class GeodesicRenderer:
155
- def __init__(self, engine_ref, chroma_ref, strunk_ref, valve_ref=None):
156
- self.eng = engine_ref
157
- self.projector = Projector()
158
- self.vsl_chroma = chroma_ref
159
- self.strunk_white = strunk_ref
160
- self.valve = valve_ref
161
- self.soul_dashboard = SoulDashboard(engine_ref)
162
- self.NOISE_PATTERNS = [
163
- "stabilizer:",
164
- "pid_",
165
- "flux",
166
- "phase execution",
167
- "vector collapse",
168
- "manifold",
169
- "orbit:",
170
- "update_coordinates",
171
- "active correction",
172
- "drag reduced",
173
- "voltage spiked",
174
- "live state mirror",
175
- "auto_trace",
176
- "wayfinder",
177
- ]
178
-
179
- def render_frame(
180
- self, ctx, tick: int, current_events: List[Dict]
181
- ) -> Dict[str, Any]:
182
- physics = ctx.physics
183
- bio = ctx.bio_result
184
- raw_dashboard = self.render_dashboard(ctx)
185
- colored_ui = self.vsl_chroma.modulate(raw_dashboard, physics.get("vector", {}))
186
- if self.strunk_white:
187
- clean_ui, style_log = self.strunk_white.sanitize(colored_ui)
188
- if style_log:
189
- self._punish_style_crime(style_log)
190
- else:
191
- clean_ui = colored_ui
192
- if "The system is listening." in clean_ui:
193
- clean_ui = clean_ui.replace("The system is listening.", "")
194
- structured_logs = self.compose_logs(ctx.logs, current_events, tick)
195
- return {
196
- "type": "GEODESIC_FRAME",
197
- "ui": clean_ui,
198
- "logs": structured_logs,
199
- "metrics": self.eng.get_metrics(bio.get("atp", 0.0)),
200
- }
201
-
202
- def render_dashboard(self, ctx) -> str:
203
- physics = ctx.physics
204
- mind = ctx.mind_state
205
- mind_tuple = (mind.get("lens"), mind.get("thought"), mind.get("role"))
206
- bio_data = ctx.bio_result or {}
207
- metrics = self.eng.get_metrics()
208
- bio_data["atp"] = metrics.get("atp", 0.0)
209
- data_ctx = {
210
- "health": self.eng.health,
211
- "stamina": self.eng.stamina,
212
- "bio": bio_data,
213
- "dignity": (
214
- getattr(self.eng.soul.anchor, "dignity_reserve", 100.0)
215
- if hasattr(self.eng, "soul")
216
- else 100.0
217
- ),
218
- "vectors": physics.get("vector", {}),
219
- }
220
- if hasattr(self.eng, "consultant"):
221
- data_ctx["vsl"] = {
222
- "E": self.eng.consultant.state.E,
223
- "B": self.eng.consultant.state.B,
224
- "L": getattr(self.eng.consultant.state, "L", 0.0),
225
- "O": getattr(self.eng.consultant.state, "O", 1.0),
226
- }
227
- mode = self.eng.config.get("boot_mode", "ADVENTURE").upper()
228
- current_depth = 1
229
- if hasattr(ctx, "reality_stack"):
230
- current_depth = ctx.reality_stack.current_depth
231
- if mode == "TECHNICAL":
232
- return self.projector.render_technical(physics, data_ctx, mind_tuple)
233
- elif mode == "CONVERSATION":
234
- labels = {"HP": "LINK", "STM": "SYNC", "SHOW_PHYSICS": False}
235
- return self.projector.render(
236
- {"physics": physics}, data_ctx, mind_tuple, current_depth, labels
237
- )
238
- elif mode == "CREATIVE":
239
- labels = {"HP": "INT", "STM": "FLOW", "SHOW_PHYSICS": True}
240
- return self.projector.render(
241
- {"physics": physics}, data_ctx, mind_tuple, current_depth, labels
242
- )
243
- else:
244
- labels = {"HP": "HP", "STM": "STM", "SHOW_PHYSICS": False}
245
- return self.projector.render(
246
- {"physics": physics}, data_ctx, mind_tuple, reality_depth=current_depth, labels=labels
247
- )
248
-
249
- @staticmethod
250
- def render_soul_strip(soul_ref) -> str:
251
- if not soul_ref:
252
- return ""
253
- if not soul_ref.current_obsession:
254
- return ""
255
- return (
256
- f"{Prisma.GRY}--- Obsession: {soul_ref.current_obsession} ---{Prisma.RST}"
257
- )
258
-
259
- def compose_logs(self, logs: list, events: list, _tick: int = 0) -> List[str]:
260
- all_logs = [str(l) for l in logs if l is not None]
261
- for e in events:
262
- if e and e.get("text"):
263
- all_logs.append(e["text"])
264
- if not all_logs:
265
- return []
266
- unique_logs = []
267
- seen = set()
268
- for l in all_logs:
269
- clean_l = Prisma.strip(l).lower()
270
- if any(pattern in clean_l for pattern in self.NOISE_PATTERNS):
271
- continue
272
- if l not in seen:
273
- unique_logs.append(l)
274
- seen.add(l)
275
- structured = []
276
- for log in unique_logs:
277
- if "CRITICAL" in log or "RUPTURE" in log:
278
- structured.append(f"{Prisma.RED}► {log}{Prisma.RST}")
279
- elif "Bio-Alert" in log or "SENSATION" in log:
280
- structured.append(f"{Prisma.CYN}• {log}{Prisma.RST}")
281
- elif "TOWN HALL" in log or "VITAL SIGNS" in log:
282
- structured.append(f"{Prisma.CYN}📜 {log}{Prisma.RST}")
283
- elif "PARADOX" in log:
284
- structured.append(f"{Prisma.MAG}🌷 {log}{Prisma.RST}")
285
- elif "ITEM:" in log or "GAINED" in log:
286
- structured.append(f"{Prisma.YEL}★ {log}{Prisma.RST}")
287
- else:
288
- structured.append(f"{Prisma.GRY}• {log}{Prisma.RST}")
289
- return structured
290
-
291
- def _punish_style_crime(self, log_msg):
292
- if hasattr(self.eng, "events"):
293
- self.eng.events.log(log_msg, "SYS")
294
-
295
-
296
- class CachedRenderer:
297
- def __init__(self, base_renderer):
298
- self._base = base_renderer
299
- self._cache = {"dashboard": {"hash": 0, "content": ""}, "last_tick": -1}
300
-
301
- def render_frame(self, ctx, tick: int, events: List[Dict]) -> Dict:
302
- voltage = (
303
- ctx.physics.get("voltage", 0)
304
- if isinstance(ctx.physics, dict)
305
- else ctx.physics.voltage
306
- )
307
- if voltage > 15.0 or tick != self._cache["last_tick"]:
308
- frame = self._base.render_frame(ctx, tick, events)
309
- self._cache["dashboard"]["content"] = frame["ui"]
310
- self._cache["last_tick"] = tick
311
- return frame
312
- return {
313
- "type": "GEODESIC_FRAME",
314
- "ui": self._cache["dashboard"]["content"],
315
- "logs": self._base.compose_logs(ctx.logs, events, tick),
316
- "metrics": ctx.bio_result if hasattr(ctx, "bio_result") else {},
317
- }
318
-
319
-
320
- def get_renderer(engine_ref, chroma_ref, strunk_ref, valve_ref=None, mode="STANDARD"):
321
- base = GeodesicRenderer(engine_ref, chroma_ref, strunk_ref, valve_ref)
322
- if mode == "PERFORMANCE":
323
- return CachedRenderer(base)
324
- return base
325
-
326
-
327
- class AmbiguityDial:
328
- BOARDROOM = 0
329
- WORKSHOP = 1
330
- RED_TEAM = 2
331
- PALIMPSEST = 3
332
-
333
-
334
- class TruthRenderer(GeodesicRenderer):
335
- def __init__(self, engine_ref):
336
- super().__init__(engine_ref, None, None)
337
- self.engine = engine_ref
338
- self.dial_setting = AmbiguityDial.BOARDROOM
339
-
340
- def render_truth(self, cortex_packet, council_log, trauma_cost):
341
- ui_text = cortex_packet.get("ui", "")
342
- if self.dial_setting == AmbiguityDial.BOARDROOM:
343
- return f"{Prisma.paint('--- EXECUTIVE SUMMARY ---', 'W')}\n{ui_text}\n"
344
- elif self.dial_setting == AmbiguityDial.WORKSHOP:
345
- metrics = self.engine.get_metrics()
346
- return (
347
- f"{Prisma.paint('--- ENGINEER VIEW ---', 'C')}\n"
348
- f"Confidence: {cortex_packet.get('truth_ratio', 0.95):.2%}\n"
349
- f"System Drag: {metrics['stamina']:.1f}\n"
350
- f"---------------------\n{ui_text}\n"
351
- )
352
-
353
- elif self.dial_setting == AmbiguityDial.RED_TEAM:
354
- dissent = [l for l in council_log if "CRITIC" in l or "WARN" in l]
355
- return (
356
- f"{Prisma.paint('--- RED TEAM DASHBOARD ---', 'R')}\n"
357
- f"{Prisma.paint('⚠️ ADVERSARIAL SIMULATION ACTIVE', 'Y')}\n"
358
- f"Cost of Blandness: {trauma_cost:.1f} Trauma Units\n"
359
- f"Active Conflicts:\n" + "\n".join([f" > {d}" for d in dissent]) + "\n"
360
- f"---------------------\n{ui_text}\n"
361
- )
362
- elif self.dial_setting == AmbiguityDial.PALIMPSEST:
363
- drafts = cortex_packet.get("drafts", [])
364
- layer_view = ""
365
- for i, draft in enumerate(drafts):
366
- layer_view += f"{Prisma.GRY}[Draft {i}]: {draft} {Prisma.RED}[REDACTED]{Prisma.RST}\n"
367
- return (
368
- f"{Prisma.paint('--- PALIMPSEST VIEW ---', 'M')}\n"
369
- f"{layer_view}"
370
- f"{Prisma.paint('--- FINAL SURFACE ---', 'W')}\n{ui_text}\n"
371
- )
372
- return None
373
-
374
-
375
- class PulseReader:
376
- @staticmethod
377
- def derive_mood(bio_state: Dict) -> str:
378
- chem = bio_state.get("chem", {})
379
- if chem.get("COR", 0) > 0.6:
380
- return "Defensive"
381
- if chem.get("DA", 0) > 0.6:
382
- return "Manic"
383
- if chem.get("OXY", 0) > 0.6:
384
- return "Affectionate"
385
- atp = bio_state.get("mito", {}).get("atp", 100)
386
- if atp < 20:
387
- return "Exhausted"
388
- return "Neutral"
389
-
390
- @staticmethod
391
- def analyze_voltage(voltage: float) -> Tuple[str, str]:
392
- if voltage > 20.0:
393
- return "CRITICAL", "⚡"
394
- if voltage > 15.0:
395
- return "HIGH", "🔥"
396
- if voltage < 5.0:
397
- return "LOW", "❄️"
398
- return "NOMINAL", "🟢"
399
-
400
-
401
- class SoulDashboard:
402
- def __init__(self, engine_ref):
403
- self.eng = engine_ref
404
-
405
- def render(self) -> str:
406
- if not hasattr(self.eng, "soul") or not self.eng.soul:
407
- return ""
408
- if not hasattr(self.eng.soul, "anchor"):
409
- return f"{Prisma.GRY}[SOUL DETECTED - ANCHOR LOST]{Prisma.RST}"
410
- anchor = self.eng.soul.anchor
411
- soul = self.eng.soul
412
- dig = anchor.dignity_reserve
413
- if dig > 80:
414
- color = Prisma.GRN
415
- elif dig > 30:
416
- color = Prisma.OCHRE
417
- else:
418
- color = Prisma.RED
419
- filled = int(dig / 5)
420
- bar_str = f"{color}{'█' * filled}{Prisma.GRY}{'░' * (20 - filled)}{Prisma.RST}"
421
- lock_status = ""
422
- if anchor.agency_lock:
423
- lock_status = f" {Prisma.RED}[🔒 AGENCY LOCKED]{Prisma.RST}"
424
- elif dig < 30:
425
- lock_status = f" {Prisma.OCHRE}[⚠ FADING]{Prisma.RST}"
426
- arch = soul.archetype
427
- tenure = soul.archetype_tenure
428
- tenure_color = Prisma.GRY
429
- if tenure > 5:
430
- tenure_color = Prisma.OCHRE
431
- if tenure > 8:
432
- tenure_color = Prisma.RED
433
- arch_display = (
434
- f"{Prisma.CYN}{arch}{Prisma.RST} ({tenure_color}T:{tenure}{Prisma.RST})"
435
- )
436
- pet_icon = " 🐕" if (dig < 50 and not anchor.agency_lock) else ""
437
- muse = soul.current_obsession if soul.current_obsession else "Void"
438
- line1 = f"SOUL: {bar_str} {int(dig)}%{lock_status}{pet_icon}"
439
- line2 = f" DRIVER: {arch_display} MUSE: {Prisma.VIOLET}{muse}{Prisma.RST}"
440
- return f"{line1}\n{line2}"
441
-
442
-
443
- class CycleReporter:
444
- def __init__(self, engine_ref):
445
- self.eng = engine_ref
446
- self.vsl_chroma = ChromaScope()
447
- self.renderer = None
448
- self.current_mode = None
449
- self.renderers = {}
450
- self.switch_renderer("STANDARD")
451
-
452
- def switch_renderer(self, mode: str):
453
- if self.current_mode == mode and self.renderer:
454
- return
455
- if mode in self.renderers:
456
- self.renderer = self.renderers[mode]
457
- self.current_mode = mode
458
- return
459
- strunk_instance = None
460
- if hasattr(self.eng, "village") and isinstance(self.eng.village, dict):
461
- strunk_instance = self.eng.village.get("bureau")
462
- self.renderer = get_renderer(
463
- self.eng,
464
- self.vsl_chroma,
465
- strunk_instance,
466
- getattr(self, "valve", None),
467
- mode=mode,
468
- )
469
- self.renderers[mode] = self.renderer
470
- self.current_mode = mode
471
-
472
- def render_snapshot(self, ctx) -> Dict[str, Any]:
473
- try:
474
- if ctx.refusal_triggered and ctx.refusal_packet:
475
- return ctx.refusal_packet
476
- if ctx.is_bureaucratic:
477
- return self._package_bureaucracy(ctx)
478
- self._inject_diagnostics(ctx)
479
- self._inject_flux_readout(ctx)
480
- self._inject_somatic_pulse(ctx)
481
- return self.renderer.render_frame(
482
- ctx, self.eng.tick_count, self.eng.events.flush()
483
- )
484
- except Exception as e:
485
- return {
486
- "type": "CRITICAL_RENDER_FAIL",
487
- "ui": f"{Prisma.RED}RENDERER CRASH: {e}{Prisma.RST}",
488
- "logs": ctx.logs,
489
- "metrics": self.eng.get_metrics(),
490
- }
491
-
492
- def _inject_diagnostics(self, ctx):
493
- if hasattr(self.eng, "system_health"):
494
- fb = self.eng.system_health.flush_feedback()
495
- for h in fb["hints"]:
496
- ctx.logs.append(f"{Prisma.CYN}💡 {h}{Prisma.RST}")
497
- for w in fb["warnings"]:
498
- ctx.logs.append(f"{Prisma.OCHRE}⚠️ {w}{Prisma.RST}")
499
-
500
- def _inject_somatic_pulse(self, ctx):
501
- if not hasattr(self.eng, "somatic"):
502
- return
503
- qualia = self.eng.somatic.get_current_qualia(getattr(ctx, "last_impulse", None))
504
- ctx.logs.insert(
505
- 0, f"{Prisma.GRY}({qualia.internal_monologue_hint}){Prisma.RST}"
506
- )
507
- ctx.logs.insert(
508
- 0,
509
- f"{qualia.color_code}♦ SENSATION: {qualia.somatic_sensation} [{qualia.tone}]{Prisma.RST}",
510
- )
511
-
512
- @staticmethod
513
- def _inject_flux_readout(ctx):
514
- if not ctx.flux_log:
515
- return
516
- significant = []
517
- for e in ctx.flux_log[-5:]:
518
- d = abs(e["delta"])
519
- if d < 1.0 and "PID" in e["reason"]:
520
- continue
521
- icon = "⚡" if e["metric"].upper() == "VOLTAGE" else "⚓"
522
- color = Prisma.GRN if e["delta"] > 0 else Prisma.RED
523
- arrow = "▲" if e["delta"] > 0 else "▼"
524
- significant.append(
525
- f"{Prisma.GRY}[FLUX]{Prisma.RST} {icon} {e['metric'][:3].upper()} {color}{arrow} {d:.1f}{Prisma.RST} ({e['reason']})"
526
- )
527
- if significant:
528
- ctx.logs.insert(0, "")
529
- for line in reversed(significant):
530
- ctx.logs.insert(0, line)
531
-
532
- def _package_bureaucracy(self, ctx):
533
- if not self.eng.bureau:
534
- return None
535
- if ctx.is_bureaucratic or ctx.bureau_ui:
536
- base = (
537
- self.renderer.base_renderer
538
- if hasattr(self.renderer, "base_renderer")
539
- else self.renderer
540
- )
541
- bio_res = ctx.bio_result or {}
542
- return {
543
- "type": "BUREAUCRACY",
544
- "ui": ctx.bureau_ui,
545
- "logs": base.compose_logs(
546
- ctx.logs, self.eng.events.flush(), self.eng.tick_count
547
- ),
548
- "metrics": self.eng.get_metrics(bio_res.get("atp", 0.0)),
549
- }
550
- return None