dsh-biocore 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/lib/index.js +170 -27
  2. package/package.json +1 -1
  3. package/python/biocore_runtime/pipeline.py +42 -0
  4. package/python/biocore_runtime/rerank.py +201 -0
  5. package/python/mindbase/__init__.py +18 -0
  6. package/python/mindbase/__main__.py +3 -0
  7. package/python/mindbase/actions.py +56 -0
  8. package/python/mindbase/active_inference.py +54 -0
  9. package/python/mindbase/addressing.py +69 -0
  10. package/python/mindbase/affect.py +86 -0
  11. package/python/mindbase/affective.py +111 -0
  12. package/python/mindbase/allostasis.py +28 -0
  13. package/python/mindbase/appraisal.py +101 -0
  14. package/python/mindbase/attachment.py +49 -0
  15. package/python/mindbase/attention.py +30 -0
  16. package/python/mindbase/autonomy.py +81 -0
  17. package/python/mindbase/autonomy_bench.py +251 -0
  18. package/python/mindbase/autonomy_evolve.py +342 -0
  19. package/python/mindbase/autonomy_loop.py +65 -0
  20. package/python/mindbase/autonomy_meta.py +91 -0
  21. package/python/mindbase/base_only.py +28 -0
  22. package/python/mindbase/benchmark.py +61 -0
  23. package/python/mindbase/bio_adaptation.py +274 -0
  24. package/python/mindbase/bio_noise.py +39 -0
  25. package/python/mindbase/bio_semantic.py +138 -0
  26. package/python/mindbase/bm25.py +46 -0
  27. package/python/mindbase/bootstrap.py +256 -0
  28. package/python/mindbase/bootstrap_real.py +231 -0
  29. package/python/mindbase/brain.py +178 -0
  30. package/python/mindbase/care.py +78 -0
  31. package/python/mindbase/chaos_search.py +79 -0
  32. package/python/mindbase/character_profile.py +33 -0
  33. package/python/mindbase/circadian.py +38 -0
  34. package/python/mindbase/circuit.py +235 -0
  35. package/python/mindbase/clock.py +53 -0
  36. package/python/mindbase/companion_runtime.py +366 -0
  37. package/python/mindbase/companion_train.py +126 -0
  38. package/python/mindbase/config.py +66 -0
  39. package/python/mindbase/connection_state.py +76 -0
  40. package/python/mindbase/connectome_prior.py +35 -0
  41. package/python/mindbase/connectome_world.py +158 -0
  42. package/python/mindbase/constructs.py +88 -0
  43. package/python/mindbase/context_builder.py +58 -0
  44. package/python/mindbase/critical.py +36 -0
  45. package/python/mindbase/criticality.py +123 -0
  46. package/python/mindbase/defaults.py +27 -0
  47. package/python/mindbase/demo.py +163 -0
  48. package/python/mindbase/diary.py +116 -0
  49. package/python/mindbase/diary_service.py +40 -0
  50. package/python/mindbase/digital_prior.py +37 -0
  51. package/python/mindbase/diversity.py +110 -0
  52. package/python/mindbase/drives.py +106 -0
  53. package/python/mindbase/embedding.py +132 -0
  54. package/python/mindbase/embedding_memory.py +74 -0
  55. package/python/mindbase/embodiment.py +83 -0
  56. package/python/mindbase/emotion_calibration.py +39 -0
  57. package/python/mindbase/emotion_calibrator.py +50 -0
  58. package/python/mindbase/emotion_core.py +113 -0
  59. package/python/mindbase/emotion_dynamics.py +104 -0
  60. package/python/mindbase/emotion_intent.py +164 -0
  61. package/python/mindbase/emotion_layer.py +200 -0
  62. package/python/mindbase/emotion_schema.py +92 -0
  63. package/python/mindbase/engine.py +781 -0
  64. package/python/mindbase/episode_log.py +90 -0
  65. package/python/mindbase/evaluation.py +493 -0
  66. package/python/mindbase/event_appraisal.py +84 -0
  67. package/python/mindbase/evolution.py +77 -0
  68. package/python/mindbase/evolve_offline.py +232 -0
  69. package/python/mindbase/experiments.py +358 -0
  70. package/python/mindbase/expression.py +54 -0
  71. package/python/mindbase/external_brain.py +157 -0
  72. package/python/mindbase/fly_mb.py +159 -0
  73. package/python/mindbase/fly_tasks.py +45 -0
  74. package/python/mindbase/forage.py +179 -0
  75. package/python/mindbase/goal_generator.py +98 -0
  76. package/python/mindbase/goals.py +153 -0
  77. package/python/mindbase/grid_world.py +123 -0
  78. package/python/mindbase/group_autonomy.py +92 -0
  79. package/python/mindbase/group_context.py +67 -0
  80. package/python/mindbase/homeostatic.py +71 -0
  81. package/python/mindbase/homeostatic_action.py +38 -0
  82. package/python/mindbase/human_standard.py +53 -0
  83. package/python/mindbase/identity_suite.py +50 -0
  84. package/python/mindbase/image_context.py +27 -0
  85. package/python/mindbase/impression.py +119 -0
  86. package/python/mindbase/initiative_quota.py +145 -0
  87. package/python/mindbase/insight.py +51 -0
  88. package/python/mindbase/intelligence_search.py +108 -0
  89. package/python/mindbase/intention.py +76 -0
  90. package/python/mindbase/interaction_log.py +30 -0
  91. package/python/mindbase/interoception.py +67 -0
  92. package/python/mindbase/invariants.py +53 -0
  93. package/python/mindbase/iteration.py +29 -0
  94. package/python/mindbase/layered_memory.py +170 -0
  95. package/python/mindbase/layers/__init__.py +18 -0
  96. package/python/mindbase/layers/l0_substrate.py +39 -0
  97. package/python/mindbase/layers/l1_homeostasis.py +6 -0
  98. package/python/mindbase/layers/l2_affect.py +6 -0
  99. package/python/mindbase/layers/l3_attention.py +6 -0
  100. package/python/mindbase/layers/l4_learning.py +17 -0
  101. package/python/mindbase/layers/l5_self_social.py +35 -0
  102. package/python/mindbase/layers/l6_expression.py +23 -0
  103. package/python/mindbase/layers/l7_evaluation.py +45 -0
  104. package/python/mindbase/learner.py +196 -0
  105. package/python/mindbase/lexicon.py +33 -0
  106. package/python/mindbase/life_state.py +169 -0
  107. package/python/mindbase/lifecycle.py +87 -0
  108. package/python/mindbase/liquid_readout.py +48 -0
  109. package/python/mindbase/llm_adapter.py +233 -0
  110. package/python/mindbase/llm_cache.py +77 -0
  111. package/python/mindbase/llm_gate.py +85 -0
  112. package/python/mindbase/llm_openai.py +130 -0
  113. package/python/mindbase/llm_setup.py +99 -0
  114. package/python/mindbase/longrun.py +83 -0
  115. package/python/mindbase/longterm_memory.py +606 -0
  116. package/python/mindbase/mb/__init__.py +14 -0
  117. package/python/mindbase/mb/apl.py +22 -0
  118. package/python/mindbase/mb/dan.py +14 -0
  119. package/python/mindbase/mb/habituation.py +27 -0
  120. package/python/mindbase/mb/kc.py +28 -0
  121. package/python/mindbase/mb/mbon.py +23 -0
  122. package/python/mindbase/mb/mushroom_body.py +116 -0
  123. package/python/mindbase/memory.py +201 -0
  124. package/python/mindbase/memory_framework.py +158 -0
  125. package/python/mindbase/memory_retriever.py +110 -0
  126. package/python/mindbase/memory_summarizer.py +177 -0
  127. package/python/mindbase/memory_task.py +32 -0
  128. package/python/mindbase/memory_trace.py +46 -0
  129. package/python/mindbase/meta.py +32 -0
  130. package/python/mindbase/motivation.py +31 -0
  131. package/python/mindbase/multi_session.py +19 -0
  132. package/python/mindbase/narrative.py +87 -0
  133. package/python/mindbase/needs.py +77 -0
  134. package/python/mindbase/neural.py +45 -0
  135. package/python/mindbase/neuron_models.py +134 -0
  136. package/python/mindbase/noise.py +309 -0
  137. package/python/mindbase/one_on_one.py +60 -0
  138. package/python/mindbase/online_iteration.py +63 -0
  139. package/python/mindbase/ostracism.py +35 -0
  140. package/python/mindbase/parallel_eval.py +60 -0
  141. package/python/mindbase/parallel_qd.py +64 -0
  142. package/python/mindbase/persona.py +221 -0
  143. package/python/mindbase/persona_ab.py +64 -0
  144. package/python/mindbase/persona_bridge.py +129 -0
  145. package/python/mindbase/persona_compile.py +34 -0
  146. package/python/mindbase/persona_dsh.py +120 -0
  147. package/python/mindbase/persona_learner.py +157 -0
  148. package/python/mindbase/physiology.py +197 -0
  149. package/python/mindbase/population_lifecycle.py +83 -0
  150. package/python/mindbase/preferences.py +50 -0
  151. package/python/mindbase/proactive_agent.py +274 -0
  152. package/python/mindbase/proactive_gate.py +53 -0
  153. package/python/mindbase/proactive_group.py +119 -0
  154. package/python/mindbase/proactive_policy.py +422 -0
  155. package/python/mindbase/proactive_profile.py +196 -0
  156. package/python/mindbase/proactive_timing.py +28 -0
  157. package/python/mindbase/pyramid_stages.py +61 -0
  158. package/python/mindbase/quantum.py +132 -0
  159. package/python/mindbase/quantum_chaos.py +98 -0
  160. package/python/mindbase/reflection.py +68 -0
  161. package/python/mindbase/regulation_posture.py +50 -0
  162. package/python/mindbase/relationship_session.py +431 -0
  163. package/python/mindbase/relationship_suite.py +45 -0
  164. package/python/mindbase/relationships.py +70 -0
  165. package/python/mindbase/replay.py +22 -0
  166. package/python/mindbase/reply_diversity.py +53 -0
  167. package/python/mindbase/reply_gate.py +52 -0
  168. package/python/mindbase/rerank.py +41 -0
  169. package/python/mindbase/rerank_local.py +46 -0
  170. package/python/mindbase/ripple.py +187 -0
  171. package/python/mindbase/robust_search.py +68 -0
  172. package/python/mindbase/runtime.py +113 -0
  173. package/python/mindbase/scoped_identity.py +116 -0
  174. package/python/mindbase/self_insight.py +51 -0
  175. package/python/mindbase/self_model.py +116 -0
  176. package/python/mindbase/selftest.py +118 -0
  177. package/python/mindbase/semantic_memory.py +108 -0
  178. package/python/mindbase/session_store.py +175 -0
  179. package/python/mindbase/session_window.py +31 -0
  180. package/python/mindbase/shadow_eval.py +42 -0
  181. package/python/mindbase/sim_env.py +86 -0
  182. package/python/mindbase/social.py +138 -0
  183. package/python/mindbase/social_constraint.py +141 -0
  184. package/python/mindbase/social_feedback.py +95 -0
  185. package/python/mindbase/social_norm.py +225 -0
  186. package/python/mindbase/spiking_reservoir.py +204 -0
  187. package/python/mindbase/spontaneity.py +40 -0
  188. package/python/mindbase/story_loop.py +203 -0
  189. package/python/mindbase/survival_gauntlet.py +128 -0
  190. package/python/mindbase/symbolic.py +170 -0
  191. package/python/mindbase/teacher.py +244 -0
  192. package/python/mindbase/theory.py +42 -0
  193. package/python/mindbase/theory_of_mind.py +98 -0
  194. package/python/mindbase/translation_layer.py +80 -0
  195. package/python/mindbase/turn_eval.py +52 -0
  196. package/python/mindbase/types.py +78 -0
  197. package/python/mindbase/uncertainty_field.py +61 -0
  198. package/python/mindbase/user_loop.py +45 -0
  199. package/python/mindbase/user_profile.py +73 -0
  200. package/python/mindbase/value_model.py +64 -0
  201. package/python/mindbase/values.py +102 -0
  202. package/python/mindbase/vector_store.py +78 -0
  203. package/python/mindbase/viability.py +41 -0
  204. package/python/mindbase/virtual_body.py +90 -0
  205. package/python/mindbase/will.py +60 -0
  206. package/python/mindbase/working_memory.py +32 -0
  207. package/python/mindbase/workspace.py +55 -0
  208. package/ui/panel.css +16 -5
  209. package/ui/panel.html +25 -1
  210. package/ui/panel.js +57 -15
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Dict
5
+
6
+ from .digital_prior import FlyPrior
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class ConnectomePrior(FlyPrior):
11
+ """Compressed structural prior from digital-fly connectomics.
12
+
13
+ cell_types from MaleCNS 2026; MBON/DAN counts are approximate and used only
14
+ as a scale, not as an exact reconstruction.
15
+ """
16
+ cell_types: int = 11_710
17
+ mb_compartments: int = 15
18
+ mbon_count: int = 34
19
+ dan_count: int = 130
20
+
21
+ def summary(self) -> Dict[str, object]:
22
+ base = super().summary()
23
+ base.update(
24
+ {
25
+ "cell_types": self.cell_types,
26
+ "mb_compartments": self.mb_compartments,
27
+ "mbon_count": self.mbon_count,
28
+ "dan_count": self.dan_count,
29
+ "note": "MBON/DAN counts are approximate, used as scale only",
30
+ }
31
+ )
32
+ return base
33
+
34
+
35
+ CONNECTOME = ConnectomePrior()
@@ -0,0 +1,158 @@
1
+ """Connectome-constrained world model prototype.
2
+
3
+ A sparse recurrent reservoir (connectome-like wiring prior) + self-supervised
4
+ linear readout: predict the next sensory/state vector. This is a small,
5
+ honest prototype, not a whole-brain emulation.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import random
10
+ from typing import Dict, List, Sequence
11
+
12
+ import numpy as np
13
+
14
+
15
+ class ConnectomeWorldModel:
16
+ def __init__(self, n_neurons: int = 128, n_input: int = 6,
17
+ sparsity: float = 0.08, spectral_radius: float = 0.9,
18
+ seed: int = 1, n_action: int = 6,
19
+ use_action_effects: bool = False):
20
+ self.n = int(n_neurons)
21
+ self.n_input = int(n_input)
22
+ self.n_action = int(n_action)
23
+ self.use_action_effects = bool(use_action_effects)
24
+ self.action_dim = self.n_input if self.use_action_effects else self.n_action
25
+ self.action_effects = np.zeros((self.n_action, self.n_input))
26
+ self.rng = np.random.default_rng(int(seed))
27
+ w = self.rng.normal(0.0, 1.0, size=(self.n, self.n))
28
+ mask = self.rng.random((self.n, self.n)) < float(sparsity)
29
+ w = w * mask
30
+ # scale spectral radius for stable echo-state dynamics
31
+ try:
32
+ vals = np.linalg.eigvals(w)
33
+ radius = float(np.max(np.abs(vals))) if len(vals) else 1.0
34
+ w = w * (float(spectral_radius) / max(1e-9, radius))
35
+ except Exception:
36
+ w = w / max(1e-9, np.linalg.norm(w, 2))
37
+ self.W = w
38
+ self.B = self.rng.normal(0.0, 0.2, size=(self.n, self.n_input + self.action_dim))
39
+ self.C = np.zeros((self.n, self.n_input))
40
+ self.h = np.zeros(self.n)
41
+
42
+ def _step(self, sensory: np.ndarray, action: int | None = None) -> np.ndarray:
43
+ s = np.asarray(sensory, dtype=float).reshape(-1)
44
+ if s.shape[0] != self.n_input:
45
+ s = np.resize(s, self.n_input)
46
+ a = np.zeros(self.action_dim)
47
+ if action is not None:
48
+ ai = int(action) % self.n_action
49
+ if self.use_action_effects:
50
+ a = self.action_effects[ai].copy()
51
+ else:
52
+ a[ai] = 1.0
53
+ inp = np.concatenate([s, a])
54
+ self.h = np.tanh(self.W @ self.h + self.B @ inp)
55
+ return self.h
56
+
57
+ def predict_next(self, sensory: np.ndarray, action: int | None = None) -> np.ndarray:
58
+ h = self._step(sensory, action)
59
+ return np.asarray(sensory, dtype=float).reshape(-1)[:self.n_input] + h @ self.C
60
+
61
+ def fit(self, sequences: Sequence[Sequence[np.ndarray]], ridge: float = 1e-3) -> Dict[str, float]:
62
+ X: List[np.ndarray] = []
63
+ Y: List[np.ndarray] = []
64
+ for seq in sequences:
65
+ self.h = np.zeros(self.n)
66
+ prev = None
67
+ for s in seq:
68
+ s = np.asarray(s, dtype=float)
69
+ if prev is not None:
70
+ X.append(self.h.copy())
71
+ Y.append(s - prev)
72
+ self._step(s)
73
+ prev = s
74
+ if not X:
75
+ return {"n": 0, "train_mse": 0.0}
76
+ Xm = np.asarray(X)
77
+ Ym = np.asarray(Y)
78
+ # ridge: C^T = (X^T X + λI)^-1 X^T Y
79
+ A = Xm.T @ Xm + float(ridge) * np.eye(self.n)
80
+ self.C = np.linalg.solve(A, Xm.T @ Ym)
81
+ pred = Xm @ self.C
82
+ return {"n": int(len(X)), "train_mse": round(float(np.mean((pred - Ym) ** 2)), 6)}
83
+
84
+ def evaluate(self, sequences: Sequence[Sequence[np.ndarray]]) -> Dict[str, float]:
85
+ errs = []
86
+ base = []
87
+ for seq in sequences:
88
+ self.h = np.zeros(self.n)
89
+ prev = None
90
+ for s in seq:
91
+ s = np.asarray(s, dtype=float)
92
+ if prev is not None:
93
+ pred = prev + (self.h @ self.C)
94
+ errs.append(float(np.mean((pred - s) ** 2)))
95
+ base.append(float(np.mean((prev - s) ** 2)))
96
+ self._step(s)
97
+ prev = s
98
+ return {"n": len(errs),
99
+ "model_mse": round(float(np.mean(errs)) if errs else 0.0, 6),
100
+ "persistence_mse": round(float(np.mean(base)) if base else 0.0, 6)}
101
+
102
+
103
+ def fit_action(self, sequences: Sequence[Sequence[tuple]], ridge: float = 1e-3) -> Dict[str, float]:
104
+ if self.use_action_effects:
105
+ sums = np.zeros((self.n_action, self.n_input))
106
+ counts = np.zeros(self.n_action)
107
+ for seq in sequences:
108
+ for (s0, action), (s1, _a1) in zip(seq[:-1], seq[1:]):
109
+ ai = int(action) % self.n_action
110
+ sums[ai] += np.asarray(s1, dtype=float) - np.asarray(s0, dtype=float)
111
+ counts[ai] += 1
112
+ for i in range(self.n_action):
113
+ if counts[i] > 0:
114
+ self.action_effects[i] = sums[i] / counts[i]
115
+ X: List[np.ndarray] = []
116
+ Y: List[np.ndarray] = []
117
+ for seq in sequences:
118
+ self.h = np.zeros(self.n)
119
+ for (s, action), nxt in zip(seq[:-1], seq[1:]):
120
+ s_arr = np.asarray(s, dtype=float)
121
+ X.append(self.h.copy())
122
+ Y.append(np.asarray(nxt[0], dtype=float) - s_arr)
123
+ self._step(s_arr, int(action))
124
+ if not X:
125
+ return {"n": 0, "train_mse": 0.0}
126
+ Xm = np.asarray(X)
127
+ Ym = np.asarray(Y)
128
+ A = Xm.T @ Xm + float(ridge) * np.eye(self.n)
129
+ self.C = np.linalg.solve(A, Xm.T @ Ym)
130
+ pred = Xm @ self.C
131
+ return {"n": int(len(X)), "train_mse": round(float(np.mean((pred - Ym) ** 2)), 6)}
132
+
133
+ def evaluate_action(self, sequences: Sequence[Sequence[tuple]]) -> Dict[str, float]:
134
+ errs = []
135
+ base = []
136
+ for seq in sequences:
137
+ self.h = np.zeros(self.n)
138
+ for (s, action), nxt in zip(seq[:-1], seq[1:]):
139
+ s_arr = np.asarray(s, dtype=float)
140
+ nxt_arr = np.asarray(nxt[0], dtype=float)
141
+ pred = s_arr + (self.h @ self.C)
142
+ errs.append(float(np.mean((pred - nxt_arr) ** 2)))
143
+ base.append(float(np.mean((s_arr - nxt_arr) ** 2)))
144
+ self._step(s_arr, int(action))
145
+ return {"n": len(errs),
146
+ "model_mse": round(float(np.mean(errs)) if errs else 0.0, 6),
147
+ "persistence_mse": round(float(np.mean(base)) if base else 0.0, 6)}
148
+
149
+
150
+ def sequences_from_rows(rows: Sequence[Dict[str, object]], n_input: int = 6) -> List[np.ndarray]:
151
+ out = []
152
+ for r in rows:
153
+ need = float((r.get("needs") or 0.0))
154
+ vec = [float(r.get("energy", 0.0)), float(r.get("social", 0.0)),
155
+ float(r.get("stress", 0.0)), float(r.get("damage", 0.0)),
156
+ float(r.get("viability", 1.0)), need]
157
+ out.append(np.asarray(vec[:n_input], dtype=float))
158
+ return out
@@ -0,0 +1,88 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Dict, Optional, Tuple
6
+
7
+ from .noise import clip
8
+
9
+ DEFAULT_PATH = Path(__file__).with_name("constructs.json")
10
+
11
+ BOUNDS: Dict[str, Tuple[float, float]] = {
12
+ "O": (0.0, 1.0),
13
+ "C": (0.0, 1.0),
14
+ "E": (0.0, 1.0),
15
+ "A": (0.0, 1.0),
16
+ "N": (0.0, 1.0),
17
+ "baseline_v": (-1.0, 1.0),
18
+ "baseline_a": (0.0, 1.0),
19
+ "stress_reactivity": (0.0, 1.0),
20
+ "recovery_rate": (0.0, 1.0),
21
+ "social_baseline": (0.0, 1.0),
22
+ "energy_baseline": (0.0, 1.0),
23
+ "curiosity_baseline": (0.0, 1.0),
24
+ "safety_baseline": (0.0, 1.0),
25
+ "da_baseline": (0.0, 1.0),
26
+ "oa_baseline": (0.0, 1.0),
27
+ "ht_baseline": (0.0, 1.0),
28
+ "autonomy_gain": (0.0, 1.5),
29
+ "learning_rate": (0.01, 0.12),
30
+ "circadian_phase": (-0.10, 0.10),
31
+ }
32
+
33
+
34
+ class ConstructRegistry:
35
+ """Declarative construct -> numeric deltas.
36
+
37
+ Definitions are data (JSON), not if/else branches. Register a new construct
38
+ at runtime without touching the engine.
39
+ """
40
+
41
+ def __init__(self, path: Optional[Path] = None, definitions: Optional[Dict[str, dict]] = None):
42
+ self.constructs: Dict[str, dict] = {}
43
+ target = path or DEFAULT_PATH
44
+ if target.exists():
45
+ self.load(target)
46
+ if definitions:
47
+ self.register_many(definitions)
48
+
49
+ def load(self, path: Path) -> None:
50
+ data = json.loads(Path(path).read_text(encoding="utf-8"))
51
+ self.register_many(data)
52
+
53
+ def register(self, name: str, definition: dict) -> None:
54
+ if "deltas" not in definition or not isinstance(definition["deltas"], dict):
55
+ raise ValueError(f"construct {name} needs a deltas dict")
56
+ self.constructs[name] = dict(definition)
57
+
58
+ def register_many(self, definitions: Dict[str, dict]) -> None:
59
+ for name, definition in definitions.items():
60
+ self.register(name, definition)
61
+
62
+ def has(self, name: str) -> bool:
63
+ return name in self.constructs
64
+
65
+ def apply(self, numbers: Dict[str, float], scores: Dict[str, float]) -> Tuple[Dict[str, float], Dict[str, float]]:
66
+ out = dict(numbers)
67
+ extra: Dict[str, float] = {}
68
+ for name, raw_score in scores.items():
69
+ definition = self.constructs.get(name)
70
+ if definition is None:
71
+ continue
72
+ score = clip(float(raw_score), 0.0, 1.0)
73
+ for target, delta in definition["deltas"].items():
74
+ amount = score * float(delta)
75
+ if target.startswith("extra."):
76
+ key = target.split(".", 1)[1]
77
+ extra[key] = extra.get(key, 0.5) + amount
78
+ elif target in out:
79
+ out[target] = out[target] + amount
80
+ for key, (lo, hi) in BOUNDS.items():
81
+ if key in out:
82
+ out[key] = clip(float(out[key]), lo, hi)
83
+ for key in list(extra):
84
+ extra[key] = clip(extra[key], 0.0, 1.0)
85
+ return out, extra
86
+
87
+ def snapshot(self) -> Dict[str, dict]:
88
+ return {name: {"label": d.get("label", name), "description": d.get("description", "")} for name, d in self.constructs.items()}
@@ -0,0 +1,58 @@
1
+ """Prioritized context blocks and a numeric reflection trigger.
2
+
3
+ MemGPT/Letta-style core blocks + Generative-Agents-style reflection threshold.
4
+ No LLM call in the decision; the LLM is only used when the trigger fires.
5
+ """
6
+ from __future__ import annotations
7
+
8
+
9
+ class ContextBuilder:
10
+ def __init__(self, max_chars: int = 1400):
11
+ self.max_chars = int(max_chars)
12
+ self.last_blocks = {}
13
+
14
+ def build(self, facts=None, loops=None, recent: str = "") -> str:
15
+ facts = [str(x).strip() for x in (facts or []) if str(x).strip()]
16
+ loops = [str(x).strip() for x in (loops or []) if str(x).strip()]
17
+ blocks = []
18
+ used = 0
19
+ def add(label, items):
20
+ nonlocal used
21
+ if not items:
22
+ return
23
+ body = ";".join(dict.fromkeys(items))
24
+ text = label + ":" + body
25
+ if used + len(text) > self.max_chars:
26
+ remain = max(0, self.max_chars - used)
27
+ if remain < 20:
28
+ return
29
+ text = text[:remain]
30
+ blocks.append(text)
31
+ used += len(text)
32
+ add("稳定事实", facts)
33
+ add("未闭环", loops)
34
+ if recent:
35
+ add("近期", [recent])
36
+ self.last_blocks = {"facts": len(facts), "loops": len(loops), "chars": used}
37
+ return "\n".join(blocks)
38
+
39
+
40
+ class ReflectionTrigger:
41
+ def __init__(self, threshold: float = 8.0, min_interval_s: float = 1800.0):
42
+ self.threshold = float(threshold)
43
+ self.min_interval_s = float(min_interval_s)
44
+ self.accum = 0.0
45
+ self.last_at = 0.0
46
+
47
+ def note(self, importance: float) -> None:
48
+ try:
49
+ self.accum += max(0.0, min(1.0, float(importance)))
50
+ except Exception:
51
+ pass
52
+
53
+ def due(self, now: float) -> bool:
54
+ return self.accum >= self.threshold and (float(now) - self.last_at) >= self.min_interval_s
55
+
56
+ def consume(self, now: float) -> None:
57
+ self.accum = 0.0
58
+ self.last_at = float(now)
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ import numpy as np
4
+
5
+
6
+ class CriticalDynamics:
7
+ """Recurrent dynamics near the edge of chaos (spectral radius ~= 1)."""
8
+
9
+ def __init__(self, seed: int = 1, n: int = 64):
10
+ self.rng = np.random.default_rng(seed)
11
+ self.n = n
12
+ self.w = self.rng.normal(0, 1.0 / np.sqrt(n), (n, n))
13
+ radius = max(1e-6, float(np.max(np.abs(np.linalg.eigvals(self.w)))))
14
+ self.w *= 1.0 / radius
15
+ self.x = self.rng.normal(0, 0.1, n)
16
+ self.history = []
17
+
18
+ def step(self, external: float = 0.0) -> dict:
19
+ noise = self.rng.normal(0, 0.01, self.n)
20
+ self.x = np.tanh(self.w @ self.x + 0.4 * float(external) + noise)
21
+ self.history.append(float(np.mean(self.x)))
22
+ self.history = self.history[-200:]
23
+ self.metastability = float(np.std(self.history)) if len(self.history) > 5 else 0.0
24
+ return {
25
+ "mean": round(float(np.mean(self.x)), 4),
26
+ "variance": round(float(np.var(self.x)), 4),
27
+ "metastability": round(float(np.std(self.history)), 4) if len(self.history) > 5 else 0.0,
28
+ "saturation": round(float(np.mean(np.abs(self.x) > 0.95)), 4),
29
+ }
30
+
31
+ def flexibility(self) -> float:
32
+ # metastability normalized for downstream use
33
+ return round(min(1.0, max(0.0, float(self.step.__self__.history and 0 or 0))), 4) if False else round(min(1.0, abs(float(getattr(self, "metastability", 0.0)))), 4)
34
+
35
+ def spectral_radius(self) -> float:
36
+ return round(float(np.max(np.abs(np.linalg.eigvals(self.w)))), 4)
@@ -0,0 +1,123 @@
1
+ """Criticality meters and controllers for endogenous noise.
2
+
3
+ Operational proxies only: branching ratio, avalanche distribution, metastability.
4
+ These are *not* claims of consciousness; they measure structured spontaneous activity.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import math
9
+ from collections import deque
10
+ from typing import Deque, Dict, List, Optional
11
+
12
+
13
+ class BranchingRatio:
14
+ """Estimate sigma = E[n_{t+1} / n_t] for active steps (n_t > 0)."""
15
+
16
+ def __init__(self, window: int = 256):
17
+ self.window = max(8, int(window))
18
+ self.history: Deque[float] = deque(maxlen=self.window)
19
+ self.prev = 0
20
+
21
+ def reset(self) -> None:
22
+ self.history.clear()
23
+ self.prev = 0
24
+
25
+ def update(self, activity: int) -> float:
26
+ n = max(0, int(activity))
27
+ if self.prev > 0:
28
+ self.history.append(float(n) / float(self.prev))
29
+ self.prev = n
30
+ return self.sigma
31
+
32
+ @property
33
+ def sigma(self) -> float:
34
+ if not self.history:
35
+ return 0.0
36
+ return float(sum(self.history) / len(self.history))
37
+
38
+ def score(self, target: float = 1.0) -> float:
39
+ if not self.history:
40
+ return 0.0
41
+ return max(0.0, 1.0 - min(1.0, abs(self.sigma - float(target))))
42
+
43
+
44
+ class AvalancheMeter:
45
+ """Collect activity counts and fit a crude power-law slope on log bins."""
46
+
47
+ def __init__(self, capacity: int = 2048):
48
+ self.counts: Deque[int] = deque(maxlen=max(32, int(capacity)))
49
+
50
+ def reset(self) -> None:
51
+ self.counts.clear()
52
+
53
+ def update(self, activity: int) -> None:
54
+ self.counts.append(max(0, int(activity)))
55
+
56
+ def exponent(self) -> float:
57
+ vals = [x for x in self.counts if x > 0]
58
+ if len(vals) < 16:
59
+ return 0.0
60
+ # coarse log bins
61
+ bins: Dict[int, int] = {}
62
+ for x in vals:
63
+ b = int(math.floor(math.log2(max(1, x))))
64
+ bins[b] = bins.get(b, 0) + 1
65
+ xs: List[float] = []
66
+ ys: List[float] = []
67
+ for b, c in sorted(bins.items()):
68
+ if c > 0:
69
+ xs.append(math.log(max(1.0, float(2 ** b))))
70
+ ys.append(math.log(float(c)))
71
+ if len(xs) < 3:
72
+ return 0.0
73
+ mx = sum(xs) / len(xs)
74
+ my = sum(ys) / len(ys)
75
+ den = sum((x - mx) ** 2 for x in xs)
76
+ if den <= 1e-9:
77
+ return 0.0
78
+ return float(sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / den)
79
+
80
+ def score(self) -> float:
81
+ # target slope ~ -1.5 (classic avalanche exponent)
82
+ return max(0.0, 1.0 - min(1.0, abs(self.exponent() + 1.5) / 1.5))
83
+
84
+
85
+ class CriticalityController:
86
+ """Homeostatic controller: adjust a gate toward a target branching ratio."""
87
+
88
+ def __init__(self, target: float = 1.0, lr: float = 0.02, gate: float = 1.0):
89
+ self.target = float(target)
90
+ self.lr = float(lr)
91
+ self.gate = float(gate)
92
+ self.last_sigma = 0.0
93
+
94
+ def update(self, sigma: float) -> float:
95
+ self.last_sigma = float(sigma)
96
+ if self.last_sigma > 0.0:
97
+ self.gate += self.lr * (self.last_sigma - self.target)
98
+ self.gate = max(0.2, min(3.0, self.gate))
99
+ return self.gate
100
+
101
+
102
+ class MetastabilityMeter:
103
+ """Cheap state-switching / dwell-time proxy."""
104
+
105
+ def __init__(self, window: int = 256):
106
+ self.values: Deque[float] = deque(maxlen=max(16, int(window)))
107
+
108
+ def update(self, value: float) -> None:
109
+ self.values.append(float(value))
110
+
111
+ def autocorrelation(self, lag: int = 1) -> float:
112
+ xs = list(self.values)
113
+ if len(xs) <= lag + 2:
114
+ return 0.0
115
+ a = xs[:-lag]
116
+ b = xs[lag:]
117
+ ma = sum(a) / len(a)
118
+ mb = sum(b) / len(b)
119
+ va = sum((x - ma) ** 2 for x in a)
120
+ vb = sum((x - mb) ** 2 for x in b)
121
+ if va <= 1e-12 or vb <= 1e-12:
122
+ return 0.0
123
+ return float(sum((x - ma) * (y - mb) for x, y in zip(a, b)) / math.sqrt(va * vb))
@@ -0,0 +1,27 @@
1
+ """Reference defaults from digital-fly literature.
2
+
3
+ These are documented starting points, not laws. Runtime knobs live in
4
+ MindConfig; changing a default should be a deliberate design change.
5
+ """
6
+
7
+ # Digital fly (FlyWire / MaleCNS)
8
+ NEURONS = 139_255
9
+ SYNAPSES = 50_000_000
10
+ CELL_TYPES = 11_710
11
+ MB_COMPARTMENTS = 15
12
+
13
+ # Mushroom body compression
14
+ KC_COUNT = 2_000
15
+ KC_SPARSITY = 0.05
16
+ KC_SLOTS = 256
17
+ KC_ACTIVE = max(1, round(KC_SLOTS * KC_SPARSITY)) # 13
18
+
19
+ # Approximate scale only (used for comments / coarse priors)
20
+ MBON_COUNT = 34
21
+ DAN_COUNT = 130
22
+
23
+ # Runtime contract
24
+ MAX_WM_SLOTS = 5
25
+ MEMORY_CAPACITY = 256
26
+ MAX_GOALS = 3
27
+ MAX_LLM_CALLS_PER_STEP = 1