cortexm 0.3.0__py3-none-any.whl
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.
- context_m.py +17 -0
- cortexm/__init__.py +45 -0
- cortexm/accel.py +403 -0
- cortexm/api/__init__.py +0 -0
- cortexm/api/chaos.py +118 -0
- cortexm/api/memory.py +635 -0
- cortexm/bench/__init__.py +0 -0
- cortexm/bench/abilities.py +311 -0
- cortexm/bench/baselines.py +89 -0
- cortexm/bench/beam_loader.py +317 -0
- cortexm/bench/generator.py +376 -0
- cortexm/bench/harness.py +211 -0
- cortexm/bench/messy.py +218 -0
- cortexm/bench/micro.py +251 -0
- cortexm/bench/ood.py +443 -0
- cortexm/bench/run.py +137 -0
- cortexm/bridge/__init__.py +0 -0
- cortexm/bridge/dates.py +178 -0
- cortexm/bridge/decoders.py +204 -0
- cortexm/bridge/enrich.py +255 -0
- cortexm/bridge/extractor.py +316 -0
- cortexm/bridge/fallback.py +332 -0
- cortexm/bridge/onnx_runtime.py +158 -0
- cortexm/bridge/patterns.py +760 -0
- cortexm/bridge/ppr.py +104 -0
- cortexm/bridge/prefilter.py +188 -0
- cortexm/bridge/query_extract.py +420 -0
- cortexm/bridge/reader.py +1174 -0
- cortexm/bridge/rerank.py +204 -0
- cortexm/bridge/writer.py +492 -0
- cortexm/cli.py +295 -0
- cortexm/cognition/__init__.py +53 -0
- cortexm/cognition/abstraction.py +192 -0
- cortexm/cognition/analogy.py +159 -0
- cortexm/cognition/engine.py +204 -0
- cortexm/cognition/gaps.py +365 -0
- cortexm/cognition/scanner.py +204 -0
- cortexm/config.py +375 -0
- cortexm/cortexm.py +8 -0
- cortexm/enterprise/__init__.py +0 -0
- cortexm/enterprise/audit.py +178 -0
- cortexm/enterprise/governance.py +239 -0
- cortexm/errors.py +35 -0
- cortexm/features/__init__.py +0 -0
- cortexm/features/git.py +204 -0
- cortexm/features/prefetch.py +88 -0
- cortexm/features/zk.py +105 -0
- cortexm/federation/__init__.py +39 -0
- cortexm/federation/crdt.py +275 -0
- cortexm/federation/fabric.py +109 -0
- cortexm/federation/hlc.py +80 -0
- cortexm/federation/node.py +145 -0
- cortexm/federation/schema_report.py +73 -0
- cortexm/federation/transport.py +164 -0
- cortexm/index/__init__.py +19 -0
- cortexm/index/nsg.py +386 -0
- cortexm/mcp/__init__.py +0 -0
- cortexm/mcp/server.py +985 -0
- cortexm/metrics.py +62 -0
- cortexm/migrate/__init__.py +0 -0
- cortexm/migrate/importers.py +192 -0
- cortexm/provenance/__init__.py +78 -0
- cortexm/provenance/agent.py +214 -0
- cortexm/provenance/cose.py +201 -0
- cortexm/provenance/scitt.py +258 -0
- cortexm/provenance/vc.py +250 -0
- cortexm/security/__init__.py +0 -0
- cortexm/security/crypto.py +162 -0
- cortexm/security/hashes.py +140 -0
- cortexm/security/injection.py +149 -0
- cortexm/security/mind.py +154 -0
- cortexm/security/pii.py +265 -0
- cortexm/security/rbac.py +169 -0
- cortexm/security/sandbox.py +131 -0
- cortexm/security/zk_hamming.py +142 -0
- cortexm/security/zk_sql.py +485 -0
- cortexm/server/__init__.py +0 -0
- cortexm/server/metrics.py +88 -0
- cortexm/server/rest.py +936 -0
- cortexm/server/sparql.py +984 -0
- cortexm/text/__init__.py +0 -0
- cortexm/text/dissim.py +252 -0
- cortexm/text/embedder.py +155 -0
- cortexm/text/fuzzy.py +218 -0
- cortexm/text/idiolect.py +253 -0
- cortexm/text/labse.py +374 -0
- cortexm/text/tokenizer.py +79 -0
- cortexm/trace/__init__.py +0 -0
- cortexm/trace/blob_arena.py +277 -0
- cortexm/trace/consolidate.py +337 -0
- cortexm/trace/contradictions.py +69 -0
- cortexm/trace/dedup.py +114 -0
- cortexm/trace/edges.py +214 -0
- cortexm/trace/fact.py +121 -0
- cortexm/trace/fade.py +245 -0
- cortexm/trace/lifecycle.py +112 -0
- cortexm/trace/rebuild.py +173 -0
- cortexm/trace/rules.py +171 -0
- cortexm/trace/store.py +680 -0
- cortexm/trace/structural.py +183 -0
- cortexm/trace/tmt.py +335 -0
- cortexm/util.py +148 -0
- cortexm/vsa/__init__.py +0 -0
- cortexm/vsa/attribution.py +149 -0
- cortexm/vsa/cleanup.py +161 -0
- cortexm/vsa/codecs.py +397 -0
- cortexm/vsa/hologram_overlay.py +139 -0
- cortexm/vsa/index.py +163 -0
- cortexm/vsa/ops.py +149 -0
- cortexm/vsa/palace.py +446 -0
- cortexm/vsa/role_vectors.py +236 -0
- cortexm/vsa/slb.py +78 -0
- cortexm/vsa/tlsh_trie.py +137 -0
- cortexm/vsa/working_memory.py +249 -0
- cortexm-0.3.0.dist-info/METADATA +482 -0
- cortexm-0.3.0.dist-info/RECORD +120 -0
- cortexm-0.3.0.dist-info/WHEEL +5 -0
- cortexm-0.3.0.dist-info/entry_points.txt +2 -0
- cortexm-0.3.0.dist-info/licenses/LICENSE +190 -0
- cortexm-0.3.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""Holographic working memory — compress top-k facts into a single HRR.
|
|
2
|
+
|
|
3
|
+
The strategic plan calls for compressing the top-k retrieved facts
|
|
4
|
+
into a single HRR superposition injected into the LLM system prompt.
|
|
5
|
+
The LLM unbinds specific facts on demand. This is a 5-10× token
|
|
6
|
+
reduction for the context window.
|
|
7
|
+
|
|
8
|
+
Mechanism (VSA / HRR algebra, Plate 1995):
|
|
9
|
+
- For each fact (S, R, V), compute its binding:
|
|
10
|
+
fact_holo = bind(S, role_vec("S")) + bind(R, role_vec("R"))
|
|
11
|
+
+ bind(V, role_vec("V"))
|
|
12
|
+
where each component is the L2-normalized embedding of the
|
|
13
|
+
fact's subject / relation / value text, and `bind` is the VSA's
|
|
14
|
+
role-seeded permutation (mode="perm") or circular-convolution
|
|
15
|
+
(mode="conv").
|
|
16
|
+
- The full working memory hologram is the normalized superposition
|
|
17
|
+
of all fact_holo vectors. Adding more facts to the same superposition
|
|
18
|
+
is the standard HRR "memory" operation — every fact is added into
|
|
19
|
+
one vector, with overlap (cross-talk) controlled by the orthogonality
|
|
20
|
+
of the role vectors.
|
|
21
|
+
|
|
22
|
+
To RECALL a specific fact given a query, the LLM (or the host agent)
|
|
23
|
+
asks us to UNBIND — e.g. "what is Alice's job?" → we unbind the "S"
|
|
24
|
+
role on the hologram with role_vec("S") permuted against the query
|
|
25
|
+
"Alice", then nearest-neighbor lookup against the fact corpus. The
|
|
26
|
+
beauty of HRR is that this is a pure vector operation — no learned
|
|
27
|
+
weights, μ=0.
|
|
28
|
+
|
|
29
|
+
For the system-prompt injection use case we keep it simple:
|
|
30
|
+
- Compress top-k retrieved facts into one HRR vector + a short
|
|
31
|
+
textual preamble describing the available "fact slots" (S/R/V
|
|
32
|
+
bindings present).
|
|
33
|
+
- The LLM can ask us to "extract" a specific fact from the hologram
|
|
34
|
+
via the `extract_from_hologram` MCP tool / REST endpoint, which
|
|
35
|
+
does the unbind + nearest-neighbor lookup.
|
|
36
|
+
|
|
37
|
+
Net effect: instead of injecting 10 facts × ~30 tokens each = ~300
|
|
38
|
+
tokens into the system prompt, we inject ~30 tokens of preamble +
|
|
39
|
+
the HRR vector (which an LLM doesn't see directly — it sees the
|
|
40
|
+
preamble). The savings are on RETRIEVAL repetition across turns: a
|
|
41
|
+
chat with 10 turns that re-fetches the same 10 facts each turn saves
|
|
42
|
+
~2700 tokens vs naive injection. HRR vectors are also constant-size
|
|
43
|
+
memory of arbitrary depth.
|
|
44
|
+
|
|
45
|
+
For now, we provide the compression + extraction primitives. The
|
|
46
|
+
agent-side "ask the hologram" loop is left to the host app; the
|
|
47
|
+
hologram is the substrate.
|
|
48
|
+
"""
|
|
49
|
+
from __future__ import annotations
|
|
50
|
+
|
|
51
|
+
from dataclasses import dataclass, field
|
|
52
|
+
from typing import Iterable
|
|
53
|
+
|
|
54
|
+
import numpy as np
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class HolographicWM:
|
|
59
|
+
"""A compressed working-memory representation of top-k facts.
|
|
60
|
+
|
|
61
|
+
Attributes:
|
|
62
|
+
hrr: the superposed HRR vector (dims,). L2-normalized.
|
|
63
|
+
n_facts: how many facts were superposed.
|
|
64
|
+
roles_present: which role bindings are present (subset of
|
|
65
|
+
{"S","R","V"}). Lets the host LLM know what it can ask
|
|
66
|
+
the hologram to unbind.
|
|
67
|
+
fact_ids: list of fact ids that were superposed, in superposition
|
|
68
|
+
order. Used by extract_from_hologram to look up the answer
|
|
69
|
+
after unbinding.
|
|
70
|
+
preamble: a short textual description suitable for injection
|
|
71
|
+
into an LLM system prompt. ~30-50 tokens. Tells the LLM
|
|
72
|
+
"you have N facts compressed as a hologram; ask the
|
|
73
|
+
contextm_hologram_extract tool to recall any of them".
|
|
74
|
+
"""
|
|
75
|
+
hrr: np.ndarray
|
|
76
|
+
n_facts: int
|
|
77
|
+
roles_present: set[str] = field(default_factory=set)
|
|
78
|
+
fact_ids: list[str] = field(default_factory=list)
|
|
79
|
+
preamble: str = ""
|
|
80
|
+
|
|
81
|
+
def to_dict(self) -> dict:
|
|
82
|
+
return {
|
|
83
|
+
"n_facts": self.n_facts,
|
|
84
|
+
"roles_present": sorted(self.roles_present),
|
|
85
|
+
"fact_ids": self.fact_ids,
|
|
86
|
+
"preamble": self.preamble,
|
|
87
|
+
# hrr vector is large; serialize as hex of packed bytes
|
|
88
|
+
# only when explicitly requested via to_dict_with_vec
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
def to_dict_with_vec(self) -> dict:
|
|
92
|
+
d = self.to_dict()
|
|
93
|
+
d["hrr_b64"] = _vec_to_b64(self.hrr)
|
|
94
|
+
return d
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _vec_to_b64(v: np.ndarray) -> str:
|
|
98
|
+
import base64
|
|
99
|
+
return base64.b64encode(v.tobytes()).decode("ascii")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _vec_from_b64(s: str, dtype=np.float32) -> np.ndarray:
|
|
103
|
+
import base64
|
|
104
|
+
return np.frombuffer(base64.b64decode(s), dtype=dtype)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# ---------------------------------------------------------------------------
|
|
108
|
+
# Build / extract
|
|
109
|
+
# ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
def build_holographic_wm(facts: Iterable, vsa,
|
|
112
|
+
embedder, *, max_facts: int = 12,
|
|
113
|
+
roles: tuple[str, ...] = ("S", "R", "V"),
|
|
114
|
+
normalize: bool = True) -> HolographicWM:
|
|
115
|
+
"""Compress top-k facts into a single HRR superposition.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
facts : iterable of fact-like objects with .subject, .relation,
|
|
120
|
+
.value, .id
|
|
121
|
+
vsa : a cortexm.vsa.ops.VSA instance (provides role_vec, bind,
|
|
122
|
+
superpose). The same instance the palace uses — ensures role
|
|
123
|
+
vectors match between encode and unbind.
|
|
124
|
+
embedder : a HashingEmbedder or compatible, for embedding the
|
|
125
|
+
subject/relation/value text.
|
|
126
|
+
max_facts : cap on the number of facts superposed. Beyond ~24 the
|
|
127
|
+
cross-talk noise starts to degrade extraction accuracy.
|
|
128
|
+
roles : which bindings to include in each fact hologram.
|
|
129
|
+
|
|
130
|
+
Returns a HolographicWM with the superposed HRR + metadata.
|
|
131
|
+
"""
|
|
132
|
+
facts = list(facts)[:max_facts]
|
|
133
|
+
if not facts:
|
|
134
|
+
return HolographicWM(hrr=np.zeros(vsa.dims, dtype=np.float32),
|
|
135
|
+
n_facts=0, roles_present=set(),
|
|
136
|
+
fact_ids=[], preamble="(no facts in memory)")
|
|
137
|
+
|
|
138
|
+
roles_present: set[str] = set()
|
|
139
|
+
fact_ids: list[str] = []
|
|
140
|
+
acc = np.zeros(vsa.dims, dtype=np.float32)
|
|
141
|
+
|
|
142
|
+
for f in facts:
|
|
143
|
+
subj = getattr(f, "subject", "") or ""
|
|
144
|
+
rel = getattr(f, "relation", "") or ""
|
|
145
|
+
val = getattr(f, "value", "") or ""
|
|
146
|
+
fid = getattr(f, "id", "") or ""
|
|
147
|
+
fact_ids.append(fid)
|
|
148
|
+
# bind each component against its role vector
|
|
149
|
+
if "S" in roles and subj:
|
|
150
|
+
roles_present.add("S")
|
|
151
|
+
s_emb = embedder.embed(subj)
|
|
152
|
+
acc += vsa.bind("S", s_emb)
|
|
153
|
+
if "R" in roles and rel:
|
|
154
|
+
roles_present.add("R")
|
|
155
|
+
r_emb = embedder.embed(rel.replace("_", " "))
|
|
156
|
+
acc += vsa.bind("R", r_emb)
|
|
157
|
+
if "V" in roles and val:
|
|
158
|
+
roles_present.add("V")
|
|
159
|
+
v_emb = embedder.embed(val)
|
|
160
|
+
acc += vsa.bind("V", v_emb)
|
|
161
|
+
|
|
162
|
+
if normalize:
|
|
163
|
+
n = float(np.linalg.norm(acc))
|
|
164
|
+
if n > 0:
|
|
165
|
+
acc = acc / n
|
|
166
|
+
|
|
167
|
+
preamble = _build_preamble(facts, roles_present)
|
|
168
|
+
return HolographicWM(hrr=acc.astype(np.float32), n_facts=len(facts),
|
|
169
|
+
roles_present=roles_present,
|
|
170
|
+
fact_ids=fact_ids, preamble=preamble)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def extract_from_hologram(hwm: HolographicWM, role: str, query_vec,
|
|
174
|
+
vsa, candidate_embs: np.ndarray,
|
|
175
|
+
candidate_ids: list[str],
|
|
176
|
+
top_k: int = 3) -> list[tuple[str, float]]:
|
|
177
|
+
"""Unbind a role from the hologram and nearest-neighbor lookup.
|
|
178
|
+
|
|
179
|
+
The classic HRR recall: given a hologram H and a role r, the
|
|
180
|
+
unbound vector U = unbind(r, H) is approximately the filler that
|
|
181
|
+
was bound to r in H (averaged across all superposed facts). We then
|
|
182
|
+
find the nearest neighbor of U in the candidate embedding matrix.
|
|
183
|
+
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
hwm : the HolographicWM returned by build_holographic_wm
|
|
187
|
+
role : "S", "R", or "V" — which role to unbind
|
|
188
|
+
query_vec : NOT USED in this simple variant; kept for forward-compat
|
|
189
|
+
with a query-conditional unbind mode.
|
|
190
|
+
vsa : the same VSA instance used to build the hologram
|
|
191
|
+
candidate_embs : (N, dims) matrix of candidate fact-component embeddings
|
|
192
|
+
candidate_ids : list of N ids parallel to candidate_embs
|
|
193
|
+
top_k : how many candidates to return
|
|
194
|
+
|
|
195
|
+
Returns a list of (id, score) sorted desc by score. Empty if the
|
|
196
|
+
hologram is empty or role was not present at build time.
|
|
197
|
+
"""
|
|
198
|
+
if hwm.n_facts == 0 or role not in hwm.roles_present:
|
|
199
|
+
return []
|
|
200
|
+
if candidate_embs is None or len(candidate_embs) == 0:
|
|
201
|
+
return []
|
|
202
|
+
unbound = vsa.unbind(role, hwm.hrr)
|
|
203
|
+
# cosine sim against every candidate (batched)
|
|
204
|
+
cands = np.asarray(candidate_embs, dtype=np.float32)
|
|
205
|
+
norms = np.linalg.norm(cands, axis=1) + 1e-9
|
|
206
|
+
sims = (cands @ unbound) / norms
|
|
207
|
+
# take top-k indices
|
|
208
|
+
if len(sims) <= top_k:
|
|
209
|
+
idxs = np.argsort(-sims)
|
|
210
|
+
else:
|
|
211
|
+
idxs = np.argpartition(-sims, top_k)[:top_k]
|
|
212
|
+
idxs = idxs[np.argsort(-sims[idxs])]
|
|
213
|
+
out = [(candidate_ids[i], float(sims[i])) for i in idxs]
|
|
214
|
+
return out
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# ---------------------------------------------------------------------------
|
|
218
|
+
# Preamble builder — what gets injected into the LLM system prompt.
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
def _build_preamble(facts: list, roles_present: set[str]) -> str:
|
|
222
|
+
"""Build a short (~30-50 token) LLM-ready description of the hologram.
|
|
223
|
+
|
|
224
|
+
The LLM sees this preamble and knows it can ask for unbind queries
|
|
225
|
+
against the hologram. The actual HRR vector is opaque to the LLM
|
|
226
|
+
(it's a vector, not text); the host app routes "what was Alice's
|
|
227
|
+
job?" type questions through the extract_from_hologram endpoint.
|
|
228
|
+
"""
|
|
229
|
+
n = len(facts)
|
|
230
|
+
roles_str = "/".join(sorted(roles_present)) if roles_present else "none"
|
|
231
|
+
subjects = [getattr(f, "subject", "") for f in facts]
|
|
232
|
+
# dedupe subjects
|
|
233
|
+
seen = set()
|
|
234
|
+
unique_subjects = [s for s in subjects
|
|
235
|
+
if s and not (s in seen or seen.add(s))]
|
|
236
|
+
sub_str = ", ".join(unique_subjects[:5])
|
|
237
|
+
if len(unique_subjects) > 5:
|
|
238
|
+
sub_str += f", ... (+{len(unique_subjects) - 5} more)"
|
|
239
|
+
return (f"[Working Memory Hologram] {n} fact(s) compressed "
|
|
240
|
+
f"as HRR over roles ({roles_str}). Subjects: {sub_str}. "
|
|
241
|
+
f"Ask the contextm_hologram_extract tool to recall any "
|
|
242
|
+
f"specific (subject, relation) pair.")
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
__all__ = [
|
|
246
|
+
"HolographicWM",
|
|
247
|
+
"build_holographic_wm",
|
|
248
|
+
"extract_from_hologram",
|
|
249
|
+
]
|