@bcmyguest/openmem 0.0.0-stage → 0.8.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 (230) hide show
  1. package/.agents/skills/openmem/SKILL.md +34 -0
  2. package/LICENSE +190 -0
  3. package/README.md +140 -2
  4. package/bin/hindsight-project-index +530 -0
  5. package/cli/coding-agent/access-policy.mjs +38 -0
  6. package/cli/coding-agent/agents.mjs +34 -0
  7. package/cli/coding-agent/bank-from-cwd.mjs +140 -0
  8. package/cli/coding-agent/capabilities.mjs +34 -0
  9. package/cli/coding-agent/context-store.mjs +81 -0
  10. package/cli/coding-agent/context-trim.mjs +897 -0
  11. package/cli/coding-agent/file-io.mjs +72 -0
  12. package/cli/coding-agent/hook-harnesses.mjs +88 -0
  13. package/cli/coding-agent/hook-runner.mjs +284 -0
  14. package/cli/coding-agent/install-access.mjs +119 -0
  15. package/cli/coding-agent/install-context-proxy.mjs +333 -0
  16. package/cli/coding-agent/install-rtk.mjs +60 -0
  17. package/cli/coding-agent/install-shim.mjs +201 -0
  18. package/cli/coding-agent/opencode-config.mjs +107 -0
  19. package/cli/coding-agent/opencode-plugin.mjs +132 -0
  20. package/cli/coding-agent/opencode2-plugin/index.js +299 -0
  21. package/cli/coding-agent/recall-frame.mjs +29 -0
  22. package/cli/coding-agent/remove-upstream-access.mjs +122 -0
  23. package/cli/coding-agent/runtime.mjs +40 -0
  24. package/cli/coding-agent/session-db.mjs +626 -0
  25. package/cli/coding-agent/session-facade.mjs +86 -0
  26. package/cli/coding-agent/toml-edit.mjs +161 -0
  27. package/cli/cognee-mcp.mjs +260 -0
  28. package/cli/context-management.mjs +254 -0
  29. package/cli/feed-sync.mjs +27 -0
  30. package/cli/install-coding-agent.mjs +298 -0
  31. package/cli/install-memory-mcp.mjs +426 -0
  32. package/cli/is-main.mjs +18 -0
  33. package/cli/mcp/context-sql-runner.mjs +58 -0
  34. package/cli/mcp/context-store.mjs +670 -0
  35. package/cli/mcp/context.mjs +61 -0
  36. package/cli/mcp/export/cognee-dataset-name.mjs +12 -0
  37. package/cli/mcp/export/cognee.mjs +119 -0
  38. package/cli/mcp/export/hindsight.mjs +48 -0
  39. package/cli/mcp/export/index.mjs +26 -0
  40. package/cli/mcp/export/mem0.mjs +31 -0
  41. package/cli/mcp/knowledge.mjs +333 -0
  42. package/cli/mcp/llm-synthesize.mjs +50 -0
  43. package/cli/mcp/mem0-scope-id.mjs +22 -0
  44. package/cli/mcp/memory-facade.mjs +521 -0
  45. package/cli/mcp/memory-reflect-consolidate.mjs +120 -0
  46. package/cli/mcp/notebooklm-banks.mjs +21 -0
  47. package/cli/mcp/notebooklm-hindsight-rest.mjs +45 -0
  48. package/cli/mcp/notebooklm-provider.mjs +225 -0
  49. package/cli/mcp/pmm-records.mjs +23 -0
  50. package/cli/mcp/portability.mjs +158 -0
  51. package/cli/mcp/stdio.mjs +65 -0
  52. package/cli/mcp/unified-mcp-install.mjs +65 -0
  53. package/cli/mem0-mcp.mjs +108 -0
  54. package/cli/notebooklm-mcp.mjs +236 -0
  55. package/cli/openmem-mcp.mjs +38 -0
  56. package/cli/openmem.mjs +222 -0
  57. package/cli/roots.mjs +85 -0
  58. package/cli/schedule.mjs +176 -0
  59. package/cli/stack.mjs +438 -0
  60. package/cli/switch-memory-provider.mjs +358 -0
  61. package/cli/wiring-report.mjs +125 -0
  62. package/compose.bench.yaml +12 -0
  63. package/compose.yaml +227 -0
  64. package/config/coding-agent.json +13 -0
  65. package/config/hindsight.env.example +26 -0
  66. package/config/index.yml +54 -0
  67. package/config/litellm.lemond.yaml +40 -0
  68. package/config/litellm.ollama.yaml +33 -0
  69. package/config/notebooklm.yml +33 -0
  70. package/config/openmem.toml.example +124 -0
  71. package/docs/OPENMEM.md +23 -0
  72. package/docs/architecture.md +245 -0
  73. package/docs/assets/README.md +10 -0
  74. package/docs/assets/setup-demo.gif +0 -0
  75. package/docs/coding-agent-hooks.md +75 -0
  76. package/docs/coding-agent-scopes.md +22 -0
  77. package/docs/coding-agents.md +71 -0
  78. package/docs/cognee.md +37 -0
  79. package/docs/compatibility.md +80 -0
  80. package/docs/concepts.md +135 -0
  81. package/docs/context-management.md +255 -0
  82. package/docs/context-proxy.md +115 -0
  83. package/docs/context-research.md +215 -0
  84. package/docs/context-store.md +277 -0
  85. package/docs/hindsight.md +77 -0
  86. package/docs/index-sources-roadmap.md +38 -0
  87. package/docs/index-sources.md +39 -0
  88. package/docs/indexer-sinks.md +122 -0
  89. package/docs/indexing.md +57 -0
  90. package/docs/manual-stack-setup.md +74 -0
  91. package/docs/mcp-install-guide.md +4 -0
  92. package/docs/mcp-setup.md +104 -0
  93. package/docs/mem0.md +141 -0
  94. package/docs/memory-portability.md +73 -0
  95. package/docs/memory-providers.md +246 -0
  96. package/docs/meridian-litellm.md +198 -0
  97. package/docs/model-configuration.md +106 -0
  98. package/docs/notebooklm.md +83 -0
  99. package/docs/npx-install.md +172 -0
  100. package/docs/openmem-config.md +194 -0
  101. package/docs/provider-wizard-hooks.md +222 -0
  102. package/docs/quickstart.md +107 -0
  103. package/docs/setup-wizard.md +117 -0
  104. package/docs/sources-feeds.md +39 -0
  105. package/docs/sources-readwise.md +23 -0
  106. package/docs/sources-zotero.md +22 -0
  107. package/glama.json +4 -0
  108. package/indexer/Dockerfile +38 -0
  109. package/indexer/code_outline.py +146 -0
  110. package/indexer/feed_sync.py +107 -0
  111. package/indexer/index_config.py +290 -0
  112. package/indexer/pytest.ini +5 -0
  113. package/indexer/sinks/__init__.py +148 -0
  114. package/indexer/sinks/_http.py +44 -0
  115. package/indexer/sinks/cognee.py +329 -0
  116. package/indexer/sinks/hindsight.py +107 -0
  117. package/indexer/sinks/mem0.py +247 -0
  118. package/indexer/watch.py +240 -0
  119. package/package.json +96 -4
  120. package/providers/_template/compose.yaml +52 -0
  121. package/providers/cognee/OPERATOR.md +82 -0
  122. package/providers/cognee/compose.yaml +89 -0
  123. package/providers/cognee/lib/clack.mjs +157 -0
  124. package/providers/cognee/lib/coding-agent.mjs +26 -0
  125. package/providers/cognee/lib/cognee-mcp-install.mjs +153 -0
  126. package/providers/cognee/lib/config.mjs +98 -0
  127. package/providers/cognee/lib/env-file.mjs +194 -0
  128. package/providers/cognee/lib/env-setup.mjs +83 -0
  129. package/providers/cognee/lib/llm-env.mjs +382 -0
  130. package/providers/cognee/lib/ports.mjs +25 -0
  131. package/providers/cognee/lib/smoke.mjs +246 -0
  132. package/providers/cognee/lib/stack-env.mjs +134 -0
  133. package/providers/cognee/lib/state.mjs +101 -0
  134. package/providers/cognee/lib/summary.mjs +56 -0
  135. package/providers/cognee/lib/validate.mjs +97 -0
  136. package/providers/cognee/manifest.json +56 -0
  137. package/providers/cognee/wizard.mjs +134 -0
  138. package/providers/graphiti/manifest.json +15 -0
  139. package/providers/hindsight/lib/clack.mjs +347 -0
  140. package/providers/hindsight/lib/coding-agent.mjs +204 -0
  141. package/providers/hindsight/lib/config.mjs +79 -0
  142. package/providers/hindsight/lib/env-setup.mjs +72 -0
  143. package/providers/hindsight/lib/litellm-routes.mjs +196 -0
  144. package/providers/hindsight/lib/meridian.mjs +307 -0
  145. package/providers/hindsight/lib/model-backend.mjs +243 -0
  146. package/providers/hindsight/lib/notebooklm-mcp-install.mjs +127 -0
  147. package/providers/hindsight/lib/ollama-compose.mjs +51 -0
  148. package/providers/hindsight/lib/ports.mjs +30 -0
  149. package/providers/hindsight/lib/probe.mjs +54 -0
  150. package/providers/hindsight/lib/stack-env.mjs +125 -0
  151. package/providers/hindsight/lib/state.mjs +80 -0
  152. package/providers/hindsight/lib/summary.mjs +57 -0
  153. package/providers/hindsight/lib/validate.mjs +81 -0
  154. package/providers/hindsight/manifest.json +58 -0
  155. package/providers/hindsight/wizard.mjs +150 -0
  156. package/providers/letta/manifest.json +29 -0
  157. package/providers/mem0/OPERATOR.md +143 -0
  158. package/providers/mem0/compose.yaml +79 -0
  159. package/providers/mem0/lib/coding-agent.mjs +58 -0
  160. package/providers/mem0/lib/config.mjs +45 -0
  161. package/providers/mem0/lib/configure.mjs +201 -0
  162. package/providers/mem0/lib/dotenv.mjs +71 -0
  163. package/providers/mem0/lib/env-file.mjs +110 -0
  164. package/providers/mem0/lib/http.mjs +69 -0
  165. package/providers/mem0/lib/litellm.mjs +457 -0
  166. package/providers/mem0/lib/mcp-install.mjs +165 -0
  167. package/providers/mem0/lib/secret.mjs +30 -0
  168. package/providers/mem0/lib/smoke.mjs +179 -0
  169. package/providers/mem0/lib/stack-env.mjs +255 -0
  170. package/providers/mem0/lib/state.mjs +67 -0
  171. package/providers/mem0/lib/summary.mjs +88 -0
  172. package/providers/mem0/lib/url.mjs +106 -0
  173. package/providers/mem0/lib/validate.mjs +158 -0
  174. package/providers/mem0/manifest.json +47 -0
  175. package/providers/mem0/wizard.mjs +146 -0
  176. package/providers/zep/manifest.json +29 -0
  177. package/proxy/config.yaml +33 -0
  178. package/proxy/openmem_context/__init__.py +6 -0
  179. package/proxy/openmem_context/adapters.py +504 -0
  180. package/proxy/openmem_context/compress.py +53 -0
  181. package/proxy/openmem_context/core.py +606 -0
  182. package/proxy/openmem_context/embed.py +212 -0
  183. package/proxy/openmem_context/recall.py +49 -0
  184. package/proxy/openmem_context/session.py +70 -0
  185. package/proxy/openmem_context/sessiondb.py +276 -0
  186. package/proxy/openmem_context/settings.py +134 -0
  187. package/proxy/openmem_context/store.py +129 -0
  188. package/proxy/openmem_context/tokens.py +123 -0
  189. package/proxy/openmem_context/ttl.py +78 -0
  190. package/proxy/openmem_context_hook.py +34 -0
  191. package/scripts/check-pack.mjs +219 -0
  192. package/scripts/gen-masks.mjs +83 -0
  193. package/scripts/gen-masks.sh +4 -0
  194. package/scripts/promotion-provider-smoke.mjs +34 -0
  195. package/scripts/run-setup.sh +30 -0
  196. package/scripts/setup.mjs +107 -0
  197. package/scripts/setup.sh +5 -0
  198. package/scripts/spin-up.sh +45 -0
  199. package/scripts/wizard.sh +5 -0
  200. package/server.json +34 -0
  201. package/sync/Dockerfile +27 -0
  202. package/sync/memory_backend.py +87 -0
  203. package/sync/notebooklm_sync.py +664 -0
  204. package/wizard/bin/pm.mjs +97 -0
  205. package/wizard/bin/setup.mjs +33 -0
  206. package/wizard/lib/compose-version.mjs +32 -0
  207. package/wizard/lib/compose.mjs +70 -0
  208. package/wizard/lib/context-step.mjs +140 -0
  209. package/wizard/lib/curl.mjs +103 -0
  210. package/wizard/lib/docker-build.mjs +148 -0
  211. package/wizard/lib/exec.mjs +41 -0
  212. package/wizard/lib/indexer.mjs +6 -0
  213. package/wizard/lib/litellm-env.mjs +55 -0
  214. package/wizard/lib/load-machine-env.mjs +4 -0
  215. package/wizard/lib/log.mjs +32 -0
  216. package/wizard/lib/notebooklm-agent-access.mjs +92 -0
  217. package/wizard/lib/notebooklm.mjs +214 -0
  218. package/wizard/lib/parse-args.mjs +87 -0
  219. package/wizard/lib/paths.mjs +39 -0
  220. package/wizard/lib/pm-config.mjs +371 -0
  221. package/wizard/lib/ports.mjs +94 -0
  222. package/wizard/lib/prompts.mjs +85 -0
  223. package/wizard/lib/provider-wizard/helpers.mjs +98 -0
  224. package/wizard/lib/provider-wizard/run-steps.mjs +129 -0
  225. package/wizard/lib/providers/registry.mjs +262 -0
  226. package/wizard/lib/run-clack.mjs +108 -0
  227. package/wizard/lib/run-wizard.mjs +750 -0
  228. package/wizard/lib/validate-setup.mjs +62 -0
  229. package/wizard/lib/wizard-action.mjs +34 -0
  230. package/wizard/lib/wizard-conf.mjs +71 -0
package/compose.yaml ADDED
@@ -0,0 +1,227 @@
1
+ name: openmem
2
+
3
+ # Memory provider stack (Hindsight by default) and the project/Obsidian indexer.
4
+ # Set HINDSIGHT_ENV_FILE to use an env file other than ~/.config/hindsight/hindsight.env.
5
+ #
6
+ # Provider selection is by compose profile:
7
+ # - litellm and hindsight carry the profile "hindsight" (and "notebooklm", which needs them). litellm also carries
8
+ # its own profile "litellm", so a provider other than Hindsight can run the stack LiteLLM as its model gateway
9
+ # (mem0: providers/mem0/compose.yaml publishes it on loopback; docs/mem0.md "Models through the stack LiteLLM").
10
+ # - indexer and indexer-state-init have no profile and no hard provider dependency; they start for every provider.
11
+ # - Another provider ships providers/<id>/compose.yaml (see providers/_template/compose.yaml) with its own
12
+ # profile, and layers over this file: docker compose -f compose.yaml -f providers/<id>/compose.yaml --profile <id> up -d
13
+ # Compose starts no profiled service unless a profile is enabled, so the plain `docker compose up -d` of the README
14
+ # needs COMPOSE_PROFILES=hindsight in .env (or --profile hindsight). Note that a --profile flag replaces
15
+ # COMPOSE_PROFILES rather than adding to it; name every profile you want on the command line.
16
+
17
+ # Shared build for the indexer and its state-volume init step.
18
+ x-indexer-build: &indexer-build
19
+ build:
20
+ context: .
21
+ dockerfile: indexer/Dockerfile
22
+
23
+ services:
24
+ # OpenAI-compatible proxy in front of the model server. Hindsight calls it at http://litellm:4000/v1 with the
25
+ # fixed aliases memory-retain, memory-reflect, memory-consolidate. Routes live in LITELLM_CONFIG (set by scripts/setup.sh).
26
+ # Internal network only under Hindsight: nothing is published to the host. The "litellm" profile runs it without
27
+ # Hindsight; providers/mem0/compose.yaml then publishes it on 127.0.0.1 and refuses to start without a master key.
28
+ litellm:
29
+ profiles: ["hindsight", "notebooklm", "litellm"]
30
+ image: ghcr.io/berriai/litellm:v1.106.6
31
+ command: ["--config", "/app/config.yaml", "--port", "4000"]
32
+ env_file: ${LITELLM_ENV_FILE:-${HOME}/.config/hindsight/litellm.env}
33
+ volumes:
34
+ - ${LITELLM_CONFIG:?run scripts/setup.sh}:/app/config.yaml:ro
35
+ extra_hosts:
36
+ - "host.docker.internal:host-gateway"
37
+ restart: unless-stopped
38
+ healthcheck:
39
+ test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:4000/health/liveliness', timeout=5)"]
40
+ interval: 15s
41
+ timeout: 10s
42
+ retries: 10
43
+ start_period: 30s
44
+
45
+ hindsight:
46
+ profiles: ["hindsight", "notebooklm"]
47
+ depends_on:
48
+ litellm:
49
+ condition: service_healthy
50
+ # Pinned to the digest running before the pin (org.opencontainers.image.version 1.0.0). Bump deliberately.
51
+ image: ghcr.io/vectorize-io/hindsight@sha256:a88678c038b0e4340822b02a5efc566c56d8176b5bffa731bc433fd37f978e4c
52
+ # Embedded Postgres needs more than Docker's 64 MB default /dev/shm.
53
+ shm_size: 1g
54
+ env_file: ${HINDSIGHT_ENV_FILE:-${HOME}/.config/hindsight/hindsight.env}
55
+ ports:
56
+ # Host ports from .env (HINDSIGHT_PORT, HINDSIGHT_CP_PORT); defaults 8888 and 9999.
57
+ - "127.0.0.1:${HINDSIGHT_PORT:-8888}:8888"
58
+ - "127.0.0.1:${HINDSIGHT_CP_PORT:-9999}:9999"
59
+ extra_hosts:
60
+ - "host.docker.internal:host-gateway"
61
+ volumes:
62
+ # Named volume: the image's hindsight user (UID 1000) owns it on first use, unlike a host bind mount.
63
+ - hindsight-data:/home/hindsight/.pg0
64
+ restart: unless-stopped
65
+ healthcheck:
66
+ test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8888/health', timeout=5)"]
67
+ interval: 15s
68
+ timeout: 10s
69
+ retries: 10
70
+ start_period: 60s
71
+
72
+ indexer:
73
+ <<: *indexer-build
74
+ image: openmem-indexer:local
75
+ # Host UID/GID from .env, written by scripts/setup.sh. The image needs no passwd entry for this user.
76
+ user: "${HOST_UID:?run scripts/setup.sh}:${HOST_GID:?run scripts/setup.sh}"
77
+ # Same absolute paths inside the container so bank and document IDs match host paths.
78
+ # Read-only: the indexer reads repositories and writes only its state volume below. Tree-sitter outlines
79
+ # need no writes, and CodeGraph's .codegraph/ writes are gone.
80
+ # Secret paths under $HOME are masked by compose.override.yaml, generated by scripts/gen-masks.sh (required).
81
+ volumes:
82
+ - ${HOME}:${HOME}:ro
83
+ # Writable state (state.json, lock). Its mount point is inside the read-only $HOME mount.
84
+ - indexer-state:${HOME}/.cache/hindsight-project-index
85
+ environment:
86
+ HOME: ${HOME}
87
+ HINDSIGHT_URL: http://hindsight:8888
88
+ depends_on:
89
+ # Soft: waits for Hindsight to be healthy when its profile is active and is ignored otherwise (other providers
90
+ # add their own dependency in providers/<id>/compose.yaml). Unlike a hard dependency, an unhealthy Hindsight
91
+ # only logs a warning; the indexer starts anyway and its watcher retries.
92
+ hindsight:
93
+ condition: service_healthy
94
+ required: false
95
+ indexer-state-init:
96
+ condition: service_completed_successfully
97
+ restart: unless-stopped
98
+
99
+ # Named volumes are created root-owned. This one-off root step gives the state volume to the host UID, then exits.
100
+ indexer-state-init:
101
+ <<: *indexer-build
102
+ image: openmem-indexer:local
103
+ user: "0:0"
104
+ entrypoint: ["sh", "-c", "chown ${HOST_UID:?run scripts/setup.sh}:${HOST_GID:?run scripts/setup.sh} /state"]
105
+ volumes:
106
+ - indexer-state:/state
107
+ restart: "no"
108
+
109
+ # Opt-in: docker compose --profile ollama up -d ollama. Used when the host has no Ollama; LiteLLM reaches it at
110
+ # http://ollama:11434 on the compose network. Port 11434 is published on loopback so the wizard can probe and pull.
111
+ ollama:
112
+ profiles: ["ollama"]
113
+ image: ollama/ollama:latest
114
+ ports:
115
+ - "127.0.0.1:11434:11434"
116
+ volumes:
117
+ - ollama-data:/root/.ollama
118
+ restart: unless-stopped
119
+ healthcheck:
120
+ test: ["CMD-SHELL", "ollama list >/dev/null 2>&1 || exit 1"]
121
+ interval: 15s
122
+ timeout: 10s
123
+ retries: 10
124
+ start_period: 20s
125
+
126
+ # Opt-in: docker compose --profile notebooklm up -d notebooklm. Syncs into notebooklm::* banks on the active MEMORY_SINK.
127
+ # Login is on the host (README "NotebookLM"); the storage under ~/.config/notebooklm is bind-mounted read-write.
128
+ notebooklm:
129
+ profiles: ["notebooklm"]
130
+ build:
131
+ context: .
132
+ dockerfile: sync/Dockerfile
133
+ image: openmem-notebooklm:local
134
+ # Host UID/GID from .env, written by scripts/setup.sh; the bind-mounted login storage must stay host-owned.
135
+ user: "${HOST_UID:?run scripts/setup.sh}:${HOST_GID:?run scripts/setup.sh}"
136
+ environment:
137
+ HINDSIGHT_URL: http://hindsight:8888
138
+ MEMORY_SINK: ${MEMORY_SINK:-hindsight}
139
+ MEMORY_API_URL: ${MEMORY_API_URL:-}
140
+ NOTEBOOKLM_HOME: /data/notebooklm
141
+ NOTEBOOKLM_STATE: /data/state/state.json
142
+ volumes:
143
+ - type: bind
144
+ source: ${HOME}/.config/notebooklm
145
+ target: /data/notebooklm
146
+ bind:
147
+ create_host_path: false
148
+ # Per-machine override (only the keys you change). Create the file before starting; compose does not create it.
149
+ - type: bind
150
+ source: ${NOTEBOOKLM_OVERRIDE:-${HOME}/.config/hindsight/notebooklm.yml}
151
+ target: /etc/notebooklm/override.yml
152
+ read_only: true
153
+ bind:
154
+ create_host_path: false
155
+ # Writable sync state (state.json). The image creates it 0777, so Docker copies that mode into the new volume.
156
+ - notebooklm-state:/data/state
157
+ depends_on:
158
+ hindsight:
159
+ condition: service_healthy
160
+ required: false
161
+ restart: unless-stopped
162
+
163
+ # Opt-in: docker compose --profile context-proxy up -d context-proxy. LiteLLM in front of Anthropic for coding
164
+ # agents: compresses large tool results and trims long sessions (docs/context-proxy.md). Separate from the litellm
165
+ # service and outside the hindsight profile, so Hindsight's own model traffic never passes through it.
166
+ context-proxy:
167
+ profiles: ["context-proxy"]
168
+ # Dev build on purpose: v1.109.0-dev.1 is the only LiteLLM release with PR #41522, the ChatGPT/Codex
169
+ # subscription pass-through (/backend-api/codex/{endpoint}) that routes Codex here; stable releases
170
+ # (v1.106.6, v1.108.0-rc.1) lack it. The litellm service above stays on stable. Move to the first stable
171
+ # release that contains #41522, then rerun proxy/tests/image/run.py.
172
+ image: ghcr.io/berriai/litellm:v1.109.0-dev.1
173
+ command: ["--config", "/app/proxy/config.yaml", "--port", "4000"]
174
+ # LITELLM_MASTER_KEY (and any provider keys for extra routes). Written by install-coding-agent.
175
+ env_file: ${CONTEXT_PROXY_ENV_FILE:-${HOME}/.config/personal-memory/context-proxy.env}
176
+ # Host UID/GID from .env, written by scripts/setup.sh; the context store stays host-owned (docs/context-store.md).
177
+ user: "${HOST_UID:?run scripts/setup.sh}:${HOST_GID:?run scripts/setup.sh}"
178
+ ports:
179
+ - "127.0.0.1:${CONTEXT_PROXY_PORT:-4100}:4000"
180
+ environment:
181
+ HOME: /tmp
182
+ PYTHONDONTWRITEBYTECODE: "1"
183
+ OPENMEM_STATE_DIR: /state
184
+ HINDSIGHT_URL: ${CONTEXT_PROXY_HINDSIGHT_URL:-http://hindsight:8888}
185
+ CONTEXT_PROXY_ENABLED: ${CONTEXT_PROXY_ENABLED:-1}
186
+ # From config.toml [context_proxy] trim_at_tokens / trim_to_fraction / compress_over_tokens / standing_instruction / chars_per_token, [compaction] max_chars / recall
187
+ # and [context_store] ttl_days / embedding_model / embedding_timeout_s / embedding_max_chars,
188
+ # written into .env by scripts/setup.mjs and install-coding-agent; a shell export overrides .env.
189
+ # CONTEXT_TRIM_AT_TOKENS stays empty when unset, so the proxy picks the threshold by model.
190
+ CONTEXT_TRIM_AT_TOKENS: ${CONTEXT_TRIM_AT_TOKENS:-}
191
+ CONTEXT_TRIM_TO_FRACTION: ${CONTEXT_TRIM_TO_FRACTION:-0.3}
192
+ CONTEXT_COMPRESS_OVER_TOKENS: ${CONTEXT_COMPRESS_OVER_TOKENS:-4000}
193
+ CONTEXT_COMPACTION_MAX_CHARS: ${CONTEXT_COMPACTION_MAX_CHARS:-12000}
194
+ CONTEXT_COMPACTION_RECALL: ${CONTEXT_COMPACTION_RECALL:-1}
195
+ CONTEXT_STANDING_INSTRUCTION: ${CONTEXT_STANDING_INSTRUCTION:-1}
196
+ CONTEXT_CHARS_PER_TOKEN: ${CONTEXT_CHARS_PER_TOKEN:-2.5}
197
+ # Session databases (docs/context-store.md): [context_store] ttl_days and embedding_model. Vectors are off while
198
+ # CONTEXT_EMBEDDING_MODEL is empty; the embeddings URL is the container's view of an OpenAI-compatible
199
+ # /embeddings endpoint (Ollama on the host by default). CONTEXT_EMBEDDING_API_KEY, if needed, goes in the env file.
200
+ CONTEXT_STORE_TTL_DAYS: ${CONTEXT_STORE_TTL_DAYS:-30}
201
+ CONTEXT_EMBEDDING_MODEL: ${CONTEXT_EMBEDDING_MODEL:-}
202
+ CONTEXT_EMBEDDING_URL: ${CONTEXT_PROXY_EMBEDDING_URL:-http://host.docker.internal:11434/v1}
203
+ CONTEXT_EMBEDDING_TIMEOUT_S: ${CONTEXT_EMBEDDING_TIMEOUT_S:-30}
204
+ CONTEXT_EMBEDDING_MAX_CHARS: ${CONTEXT_EMBEDDING_MAX_CHARS:-4000}
205
+ volumes:
206
+ - ./proxy:/app/proxy:ro
207
+ # Create it first (mode 700, host-owned); compose would otherwise create a root-owned directory.
208
+ - type: bind
209
+ source: ${OPENMEM_STATE_DIR:-${HOME}/.local/share/openmem}/context
210
+ target: /state/context
211
+ bind:
212
+ create_host_path: false
213
+ extra_hosts:
214
+ - "host.docker.internal:host-gateway"
215
+ restart: unless-stopped
216
+ healthcheck:
217
+ test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:4000/health/liveliness', timeout=5)"]
218
+ interval: 15s
219
+ timeout: 10s
220
+ retries: 10
221
+ start_period: 30s
222
+
223
+ volumes:
224
+ hindsight-data:
225
+ indexer-state:
226
+ notebooklm-state:
227
+ ollama-data:
@@ -0,0 +1,13 @@
1
+ {
2
+ "serverMode": "self-hosted",
3
+ "apiUrl": "http://127.0.0.1:8888",
4
+ "optInOnly": true,
5
+ "optInPaths": [],
6
+ "mapPathToBank": {},
7
+ "notebooklmAccess": {
8
+ "enabled": false,
9
+ "banks": [
10
+ "*"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,26 @@
1
+ # Copy to ~/.config/hindsight/hindsight.env and edit. The real file lives outside the repository;
2
+ # compose.yaml reads it from there (or $HINDSIGHT_ENV_FILE).
3
+ # Docker reaches host services at host.docker.internal.
4
+ # All LLM calls go to the LiteLLM proxy (compose service `litellm`). Models are chosen in config/litellm.*.yaml.
5
+ # scripts/setup.sh --migrate-env writes HINDSIGHT_API_LLM_API_KEY from ~/.config/hindsight/litellm.env.
6
+ HINDSIGHT_API_LLM_PROVIDER=openai
7
+ HINDSIGHT_API_LLM_BASE_URL=http://litellm:4000/v1
8
+ HINDSIGHT_API_LLM_MODEL=memory-reflect
9
+ HINDSIGHT_API_RETAIN_LLM_MODEL=memory-retain
10
+ HINDSIGHT_API_REFLECT_LLM_MODEL=memory-reflect
11
+ HINDSIGHT_API_CONSOLIDATION_LLM_MODEL=memory-consolidate
12
+ HINDSIGHT_API_MENTAL_MODEL_REFRESH_LLM_MODEL=memory-reflect
13
+ HINDSIGHT_API_LLM_API_KEY=replace-me
14
+ HINDSIGHT_API_EMBEDDINGS_PROVIDER=local
15
+ HINDSIGHT_API_RERANKER_PROVIDER=local
16
+ HINDSIGHT_API_WORKER_ID=hindsight-personal
17
+ HINDSIGHT_API_SKIP_LLM_VERIFICATION=true
18
+ HINDSIGHT_API_LLM_MAX_CONCURRENT=1
19
+ HINDSIGHT_API_LLM_TIMEOUT=300
20
+ HINDSIGHT_API_LLM_MAX_RETRIES=1
21
+
22
+ # verbatim: store chunk text as-is; LLM only extracts entities/time/location (faster than concise).
23
+ HINDSIGHT_API_RETAIN_EXTRACTION_MODE=verbatim
24
+ HINDSIGHT_API_RETAIN_MAX_COMPLETION_TOKENS=16384
25
+ HINDSIGHT_API_REFLECT_MAX_COMPLETION_TOKENS=2048
26
+ HINDSIGHT_API_CONSOLIDATION_MAX_COMPLETION_TOKENS=2048
@@ -0,0 +1,54 @@
1
+ # Project indexer config. The indexer reads the first of: --config PATH, $HINDSIGHT_INDEX_CONFIG,
2
+ # ~/.config/hindsight/index.yml, this file. A per-machine file replaces this one entirely; keys it omits
3
+ # take the built-in values, which match this file. Paths are absolute or start with ~ (a bare ~ is null
4
+ # in YAML, which also means home under roots[].path).
5
+
6
+ # Git repositories: walk each root to `depth` levels and index the outermost repositories found.
7
+ roots:
8
+ - path: ~
9
+ depth: 3
10
+
11
+ # Extra repositories, indexed even when no root reaches them.
12
+ repos:
13
+ - ~/.config/nvim
14
+
15
+ vaults:
16
+ auto: true # any folder within a root's depth that contains .obsidian/
17
+ paths: [] # extra vault folders
18
+
19
+ # Markdown folders without .obsidian (watched like vaults; banks default to <kind>::<slug>).
20
+ notes:
21
+ paths: []
22
+ papers:
23
+ paths: [] # e.g. Zotero Better BibTeX markdown export, arXiv notes, PDF-adjacent .md
24
+ bookmarks:
25
+ paths: [] # e.g. browser export (Linkwarden, Karakeep, manual markdown dumps)
26
+
27
+ # Optional: pull RSS/arXiv/OpenAlex into out_dir; indexer watches out_dir as kind `feed`.
28
+ feeds:
29
+ out_dir: ~/.local/share/personal-memory/feeds
30
+ rss: []
31
+ openalex_queries: []
32
+
33
+ # Glob patterns on absolute paths. A source that matches is skipped.
34
+ exclude: []
35
+
36
+ # Absolute path prefix -> Hindsight bank id. The longest matching prefix wins; applies to repos and vaults.
37
+ # Unmatched repositories fall back to ~/.config/personal-memory/coding-agent.json mapPathToBank,
38
+ # then the legacy ~/.hindsight/coding-agent.json mapping, then coding-agent::<repository-name>.
39
+ banks:
40
+ ~/Documents/sample-project: coding-agent::documents-sample-project
41
+ # ~/Zotero/export-md: papers::zotero
42
+ # ~/Readwise/Full-Sync: readwise::full-sync
43
+ # ~/.local/share/personal-memory/feeds: feed::cache
44
+
45
+ # Largest file indexed, in kilobytes (1 KB = 1000 bytes).
46
+ max_file_kb: 128
47
+
48
+ # Directory names never descended into (dot-prefixed directories are always skipped).
49
+ skip_dirs: [.cache, .codegraph, .decision, .git, .next, .tasks, .venv, build, dist, node_modules, target, vendor]
50
+
51
+ # Watcher timings, in seconds. Environment variables POLL_SECONDS, VAULT_QUIET_SECONDS and RELIST_SECONDS override them.
52
+ poll_seconds: 60
53
+ vault_quiet_seconds: 30
54
+ relist_seconds: 600
@@ -0,0 +1,40 @@
1
+ # LiteLLM routes for Hindsight, backend: lemond on this machine (llama.cpp).
2
+ # Selected by scripts/setup.sh when MEMORY_BACKEND=lemond (the default). See README "Model configuration".
3
+ # Hindsight asks for the fixed aliases below; change the model behind an alias here, not in Hindsight.
4
+ # Every alias runs Nemotron 3.5 Bolt E4B (JSON output and tool calls checked 2026-10-23) with thinking disabled:
5
+ # thinking adds tokens before the answer, and at max_tokens 200 can leave content empty.
6
+ # Passed through to lemond's chat template. Hindsight's per-request reasoning_effort cannot override it.
7
+ model_list:
8
+ - model_name: memory-retain
9
+ litellm_params:
10
+ model: openai/Nemotron-3.5-Bolt-E4B-GGUF
11
+ api_base: http://host.docker.internal:13305/v1
12
+ max_tokens: 4096
13
+ timeout: 300
14
+ api_key: os.environ/LEMOND_API_KEY
15
+ extra_body:
16
+ chat_template_kwargs:
17
+ enable_thinking: false
18
+ - model_name: memory-reflect
19
+ litellm_params:
20
+ model: openai/Nemotron-3.5-Bolt-E4B-GGUF
21
+ api_base: http://host.docker.internal:13305/v1
22
+ max_tokens: 4096
23
+ timeout: 300
24
+ api_key: os.environ/LEMOND_API_KEY
25
+ extra_body:
26
+ chat_template_kwargs:
27
+ enable_thinking: false
28
+ - model_name: memory-consolidate
29
+ litellm_params:
30
+ model: openai/Nemotron-3.5-Bolt-E4B-GGUF
31
+ api_base: http://host.docker.internal:13305/v1
32
+ max_tokens: 4096
33
+ timeout: 300
34
+ api_key: os.environ/LEMOND_API_KEY
35
+ extra_body:
36
+ chat_template_kwargs:
37
+ enable_thinking: false
38
+
39
+ general_settings:
40
+ master_key: os.environ/LITELLM_MASTER_KEY
@@ -0,0 +1,33 @@
1
+ # LiteLLM routes for Hindsight, backend: Ollama on a laptop.
2
+ # Selected by scripts/setup.sh when MEMORY_BACKEND=ollama. See README "Model configuration".
3
+ # Hindsight asks for the fixed aliases below; change the model behind an alias here, not in Hindsight.
4
+ # Every alias disables Gemma thinking: thinking adds tokens before the answer, and at max_tokens 200 can leave content empty.
5
+ # Sent as Ollama's top-level "think": false. Overrides Hindsight's per-request reasoning_effort.
6
+ model_list:
7
+ - model_name: memory-retain
8
+ litellm_params:
9
+ model: ollama_chat/gemma4:e2b
10
+ api_base: http://host.docker.internal:11434
11
+ max_tokens: 4096
12
+ timeout: 300
13
+ extra_body:
14
+ think: false
15
+ - model_name: memory-reflect
16
+ litellm_params:
17
+ model: ollama_chat/gemma4:e4b
18
+ api_base: http://host.docker.internal:11434
19
+ max_tokens: 4096
20
+ timeout: 300
21
+ extra_body:
22
+ think: false
23
+ - model_name: memory-consolidate
24
+ litellm_params:
25
+ model: ollama_chat/gemma4:e2b
26
+ api_base: http://host.docker.internal:11434
27
+ max_tokens: 4096
28
+ timeout: 300
29
+ extra_body:
30
+ think: false
31
+
32
+ general_settings:
33
+ master_key: os.environ/LITELLM_MASTER_KEY
@@ -0,0 +1,33 @@
1
+ # NotebookLM sync (opt-in: docker compose --profile notebooklm up -d notebooklm).
2
+ # Per-machine override: ~/.config/hindsight/notebooklm.yml. Put only the keys you change there;
3
+ # mappings merge key by key, lists and scalars replace the shipped value.
4
+
5
+ enabled: false
6
+
7
+ # client: unofficial notebooklm-py client, uses the browser login stored in ~/.config/notebooklm.
8
+ # enterprise: documented NotebookLM Enterprise REST API (notebook list only; see README).
9
+ backend: client
10
+
11
+ interval_minutes: 60
12
+
13
+ # Hindsight bank per notebook: <bank_prefix>::<slug of notebook title>.
14
+ bank_prefix: notebooklm
15
+
16
+ # Title globs (fnmatch, case-insensitive). include empty means every notebook.
17
+ include_notebooks: []
18
+ exclude_notebooks: []
19
+
20
+ include:
21
+ notes: true
22
+ sources: true # source list, URLs, full text and guide summary where the client returns them
23
+ chats: false # saved chat question/answer history
24
+
25
+ client:
26
+ # Empty uses NOTEBOOKLM_HOME (set to /data/notebooklm in the container).
27
+ storage_path: ""
28
+
29
+ enterprise:
30
+ project_number: "" # numeric project number, required for backend: enterprise
31
+ location: global # global | us | eu
32
+ service_account_file: "" # path inside the container; empty uses Application Default Credentials
33
+ notebook_limit: 500 # listRecentlyViewed page size, 1..500
@@ -0,0 +1,124 @@
1
+ # Mise-like declarative config for the openmem meta wizard.
2
+ #
3
+ # mkdir -p ~/.config/personal-memory
4
+ # cp config/openmem.toml.example ~/.config/personal-memory/config.toml
5
+ # $EDITOR ~/.config/personal-memory/config.toml
6
+ # ./setup --yes
7
+ #
8
+ # Precedence (highest wins): CLI flags → environment variables →
9
+ # ~/.config/personal-memory/config.toml → ./personal-memory.toml (stack root) →
10
+ # ~/.config/hindsight/wizard.conf (last configure run).
11
+ #
12
+ # Provider-native settings (mem0 cloud, Hindsight product UI, etc.) stay in those tools;
13
+ # this file only describes how this machine runs the shared stack.
14
+
15
+ [memory]
16
+ provider = "hindsight"
17
+
18
+ [stack]
19
+ project = "openmem"
20
+ api_port = 8888
21
+ control_plane_port = 9999
22
+
23
+ # Default wizard action when ./setup runs non-interactively without --up/--down
24
+ [wizard]
25
+ action = "configure" # configure | up | down
26
+
27
+ # LLM routing for Hindsight (LiteLLM → lemond/Ollama/custom/Meridian). Not lemond's own config.
28
+ [model]
29
+ backend = "lemond" # lemond | ollama | custom | meridian (Claude subscription, docs/meridian-litellm.md)
30
+ retain = "Gemma-4-E2B-it-GGUF"
31
+ reflect = "" # empty = shipped memory-reflect route
32
+ api_base = "" # custom backend only
33
+
34
+ [model.lemond]
35
+ host = "http://127.0.0.1:13305"
36
+
37
+ [model.ollama]
38
+ host = "http://127.0.0.1:11434"
39
+
40
+ # meridian backend only: Meridian's URL as seen from this host. The wizard does not run Meridian.
41
+ # [model.meridian]
42
+ # host = "http://127.0.0.1:3456"
43
+
44
+ # Coding-agent wiring, written by `install-coding-agent`.
45
+ # integration: "openmem" = OpenMem session hooks; "provider" = the provider's own plugin
46
+ # (Hindsight: @vectorize-io/hindsight-coding-agents). The two hook sets are exclusive.
47
+ [agents]
48
+ integration = "openmem"
49
+
50
+ # Local LiteLLM context proxy (`install-coding-agent --context-proxy`). When enabled,
51
+ # Claude Code's ANTHROPIC_BASE_URL points at http://127.0.0.1:<port>.
52
+ # trim_at_tokens / compress_over_tokens (and [compaction] max_chars) reach the proxy
53
+ # container through the stack .env (written by ./setup and install-coding-agent) and the
54
+ # OpenCode 2 plugin; the env vars CONTEXT_TRIM_AT_TOKENS, CONTEXT_COMPRESS_OVER_TOKENS,
55
+ # CONTEXT_TRIM_TO_FRACTION, CONTEXT_STANDING_INSTRUCTION, CONTEXT_CHARS_PER_TOKEN and CONTEXT_COMPACTION_MAX_CHARS
56
+ # override them.
57
+ [context_proxy]
58
+ # enabled = false # master switch; agents without a key below follow it (unset: opencode2 on, others off)
59
+ port = 4100
60
+ trim_at_tokens = 120000 # trim a session once its request exceeds this many tokens
61
+ trim_to_fraction = 0.3 # a trim keeps older in-turn exchanges while the request is under this fraction of trim_at_tokens (0 < x < 1)
62
+ compress_over_tokens = 4000 # compress tool results larger than this
63
+ standing_instruction = true # constant system-prompt note telling the agent to search trimmed turns
64
+ chars_per_token = 2.5 # token estimate before a session reports usage; reported usage calibrates it after
65
+
66
+ # Session databases (sessions/<sid>.db, docs/context-store.md): every message of a trimmed session.
67
+ # ttl_days: delete sessions idle longer than this, checked at proxy / MCP start at most once a day (0 = keep).
68
+ # embedding_model: OpenAI-compatible embedding model for hybrid smart_compact_search; empty = vectors off.
69
+ # The stack ships no embedding route; e.g. `ollama pull nomic-embed-text` and set it here.
70
+ # embedding_url: that endpoint as this host sees it (the proxy container uses CONTEXT_PROXY_EMBEDDING_URL).
71
+ # embedding_timeout_s: seconds per row of a background embeddings call (a batch of n rows gets n times this).
72
+ # Batches start at 4 rows, double while calls finish well inside the timeout and halve on a failure.
73
+ # embedding_max_chars: characters of each row's head that are embedded; the vector covers only that part.
74
+ # 4000 fits nomic-embed-text's 2048-token context; raise it only for a model with a longer one.
75
+ [context_store]
76
+ ttl_days = 30
77
+ embedding_model = ""
78
+ embedding_url = "http://127.0.0.1:11434/v1"
79
+ embedding_timeout_s = 30
80
+ embedding_max_chars = 4000
81
+
82
+ # Optional per-agent overrides (written by the wizard and `openmem context on|off --agents`).
83
+ # claude-code and opencode1 go through the context-proxy service, which install-coding-agent starts
84
+ # when one of them is on and stops when none is. opencode2 trims in its own plugin (no service;
85
+ # CONTEXT_PROXY_ENABLED overrides it); with neither its key nor `enabled` set it is on.
86
+ # codex is accepted but not routed yet.
87
+ # [context_proxy.agents]
88
+ # claude-code = true
89
+ # opencode1 = true
90
+ # codex = false
91
+ # opencode2 = true
92
+
93
+ # native (OpenCode 2 only): when OpenCode compacts a session, OpenMem's plugin supplies the
94
+ # smart_compact_search pointer + recall as the summary instead of a model call.
95
+ # false leaves compaction to OpenCode.
96
+ # max_chars: cap on the recall text placed after a trim or compaction pointer.
97
+ [compaction]
98
+ native = true
99
+ max_chars = 12000
100
+ # recall = true # provider recall in the trim pointer, framed as untrusted data (env CONTEXT_COMPACTION_RECALL)
101
+
102
+ # Optional indexer defaults (wizard may still prompt interactively)
103
+ # [[index.roots]]
104
+ # path = "~"
105
+ # depth = 3
106
+
107
+ # Mise-style named tasks (run via ./pm <name>)
108
+ [tasks.configure]
109
+ description = "Secrets, index sources, build images, compose up"
110
+
111
+ [tasks.up]
112
+ description = "Start stack using existing config"
113
+
114
+ [tasks.down]
115
+ description = "docker compose down for this project"
116
+
117
+ [tasks.doctor]
118
+ description = "Validate memory setup on this machine"
119
+
120
+ # Provider-native options live in their own tables, not under [model].
121
+ # mem0 is URL-only: point at a self-hosted REST server (not https://api.mem0.ai).
122
+ # [memory.mem0]
123
+ # api_url = "http://127.0.0.1:18888"
124
+ # env_file = "~/.config/personal-memory/mem0.env"
@@ -0,0 +1,23 @@
1
+ # OpenMem
2
+
3
+ **OpenMem** is the product name for this repository (formerly *personal-memory*).
4
+
5
+ For the product idea — memory interface for coding agents, providers, `memory_*`, banks, formats — start with **[Concepts](https://bcmyguest.github.io/openmem/docs/concepts/)**.
6
+
7
+ ## CLI
8
+
9
+ ```sh
10
+ npx @bcmyguest/openmem
11
+ openmem setup
12
+ openmem doctor
13
+ ```
14
+
15
+ Bins: `openmem`, `openmem-setup`, `openmem-mcp`, `openmem-install-mcp`, `openmem-install-coding-agent`, `openmem-switch-provider`, `openmem-notebooklm-mcp`, `openmem-cognee-mcp`.
16
+
17
+ Machine config paths under `~/.config/personal-memory/` and `~/.config/hindsight/` stay as-is for now so existing installs keep working. Installers rewrite leftover `personal-memory` MCP server entries to `openmem`.
18
+
19
+ ## Repo
20
+
21
+ - GitHub: [bcmyguest/openmem](https://github.com/bcmyguest/openmem)
22
+ - Docs: [site](https://bcmyguest.github.io/openmem/) · [Concepts](https://bcmyguest.github.io/openmem/docs/concepts/) · [Quickstart](https://bcmyguest.github.io/openmem/docs/getting-started/)
23
+ - npm: `openmem` (package formerly `personal-memory`)