chip-memory 1.1.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.
- chip_memory/__init__.py +31 -0
- chip_memory/__main__.py +83 -0
- chip_memory/_stopwords.py +52 -0
- chip_memory/_utils.py +38 -0
- chip_memory/api.py +628 -0
- chip_memory/auto_write.py +451 -0
- chip_memory/automagic_token.py +35 -0
- chip_memory/bm25.py +231 -0
- chip_memory/collect/__init__.py +22 -0
- chip_memory/collect/absorb.py +631 -0
- chip_memory/collect/adapters/__init__.py +0 -0
- chip_memory/collect/adapters/claude_code.py +352 -0
- chip_memory/collect/adapters/git.py +353 -0
- chip_memory/collect/adapters/shell.py +524 -0
- chip_memory/collect/correlator.py +462 -0
- chip_memory/collect/dedup.py +212 -0
- chip_memory/collect/events.py +204 -0
- chip_memory/collect/redact.py +132 -0
- chip_memory/collect/review_cli.py +10 -0
- chip_memory/collect/signal_detector.py +594 -0
- chip_memory/connect_cmd.py +195 -0
- chip_memory/consolidation.py +353 -0
- chip_memory/contradiction.py +366 -0
- chip_memory/daemon.py +399 -0
- chip_memory/dashboard/static/data.json +327 -0
- chip_memory/dashboard/static/index.html +1141 -0
- chip_memory/dashboard/static/vendor/OrbitControls.js +1417 -0
- chip_memory/dashboard/static/vendor/three.module.js +53044 -0
- chip_memory/dashboard.py +480 -0
- chip_memory/dashboard_cmd.py +80 -0
- chip_memory/doctor.py +268 -0
- chip_memory/eval.py +330 -0
- chip_memory/export.py +228 -0
- chip_memory/export_wiki.py +467 -0
- chip_memory/graph/__init__.py +5 -0
- chip_memory/graph/aliases.py +251 -0
- chip_memory/graph/predicate_vocab.py +177 -0
- chip_memory/graph/typed_edges.py +860 -0
- chip_memory/health.py +191 -0
- chip_memory/hermes.py +363 -0
- chip_memory/linker.py +503 -0
- chip_memory/map_cmd.py +140 -0
- chip_memory/mcp_server.py +491 -0
- chip_memory/node.py +598 -0
- chip_memory/paths.py +109 -0
- chip_memory/pending.py +78 -0
- chip_memory/py.typed +0 -0
- chip_memory/query/__init__.py +2 -0
- chip_memory/query/triple_query.py +347 -0
- chip_memory/rebalance.py +67 -0
- chip_memory/recall.py +149 -0
- chip_memory/search.py +477 -0
- chip_memory/seed.py +86 -0
- chip_memory/server.py +355 -0
- chip_memory/synthesis/__init__.py +6 -0
- chip_memory/synthesis/think.py +965 -0
- chip_memory/telegram_watch.py +590 -0
- chip_memory/timeline.py +489 -0
- chip_memory/timeline_cmd.py +93 -0
- chip_memory/tui.py +678 -0
- chip_memory/uninstall.py +179 -0
- chip_memory/watch_context.py +360 -0
- chip_memory/why.py +32 -0
- chip_memory-1.1.0.dist-info/METADATA +289 -0
- chip_memory-1.1.0.dist-info/RECORD +69 -0
- chip_memory-1.1.0.dist-info/WHEEL +5 -0
- chip_memory-1.1.0.dist-info/entry_points.txt +2 -0
- chip_memory-1.1.0.dist-info/licenses/LICENSE +21 -0
- chip_memory-1.1.0.dist-info/top_level.txt +1 -0
chip_memory/__init__.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
chip_memory — local-first, self-organizing memory layer for AI agents.
|
|
3
|
+
|
|
4
|
+
Inspired by how microchips work: isolated nodes (transistors) organized in
|
|
5
|
+
layers, with a daemon (electricity) always running, become a CPU (a brain).
|
|
6
|
+
|
|
7
|
+
Public API:
|
|
8
|
+
- chip_memory.search — semantic search over the brain
|
|
9
|
+
- chip_memory.health — brain health score + per-domain stats
|
|
10
|
+
- chip_memory.auto_write — extract nodes from a transcript
|
|
11
|
+
- chip_memory.pending — process pending/ → write nodes
|
|
12
|
+
- chip_memory.seed — seed demo nodes for trying the system
|
|
13
|
+
- chip_memory.rebalance — adjust importance/heat of existing nodes
|
|
14
|
+
- chip_memory.daemon — the always-on loop
|
|
15
|
+
- chip_memory.server — tiny HTTP API (run separately)
|
|
16
|
+
"""
|
|
17
|
+
__version__ = "1.1.0"
|
|
18
|
+
__all__ = [
|
|
19
|
+
"api",
|
|
20
|
+
"auto_write",
|
|
21
|
+
"daemon",
|
|
22
|
+
"dashboard",
|
|
23
|
+
"health",
|
|
24
|
+
"node",
|
|
25
|
+
"paths",
|
|
26
|
+
"pending",
|
|
27
|
+
"rebalance",
|
|
28
|
+
"search",
|
|
29
|
+
"seed",
|
|
30
|
+
"server",
|
|
31
|
+
]
|
chip_memory/__main__.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""CLI entry point: `python3 -m chip_memory <command> [args]`
|
|
2
|
+
|
|
3
|
+
Examples:
|
|
4
|
+
python3 -m chip_memory search "what do I know about polish ecommerce"
|
|
5
|
+
python3 -m chip_memory health
|
|
6
|
+
python3 -m chip_memory health --json
|
|
7
|
+
python3 -m chip_memory seed
|
|
8
|
+
python3 -m chip_memory auto-write --input examples/example_session.md
|
|
9
|
+
python3 -m chip_memory daemon
|
|
10
|
+
python3 -m chip_memory server --port 7331
|
|
11
|
+
python3 -m chip_memory rebalance --tags "portfolio,career"
|
|
12
|
+
"""
|
|
13
|
+
import argparse
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
from . import __version__
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
COMMANDS = {
|
|
20
|
+
"absorb": ("chip_memory.collect.absorb", "Absorb knowledge from shell history, git, and Claude Code sessions"),
|
|
21
|
+
"audit": ("chip_memory.contradiction", "Detect contradictions and anomalies in the brain"),
|
|
22
|
+
"auto-write": ("chip_memory.auto_write", "Extract memory nodes from a session transcript"),
|
|
23
|
+
"autowrite": ("chip_memory.auto_write", "Extract memory nodes from a session transcript"),
|
|
24
|
+
"connect": ("chip_memory.connect_cmd", "Find the path connecting two entities through typed edges"),
|
|
25
|
+
"consolidate": ("chip_memory.consolidation", "Run consolidation pass — cluster related knowledge"),
|
|
26
|
+
"daemon": ("chip_memory.daemon", "Start the always-on daemon loop"),
|
|
27
|
+
"dashboard": ("chip_memory.dashboard_cmd", "Launch the web dashboard"),
|
|
28
|
+
"doctor": ("chip_memory.doctor", "Run diagnostic checks on the brain"),
|
|
29
|
+
"eval": ("chip_memory.eval", "Run evaluation benchmarks"),
|
|
30
|
+
"export": ("chip_memory.export", "Export the brain as Markdown"),
|
|
31
|
+
"export-wiki": ("chip_memory.export_wiki", "Export a Karpathy-style LLM wiki"),
|
|
32
|
+
"health": ("chip_memory.health", "Show brain health score and per-domain stats"),
|
|
33
|
+
"hermes": ("chip_memory.hermes", "Hermes bridge — quick context queries"),
|
|
34
|
+
"hubs": ("chip_memory.map_cmd", "List hub nodes (highly-connected)"),
|
|
35
|
+
"map": ("chip_memory.map_cmd", "Explore the knowledge graph structure"),
|
|
36
|
+
"mcp": ("chip_memory.mcp_server", "Start MCP server for Claude Desktop/Code"),
|
|
37
|
+
"pending": ("chip_memory.pending", "Process pending items into memory nodes"),
|
|
38
|
+
"rebalance": ("chip_memory.rebalance", "Adjust importance and heat of existing nodes"),
|
|
39
|
+
"recall": ("chip_memory.recall", "Query episodic memory from the timeline"),
|
|
40
|
+
"remember": ("chip_memory.api", "Remember a fact (CLI wrapper for the API)"),
|
|
41
|
+
"review": ("chip_memory.collect.review_cli", "Review collected items before absorbing"),
|
|
42
|
+
"search": ("chip_memory.search", "Semantic search over the brain"),
|
|
43
|
+
"seed": ("chip_memory.seed", "Seed demo nodes for testing"),
|
|
44
|
+
"think": ("chip_memory.synthesis.think", "Think mode — answer a query with cited evidence and knowledge gaps"),
|
|
45
|
+
"server": ("chip_memory.server", "Start the HTTP API server"),
|
|
46
|
+
"signal": ("chip_memory.collect.signal_detector", "Signal detector — auto-ingest knowledge from agent messages"),
|
|
47
|
+
"telegram": ("chip_memory.telegram_watch", "Start Telegram watch daemon"),
|
|
48
|
+
"timeline": ("chip_memory.timeline_cmd", "Show the brain timeline diary"),
|
|
49
|
+
"tui": ("chip_memory.tui", "Launch the curses TUI"),
|
|
50
|
+
"uninstall": ("chip_memory.uninstall", "Safely remove chip-memory data"),
|
|
51
|
+
"watch-context": ("chip_memory.watch_context", "Watch and log context queries"),
|
|
52
|
+
"why": ("chip_memory.why", "Show detailed provenance and usage info for a node"),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def main():
|
|
57
|
+
# Handle --version before any command dispatch
|
|
58
|
+
if "--version" in sys.argv:
|
|
59
|
+
ap = argparse.ArgumentParser(add_help=False)
|
|
60
|
+
ap.add_argument("--version", action="version", version=f"chip-memory {__version__}")
|
|
61
|
+
ap.parse_args(["--version"]) # exits after printing version
|
|
62
|
+
|
|
63
|
+
if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help", "help"):
|
|
64
|
+
print(__doc__)
|
|
65
|
+
print("\nAvailable commands:")
|
|
66
|
+
for cmd in sorted(COMMANDS):
|
|
67
|
+
module, desc = COMMANDS[cmd]
|
|
68
|
+
print(f" {cmd:20s} {desc}")
|
|
69
|
+
sys.exit(0 if len(sys.argv) >= 2 else 1)
|
|
70
|
+
|
|
71
|
+
cmd = sys.argv[1]
|
|
72
|
+
if cmd not in COMMANDS:
|
|
73
|
+
print(f"unknown command: {cmd!r}\navailable: {', '.join(sorted(COMMANDS))}")
|
|
74
|
+
sys.exit(2)
|
|
75
|
+
|
|
76
|
+
# Re-exec as `python3 -m <module>` with the rest of argv
|
|
77
|
+
import runpy
|
|
78
|
+
sys.argv = [sys.argv[0]] + sys.argv[2:]
|
|
79
|
+
runpy.run_module(COMMANDS[cmd][0], run_name="__main__", alter_sys=True)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
main()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared stopword set used by both BM25 search and the linker.
|
|
3
|
+
|
|
4
|
+
Single source of truth — if you need to add or remove a stopword,
|
|
5
|
+
do it here and both modules pick up the change automatically.
|
|
6
|
+
"""
|
|
7
|
+
STOPWORDS = frozenset({
|
|
8
|
+
# Articles & basic determiners
|
|
9
|
+
"the", "a", "an", "and", "or", "but", "if", "then", "so", "that",
|
|
10
|
+
"this", "these", "those", "each", "every", "other", "another",
|
|
11
|
+
"some", "any", "no", "none", "both", "either", "neither",
|
|
12
|
+
|
|
13
|
+
# Prepositions
|
|
14
|
+
"to", "of", "in", "on", "at", "by", "for", "with", "from",
|
|
15
|
+
"into", "about", "since", "though", "although", "whether",
|
|
16
|
+
"rather", "instead", "therefore", "thus", "hence", "whereas",
|
|
17
|
+
"whereby",
|
|
18
|
+
|
|
19
|
+
# Verbs (common)
|
|
20
|
+
"is", "are", "was", "were", "be", "been", "being", "have",
|
|
21
|
+
"has", "had", "do", "does", "done", "doing", "make", "made",
|
|
22
|
+
"makes", "using", "used", "uses", "get", "got", "gets",
|
|
23
|
+
"getting", "set", "sets", "put", "puts", "take", "takes",
|
|
24
|
+
"took", "taken", "give", "gave", "given", "find", "found",
|
|
25
|
+
"finds", "keep", "kept", "keeps", "tell", "tells", "told",
|
|
26
|
+
"ask", "asks", "asked", "seem", "seems", "seemed", "show",
|
|
27
|
+
"shows", "showed", "shown", "know", "knew", "known", "need",
|
|
28
|
+
"needs", "want", "wanted", "wants", "going", "goes",
|
|
29
|
+
|
|
30
|
+
# Modals & auxiliaries
|
|
31
|
+
"will", "would", "could", "should", "can", "may", "might",
|
|
32
|
+
"must", "shall",
|
|
33
|
+
|
|
34
|
+
# Pronouns & possessives
|
|
35
|
+
"they", "them", "their", "there", "your", "yours", "our",
|
|
36
|
+
"ours", "my", "mine", "its", "who", "whom", "whose",
|
|
37
|
+
"which", "where", "when", "what", "while",
|
|
38
|
+
|
|
39
|
+
# Common adverbs
|
|
40
|
+
"also", "just", "like", "such", "only", "very", "more",
|
|
41
|
+
"most", "much", "many", "really", "actually", "probably",
|
|
42
|
+
"maybe", "perhaps", "always", "never", "often", "sometimes",
|
|
43
|
+
"usually", "however", "because",
|
|
44
|
+
|
|
45
|
+
# Quantifiers / indefinite
|
|
46
|
+
"thing", "things", "kind", "sort", "way", "ways",
|
|
47
|
+
"anyone", "anywhere", "something", "nothing", "everything",
|
|
48
|
+
"someone", "everyone",
|
|
49
|
+
|
|
50
|
+
# Extra high-frequency noise
|
|
51
|
+
"than", "then", "also", "upon", "versus", "via",
|
|
52
|
+
})
|
chip_memory/_utils.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
chip_memory._utils — shared utility functions.
|
|
3
|
+
|
|
4
|
+
Centralizing common patterns (ISO date parsing, text truncation, word
|
|
5
|
+
extraction) to eliminate duplication across the codebase.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_WORD_RE = re.compile(r"[\w_]+")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def parse_iso_datetime(s: str) -> datetime:
|
|
17
|
+
"""Parse an ISO 8601 datetime string, handling 'Z' suffix."""
|
|
18
|
+
return datetime.fromisoformat(s.replace("Z", "+00:00"))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def truncate_preview(text: str, max_len: int = 120) -> str:
|
|
22
|
+
"""Truncate text to max_len with ellipsis if needed."""
|
|
23
|
+
if len(text) > max_len:
|
|
24
|
+
return text[:max_len] + "..."
|
|
25
|
+
return text
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def extract_words(text: str) -> list[str]:
|
|
29
|
+
"""Extract lowercase word tokens from text using regex.
|
|
30
|
+
|
|
31
|
+
Returns all word-like tokens (letters, digits, underscore).
|
|
32
|
+
Returns empty list for None or empty input.
|
|
33
|
+
"""
|
|
34
|
+
if not text:
|
|
35
|
+
return []
|
|
36
|
+
return _WORD_RE.findall(text.lower())
|
|
37
|
+
|
|
38
|
+
|