dsh-biocore 0.3.3 → 0.5.0

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 (59) hide show
  1. package/lib/index.js +30 -1
  2. package/lib/modules/standby.js +61 -0
  3. package/lib/modules/state.js +22 -3
  4. package/package.json +1 -1
  5. package/python/biocore_memory/core/config.py +7 -3
  6. package/python/biocore_memory/engine.py +91 -6
  7. package/python/biocore_memory/recall/embedding.py +0 -51
  8. package/python/biocore_memory/recall/feedback.py +34 -7
  9. package/python/biocore_memory/recall/fusion.py +5 -1
  10. package/python/biocore_memory/scoring.py +203 -0
  11. package/python/biocore_memory/space.py +355 -0
  12. package/python/biocore_memory/store/dedupe.py +1 -0
  13. package/python/biocore_memory/store/tiering.py +14 -3
  14. package/python/biocore_model/affective_labor.py +14 -1
  15. package/python/biocore_model/appraisal.py +172 -3
  16. package/python/biocore_model/bio_tick.py +43 -13
  17. package/python/biocore_model/emotion_geometry.py +9 -0
  18. package/python/biocore_model/envy.py +21 -0
  19. package/python/biocore_model/feedback_memory.py +53 -0
  20. package/python/biocore_model/needs_events.py +32 -11
  21. package/python/biocore_model/regulation_strategies.py +5 -0
  22. package/python/biocore_model/repair_after_boundary.py +1 -0
  23. package/python/biocore_model/self_esteem.py +14 -2
  24. package/python/biocore_model/self_intent.py +6 -4
  25. package/python/biocore_model/tests/test_autonomy_self.py +153 -153
  26. package/python/biocore_model/tests/test_cache_series.py +137 -0
  27. package/python/biocore_model/tests/test_core_state.py +240 -240
  28. package/python/biocore_model/tests/test_extensions.py +167 -167
  29. package/python/biocore_model/tests/test_field_arbiter.py +444 -0
  30. package/python/biocore_model/tests/test_governance.py +181 -181
  31. package/python/biocore_model/tests/test_lifecycle.py +153 -0
  32. package/python/biocore_model/tests/test_memory_inject.py +211 -211
  33. package/python/biocore_model/tests/test_retrieval_plus.py +143 -0
  34. package/python/biocore_model/tests/test_signals.py +106 -106
  35. package/python/biocore_model/tests/test_standby.py +199 -0
  36. package/python/biocore_runtime/__init__.py +3 -0
  37. package/python/biocore_runtime/arbiter.py +307 -0
  38. package/python/biocore_runtime/batch_b.py +724 -0
  39. package/python/biocore_runtime/batch_c.py +186 -0
  40. package/python/biocore_runtime/batch_d.py +659 -0
  41. package/python/biocore_runtime/batch_e.py +328 -0
  42. package/python/biocore_runtime/batch_registry.py +446 -0
  43. package/python/biocore_runtime/cache_stats.py +161 -0
  44. package/python/biocore_runtime/core_state.py +106 -3
  45. package/python/biocore_runtime/dimensions.py +419 -0
  46. package/python/biocore_runtime/expression.py +261 -0
  47. package/python/biocore_runtime/field.py +440 -0
  48. package/python/biocore_runtime/lifecycle.py +233 -0
  49. package/python/biocore_runtime/perception.py +1045 -0
  50. package/python/biocore_runtime/pipeline.py +4458 -2974
  51. package/python/biocore_runtime/priority.py +210 -0
  52. package/python/biocore_runtime/retrieval_plus.py +352 -0
  53. package/python/biocore_runtime/standby.py +581 -472
  54. package/python/biocore_runtime/timescales.py +263 -0
  55. package/python/data/signals.json +3266 -206
  56. package/ui/panel-layout.js +32 -29
  57. package/ui/panel.css +563 -974
  58. package/ui/panel.html +427 -401
  59. package/ui/panel.js +543 -450
@@ -1,167 +1,167 @@
1
- # -*- coding: utf-8 -*-
2
- """task-225 (5b): P0 memory extensions + expression modules."""
3
- import json
4
- import tempfile
5
- import time
6
- import unittest
7
- from pathlib import Path
8
-
9
- from biocore_model import (entity_graph, entity_resolve, expr_template,
10
- graph_extract, graph_recall, layered_memory,
11
- memory_dual, prompt_rules, prospective,
12
- reconstruction, template_expr, topic_control,
13
- turn_memory, voice_bank)
14
- from biocore_runtime import extensions, pipeline
15
-
16
-
17
- def entry(i, text, ts=1700000000.0):
18
- return {"id": i, "text": text, "role": "user", "ts": ts,
19
- "importance": 0.5, "hits": 1}
20
-
21
-
22
- class Case(unittest.TestCase):
23
- def setUp(self):
24
- self.tmp = tempfile.TemporaryDirectory()
25
- self.data_dir = Path(self.tmp.name) / "data"
26
- self.store = self.data_dir / "memory"
27
- (self.store / "sessions" / "s1").mkdir(parents=True)
28
-
29
- def tearDown(self):
30
- self.tmp.cleanup()
31
-
32
-
33
- class GraphTest(Case):
34
- def test_entity_graph_build_search(self):
35
- graph, _ = extensions._entity_graph([
36
- entry("a", "苹果 很甜"), entry("b", "苹果 咖啡")])
37
- self.assertGreaterEqual(len(graph.get("entities") or []), 1)
38
- hits = entity_graph.search(graph, "苹果", limit=4)
39
- self.assertTrue(hits)
40
-
41
- def test_entity_resolve(self):
42
- self.assertEqual(entity_resolve.normalize("苹果 甜"), "苹果甜")
43
- self.assertGreaterEqual(entity_resolve.similarity("苹果", "苹果"), 0.9)
44
-
45
- def test_graph_extract(self):
46
- self.assertEqual(graph_extract.canonical_type("人物"), "person")
47
- self.assertGreater(graph_extract.when_to_ts("明天", 1000.0), 1000.0)
48
-
49
- def test_graph_recall_window(self):
50
- window = graph_recall.detect_window("上周")
51
- self.assertNotEqual(window, None)
52
-
53
- def test_graph_hits_extra(self):
54
- rows = [entry("a", "苹果 很甜"), entry("b", "苹果 咖啡"),
55
- entry("c", "香蕉")]
56
- hits, stats = extensions.graph_hits(rows, "苹果")
57
- self.assertGreaterEqual(stats["hits"], 0)
58
- self.assertIsInstance(hits, list)
59
-
60
-
61
- class MemoryExtTest(Case):
62
- def test_layered_select(self):
63
- result = layered_memory.select([entry("a", "早上的事"), entry("b", "刚才的事")],
64
- recalled_ids=["b"])
65
- self.assertIn("resident", result)
66
- self.assertIn("retrieval", result)
67
- self.assertTrue(result["resident"] or result["retrieval"])
68
-
69
- def test_memory_dual_score(self):
70
- e = memory_dual.encode("苹果", 1700000000.0, arousal=0.5)
71
- self.assertGreater(memory_dual.score(e, 1700000100.0), 0)
72
- self.assertTrue(memory_dual.select([e], 1700000100.0, limit=2))
73
-
74
- def test_prospective_due(self):
75
- now = time.time()
76
- rec = prospective.entry("his_event", "体检", now - 10)
77
- items, changed = prospective.add([], rec)
78
- self.assertTrue(changed)
79
- due = prospective.due_now(items, now, window_s=60)
80
- self.assertEqual(len(due), 1)
81
- self.assertTrue(prospective.build_hint(due[0], now))
82
- self.assertEqual(prospective.stats(items)["by_status"]["pending"], 1)
83
-
84
- def test_reconstruction(self):
85
- out = reconstruction.conserve([entry("a", "旧的记忆")])
86
- self.assertIn("total", out)
87
-
88
- def test_turn_memory(self):
89
- rows = turn_memory.build([{"entry_id": "a", "text": "记得喝水",
90
- "source": "recall"}])
91
- self.assertEqual(len(rows), 1)
92
- record = turn_memory.build_record(rows, reply="好", ts=10.0)
93
- self.assertTrue(turn_memory.render_receipt(record))
94
-
95
- def test_recall_graph_expansion(self):
96
- rows = [entry("a", "苹果 很甜", 1700000001.0),
97
- entry("b", "苹果 咖啡", 1700000002.0),
98
- entry("c", "香蕉 黄", 1700000003.0)]
99
- (self.store / "sessions" / "s1" / "memory.json").write_text(
100
- json.dumps({"entries": rows}), encoding="utf-8")
101
- out = pipeline.inject_block("s1", str(self.store), query="苹果 咖啡",
102
- mode="query", top_k=3)
103
- self.assertGreaterEqual(len(out["ids"]), 2)
104
- self.assertIn("b", out["ids"])
105
-
106
-
107
- class ExpressionTest(Case):
108
- def test_expr_template(self):
109
- out = expr_template.build_reply({"v": 0.2}, {"trust": 0.5})
110
- self.assertIsInstance(out, dict)
111
-
112
- def test_prompt_rules(self):
113
- text = prompt_rules.render_rules(affect={"valence": -0.4, "stress": 0.7},
114
- relation={"closeness": 0.5},
115
- certainty=0.7, soft_target=12,
116
- soft_max=30)
117
- self.assertIsInstance(text, str)
118
- self.assertTrue(text)
119
-
120
- def test_template_expr(self):
121
- self.assertEqual(template_expr.render("你好 {{name}}", {"name": "主管"}),
122
- "你好 主管")
123
-
124
- def test_topic_control(self):
125
- result = topic_control.topic_control(turns=[], state={"v": 0.0},
126
- relationship={"trust": 0.5})
127
- self.assertIsInstance(result, dict)
128
- self.assertTrue("tendency" in result or "holder" in result)
129
-
130
- def test_voice_bank(self):
131
- bank = [{"id": "v1", "phrase": "嗯。", "weight": 1.0,
132
- "when": {"v_min": -1, "v_max": 1, "tension_min": 0,
133
- "tension_max": 1}, "cooldown_s": 0}]
134
- picked = voice_bank.pick({"v": 0.1, "tension": 0.2},
135
- {"stage": "normal"}, [], time.time(),
136
- entries=bank)
137
- self.assertTrue(picked)
138
-
139
- def test_expression_block(self):
140
- block = extensions.expression_block(
141
- str(self.store), {"core": {"v": -0.2, "stress": 0.7}},
142
- {"trust": 0.5, "closeness": 0.4, "stage": "normal"},
143
- soft_target=12, soft_max=30)
144
- self.assertTrue(block["rules"] or block["template"])
145
- self.assertIn("template_name", block)
146
-
147
-
148
- class StateTest(Case):
149
- def test_state_exposes_extensions(self):
150
- rows = [entry("a", "苹果 很甜"), entry("b", "香蕉")]
151
- (self.store / "sessions" / "s1" / "memory.json").write_text(
152
- json.dumps({"entries": rows}), encoding="utf-8")
153
- pipeline.dispatch("turn_end", {
154
- "store": str(self.store), "session_id": "s1",
155
- "user_text": "苹果很甜", "assistant_text": "嗯。",
156
- "capture": False,
157
- "persona_profile": str(Path(self.tmp.name) / "missing.json")})
158
- body = pipeline.dispatch("state", {
159
- "store": str(self.store), "session_id": "s1",
160
- "persona_profile": str(Path(self.tmp.name) / "missing.json")})["state"]
161
- self.assertIn("extensions", body)
162
- self.assertIn("graph", body["extensions"])
163
- self.assertIn("layered", body["extensions"])
164
-
165
-
166
- if __name__ == "__main__":
167
- unittest.main()
1
+ # -*- coding: utf-8 -*-
2
+ """task-225 (5b): P0 memory extensions + expression modules."""
3
+ import json
4
+ import tempfile
5
+ import time
6
+ import unittest
7
+ from pathlib import Path
8
+
9
+ from biocore_model import (entity_graph, entity_resolve, expr_template,
10
+ graph_extract, graph_recall, layered_memory,
11
+ memory_dual, prompt_rules, prospective,
12
+ reconstruction, template_expr, topic_control,
13
+ turn_memory, voice_bank)
14
+ from biocore_runtime import extensions, pipeline
15
+
16
+
17
+ def entry(i, text, ts=1700000000.0):
18
+ return {"id": i, "text": text, "role": "user", "ts": ts,
19
+ "importance": 0.5, "hits": 1}
20
+
21
+
22
+ class Case(unittest.TestCase):
23
+ def setUp(self):
24
+ self.tmp = tempfile.TemporaryDirectory()
25
+ self.data_dir = Path(self.tmp.name) / "data"
26
+ self.store = self.data_dir / "memory"
27
+ (self.store / "sessions" / "s1").mkdir(parents=True)
28
+
29
+ def tearDown(self):
30
+ self.tmp.cleanup()
31
+
32
+
33
+ class GraphTest(Case):
34
+ def test_entity_graph_build_search(self):
35
+ graph, _ = extensions._entity_graph([
36
+ entry("a", "苹果 很甜"), entry("b", "苹果 咖啡")])
37
+ self.assertGreaterEqual(len(graph.get("entities") or []), 1)
38
+ hits = entity_graph.search(graph, "苹果", limit=4)
39
+ self.assertTrue(hits)
40
+
41
+ def test_entity_resolve(self):
42
+ self.assertEqual(entity_resolve.normalize("苹果 甜"), "苹果甜")
43
+ self.assertGreaterEqual(entity_resolve.similarity("苹果", "苹果"), 0.9)
44
+
45
+ def test_graph_extract(self):
46
+ self.assertEqual(graph_extract.canonical_type("人物"), "person")
47
+ self.assertGreater(graph_extract.when_to_ts("明天", 1000.0), 1000.0)
48
+
49
+ def test_graph_recall_window(self):
50
+ window = graph_recall.detect_window("上周")
51
+ self.assertNotEqual(window, None)
52
+
53
+ def test_graph_hits_extra(self):
54
+ rows = [entry("a", "苹果 很甜"), entry("b", "苹果 咖啡"),
55
+ entry("c", "香蕉")]
56
+ hits, stats = extensions.graph_hits(rows, "苹果")
57
+ self.assertGreaterEqual(stats["hits"], 0)
58
+ self.assertIsInstance(hits, list)
59
+
60
+
61
+ class MemoryExtTest(Case):
62
+ def test_layered_select(self):
63
+ result = layered_memory.select([entry("a", "早上的事"), entry("b", "刚才的事")],
64
+ recalled_ids=["b"])
65
+ self.assertIn("resident", result)
66
+ self.assertIn("retrieval", result)
67
+ self.assertTrue(result["resident"] or result["retrieval"])
68
+
69
+ def test_memory_dual_score(self):
70
+ e = memory_dual.encode("苹果", 1700000000.0, arousal=0.5)
71
+ self.assertGreater(memory_dual.score(e, 1700000100.0), 0)
72
+ self.assertTrue(memory_dual.select([e], 1700000100.0, limit=2))
73
+
74
+ def test_prospective_due(self):
75
+ now = time.time()
76
+ rec = prospective.entry("his_event", "体检", now - 10)
77
+ items, changed = prospective.add([], rec)
78
+ self.assertTrue(changed)
79
+ due = prospective.due_now(items, now, window_s=60)
80
+ self.assertEqual(len(due), 1)
81
+ self.assertTrue(prospective.build_hint(due[0], now))
82
+ self.assertEqual(prospective.stats(items)["by_status"]["pending"], 1)
83
+
84
+ def test_reconstruction(self):
85
+ out = reconstruction.conserve([entry("a", "旧的记忆")])
86
+ self.assertIn("total", out)
87
+
88
+ def test_turn_memory(self):
89
+ rows = turn_memory.build([{"entry_id": "a", "text": "记得喝水",
90
+ "source": "recall"}])
91
+ self.assertEqual(len(rows), 1)
92
+ record = turn_memory.build_record(rows, reply="好", ts=10.0)
93
+ self.assertTrue(turn_memory.render_receipt(record))
94
+
95
+ def test_recall_graph_expansion(self):
96
+ rows = [entry("a", "苹果 很甜", 1700000001.0),
97
+ entry("b", "苹果 咖啡", 1700000002.0),
98
+ entry("c", "香蕉 黄", 1700000003.0)]
99
+ (self.store / "sessions" / "s1" / "memory.json").write_text(
100
+ json.dumps({"entries": rows}), encoding="utf-8")
101
+ out = pipeline.inject_block("s1", str(self.store), query="苹果 咖啡",
102
+ mode="query", top_k=3)
103
+ self.assertGreaterEqual(len(out["ids"]), 2)
104
+ self.assertIn("b", out["ids"])
105
+
106
+
107
+ class ExpressionTest(Case):
108
+ def test_expr_template(self):
109
+ out = expr_template.build_reply({"v": 0.2}, {"trust": 0.5})
110
+ self.assertIsInstance(out, dict)
111
+
112
+ def test_prompt_rules(self):
113
+ text = prompt_rules.render_rules(affect={"valence": -0.4, "stress": 0.7},
114
+ relation={"closeness": 0.5},
115
+ certainty=0.7, soft_target=12,
116
+ soft_max=30)
117
+ self.assertIsInstance(text, str)
118
+ self.assertTrue(text)
119
+
120
+ def test_template_expr(self):
121
+ self.assertEqual(template_expr.render("你好 {{name}}", {"name": "主管"}),
122
+ "你好 主管")
123
+
124
+ def test_topic_control(self):
125
+ result = topic_control.topic_control(turns=[], state={"v": 0.0},
126
+ relationship={"trust": 0.5})
127
+ self.assertIsInstance(result, dict)
128
+ self.assertTrue("tendency" in result or "holder" in result)
129
+
130
+ def test_voice_bank(self):
131
+ bank = [{"id": "v1", "phrase": "嗯。", "weight": 1.0,
132
+ "when": {"v_min": -1, "v_max": 1, "tension_min": 0,
133
+ "tension_max": 1}, "cooldown_s": 0}]
134
+ picked = voice_bank.pick({"v": 0.1, "tension": 0.2},
135
+ {"stage": "normal"}, [], time.time(),
136
+ entries=bank)
137
+ self.assertTrue(picked)
138
+
139
+ def test_expression_block(self):
140
+ block = extensions.expression_block(
141
+ str(self.store), {"core": {"v": -0.2, "stress": 0.7}},
142
+ {"trust": 0.5, "closeness": 0.4, "stage": "normal"},
143
+ soft_target=12, soft_max=30)
144
+ self.assertTrue(block["rules"] or block["template"])
145
+ self.assertIn("template_name", block)
146
+
147
+
148
+ class StateTest(Case):
149
+ def test_state_exposes_extensions(self):
150
+ rows = [entry("a", "苹果 很甜"), entry("b", "香蕉")]
151
+ (self.store / "sessions" / "s1" / "memory.json").write_text(
152
+ json.dumps({"entries": rows}), encoding="utf-8")
153
+ pipeline.dispatch("turn_end", {
154
+ "store": str(self.store), "session_id": "s1",
155
+ "user_text": "苹果很甜", "assistant_text": "嗯。",
156
+ "capture": False,
157
+ "persona_profile": str(Path(self.tmp.name) / "missing.json")})
158
+ body = pipeline.dispatch("state", {
159
+ "store": str(self.store), "session_id": "s1",
160
+ "persona_profile": str(Path(self.tmp.name) / "missing.json")})["state"]
161
+ self.assertIn("extensions", body)
162
+ self.assertIn("graph", body["extensions"])
163
+ self.assertIn("layered", body["extensions"])
164
+
165
+
166
+ if __name__ == "__main__":
167
+ unittest.main()