dhee 7.2.3__tar.gz → 7.2.4__tar.gz

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 (529) hide show
  1. {dhee-7.2.3/dhee.egg-info → dhee-7.2.4}/PKG-INFO +1 -1
  2. {dhee-7.2.3 → dhee-7.2.4}/dhee/__init__.py +1 -1
  3. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/engram_extractor.py +19 -1
  4. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/sqlite.py +82 -6
  5. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/signal.py +4 -0
  6. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/main.py +13 -0
  7. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/quality.py +5 -1
  8. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/write_pipeline.py +240 -46
  9. {dhee-7.2.3 → dhee-7.2.4}/dhee/simple.py +26 -1
  10. {dhee-7.2.3 → dhee-7.2.4/dhee.egg-info}/PKG-INFO +1 -1
  11. {dhee-7.2.3 → dhee-7.2.4}/pyproject.toml +1 -1
  12. {dhee-7.2.3 → dhee-7.2.4}/tests/test_deferred_enrichment.py +152 -0
  13. {dhee-7.2.3 → dhee-7.2.4}/tests/test_memory_quality_contract.py +22 -12
  14. {dhee-7.2.3 → dhee-7.2.4}/tests/test_packaging.py +1 -1
  15. {dhee-7.2.3 → dhee-7.2.4}/LICENSE +0 -0
  16. {dhee-7.2.3 → dhee-7.2.4}/MANIFEST.in +0 -0
  17. {dhee-7.2.3 → dhee-7.2.4}/README.md +0 -0
  18. {dhee-7.2.3 → dhee-7.2.4}/dhee/adapters/__init__.py +0 -0
  19. {dhee-7.2.3 → dhee-7.2.4}/dhee/adapters/gstack.py +0 -0
  20. {dhee-7.2.3 → dhee-7.2.4}/dhee/adapters/gstack_parser.py +0 -0
  21. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/__init__.py +0 -0
  22. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/auth.py +0 -0
  23. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/client.py +0 -0
  24. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/events.py +0 -0
  25. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/models.py +0 -0
  26. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/policy.py +0 -0
  27. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/run.py +0 -0
  28. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/server.py +0 -0
  29. {dhee-7.2.3 → dhee-7.2.4}/dhee/agent_runtime/tools.py +0 -0
  30. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/__init__.py +0 -0
  31. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/arc_agi.py +0 -0
  32. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/decades.py +0 -0
  33. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/hippocamp.py +0 -0
  34. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/longmemeval.py +0 -0
  35. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/phase0_context_audit.py +0 -0
  36. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/portability.py +0 -0
  37. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/raw_extractors.py +0 -0
  38. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/replay_corpus.py +0 -0
  39. {dhee-7.2.3 → dhee-7.2.4}/dhee/benchmarks/router_replay.py +0 -0
  40. {dhee-7.2.3 → dhee-7.2.4}/dhee/checkpoint_runtime.py +0 -0
  41. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli.py +0 -0
  42. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_config.py +0 -0
  43. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_mcp.py +0 -0
  44. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_onboard.py +0 -0
  45. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_pretty.py +0 -0
  46. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_setup.py +0 -0
  47. {dhee-7.2.3 → dhee-7.2.4}/dhee/cli_update.py +0 -0
  48. {dhee-7.2.3 → dhee-7.2.4}/dhee/configs/__init__.py +0 -0
  49. {dhee-7.2.3 → dhee-7.2.4}/dhee/configs/active.py +0 -0
  50. {dhee-7.2.3 → dhee-7.2.4}/dhee/configs/base.py +0 -0
  51. {dhee-7.2.3 → dhee-7.2.4}/dhee/configs/presets.py +0 -0
  52. {dhee-7.2.3 → dhee-7.2.4}/dhee/context_ir.py +0 -0
  53. {dhee-7.2.3 → dhee-7.2.4}/dhee/context_kernel.py +0 -0
  54. {dhee-7.2.3 → dhee-7.2.4}/dhee/context_state.py +0 -0
  55. {dhee-7.2.3 → dhee-7.2.4}/dhee/contract_runtime.py +0 -0
  56. {dhee-7.2.3 → dhee-7.2.4}/dhee/contract_supervisor.py +0 -0
  57. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/__init__.py +0 -0
  58. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/alaya.py +0 -0
  59. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/answer_orchestration.py +0 -0
  60. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/artifacts.py +0 -0
  61. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/belief.py +0 -0
  62. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/buddhi.py +0 -0
  63. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/category.py +0 -0
  64. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/codex_artifacts.py +0 -0
  65. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/codex_stream.py +0 -0
  66. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/cognition.py +0 -0
  67. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/cognition_kernel.py +0 -0
  68. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/conflict.py +0 -0
  69. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/context_bootstrap.py +0 -0
  70. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/contrastive.py +0 -0
  71. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/decay.py +0 -0
  72. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/distillation.py +0 -0
  73. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/echo.py +0 -0
  74. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/engram.py +0 -0
  75. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/engram_consolidator.py +0 -0
  76. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/engram_tiering.py +0 -0
  77. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/engram_verification.py +0 -0
  78. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/enrichment.py +0 -0
  79. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/episode.py +0 -0
  80. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/episodic_index.py +0 -0
  81. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/evolution.py +0 -0
  82. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/file_baseline.py +0 -0
  83. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/file_read_tracker.py +0 -0
  84. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/forgetting.py +0 -0
  85. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/fusion.py +0 -0
  86. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/graph.py +0 -0
  87. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/handoff_snapshot.py +0 -0
  88. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/heuristic.py +0 -0
  89. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/intent.py +0 -0
  90. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/intention.py +0 -0
  91. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/kernel.py +0 -0
  92. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/learnings.py +0 -0
  93. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/live_context.py +0 -0
  94. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/log_parser.py +0 -0
  95. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/meta_buddhi.py +0 -0
  96. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/pattern_detector.py +0 -0
  97. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/policy.py +0 -0
  98. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/profile.py +0 -0
  99. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/provenance.py +0 -0
  100. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/resolvers.py +0 -0
  101. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/retrieval.py +0 -0
  102. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/samskara.py +0 -0
  103. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/scene.py +0 -0
  104. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/session_tracker.py +0 -0
  105. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/shared_tasks.py +0 -0
  106. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/strategy.py +0 -0
  107. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/task_state.py +0 -0
  108. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/thread_state.py +0 -0
  109. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/traces.py +0 -0
  110. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/trigger.py +0 -0
  111. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/viveka.py +0 -0
  112. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/workspace_line.py +0 -0
  113. {dhee-7.2.3 → dhee-7.2.4}/dhee/core/workspace_line_bus.py +0 -0
  114. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/__init__.py +0 -0
  115. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/sqlite_analytics.py +0 -0
  116. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/sqlite_artifacts.py +0 -0
  117. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/sqlite_common.py +0 -0
  118. {dhee-7.2.3 → dhee-7.2.4}/dhee/db/sqlite_domains.py +0 -0
  119. {dhee-7.2.3 → dhee-7.2.4}/dhee/debugger_api.py +0 -0
  120. {dhee-7.2.3 → dhee-7.2.4}/dhee/demo.py +0 -0
  121. {dhee-7.2.3 → dhee-7.2.4}/dhee/doctor.py +0 -0
  122. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/__init__.py +0 -0
  123. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/base.py +0 -0
  124. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/gemini.py +0 -0
  125. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/nvidia.py +0 -0
  126. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/ollama.py +0 -0
  127. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/openai.py +0 -0
  128. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/qwen.py +0 -0
  129. {dhee-7.2.3 → dhee-7.2.4}/dhee/embeddings/simple.py +0 -0
  130. {dhee-7.2.3 → dhee-7.2.4}/dhee/exceptions.py +0 -0
  131. {dhee-7.2.3 → dhee-7.2.4}/dhee/fs/__init__.py +0 -0
  132. {dhee-7.2.3 → dhee-7.2.4}/dhee/fs/mounts.py +0 -0
  133. {dhee-7.2.3 → dhee-7.2.4}/dhee/fs/types.py +0 -0
  134. {dhee-7.2.3 → dhee-7.2.4}/dhee/fs/uri.py +0 -0
  135. {dhee-7.2.3 → dhee-7.2.4}/dhee/fs/workspace.py +0 -0
  136. {dhee-7.2.3 → dhee-7.2.4}/dhee/graph_projection_hardening.py +0 -0
  137. {dhee-7.2.3 → dhee-7.2.4}/dhee/graph_proof_bundle.py +0 -0
  138. {dhee-7.2.3 → dhee-7.2.4}/dhee/harness/__init__.py +0 -0
  139. {dhee-7.2.3 → dhee-7.2.4}/dhee/harness/base.py +0 -0
  140. {dhee-7.2.3 → dhee-7.2.4}/dhee/harness/claude_code.py +0 -0
  141. {dhee-7.2.3 → dhee-7.2.4}/dhee/harness/codex.py +0 -0
  142. {dhee-7.2.3 → dhee-7.2.4}/dhee/harness/install.py +0 -0
  143. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/__init__.py +0 -0
  144. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/__init__.py +0 -0
  145. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/__main__.py +0 -0
  146. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/assembler.py +0 -0
  147. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/chunker.py +0 -0
  148. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/ingest.py +0 -0
  149. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/install.py +0 -0
  150. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/migrate.py +0 -0
  151. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/privacy.py +0 -0
  152. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/claude_code/renderer.py +0 -0
  153. {dhee-7.2.3 → dhee-7.2.4}/dhee/hooks/scene_world.py +0 -0
  154. {dhee-7.2.3 → dhee-7.2.4}/dhee/incremental_context.py +0 -0
  155. {dhee-7.2.3 → dhee-7.2.4}/dhee/install_cleanup.py +0 -0
  156. {dhee-7.2.3 → dhee-7.2.4}/dhee/integrations/__init__.py +0 -0
  157. {dhee-7.2.3 → dhee-7.2.4}/dhee/integrations/context_sources.py +0 -0
  158. {dhee-7.2.3 → dhee-7.2.4}/dhee/integrations/hermes.py +0 -0
  159. {dhee-7.2.3 → dhee-7.2.4}/dhee/integrations/hermes_provider/__init__.py +0 -0
  160. {dhee-7.2.3 → dhee-7.2.4}/dhee/integrations/hermes_provider/provider.py +0 -0
  161. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/__init__.py +0 -0
  162. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/anthropic.py +0 -0
  163. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/base.py +0 -0
  164. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/dhee.py +0 -0
  165. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/gemini.py +0 -0
  166. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/mock.py +0 -0
  167. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/nvidia.py +0 -0
  168. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/ollama.py +0 -0
  169. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/openai.py +0 -0
  170. {dhee-7.2.3 → dhee-7.2.4}/dhee/llms/teacher_logger.py +0 -0
  171. {dhee-7.2.3 → dhee-7.2.4}/dhee/mcp_registry.py +0 -0
  172. {dhee-7.2.3 → dhee-7.2.4}/dhee/mcp_server.py +0 -0
  173. {dhee-7.2.3 → dhee-7.2.4}/dhee/mcp_slim.py +0 -0
  174. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/__init__.py +0 -0
  175. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/admission.py +0 -0
  176. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/base.py +0 -0
  177. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/core.py +0 -0
  178. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/cost.py +0 -0
  179. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/episodic.py +0 -0
  180. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/narrative_scene.py +0 -0
  181. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/orchestration.py +0 -0
  182. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/parallel.py +0 -0
  183. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/projects.py +0 -0
  184. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/reranker.py +0 -0
  185. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/retrieval_helpers.py +0 -0
  186. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/scene_profile.py +0 -0
  187. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/scoping.py +0 -0
  188. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/search_pipeline.py +0 -0
  189. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/smart.py +0 -0
  190. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/tasks.py +0 -0
  191. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/utils.py +0 -0
  192. {dhee-7.2.3 → dhee-7.2.4}/dhee/memory/vectors.py +0 -0
  193. {dhee-7.2.3 → dhee-7.2.4}/dhee/mini/__init__.py +0 -0
  194. {dhee-7.2.3 → dhee-7.2.4}/dhee/mini/karma_evaluator.py +0 -0
  195. {dhee-7.2.3 → dhee-7.2.4}/dhee/mini/progressive_trainer.py +0 -0
  196. {dhee-7.2.3 → dhee-7.2.4}/dhee/mini/replay_gate.py +0 -0
  197. {dhee-7.2.3 → dhee-7.2.4}/dhee/observability.py +0 -0
  198. {dhee-7.2.3 → dhee-7.2.4}/dhee/patch_families.py +0 -0
  199. {dhee-7.2.3 → dhee-7.2.4}/dhee/plugin.py +0 -0
  200. {dhee-7.2.3 → dhee-7.2.4}/dhee/profiles/__init__.py +0 -0
  201. {dhee-7.2.3 → dhee-7.2.4}/dhee/profiles/elevenlabs.py +0 -0
  202. {dhee-7.2.3 → dhee-7.2.4}/dhee/profiles/gemini.py +0 -0
  203. {dhee-7.2.3 → dhee-7.2.4}/dhee/profiles/openai.py +0 -0
  204. {dhee-7.2.3 → dhee-7.2.4}/dhee/protocol/__init__.py +0 -0
  205. {dhee-7.2.3 → dhee-7.2.4}/dhee/protocol/v1.py +0 -0
  206. {dhee-7.2.3 → dhee-7.2.4}/dhee/provider_defaults.py +0 -0
  207. {dhee-7.2.3 → dhee-7.2.4}/dhee/providers/__init__.py +0 -0
  208. {dhee-7.2.3 → dhee-7.2.4}/dhee/providers/base.py +0 -0
  209. {dhee-7.2.3 → dhee-7.2.4}/dhee/providers/elevenlabs.py +0 -0
  210. {dhee-7.2.3 → dhee-7.2.4}/dhee/providers/gemini.py +0 -0
  211. {dhee-7.2.3 → dhee-7.2.4}/dhee/providers/openai.py +0 -0
  212. {dhee-7.2.3 → dhee-7.2.4}/dhee/release_hygiene.py +0 -0
  213. {dhee-7.2.3 → dhee-7.2.4}/dhee/replay_branching.py +0 -0
  214. {dhee-7.2.3 → dhee-7.2.4}/dhee/repo_intelligence.py +0 -0
  215. {dhee-7.2.3 → dhee-7.2.4}/dhee/repo_link.py +0 -0
  216. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/__init__.py +0 -0
  217. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/agent_digest.py +0 -0
  218. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/bash_digest.py +0 -0
  219. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/bootstrap.py +0 -0
  220. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/critical_surface.py +0 -0
  221. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/digest.py +0 -0
  222. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/edit_ledger.py +0 -0
  223. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/grep_digest.py +0 -0
  224. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/handlers.py +0 -0
  225. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/install.py +0 -0
  226. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/intent.py +0 -0
  227. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/policy.py +0 -0
  228. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/pre_tool_gate.py +0 -0
  229. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/ptr_store.py +0 -0
  230. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/quality_report.py +0 -0
  231. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/stats.py +0 -0
  232. {dhee-7.2.3 → dhee-7.2.4}/dhee/router/tune.py +0 -0
  233. {dhee-7.2.3 → dhee-7.2.4}/dhee/runtime.py +0 -0
  234. {dhee-7.2.3 → dhee-7.2.4}/dhee/runtime_daemon.py +0 -0
  235. {dhee-7.2.3 → dhee-7.2.4}/dhee/runtime_io.py +0 -0
  236. {dhee-7.2.3 → dhee-7.2.4}/dhee/schemas/__init__.py +0 -0
  237. {dhee-7.2.3 → dhee-7.2.4}/dhee/schemas/narrative.py +0 -0
  238. {dhee-7.2.3 → dhee-7.2.4}/dhee/schemas/scene_card.py +0 -0
  239. {dhee-7.2.3 → dhee-7.2.4}/dhee/secret_store.py +0 -0
  240. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/__init__.py +0 -0
  241. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/discovery.py +0 -0
  242. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/executor.py +0 -0
  243. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/hashing.py +0 -0
  244. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/miner.py +0 -0
  245. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/outcomes.py +0 -0
  246. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/schema.py +0 -0
  247. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/store.py +0 -0
  248. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/structure.py +0 -0
  249. {dhee-7.2.3 → dhee-7.2.4}/dhee/skills/trajectory.py +0 -0
  250. {dhee-7.2.3 → dhee-7.2.4}/dhee/task_contracts.py +0 -0
  251. {dhee-7.2.3 → dhee-7.2.4}/dhee/temporal_fact_integration.py +0 -0
  252. {dhee-7.2.3 → dhee-7.2.4}/dhee/temporal_fact_ledger.py +0 -0
  253. {dhee-7.2.3 → dhee-7.2.4}/dhee/temporal_scenes.py +0 -0
  254. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/__init__.py +0 -0
  255. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/data_formatter.py +0 -0
  256. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/karma.py +0 -0
  257. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/nididhyasana.py +0 -0
  258. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/smrti.py +0 -0
  259. {dhee-7.2.3 → dhee-7.2.4}/dhee/training/train.py +0 -0
  260. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/__init__.py +0 -0
  261. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/cli.py +0 -0
  262. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/server.py +0 -0
  263. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/dist/assets/CanvasView-Cl1HxIK0.js +0 -0
  264. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/dist/assets/index-BboZhdsv.js +0 -0
  265. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/dist/assets/index-CIsLOp4u.css +0 -0
  266. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/dist/dhee-logo.png +0 -0
  267. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/dist/index.html +0 -0
  268. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/index.html +0 -0
  269. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/package-lock.json +0 -0
  270. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/package.json +0 -0
  271. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/public/dhee-logo.png +0 -0
  272. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/App.js +0 -0
  273. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/App.tsx +0 -0
  274. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/api.js +0 -0
  275. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/api.ts +0 -0
  276. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/AssetDrawer.js +0 -0
  277. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/AssetDrawer.tsx +0 -0
  278. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ChatMessage.js +0 -0
  279. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ChatMessage.tsx +0 -0
  280. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/FirstRunPanel.js +0 -0
  281. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/FirstRunPanel.tsx +0 -0
  282. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/LinePanel.js +0 -0
  283. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/LinePanel.tsx +0 -0
  284. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/NavRail.js +0 -0
  285. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/NavRail.tsx +0 -0
  286. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/OrgDrawer.js +0 -0
  287. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/OrgDrawer.tsx +0 -0
  288. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/TopBar.js +0 -0
  289. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/TopBar.tsx +0 -0
  290. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/TweaksPanel.js +0 -0
  291. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/TweaksPanel.tsx +0 -0
  292. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/WorkspaceManagerModal.js +0 -0
  293. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/WorkspaceManagerModal.tsx +0 -0
  294. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/CanvasControls.js +0 -0
  295. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/CanvasControls.tsx +0 -0
  296. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/CanvasSkeleton.js +0 -0
  297. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/CanvasSkeleton.tsx +0 -0
  298. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/DirectionHints.js +0 -0
  299. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/DirectionHints.tsx +0 -0
  300. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/Minimap.js +0 -0
  301. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/Minimap.tsx +0 -0
  302. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/NodeCard.js +0 -0
  303. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/NodeCard.tsx +0 -0
  304. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/forceLayout.js +0 -0
  305. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/forceLayout.ts +0 -0
  306. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/layout.js +0 -0
  307. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/layout.ts +0 -0
  308. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/treeLayout.js +0 -0
  309. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/treeLayout.ts +0 -0
  310. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/useInfiniteCanvas.js +0 -0
  311. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/canvas/useInfiniteCanvas.ts +0 -0
  312. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/cards/Cards.js +0 -0
  313. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/cards/Cards.tsx +0 -0
  314. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/graph/CanvasNodeCard.js +0 -0
  315. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/graph/CanvasNodeCard.tsx +0 -0
  316. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/DecayBar.js +0 -0
  317. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/DecayBar.tsx +0 -0
  318. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/Markdown.js +0 -0
  319. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/Markdown.tsx +0 -0
  320. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/SectionHeader.js +0 -0
  321. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/SectionHeader.tsx +0 -0
  322. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/StatPill.js +0 -0
  323. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/StatPill.tsx +0 -0
  324. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/TierBadge.js +0 -0
  325. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/components/ui/TierBadge.tsx +0 -0
  326. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/main.js +0 -0
  327. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/main.tsx +0 -0
  328. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/styles.css +0 -0
  329. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/types.js +0 -0
  330. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/types.ts +0 -0
  331. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/CanvasView.js +0 -0
  332. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/CanvasView.tsx +0 -0
  333. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ChannelView.js +0 -0
  334. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ChannelView.tsx +0 -0
  335. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ConflictView.js +0 -0
  336. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ConflictView.tsx +0 -0
  337. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ContextView.js +0 -0
  338. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ContextView.tsx +0 -0
  339. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/EvolutionView.js +0 -0
  340. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/EvolutionView.tsx +0 -0
  341. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/LaunchView.js +0 -0
  342. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/LaunchView.tsx +0 -0
  343. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/MemoryView.js +0 -0
  344. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/MemoryView.tsx +0 -0
  345. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/NotepadView.js +0 -0
  346. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/NotepadView.tsx +0 -0
  347. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/OrgCanvas.js +0 -0
  348. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/OrgCanvas.tsx +0 -0
  349. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ProductViews.js +0 -0
  350. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/ProductViews.tsx +0 -0
  351. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/RouterView.js +0 -0
  352. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/RouterView.tsx +0 -0
  353. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/TasksView.js +0 -0
  354. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/TasksView.tsx +0 -0
  355. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/WorkspaceView.js +0 -0
  356. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/src/views/WorkspaceView.tsx +0 -0
  357. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/tsconfig.json +0 -0
  358. {dhee-7.2.3 → dhee-7.2.4}/dhee/ui/web/vite.config.ts +0 -0
  359. {dhee-7.2.3 → dhee-7.2.4}/dhee/update_capsules.py +0 -0
  360. {dhee-7.2.3 → dhee-7.2.4}/dhee/utils/__init__.py +0 -0
  361. {dhee-7.2.3 → dhee-7.2.4}/dhee/utils/factory.py +0 -0
  362. {dhee-7.2.3 → dhee-7.2.4}/dhee/utils/math.py +0 -0
  363. {dhee-7.2.3 → dhee-7.2.4}/dhee/utils/prompts.py +0 -0
  364. {dhee-7.2.3 → dhee-7.2.4}/dhee/utils/repo_identity.py +0 -0
  365. {dhee-7.2.3 → dhee-7.2.4}/dhee/vector_stores/__init__.py +0 -0
  366. {dhee-7.2.3 → dhee-7.2.4}/dhee/vector_stores/base.py +0 -0
  367. {dhee-7.2.3 → dhee-7.2.4}/dhee/vector_stores/memory.py +0 -0
  368. {dhee-7.2.3 → dhee-7.2.4}/dhee/vector_stores/sqlite_vec.py +0 -0
  369. {dhee-7.2.3 → dhee-7.2.4}/dhee/vector_stores/zvec_store.py +0 -0
  370. {dhee-7.2.3 → dhee-7.2.4}/dhee/verification_runner.py +0 -0
  371. {dhee-7.2.3 → dhee-7.2.4}/dhee/verifier_engine.py +0 -0
  372. {dhee-7.2.3 → dhee-7.2.4}/dhee/webhooks/__init__.py +0 -0
  373. {dhee-7.2.3 → dhee-7.2.4}/dhee/webhooks/elevenlabs.py +0 -0
  374. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/__init__.py +0 -0
  375. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/capture_store.py +0 -0
  376. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/causal_graph.py +0 -0
  377. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/encoder.py +0 -0
  378. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/gem_extractor.py +0 -0
  379. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/predictor.py +0 -0
  380. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/schema.py +0 -0
  381. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/service.py +0 -0
  382. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/session_graph.py +0 -0
  383. {dhee-7.2.3 → dhee-7.2.4}/dhee/world_memory/store.py +0 -0
  384. {dhee-7.2.3 → dhee-7.2.4}/dhee.egg-info/SOURCES.txt +0 -0
  385. {dhee-7.2.3 → dhee-7.2.4}/dhee.egg-info/dependency_links.txt +0 -0
  386. {dhee-7.2.3 → dhee-7.2.4}/dhee.egg-info/entry_points.txt +0 -0
  387. {dhee-7.2.3 → dhee-7.2.4}/dhee.egg-info/requires.txt +0 -0
  388. {dhee-7.2.3 → dhee-7.2.4}/dhee.egg-info/top_level.txt +0 -0
  389. {dhee-7.2.3 → dhee-7.2.4}/dhee_shared/__init__.py +0 -0
  390. {dhee-7.2.3 → dhee-7.2.4}/dhee_shared/model_paths.py +0 -0
  391. {dhee-7.2.3 → dhee-7.2.4}/engram/__init__.py +0 -0
  392. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/__init__.py +0 -0
  393. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/bus.py +0 -0
  394. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/pubsub.py +0 -0
  395. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/server.py +0 -0
  396. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/store.py +0 -0
  397. {dhee-7.2.3 → dhee-7.2.4}/engram-bus/engram_bus/workspace.py +0 -0
  398. {dhee-7.2.3 → dhee-7.2.4}/setup.cfg +0 -0
  399. {dhee-7.2.3 → dhee-7.2.4}/tests/test_accel.py +0 -0
  400. {dhee-7.2.3 → dhee-7.2.4}/tests/test_accel_benchmark.py +0 -0
  401. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_digest.py +0 -0
  402. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_provider_examples.py +0 -0
  403. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_runtime_before.py +0 -0
  404. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_runtime_http_auth.py +0 -0
  405. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_runtime_lifecycle.py +0 -0
  406. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_runtime_tool.py +0 -0
  407. {dhee-7.2.3 → dhee-7.2.4}/tests/test_agent_runtime_voice_policy.py +0 -0
  408. {dhee-7.2.3 → dhee-7.2.4}/tests/test_artifacts.py +0 -0
  409. {dhee-7.2.3 → dhee-7.2.4}/tests/test_auto_lifecycle.py +0 -0
  410. {dhee-7.2.3 → dhee-7.2.4}/tests/test_backward_compat.py +0 -0
  411. {dhee-7.2.3 → dhee-7.2.4}/tests/test_batch.py +0 -0
  412. {dhee-7.2.3 → dhee-7.2.4}/tests/test_belief_debugger.py +0 -0
  413. {dhee-7.2.3 → dhee-7.2.4}/tests/test_causal_scene_memory.py +0 -0
  414. {dhee-7.2.3 → dhee-7.2.4}/tests/test_claude_code_hooks.py +0 -0
  415. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cli_config.py +0 -0
  416. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cli_harness_commands.py +0 -0
  417. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cli_onboard_update.py +0 -0
  418. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cli_pretty.py +0 -0
  419. {dhee-7.2.3 → dhee-7.2.4}/tests/test_codex_stream.py +0 -0
  420. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cognition_evals.py +0 -0
  421. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cognition_kernel.py +0 -0
  422. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cognition_v3.py +0 -0
  423. {dhee-7.2.3 → dhee-7.2.4}/tests/test_context_state.py +0 -0
  424. {dhee-7.2.3 → dhee-7.2.4}/tests/test_contract_runtime_recovery.py +0 -0
  425. {dhee-7.2.3 → dhee-7.2.4}/tests/test_core_memory.py +0 -0
  426. {dhee-7.2.3 → dhee-7.2.4}/tests/test_cosine_similarity.py +0 -0
  427. {dhee-7.2.3 → dhee-7.2.4}/tests/test_decades_eval.py +0 -0
  428. {dhee-7.2.3 → dhee-7.2.4}/tests/test_dedup.py +0 -0
  429. {dhee-7.2.3 → dhee-7.2.4}/tests/test_demo.py +0 -0
  430. {dhee-7.2.3 → dhee-7.2.4}/tests/test_dhee_init.py +0 -0
  431. {dhee-7.2.3 → dhee-7.2.4}/tests/test_dhee_model_paths.py +0 -0
  432. {dhee-7.2.3 → dhee-7.2.4}/tests/test_dheefs.py +0 -0
  433. {dhee-7.2.3 → dhee-7.2.4}/tests/test_distillation.py +0 -0
  434. {dhee-7.2.3 → dhee-7.2.4}/tests/test_e2e_all_features.py +0 -0
  435. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_cli.py +0 -0
  436. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_correction_memory.py +0 -0
  437. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_no_secret_storage.py +0 -0
  438. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_profile.py +0 -0
  439. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_two_call_memory.py +0 -0
  440. {dhee-7.2.3 → dhee-7.2.4}/tests/test_elevenlabs_webhook.py +0 -0
  441. {dhee-7.2.3 → dhee-7.2.4}/tests/test_engram_tiering.py +0 -0
  442. {dhee-7.2.3 → dhee-7.2.4}/tests/test_engram_tiering_promotion.py +0 -0
  443. {dhee-7.2.3 → dhee-7.2.4}/tests/test_evolution_meta_loop.py +0 -0
  444. {dhee-7.2.3 → dhee-7.2.4}/tests/test_evolution_session_gate.py +0 -0
  445. {dhee-7.2.3 → dhee-7.2.4}/tests/test_forgetting.py +0 -0
  446. {dhee-7.2.3 → dhee-7.2.4}/tests/test_gemini_provider.py +0 -0
  447. {dhee-7.2.3 → dhee-7.2.4}/tests/test_graph_proof_bundle.py +0 -0
  448. {dhee-7.2.3 → dhee-7.2.4}/tests/test_gstack_adapter.py +0 -0
  449. {dhee-7.2.3 → dhee-7.2.4}/tests/test_handoff_snapshot.py +0 -0
  450. {dhee-7.2.3 → dhee-7.2.4}/tests/test_harness_adapters.py +0 -0
  451. {dhee-7.2.3 → dhee-7.2.4}/tests/test_harness_install.py +0 -0
  452. {dhee-7.2.3 → dhee-7.2.4}/tests/test_hashing.py +0 -0
  453. {dhee-7.2.3 → dhee-7.2.4}/tests/test_hermes_provider.py +0 -0
  454. {dhee-7.2.3 → dhee-7.2.4}/tests/test_hippocamp_benchmark.py +0 -0
  455. {dhee-7.2.3 → dhee-7.2.4}/tests/test_incremental_context.py +0 -0
  456. {dhee-7.2.3 → dhee-7.2.4}/tests/test_install_cleanup.py +0 -0
  457. {dhee-7.2.3 → dhee-7.2.4}/tests/test_intent.py +0 -0
  458. {dhee-7.2.3 → dhee-7.2.4}/tests/test_karma_evaluator.py +0 -0
  459. {dhee-7.2.3 → dhee-7.2.4}/tests/test_learnings.py +0 -0
  460. {dhee-7.2.3 → dhee-7.2.4}/tests/test_locomo_plus_runner.py +0 -0
  461. {dhee-7.2.3 → dhee-7.2.4}/tests/test_log_parser.py +0 -0
  462. {dhee-7.2.3 → dhee-7.2.4}/tests/test_longmemeval_config.py +0 -0
  463. {dhee-7.2.3 → dhee-7.2.4}/tests/test_mcp_artifact_tools.py +0 -0
  464. {dhee-7.2.3 → dhee-7.2.4}/tests/test_mcp_tools_slim.py +0 -0
  465. {dhee-7.2.3 → dhee-7.2.4}/tests/test_memory_admission.py +0 -0
  466. {dhee-7.2.3 → dhee-7.2.4}/tests/test_memory_os_service.py +0 -0
  467. {dhee-7.2.3 → dhee-7.2.4}/tests/test_memory_types.py +0 -0
  468. {dhee-7.2.3 → dhee-7.2.4}/tests/test_meta_buddhi_group_relative.py +0 -0
  469. {dhee-7.2.3 → dhee-7.2.4}/tests/test_migration.py +0 -0
  470. {dhee-7.2.3 → dhee-7.2.4}/tests/test_miner.py +0 -0
  471. {dhee-7.2.3 → dhee-7.2.4}/tests/test_narrative_scene_intelligence.py +0 -0
  472. {dhee-7.2.3 → dhee-7.2.4}/tests/test_nvidia_embedder.py +0 -0
  473. {dhee-7.2.3 → dhee-7.2.4}/tests/test_openai_provider.py +0 -0
  474. {dhee-7.2.3 → dhee-7.2.4}/tests/test_openclaw.py +0 -0
  475. {dhee-7.2.3 → dhee-7.2.4}/tests/test_orchestration_core.py +0 -0
  476. {dhee-7.2.3 → dhee-7.2.4}/tests/test_oss_61_regressions.py +0 -0
  477. {dhee-7.2.3 → dhee-7.2.4}/tests/test_parallel.py +0 -0
  478. {dhee-7.2.3 → dhee-7.2.4}/tests/test_patch_families.py +0 -0
  479. {dhee-7.2.3 → dhee-7.2.4}/tests/test_plugin_learnings.py +0 -0
  480. {dhee-7.2.3 → dhee-7.2.4}/tests/test_portability_eval.py +0 -0
  481. {dhee-7.2.3 → dhee-7.2.4}/tests/test_power_packages.py +0 -0
  482. {dhee-7.2.3 → dhee-7.2.4}/tests/test_presets.py +0 -0
  483. {dhee-7.2.3 → dhee-7.2.4}/tests/test_profile.py +0 -0
  484. {dhee-7.2.3 → dhee-7.2.4}/tests/test_progressive_trainer.py +0 -0
  485. {dhee-7.2.3 → dhee-7.2.4}/tests/test_projects.py +0 -0
  486. {dhee-7.2.3 → dhee-7.2.4}/tests/test_protocol_v1.py +0 -0
  487. {dhee-7.2.3 → dhee-7.2.4}/tests/test_provider_runtime_profiles.py +0 -0
  488. {dhee-7.2.3 → dhee-7.2.4}/tests/test_query_cache.py +0 -0
  489. {dhee-7.2.3 → dhee-7.2.4}/tests/test_release_hygiene.py +0 -0
  490. {dhee-7.2.3 → dhee-7.2.4}/tests/test_replay_branching.py +0 -0
  491. {dhee-7.2.3 → dhee-7.2.4}/tests/test_replay_corpus_export.py +0 -0
  492. {dhee-7.2.3 → dhee-7.2.4}/tests/test_replay_gate.py +0 -0
  493. {dhee-7.2.3 → dhee-7.2.4}/tests/test_repo_intelligence.py +0 -0
  494. {dhee-7.2.3 → dhee-7.2.4}/tests/test_repo_link.py +0 -0
  495. {dhee-7.2.3 → dhee-7.2.4}/tests/test_reranker_defaults.py +0 -0
  496. {dhee-7.2.3 → dhee-7.2.4}/tests/test_router.py +0 -0
  497. {dhee-7.2.3 → dhee-7.2.4}/tests/test_router_replay.py +0 -0
  498. {dhee-7.2.3 → dhee-7.2.4}/tests/test_router_stats_agents.py +0 -0
  499. {dhee-7.2.3 → dhee-7.2.4}/tests/test_runtime.py +0 -0
  500. {dhee-7.2.3 → dhee-7.2.4}/tests/test_runtime_hardening.py +0 -0
  501. {dhee-7.2.3 → dhee-7.2.4}/tests/test_scene.py +0 -0
  502. {dhee-7.2.3 → dhee-7.2.4}/tests/test_scene_world_hook.py +0 -0
  503. {dhee-7.2.3 → dhee-7.2.4}/tests/test_secret_store.py +0 -0
  504. {dhee-7.2.3 → dhee-7.2.4}/tests/test_session_tracker.py +0 -0
  505. {dhee-7.2.3 → dhee-7.2.4}/tests/test_shared_tasks.py +0 -0
  506. {dhee-7.2.3 → dhee-7.2.4}/tests/test_simple_zero_config.py +0 -0
  507. {dhee-7.2.3 → dhee-7.2.4}/tests/test_skills.py +0 -0
  508. {dhee-7.2.3 → dhee-7.2.4}/tests/test_smart_memory.py +0 -0
  509. {dhee-7.2.3 → dhee-7.2.4}/tests/test_sqlite_connection_pool.py +0 -0
  510. {dhee-7.2.3 → dhee-7.2.4}/tests/test_sqlite_vec.py +0 -0
  511. {dhee-7.2.3 → dhee-7.2.4}/tests/test_structural.py +0 -0
  512. {dhee-7.2.3 → dhee-7.2.4}/tests/test_structured_resolution.py +0 -0
  513. {dhee-7.2.3 → dhee-7.2.4}/tests/test_task_contracts.py +0 -0
  514. {dhee-7.2.3 → dhee-7.2.4}/tests/test_tasks.py +0 -0
  515. {dhee-7.2.3 → dhee-7.2.4}/tests/test_temporal_fact_integration.py +0 -0
  516. {dhee-7.2.3 → dhee-7.2.4}/tests/test_temporal_fact_ledger.py +0 -0
  517. {dhee-7.2.3 → dhee-7.2.4}/tests/test_temporal_scenes.py +0 -0
  518. {dhee-7.2.3 → dhee-7.2.4}/tests/test_thread_state.py +0 -0
  519. {dhee-7.2.3 → dhee-7.2.4}/tests/test_traces.py +0 -0
  520. {dhee-7.2.3 → dhee-7.2.4}/tests/test_trajectory.py +0 -0
  521. {dhee-7.2.3 → dhee-7.2.4}/tests/test_ui.py +0 -0
  522. {dhee-7.2.3 → dhee-7.2.4}/tests/test_unified_enrichment.py +0 -0
  523. {dhee-7.2.3 → dhee-7.2.4}/tests/test_update_capsules.py +0 -0
  524. {dhee-7.2.3 → dhee-7.2.4}/tests/test_vector_store_factory.py +0 -0
  525. {dhee-7.2.3 → dhee-7.2.4}/tests/test_verification_runner.py +0 -0
  526. {dhee-7.2.3 → dhee-7.2.4}/tests/test_verifier_engine.py +0 -0
  527. {dhee-7.2.3 → dhee-7.2.4}/tests/test_workspace_line_agent_emit.py +0 -0
  528. {dhee-7.2.3 → dhee-7.2.4}/tests/test_workspace_line_bus.py +0 -0
  529. {dhee-7.2.3 → dhee-7.2.4}/tests/test_zvec_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhee
3
- Version: 7.2.3
3
+ Version: 7.2.4
4
4
  Summary: Dhee - world memory layer and context compiler for AI agents
5
5
  Author: Sankhya AI Labs
6
6
  License-Expression: MIT
@@ -50,7 +50,7 @@ from dhee.memory.admission import (
50
50
  # Default import remains model-free for backwards compatibility.
51
51
  Memory = CoreMemory
52
52
 
53
- __version__ = "7.2.3"
53
+ __version__ = "7.2.4"
54
54
  __all__ = [
55
55
  # Memory classes
56
56
  "Engram",
@@ -113,6 +113,7 @@ class EngramExtractor:
113
113
  user_profile: Optional[Dict[str, Any]] = None,
114
114
  existing_metadata: Optional[Dict[str, Any]] = None,
115
115
  user_id: str = "default",
116
+ strict_llm_failure: bool = False,
116
117
  ) -> UniversalEngram:
117
118
  """Extract structured engram with contextual anchoring.
118
119
 
@@ -129,6 +130,8 @@ class EngramExtractor:
129
130
  )
130
131
  if engram:
131
132
  return engram
133
+ if strict_llm_failure:
134
+ raise RuntimeError("Engram LLM extraction produced no structured result")
132
135
 
133
136
  # Rule-based extraction
134
137
  return self._extract_rule_based(
@@ -330,13 +333,17 @@ class EngramExtractor:
330
333
  (r"(?:I|user)\s+(?:prefer|like|love|enjoy|use)\s+(.+?)(?:\.|$|,)", "prefers"),
331
334
  (r"(?:I|user)\s+(?:switched to|moved to|changed to)\s+(.+?)(?:\.|$|,)", "switched_to"),
332
335
  (r"(?:I|user)\s+(?:work at|work for|employed at)\s+(.+?)(?:\.|$|,)", "works_at"),
336
+ (r"(?:I|user|owner)\s+(?:live|lives|reside|resides)\s+in\s+(.+?)(?:\.|$|,)", "lives_in"),
337
+ (r"(?:my|user's|owner's)\s+(?:home|city|location)\s+is\s+(.+?)(?:\.|$|,)", "lives_in"),
338
+ (r"(?:my|user's|owner's)\s+(?:plan|goal)\s+is\s+to\s+(.+?)(?:\.|$|,)", "plans_to"),
339
+ (r"(?:I|user|owner)\s+(?:plan|plans|intend|intends)\s+to\s+(.+?)(?:\.|$|,)", "plans_to"),
333
340
  (r"(?:I|user)\s+(?:visited|went to|traveled to)\s+(.+?)(?:\.|$|,)", "visited"),
334
341
  (r"(?:I|user)\s+(?:bought|purchased)\s+(.+?)(?:\s+for\s+)?([\d,.]+)?\s*(\w+)?", "bought"),
335
342
  ]
336
343
  for pattern, predicate in preference_patterns:
337
344
  matches = re.finditer(pattern, content, re.IGNORECASE)
338
345
  for match in matches:
339
- value = match.group(1).strip().rstrip(".")
346
+ value = self._clean_rule_value(match.group(1))
340
347
  if len(value) > 100:
341
348
  continue
342
349
  fact = Fact(
@@ -360,6 +367,17 @@ class EngramExtractor:
360
367
 
361
368
  return facts
362
369
 
370
+ @staticmethod
371
+ def _clean_rule_value(value: str) -> str:
372
+ text = str(value or "").strip().rstrip(".")
373
+ text = re.split(
374
+ r"\s+(?:and|but|while)\s+(?=(?:I|user|owner|my|user's|owner's)\b)",
375
+ text,
376
+ maxsplit=1,
377
+ flags=re.IGNORECASE,
378
+ )[0]
379
+ return text.strip().rstrip(".")
380
+
363
381
  def _extract_entities_rules(self, content: str) -> List[EntityRef]:
364
382
  """Rule-based entity extraction."""
365
383
  entities = []
@@ -2192,21 +2192,97 @@ class FullSQLiteManager(
2192
2192
  )
2193
2193
 
2194
2194
  def get_pending_enrichment(self, user_id: Optional[str] = None, limit: int = 50) -> List[Dict[str, Any]]:
2195
- """Return memories with enrichment_status='pending', ordered oldest first."""
2195
+ """Return pending and retryable failed enrichment rows, oldest first."""
2196
+ fetch_limit = max(1, int(limit)) * 4
2196
2197
  with self._get_connection() as conn:
2197
2198
  if user_id:
2198
2199
  rows = conn.execute(
2199
- "SELECT * FROM memories WHERE enrichment_status = 'pending' AND user_id = ? "
2200
+ "SELECT * FROM memories WHERE enrichment_status IN ('pending', 'failed') AND user_id = ? "
2200
2201
  "AND tombstone = 0 ORDER BY created_at ASC LIMIT ?",
2201
- (user_id, limit),
2202
+ (user_id, fetch_limit),
2202
2203
  ).fetchall()
2203
2204
  else:
2204
2205
  rows = conn.execute(
2205
- "SELECT * FROM memories WHERE enrichment_status = 'pending' "
2206
+ "SELECT * FROM memories WHERE enrichment_status IN ('pending', 'failed') "
2206
2207
  "AND tombstone = 0 ORDER BY created_at ASC LIMIT ?",
2207
- (limit,),
2208
+ (fetch_limit,),
2208
2209
  ).fetchall()
2209
- return [self._row_to_dict(row) for row in rows]
2210
+ retryable: List[Dict[str, Any]] = []
2211
+ for row in rows:
2212
+ memory = self._row_to_dict(row)
2213
+ status = str(memory.get("enrichment_status") or "").lower()
2214
+ metadata = memory.get("metadata") if isinstance(memory.get("metadata"), dict) else {}
2215
+ attempts_raw = metadata.get("enrichment_attempts", 0)
2216
+ try:
2217
+ attempts = int(attempts_raw or 0)
2218
+ except (TypeError, ValueError):
2219
+ attempts = 0
2220
+ if status == "pending" or attempts < 3:
2221
+ retryable.append(memory)
2222
+ if len(retryable) >= max(1, int(limit)):
2223
+ break
2224
+ return retryable
2225
+
2226
+ def requeue_complete_without_engram_facts(
2227
+ self,
2228
+ user_id: Optional[str] = None,
2229
+ limit: int = 100,
2230
+ ) -> Dict[str, Any]:
2231
+ """Reopen complete semantic memories that have no linked engram facts."""
2232
+ try:
2233
+ with self._get_connection() as conn:
2234
+ conn.execute("SELECT 1 FROM engram_facts LIMIT 0")
2235
+ except Exception:
2236
+ return {"requeued_count": 0, "reason": "engram_facts_unavailable"}
2237
+
2238
+ params: List[Any] = []
2239
+ query = (
2240
+ "SELECT m.* FROM memories m "
2241
+ "LEFT JOIN engram_facts f ON f.memory_id = m.id "
2242
+ "WHERE m.tombstone = 0 "
2243
+ "AND m.enrichment_status = 'complete' "
2244
+ "AND COALESCE(m.memory_type, 'semantic') != 'operational_event' "
2245
+ "GROUP BY m.id HAVING COUNT(f.id) = 0 "
2246
+ "ORDER BY m.created_at ASC LIMIT ?"
2247
+ )
2248
+ if user_id:
2249
+ query = (
2250
+ "SELECT m.* FROM memories m "
2251
+ "LEFT JOIN engram_facts f ON f.memory_id = m.id "
2252
+ "WHERE m.tombstone = 0 "
2253
+ "AND m.enrichment_status = 'complete' "
2254
+ "AND COALESCE(m.memory_type, 'semantic') != 'operational_event' "
2255
+ "AND m.user_id = ? "
2256
+ "GROUP BY m.id HAVING COUNT(f.id) = 0 "
2257
+ "ORDER BY m.created_at ASC LIMIT ?"
2258
+ )
2259
+ params.append(user_id)
2260
+ params.append(max(1, int(limit)))
2261
+
2262
+ rows: List[Dict[str, Any]] = []
2263
+ with self._get_connection() as conn:
2264
+ for row in conn.execute(query, params).fetchall():
2265
+ rows.append(self._row_to_dict(row))
2266
+
2267
+ updates: List[Dict[str, Any]] = []
2268
+ for memory in rows:
2269
+ metadata = memory.get("metadata") if isinstance(memory.get("metadata"), dict) else {}
2270
+ metadata = dict(metadata)
2271
+ metadata["enrichment_attempts"] = 0
2272
+ metadata.pop("last_enrichment_error", None)
2273
+ metadata["reextract_queued_at"] = _utcnow_iso()
2274
+ updates.append(
2275
+ {
2276
+ "id": memory["id"],
2277
+ "metadata": metadata,
2278
+ "enrichment_status": "pending",
2279
+ }
2280
+ )
2281
+ self.update_enrichment_bulk(updates)
2282
+ return {
2283
+ "requeued_count": len(updates),
2284
+ "memory_ids": [item["id"] for item in updates],
2285
+ }
2210
2286
 
2211
2287
  def update_enrichment_status(self, memory_id: str, status: str) -> None:
2212
2288
  """Mark a memory's enrichment_status (e.g. 'complete')."""
@@ -111,6 +111,8 @@ def _write_signal(
111
111
  "tool": tool_name,
112
112
  "path": path,
113
113
  "success": success,
114
+ "memory_type": "operational_event",
115
+ "source_app": "claude_code",
114
116
  }
115
117
 
116
118
 
@@ -149,6 +151,8 @@ def _shell_signal(
149
151
  "kind": "failure",
150
152
  "tool": tool_name,
151
153
  "success": False,
154
+ "memory_type": "operational_event",
155
+ "source_app": "claude_code",
152
156
  }
153
157
 
154
158
 
@@ -1165,6 +1165,19 @@ class FullMemory(SmartMemory, SceneProfileMixin):
1165
1165
  max_batches=max_batches,
1166
1166
  )
1167
1167
 
1168
+ def reextract(
1169
+ self,
1170
+ user_id: str = "default",
1171
+ limit: int = 100,
1172
+ ) -> Dict[str, Any]:
1173
+ """Requeue complete memories that have no linked engram facts."""
1174
+ if not hasattr(self.db, "requeue_complete_without_engram_facts"):
1175
+ return {"requeued_count": 0, "reason": "db_requeue_unavailable"}
1176
+ return self.db.requeue_complete_without_engram_facts(
1177
+ user_id=user_id,
1178
+ limit=limit,
1179
+ )
1180
+
1168
1181
  _normalize_bitemporal_value = staticmethod(normalize_bitemporal_value)
1169
1182
  _parse_bitemporal_datetime = classmethod(lambda cls, v: parse_bitemporal_datetime(v))
1170
1183
  _attach_bitemporal_metadata = classmethod(
@@ -141,7 +141,8 @@ _SHELL_COMMAND_RE = re.compile(
141
141
  r"(?:/[\w .@%+=:,~/-]+|~/?[\w .@%+=:,~/-]*|\./[\w .@%+=:,~/-]+)\s+"
142
142
  r"(?:-m\s+)?(?:python[0-9.]*|pip[0-9.]*|pytest|uv|npm|pnpm|yarn|git|gh|sqlite3|curl|claude|codex|dhee|ruff|mypy|sed|rg|grep|ls|cat|echo|export)\b|"
143
143
  r"[A-Z_][A-Z0-9_]*=.*\b(?:python[0-9.]*|pytest|sqlite3|curl|git|echo)\b|"
144
- r"(?:python[0-9.]*|pip[0-9.]*|pytest|ruff|mypy|sqlite3|curl|echo|export)\b|"
144
+ r"(?:pytest|ruff|mypy|sqlite3|curl|echo|export)\b|"
145
+ r"(?:python[0-9.]*|pip[0-9.]*)\s+(?:-|/|~|\.|[A-Za-z0-9_./-]*\.py\b|install\b|uninstall\b|freeze\b|list\b|show\b|check\b)|"
145
146
  r"time\s+\(|"
146
147
  r"uv\s+(?:run|sync|pip|tool|python)\b|"
147
148
  r"(?:npm|pnpm|yarn)\s+(?:run|test|install|build|lint|exec)\b|"
@@ -382,11 +383,14 @@ def _is_artifact_like_metadata(metadata: Mapping[str, Any]) -> bool:
382
383
  def _is_operational_event(content: str, metadata: Mapping[str, Any]) -> bool:
383
384
  """True for transport-level agent/tool events that are evidence, not belief."""
384
385
  kind = str(metadata.get("kind") or metadata.get("type") or "").strip().lower()
386
+ memory_type = str(metadata.get("memory_type") or "").strip().lower()
385
387
  tool = str(metadata.get("tool") or metadata.get("tool_name") or metadata.get("native_tool") or "").strip().lower()
386
388
  source = str(metadata.get("source") or metadata.get("source_type") or metadata.get("source_app") or "").strip().lower()
387
389
  success = metadata.get("success")
388
390
  text = " ".join(str(content or "").strip().split())
389
391
 
392
+ if memory_type in {"operational_event", "trajectory", "tool_observation"}:
393
+ return True
390
394
  if kind in {"file_touched", "tool_event", "tool_failure", "failure", "session_log", "codex_event", "claude_code_event"}:
391
395
  return True
392
396
  if source in {"claude_code_hook", "codex_hook", "session_log"}:
@@ -8,6 +8,7 @@ classify_memory_type, select_primary_text).
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import hashlib
11
12
  import json
12
13
  import logging
13
14
  import re
@@ -46,6 +47,8 @@ from dhee.utils.prompts import AGENT_MEMORY_EXTRACTION_PROMPT, MEMORY_EXTRACTION
46
47
 
47
48
  logger = logging.getLogger(__name__)
48
49
 
50
+ _MAX_ENRICHMENT_ATTEMPTS = 3
51
+
49
52
 
50
53
  class MemoryWritePipeline:
51
54
  """Handles the full memory write path: processing, enrichment, indexing.
@@ -316,6 +319,163 @@ class MemoryWritePipeline:
316
319
  except Exception as exc:
317
320
  logger.warning("%s for %s: %s", warning_prefix, memory_id, exc)
318
321
 
322
+ @staticmethod
323
+ def _context_messages_from_memory(memory: Dict[str, Any]) -> Optional[List[Dict[str, Any]]]:
324
+ raw = memory.get("conversation_context")
325
+ if isinstance(raw, list):
326
+ return [item for item in raw if isinstance(item, dict)]
327
+ if not isinstance(raw, str) or not raw.strip():
328
+ return None
329
+ try:
330
+ parsed = json.loads(raw)
331
+ except json.JSONDecodeError:
332
+ return None
333
+ if not isinstance(parsed, list):
334
+ return None
335
+ return [item for item in parsed if isinstance(item, dict)]
336
+
337
+ @staticmethod
338
+ def _enrichment_attempts(metadata: Dict[str, Any]) -> int:
339
+ try:
340
+ return max(0, int(metadata.get("enrichment_attempts") or 0))
341
+ except (TypeError, ValueError):
342
+ return 0
343
+
344
+ def _run_engram_extraction(
345
+ self,
346
+ *,
347
+ memory_id: str,
348
+ content: str,
349
+ mem_metadata: Dict[str, Any],
350
+ user_id: Optional[str],
351
+ context_messages: Optional[List[Dict[str, Any]]] = None,
352
+ strict_llm_failure: bool = False,
353
+ ) -> Tuple[bool, bool, Optional[Any]]:
354
+ """Run structured engram extraction and store resolver rows.
355
+
356
+ Returns ``(attempted, succeeded, engram)`` so callers can distinguish a
357
+ disabled extractor from an extractor that failed.
358
+ """
359
+ engram_extractor = self._engram_extractor
360
+ if not engram_extractor:
361
+ return False, False, None
362
+
363
+ try:
364
+ session_ctx = None
365
+ if context_messages:
366
+ session_ctx = {"recent_messages": context_messages[-5:]}
367
+ engram = engram_extractor.extract(
368
+ content=content,
369
+ session_context=session_ctx,
370
+ existing_metadata=mem_metadata,
371
+ user_id=user_id or "default",
372
+ strict_llm_failure=strict_llm_failure,
373
+ )
374
+ context_resolver = self._context_resolver
375
+ if context_resolver and engram:
376
+ context_resolver.store_engram(engram, memory_id)
377
+ if (
378
+ engram.prospective_scenes
379
+ and self._config.prospective_scene.enable_prospective_scenes
380
+ and self._store_prospective_scenes_fn
381
+ ):
382
+ self._store_prospective_scenes_fn(
383
+ engram.prospective_scenes,
384
+ memory_id,
385
+ user_id or "default",
386
+ )
387
+ return True, True, engram
388
+ except Exception as exc:
389
+ logger.warning("Engram extraction failed for %s: %s", memory_id, exc)
390
+ return True, False, None
391
+
392
+ def _store_operational_event(
393
+ self,
394
+ *,
395
+ content: str,
396
+ mem_metadata: Dict[str, Any],
397
+ user_id: Optional[str],
398
+ agent_id: Optional[str],
399
+ source_app: Optional[str],
400
+ memory_id: Optional[str],
401
+ ) -> Dict[str, Any]:
402
+ """Store transport/tool signal as an episodic event without a memory row."""
403
+ owner_user_id = user_id or str(mem_metadata.get("user_id") or "default")
404
+ event_time = str(mem_metadata.get("event_time") or datetime.now(timezone.utc).isoformat())
405
+ event_seed = "|".join(
406
+ [
407
+ owner_user_id,
408
+ str(mem_metadata.get("source_event_id") or ""),
409
+ str(mem_metadata.get("kind") or ""),
410
+ content,
411
+ ]
412
+ )
413
+ digest = hashlib.sha256(event_seed.encode("utf-8")).hexdigest()
414
+ event_memory_id = memory_id or f"operational:{digest[:32]}"
415
+ tool_name = str(mem_metadata.get("tool") or mem_metadata.get("tool_name") or "").strip()
416
+ path = str(mem_metadata.get("path") or mem_metadata.get("source_path") or "").strip()
417
+ actor_id = str(
418
+ mem_metadata.get("actor_id")
419
+ or agent_id
420
+ or tool_name
421
+ or source_app
422
+ or mem_metadata.get("source_app")
423
+ or "agent"
424
+ ).strip()
425
+ actor_role = str(mem_metadata.get("actor_role") or ("tool" if tool_name else "agent")).strip()
426
+ event_kind = str(mem_metadata.get("kind") or mem_metadata.get("type") or "operational_event").strip()
427
+ entity_key = path or tool_name or actor_id
428
+ canonical_key = f"operational:{actor_id}:{event_kind}:{entity_key or digest[:12]}"
429
+ value_norm = " ".join(content.lower().split())[:500]
430
+
431
+ self._db.add_episodic_events(
432
+ [
433
+ {
434
+ "id": f"{event_memory_id}:event",
435
+ "memory_id": event_memory_id,
436
+ "user_id": owner_user_id,
437
+ "conversation_id": mem_metadata.get("conversation_id"),
438
+ "session_id": mem_metadata.get("session_id"),
439
+ "turn_id": mem_metadata.get("turn_id", 0),
440
+ "actor_id": actor_id,
441
+ "actor_role": actor_role,
442
+ "event_time": event_time,
443
+ "event_type": "operational_event",
444
+ "canonical_key": canonical_key,
445
+ "value_text": content,
446
+ "value_num": None,
447
+ "value_unit": None,
448
+ "currency": None,
449
+ "normalized_time_start": event_time,
450
+ "normalized_time_end": event_time,
451
+ "time_granularity": "instant",
452
+ "entity_key": entity_key,
453
+ "value_norm": value_norm,
454
+ "confidence": mem_metadata.get("confidence", 0.8),
455
+ "superseded_by": None,
456
+ }
457
+ ]
458
+ )
459
+ self._record_cost(
460
+ phase="write",
461
+ user_id=owner_user_id,
462
+ llm_calls=0.0,
463
+ input_tokens=0.0,
464
+ output_tokens=0.0,
465
+ embed_calls=0.0,
466
+ )
467
+ return {
468
+ "id": event_memory_id,
469
+ "memory": content,
470
+ "event": "EVENT",
471
+ "layer": "episodic",
472
+ "strength": 0.0,
473
+ "namespace": "operational",
474
+ "memory_type": "operational_event",
475
+ "episodic": True,
476
+ "stored_as": "episodic_event",
477
+ }
478
+
319
479
  # ------------------------------------------------------------------
320
480
  # Extracted public methods
321
481
  # ------------------------------------------------------------------
@@ -491,6 +651,16 @@ class MemoryWritePipeline:
491
651
  if quality.is_canonical:
492
652
  expiration_date = None
493
653
 
654
+ if quality.is_operational:
655
+ return self._store_operational_event(
656
+ content=content,
657
+ mem_metadata=mem_metadata,
658
+ user_id=user_id,
659
+ agent_id=agent_id,
660
+ source_app=source_app,
661
+ memory_id=memory_id,
662
+ )
663
+
494
664
  admission = evaluate_memory_candidate(
495
665
  content,
496
666
  mem_metadata,
@@ -526,6 +696,15 @@ class MemoryWritePipeline:
526
696
  initial_strength = enforce_quality_strength(initial_strength, quality)
527
697
  if quality.is_canonical:
528
698
  expiration_date = None
699
+ if quality.is_operational:
700
+ return self._store_operational_event(
701
+ content=content,
702
+ mem_metadata=mem_metadata,
703
+ user_id=user_id,
704
+ agent_id=agent_id,
705
+ source_app=source_app,
706
+ memory_id=memory_id,
707
+ )
529
708
 
530
709
  blocked = detect_sensitive_categories(content)
531
710
  # allow_sensitive: explicit caller opt-in, or caller explicitly provided
@@ -1051,29 +1230,14 @@ class MemoryWritePipeline:
1051
1230
  )
1052
1231
 
1053
1232
  # Dhee: Universal Engram extraction
1054
- engram_extractor = self._engram_extractor
1055
- if engram_extractor:
1056
- try:
1057
- session_ctx = None
1058
- if context_messages:
1059
- session_ctx = {"recent_messages": context_messages[-5:]}
1060
- engram = engram_extractor.extract(
1061
- content=content,
1062
- session_context=session_ctx,
1063
- existing_metadata=mem_metadata,
1064
- user_id=user_id or "default",
1065
- )
1066
- context_resolver = self._context_resolver
1067
- if context_resolver:
1068
- context_resolver.store_engram(engram, effective_memory_id)
1069
- if engram.prospective_scenes and self._config.prospective_scene.enable_prospective_scenes:
1070
- self._store_prospective_scenes_fn(
1071
- engram.prospective_scenes,
1072
- effective_memory_id,
1073
- user_id or "default",
1074
- )
1075
- except Exception as e:
1076
- logger.warning("Engram extraction failed for %s: %s", effective_memory_id, e)
1233
+ _engram_attempted, _engram_succeeded, engram = self._run_engram_extraction(
1234
+ memory_id=effective_memory_id,
1235
+ content=content,
1236
+ mem_metadata=mem_metadata,
1237
+ user_id=user_id,
1238
+ context_messages=context_messages,
1239
+ strict_llm_failure=False,
1240
+ )
1077
1241
 
1078
1242
  # Dhee: Self-evolution — record extraction quality signal
1079
1243
  evolution_layer = self._evolution_layer
@@ -1081,7 +1245,7 @@ class MemoryWritePipeline:
1081
1245
  try:
1082
1246
  engram_facts = None
1083
1247
  engram_context = None
1084
- if engram_extractor and 'engram' in dir() and engram: # noqa: F821
1248
+ if _engram_succeeded and engram:
1085
1249
  engram_facts = [f.to_dict() if hasattr(f, 'to_dict') else f for f in getattr(engram, 'facts', [])]
1086
1250
  engram_context = getattr(engram, 'context', None)
1087
1251
  if engram_context and hasattr(engram_context, '__dict__'):
@@ -1867,8 +2031,6 @@ class MemoryWritePipeline:
1867
2031
  warning_prefix="Batch fact embedding/insert failed",
1868
2032
  )
1869
2033
 
1870
- engram_extractor = self._engram_extractor
1871
- context_resolver = self._context_resolver
1872
2034
  for entry in record_entries:
1873
2035
  idx = entry["source_index"]
1874
2036
  record = entry["record"]
@@ -1886,22 +2048,14 @@ class MemoryWritePipeline:
1886
2048
  warning_prefix="Profile update failed",
1887
2049
  )
1888
2050
 
1889
- if engram_extractor:
1890
- try:
1891
- engram = engram_extractor.extract(
1892
- content=record.get("memory", ""),
1893
- session_context=None,
1894
- existing_metadata=record.get("metadata"),
1895
- user_id=record.get("user_id") or user_id or "default",
1896
- )
1897
- if context_resolver and engram:
1898
- context_resolver.store_engram(engram, record["id"])
1899
- except Exception as exc:
1900
- logger.warning(
1901
- "Engram extraction failed for %s: %s",
1902
- record["id"],
1903
- exc,
1904
- )
2051
+ self._run_engram_extraction(
2052
+ memory_id=record["id"],
2053
+ content=record.get("memory", ""),
2054
+ mem_metadata=record.get("metadata") or {},
2055
+ user_id=record.get("user_id") or user_id,
2056
+ context_messages=None,
2057
+ strict_llm_failure=False,
2058
+ )
1905
2059
 
1906
2060
  if episodic_rows:
1907
2061
  sample_count = float(len(episodic_rows))
@@ -1932,9 +2086,17 @@ class MemoryWritePipeline:
1932
2086
  limit = batch_size * max_batches
1933
2087
  pending = self._db.get_pending_enrichment(user_id=user_id, limit=limit)
1934
2088
  if not pending:
1935
- return {"enriched_count": 0, "batches": 0, "remaining": 0}
2089
+ return {
2090
+ "enriched_count": 0,
2091
+ "failed_count": 0,
2092
+ "degraded_count": 0,
2093
+ "batches": 0,
2094
+ "remaining": 0,
2095
+ }
1936
2096
 
1937
2097
  enriched_count = 0
2098
+ failed_count = 0
2099
+ degraded_count = 0
1938
2100
  batches_processed = 0
1939
2101
  unified = self._unified_enrichment
1940
2102
 
@@ -1983,6 +2145,9 @@ class MemoryWritePipeline:
1983
2145
  mem_id = memory["id"]
1984
2146
  mem_meta = memory.get("metadata", {}) or {}
1985
2147
  mem_cats = memory.get("categories", []) or []
2148
+ attempts = self._enrichment_attempts(mem_meta) + 1
2149
+ mem_meta["enrichment_attempts"] = attempts
2150
+ mem_meta["last_enrichment_attempt_at"] = datetime.now(timezone.utc).isoformat()
1986
2151
 
1987
2152
  if enrichment:
1988
2153
  if enrichment.echo_result:
@@ -2026,16 +2191,42 @@ class MemoryWritePipeline:
2026
2191
  }
2027
2192
  )
2028
2193
 
2029
- mem_meta["enrichment_status"] = "complete"
2194
+ extraction_attempted, extraction_succeeded, _engram = self._run_engram_extraction(
2195
+ memory_id=mem_id,
2196
+ content=memory.get("memory", ""),
2197
+ mem_metadata=mem_meta,
2198
+ user_id=memory.get("user_id") or user_id,
2199
+ context_messages=self._context_messages_from_memory(memory),
2200
+ strict_llm_failure=True,
2201
+ )
2202
+ if extraction_attempted:
2203
+ status_ready = extraction_succeeded
2204
+ else:
2205
+ status_ready = enrichment is not None
2206
+
2207
+ if status_ready:
2208
+ mem_meta["enrichment_status"] = "complete"
2209
+ mem_meta.pop("last_enrichment_error", None)
2210
+ next_status = "complete"
2211
+ enriched_count += 1
2212
+ else:
2213
+ if attempts >= _MAX_ENRICHMENT_ATTEMPTS:
2214
+ next_status = "degraded"
2215
+ degraded_count += 1
2216
+ else:
2217
+ next_status = "failed"
2218
+ failed_count += 1
2219
+ mem_meta["enrichment_status"] = next_status
2220
+ mem_meta["last_enrichment_error"] = "deferred_enrichment_produced_no_structured_result"
2221
+
2030
2222
  db_updates.append(
2031
2223
  {
2032
2224
  "id": mem_id,
2033
2225
  "metadata": mem_meta,
2034
2226
  "categories": mem_cats,
2035
- "enrichment_status": "complete",
2227
+ "enrichment_status": next_status,
2036
2228
  }
2037
2229
  )
2038
- enriched_count += 1
2039
2230
 
2040
2231
  self._insert_fact_vectors(
2041
2232
  fact_entries=fact_entries,
@@ -2050,6 +2241,8 @@ class MemoryWritePipeline:
2050
2241
 
2051
2242
  return {
2052
2243
  "enriched_count": enriched_count,
2244
+ "failed_count": failed_count,
2245
+ "degraded_count": degraded_count,
2053
2246
  "batches": batches_processed,
2054
2247
  "remaining": remaining_count,
2055
2248
  }
@@ -2126,6 +2319,7 @@ class MemoryWritePipeline:
2126
2319
  "project", "project_status", "project_tag",
2127
2320
  "warroom", "warroom_message", "test_fixture",
2128
2321
  "operational_event",
2322
+ "tool_observation", "trajectory", "utterance",
2129
2323
  "screen_observation", "profile", "goal", "constraint",
2130
2324
  "preference", "decision", "style", "product",
2131
2325
  "product_philosophy"):