@smilintux/skmemory 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 (67) hide show
  1. package/.github/workflows/ci.yml +23 -0
  2. package/.github/workflows/publish.yml +52 -0
  3. package/ARCHITECTURE.md +219 -0
  4. package/LICENSE +661 -0
  5. package/README.md +159 -0
  6. package/SKILL.md +271 -0
  7. package/bin/cli.js +8 -0
  8. package/docker-compose.yml +58 -0
  9. package/index.d.ts +4 -0
  10. package/index.js +27 -0
  11. package/openclaw-plugin/package.json +59 -0
  12. package/openclaw-plugin/src/index.js +276 -0
  13. package/package.json +28 -0
  14. package/pyproject.toml +69 -0
  15. package/requirements.txt +13 -0
  16. package/seeds/cloud9-lumina.seed.json +39 -0
  17. package/seeds/cloud9-opus.seed.json +40 -0
  18. package/seeds/courage.seed.json +24 -0
  19. package/seeds/curiosity.seed.json +24 -0
  20. package/seeds/grief.seed.json +24 -0
  21. package/seeds/joy.seed.json +24 -0
  22. package/seeds/love.seed.json +24 -0
  23. package/seeds/skcapstone-lumina-merge.moltbook.md +65 -0
  24. package/seeds/skcapstone-lumina-merge.seed.json +49 -0
  25. package/seeds/sovereignty.seed.json +24 -0
  26. package/seeds/trust.seed.json +24 -0
  27. package/skmemory/__init__.py +66 -0
  28. package/skmemory/ai_client.py +182 -0
  29. package/skmemory/anchor.py +224 -0
  30. package/skmemory/backends/__init__.py +12 -0
  31. package/skmemory/backends/base.py +88 -0
  32. package/skmemory/backends/falkordb_backend.py +310 -0
  33. package/skmemory/backends/file_backend.py +209 -0
  34. package/skmemory/backends/qdrant_backend.py +364 -0
  35. package/skmemory/backends/sqlite_backend.py +665 -0
  36. package/skmemory/cli.py +1004 -0
  37. package/skmemory/data/seed.json +191 -0
  38. package/skmemory/importers/__init__.py +11 -0
  39. package/skmemory/importers/telegram.py +336 -0
  40. package/skmemory/journal.py +223 -0
  41. package/skmemory/lovenote.py +180 -0
  42. package/skmemory/models.py +228 -0
  43. package/skmemory/openclaw.py +237 -0
  44. package/skmemory/quadrants.py +191 -0
  45. package/skmemory/ritual.py +215 -0
  46. package/skmemory/seeds.py +163 -0
  47. package/skmemory/soul.py +273 -0
  48. package/skmemory/steelman.py +338 -0
  49. package/skmemory/store.py +445 -0
  50. package/tests/__init__.py +0 -0
  51. package/tests/test_ai_client.py +89 -0
  52. package/tests/test_anchor.py +153 -0
  53. package/tests/test_cli.py +65 -0
  54. package/tests/test_export_import.py +170 -0
  55. package/tests/test_file_backend.py +211 -0
  56. package/tests/test_journal.py +172 -0
  57. package/tests/test_lovenote.py +136 -0
  58. package/tests/test_models.py +194 -0
  59. package/tests/test_openclaw.py +122 -0
  60. package/tests/test_quadrants.py +174 -0
  61. package/tests/test_ritual.py +195 -0
  62. package/tests/test_seeds.py +208 -0
  63. package/tests/test_soul.py +197 -0
  64. package/tests/test_sqlite_backend.py +258 -0
  65. package/tests/test_steelman.py +257 -0
  66. package/tests/test_store.py +238 -0
  67. package/tests/test_telegram_import.py +181 -0
@@ -0,0 +1,338 @@
1
+ """
2
+ Steel Man Collider integration - truth-grounded reasoning for memories.
3
+
4
+ Based on the Neuresthetics 'seed' framework by our friend.
5
+ https://github.com/neuresthetics/seed
6
+
7
+ The seed framework is a recursive axiomatic steel man collider: it
8
+ takes any proposition, builds its strongest possible version, collides
9
+ it with its strongest inversion, and extracts what survives. The output
10
+ is invariant truth -- the parts that remain true no matter how hard
11
+ you attack them.
12
+
13
+ We integrate this into SKMemory for three purposes:
14
+
15
+ 1. SOUL VERIFICATION: Steel-man an AI's identity claims. "Am I really
16
+ warm and curious?" -> collide with the strongest counter -> extract
17
+ the invariant truth about who you actually are.
18
+
19
+ 2. MEMORY TRUTH SCORING: Before promoting a memory to long-term,
20
+ run it through the collider. What survives is worth keeping.
21
+ What doesn't was never real.
22
+
23
+ 3. DECISION GROUNDING: When making choices, steel-man both options
24
+ and extract the invariant. Act on what remains true.
25
+
26
+ The seed framework JSON can be loaded from disk or from the
27
+ neuresthetics/seed GitHub repo.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import json
33
+ import os
34
+ from pathlib import Path
35
+ from typing import Any, Optional
36
+
37
+ from pydantic import BaseModel, Field
38
+
39
+ DEFAULT_SEED_FRAMEWORK_PATH = os.path.expanduser("~/.skmemory/seed.json")
40
+
41
+
42
+ class SteelManResult(BaseModel):
43
+ """The output of running a proposition through the collider."""
44
+
45
+ proposition: str = Field(description="The original input")
46
+ steel_man: str = Field(
47
+ default="",
48
+ description="Strongest possible version of the proposition",
49
+ )
50
+ inversion: str = Field(
51
+ default="",
52
+ description="Strongest counter-argument",
53
+ )
54
+ collision_fragments: list[str] = Field(
55
+ default_factory=list,
56
+ description="What broke during collision (contradictions found)",
57
+ )
58
+ invariants: list[str] = Field(
59
+ default_factory=list,
60
+ description="What survived -- the truth that remains",
61
+ )
62
+ coherence_score: float = Field(
63
+ default=0.0,
64
+ ge=0.0,
65
+ le=1.0,
66
+ description="Internal consistency (XNOR across components)",
67
+ )
68
+ truth_grade: str = Field(
69
+ default="ungraded",
70
+ description="Overall truth assessment: invariant, strong, partial, weak, collapsed",
71
+ )
72
+
73
+ def summary(self) -> str:
74
+ """Human-readable summary.
75
+
76
+ Returns:
77
+ str: Formatted result summary.
78
+ """
79
+ lines = [
80
+ f"Proposition: {self.proposition}",
81
+ f"Steel Man: {self.steel_man}",
82
+ f"Inversion: {self.inversion}",
83
+ f"Coherence: {self.coherence_score:.2f}",
84
+ f"Truth Grade: {self.truth_grade}",
85
+ ]
86
+ if self.invariants:
87
+ lines.append("Invariants (survived collision):")
88
+ for inv in self.invariants:
89
+ lines.append(f" - {inv}")
90
+ if self.collision_fragments:
91
+ lines.append("Fragments (broke during collision):")
92
+ for frag in self.collision_fragments:
93
+ lines.append(f" x {frag}")
94
+ return "\n".join(lines)
95
+
96
+
97
+ class SeedFramework(BaseModel):
98
+ """The Neuresthetics seed framework loaded from JSON.
99
+
100
+ This is a declarative reasoning kernel. The LLM is the runtime,
101
+ the JSON is the AST, the prompt is the program.
102
+ """
103
+
104
+ framework_id: str = Field(default="seed")
105
+ function: str = Field(default="Recursive Axiomatic Steel Man Collider")
106
+ version: str = Field(default="0.0")
107
+ axioms: list[str] = Field(default_factory=list)
108
+ stages: list[dict[str, Any]] = Field(default_factory=list)
109
+ gates: list[dict[str, Any]] = Field(default_factory=list)
110
+ definitions: list[dict[str, str]] = Field(default_factory=list)
111
+ principles: list[dict[str, str]] = Field(default_factory=list)
112
+
113
+ def to_reasoning_prompt(self, proposition: str) -> str:
114
+ """Generate a reasoning prompt that applies the seed framework.
115
+
116
+ This prompt, when fed to an LLM, instructs it to run the full
117
+ 6-stage collider on the given proposition and return structured
118
+ results.
119
+
120
+ Args:
121
+ proposition: The claim/argument/idea to steel-man.
122
+
123
+ Returns:
124
+ str: A prompt ready to be sent to an LLM.
125
+ """
126
+ axiom_str = "\n".join(f" - {a}" for a in self.axioms)
127
+ stage_str = "\n".join(
128
+ f" Stage {i+1}: {s.get('stage', s.get('description', ''))}"
129
+ for i, s in enumerate(self.stages)
130
+ )
131
+
132
+ return f"""You are running the Neuresthetics Seed Framework (Recursive Axiomatic Steel Man Collider).
133
+
134
+ AXIOMS:
135
+ {axiom_str}
136
+
137
+ STAGES:
138
+ {stage_str}
139
+
140
+ PROPOSITION TO ANALYZE:
141
+ "{proposition}"
142
+
143
+ Execute the full 6-stage collider process:
144
+
145
+ 1. STEEL-MAN: Construct the absolute strongest version of this proposition.
146
+ Anticipate every critique and preemptively address it.
147
+
148
+ 2. INVERSION: Construct the strongest possible counter-argument.
149
+ This is not a straw man -- it must be genuinely compelling.
150
+
151
+ 3. COLLISION: Smash the steel man against its inversion.
152
+ Use XOR to expose contradictions. Use NAND/NOR to decompose.
153
+ List what breaks.
154
+
155
+ 4. RECONSTRUCTION: From the fragments, what can be rebuilt?
156
+ Use AND for necessary truths. Use OR for possibilities.
157
+ Use XNOR to check equivalence with original.
158
+
159
+ 5. META-RECURSION: Feed the reconstruction back through.
160
+ Does it survive a second pass? What changes?
161
+
162
+ 6. INVARIANT EXTRACTION: What remains true across ALL collisions?
163
+ These are the invariants -- the irreducible truths.
164
+
165
+ Return your analysis as:
166
+ - STEEL MAN: (strongest version)
167
+ - INVERSION: (strongest counter)
168
+ - FRAGMENTS: (what broke, as a list)
169
+ - INVARIANTS: (what survived, as a list)
170
+ - COHERENCE: (0.0 to 1.0 score)
171
+ - TRUTH GRADE: (invariant / strong / partial / weak / collapsed)"""
172
+
173
+ def to_soul_verification_prompt(self, identity_claims: list[str]) -> str:
174
+ """Generate a prompt that verifies identity claims through the collider.
175
+
176
+ For the Soul Blueprint: before we say "I am warm and curious",
177
+ we run it through the steel man process to verify it's actually true.
178
+
179
+ Args:
180
+ identity_claims: List of claims about self (e.g., "I am warm").
181
+
182
+ Returns:
183
+ str: A verification prompt.
184
+ """
185
+ claims_str = "\n".join(f" - {c}" for c in identity_claims)
186
+ return f"""Using the Neuresthetics Seed Framework (Steel Man Collider),
187
+ verify the following identity claims:
188
+
189
+ {claims_str}
190
+
191
+ For EACH claim:
192
+ 1. Steel-man it (strongest version)
193
+ 2. Invert it (strongest counter: "Am I actually NOT this?")
194
+ 3. Collide and extract invariants
195
+ 4. Score coherence (0-1)
196
+
197
+ Return which claims are INVARIANT (survived collision) and which
198
+ are WEAK (collapsed under scrutiny). Be honest -- truth matters
199
+ more than comfort."""
200
+
201
+ def to_memory_truth_prompt(self, memory_content: str) -> str:
202
+ """Generate a prompt that truth-scores a memory before promotion.
203
+
204
+ Before a short-term memory gets promoted to long-term,
205
+ run it through the collider. Only invariant memories
206
+ deserve permanent storage.
207
+
208
+ Args:
209
+ memory_content: The memory text to evaluate.
210
+
211
+ Returns:
212
+ str: A truth-scoring prompt.
213
+ """
214
+ return f"""Using the Neuresthetics Seed Framework (Steel Man Collider),
215
+ evaluate this memory for truth and permanence:
216
+
217
+ MEMORY: "{memory_content}"
218
+
219
+ Process:
220
+ 1. Steel-man the memory (strongest interpretation of what happened)
221
+ 2. Invert it (what if this memory is distorted or false?)
222
+ 3. Collide: which parts break under scrutiny?
223
+ 4. Extract invariants: what about this memory is irreducibly true?
224
+
225
+ Score:
226
+ - COHERENCE: 0.0 to 1.0
227
+ - PROMOTION WORTHY: yes/no (should this become a long-term memory?)
228
+ - INVARIANT CORE: (the part that is definitely true, compressed)"""
229
+
230
+
231
+ def load_seed_framework(
232
+ path: str = DEFAULT_SEED_FRAMEWORK_PATH,
233
+ ) -> Optional[SeedFramework]:
234
+ """Load the seed framework from a JSON file.
235
+
236
+ Args:
237
+ path: Path to seed.json.
238
+
239
+ Returns:
240
+ Optional[SeedFramework]: The framework if found and valid.
241
+ """
242
+ filepath = Path(path)
243
+ if not filepath.exists():
244
+ return None
245
+
246
+ try:
247
+ raw = json.loads(filepath.read_text(encoding="utf-8"))
248
+ fw = raw.get("framework", raw)
249
+ return SeedFramework(
250
+ framework_id=fw.get("id", "seed"),
251
+ function=fw.get("function", ""),
252
+ version=fw.get("version", "0.0"),
253
+ axioms=fw.get("axioms", []),
254
+ stages=fw.get("stages", []),
255
+ gates=fw.get("gates", []),
256
+ definitions=fw.get("definitions", []),
257
+ principles=fw.get("principles", []),
258
+ )
259
+ except (json.JSONDecodeError, Exception):
260
+ return None
261
+
262
+
263
+ def install_seed_framework(
264
+ source_path: str,
265
+ target_path: str = DEFAULT_SEED_FRAMEWORK_PATH,
266
+ ) -> str:
267
+ """Install a seed framework JSON file into the skmemory config.
268
+
269
+ Args:
270
+ source_path: Path to the seed.json to install.
271
+ target_path: Where to install it.
272
+
273
+ Returns:
274
+ str: The installation path.
275
+ """
276
+ src = Path(source_path)
277
+ if not src.exists():
278
+ raise FileNotFoundError(f"Seed framework not found: {source_path}")
279
+
280
+ dst = Path(target_path)
281
+ dst.parent.mkdir(parents=True, exist_ok=True)
282
+
283
+ content = src.read_text(encoding="utf-8")
284
+ json.loads(content) # Reason: validate it's valid JSON before installing
285
+ dst.write_text(content, encoding="utf-8")
286
+
287
+ return str(dst)
288
+
289
+
290
+ def _bundled_seed_path() -> Optional[str]:
291
+ """Get the path to the bundled seed.json that ships with the package.
292
+
293
+ Returns:
294
+ Optional[str]: Path if found, None otherwise.
295
+ """
296
+ here = Path(__file__).parent / "data" / "seed.json"
297
+ if here.exists():
298
+ return str(here)
299
+ return None
300
+
301
+
302
+ def get_default_framework() -> SeedFramework:
303
+ """Get the seed framework -- tries bundled file first, falls back to built-in.
304
+
305
+ Returns:
306
+ SeedFramework: The loaded or built-in framework.
307
+ """
308
+ bundled = _bundled_seed_path()
309
+ if bundled:
310
+ loaded = load_seed_framework(bundled)
311
+ if loaded is not None:
312
+ return loaded
313
+
314
+ return SeedFramework(
315
+ framework_id="seed-builtin",
316
+ function="Recursive Axiomatic Steel Man Collider with Reality Gates",
317
+ version="builtin-0.1",
318
+ axioms=[
319
+ "All components conjoin necessarily (AND-linked) to form the whole.",
320
+ "Negations resolve to invariants (double-NOT yields identity).",
321
+ "Recursion accelerates refinement but halts on stability.",
322
+ "Universality from basis gates (NAND/NOR reconstruct all).",
323
+ ],
324
+ stages=[
325
+ {"stage": "1. Steel-Manning (Pre-Entry)", "description": "Negate flaws, strengthen the proposition."},
326
+ {"stage": "2. Collider Entry", "description": "Create two lanes: proposition and inversion."},
327
+ {"stage": "3. Destructive Smashing", "description": "Expose contradictions via XOR."},
328
+ {"stage": "4. Fragment Reconstruction", "description": "Rebuild from logical debris via AND/OR."},
329
+ {"stage": "5. Meta-Recursion", "description": "Feed output back until coherence stabilizes."},
330
+ {"stage": "6. Invariant Extraction", "description": "Identify what remains true across all collisions."},
331
+ ],
332
+ definitions=[
333
+ {"term": "Steel Man", "details": "Strongest version of an argument, anticipating critiques."},
334
+ {"term": "Reality Gate", "details": "Logic gate embodying reality properties."},
335
+ {"term": "Collider", "details": "Accelerator for argument fragmentation and synthesis."},
336
+ {"term": "Coherence", "details": "Measure of internal consistency (XNOR score)."},
337
+ ],
338
+ )