dhee 7.2.3__tar.gz → 7.2.5__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 (532) hide show
  1. {dhee-7.2.3/dhee.egg-info → dhee-7.2.5}/PKG-INFO +1 -1
  2. {dhee-7.2.3 → dhee-7.2.5}/dhee/__init__.py +1 -1
  3. {dhee-7.2.3 → dhee-7.2.5}/dhee/configs/base.py +9 -3
  4. {dhee-7.2.3 → dhee-7.2.5}/dhee/contract_runtime.py +3 -6
  5. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/engram_extractor.py +19 -1
  6. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/scene.py +81 -8
  7. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/sqlite.py +82 -6
  8. {dhee-7.2.3 → dhee-7.2.5}/dhee/doctor.py +71 -0
  9. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/signal.py +4 -0
  10. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/nvidia.py +35 -1
  11. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/main.py +232 -1
  12. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/quality.py +5 -1
  13. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/write_pipeline.py +240 -46
  14. {dhee-7.2.3 → dhee-7.2.5}/dhee/provider_defaults.py +1 -1
  15. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/handlers.py +27 -0
  16. {dhee-7.2.3 → dhee-7.2.5}/dhee/simple.py +43 -4
  17. {dhee-7.2.3 → dhee-7.2.5}/dhee/verification_runner.py +20 -1
  18. {dhee-7.2.3 → dhee-7.2.5/dhee.egg-info}/PKG-INFO +1 -1
  19. {dhee-7.2.3 → dhee-7.2.5}/dhee.egg-info/SOURCES.txt +3 -0
  20. {dhee-7.2.3 → dhee-7.2.5}/pyproject.toml +1 -1
  21. dhee-7.2.5/tests/test_data_dir_paths.py +29 -0
  22. {dhee-7.2.3 → dhee-7.2.5}/tests/test_deferred_enrichment.py +152 -0
  23. {dhee-7.2.3 → dhee-7.2.5}/tests/test_memory_quality_contract.py +22 -12
  24. dhee-7.2.5/tests/test_nvidia_llm.py +59 -0
  25. {dhee-7.2.3 → dhee-7.2.5}/tests/test_packaging.py +1 -1
  26. dhee-7.2.5/tests/test_scene_maintenance.py +73 -0
  27. {dhee-7.2.3 → dhee-7.2.5}/LICENSE +0 -0
  28. {dhee-7.2.3 → dhee-7.2.5}/MANIFEST.in +0 -0
  29. {dhee-7.2.3 → dhee-7.2.5}/README.md +0 -0
  30. {dhee-7.2.3 → dhee-7.2.5}/dhee/adapters/__init__.py +0 -0
  31. {dhee-7.2.3 → dhee-7.2.5}/dhee/adapters/gstack.py +0 -0
  32. {dhee-7.2.3 → dhee-7.2.5}/dhee/adapters/gstack_parser.py +0 -0
  33. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/__init__.py +0 -0
  34. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/auth.py +0 -0
  35. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/client.py +0 -0
  36. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/events.py +0 -0
  37. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/models.py +0 -0
  38. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/policy.py +0 -0
  39. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/run.py +0 -0
  40. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/server.py +0 -0
  41. {dhee-7.2.3 → dhee-7.2.5}/dhee/agent_runtime/tools.py +0 -0
  42. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/__init__.py +0 -0
  43. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/arc_agi.py +0 -0
  44. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/decades.py +0 -0
  45. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/hippocamp.py +0 -0
  46. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/longmemeval.py +0 -0
  47. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/phase0_context_audit.py +0 -0
  48. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/portability.py +0 -0
  49. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/raw_extractors.py +0 -0
  50. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/replay_corpus.py +0 -0
  51. {dhee-7.2.3 → dhee-7.2.5}/dhee/benchmarks/router_replay.py +0 -0
  52. {dhee-7.2.3 → dhee-7.2.5}/dhee/checkpoint_runtime.py +0 -0
  53. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli.py +0 -0
  54. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_config.py +0 -0
  55. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_mcp.py +0 -0
  56. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_onboard.py +0 -0
  57. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_pretty.py +0 -0
  58. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_setup.py +0 -0
  59. {dhee-7.2.3 → dhee-7.2.5}/dhee/cli_update.py +0 -0
  60. {dhee-7.2.3 → dhee-7.2.5}/dhee/configs/__init__.py +0 -0
  61. {dhee-7.2.3 → dhee-7.2.5}/dhee/configs/active.py +0 -0
  62. {dhee-7.2.3 → dhee-7.2.5}/dhee/configs/presets.py +0 -0
  63. {dhee-7.2.3 → dhee-7.2.5}/dhee/context_ir.py +0 -0
  64. {dhee-7.2.3 → dhee-7.2.5}/dhee/context_kernel.py +0 -0
  65. {dhee-7.2.3 → dhee-7.2.5}/dhee/context_state.py +0 -0
  66. {dhee-7.2.3 → dhee-7.2.5}/dhee/contract_supervisor.py +0 -0
  67. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/__init__.py +0 -0
  68. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/alaya.py +0 -0
  69. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/answer_orchestration.py +0 -0
  70. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/artifacts.py +0 -0
  71. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/belief.py +0 -0
  72. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/buddhi.py +0 -0
  73. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/category.py +0 -0
  74. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/codex_artifacts.py +0 -0
  75. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/codex_stream.py +0 -0
  76. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/cognition.py +0 -0
  77. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/cognition_kernel.py +0 -0
  78. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/conflict.py +0 -0
  79. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/context_bootstrap.py +0 -0
  80. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/contrastive.py +0 -0
  81. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/decay.py +0 -0
  82. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/distillation.py +0 -0
  83. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/echo.py +0 -0
  84. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/engram.py +0 -0
  85. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/engram_consolidator.py +0 -0
  86. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/engram_tiering.py +0 -0
  87. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/engram_verification.py +0 -0
  88. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/enrichment.py +0 -0
  89. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/episode.py +0 -0
  90. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/episodic_index.py +0 -0
  91. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/evolution.py +0 -0
  92. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/file_baseline.py +0 -0
  93. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/file_read_tracker.py +0 -0
  94. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/forgetting.py +0 -0
  95. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/fusion.py +0 -0
  96. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/graph.py +0 -0
  97. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/handoff_snapshot.py +0 -0
  98. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/heuristic.py +0 -0
  99. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/intent.py +0 -0
  100. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/intention.py +0 -0
  101. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/kernel.py +0 -0
  102. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/learnings.py +0 -0
  103. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/live_context.py +0 -0
  104. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/log_parser.py +0 -0
  105. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/meta_buddhi.py +0 -0
  106. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/pattern_detector.py +0 -0
  107. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/policy.py +0 -0
  108. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/profile.py +0 -0
  109. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/provenance.py +0 -0
  110. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/resolvers.py +0 -0
  111. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/retrieval.py +0 -0
  112. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/samskara.py +0 -0
  113. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/session_tracker.py +0 -0
  114. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/shared_tasks.py +0 -0
  115. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/strategy.py +0 -0
  116. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/task_state.py +0 -0
  117. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/thread_state.py +0 -0
  118. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/traces.py +0 -0
  119. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/trigger.py +0 -0
  120. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/viveka.py +0 -0
  121. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/workspace_line.py +0 -0
  122. {dhee-7.2.3 → dhee-7.2.5}/dhee/core/workspace_line_bus.py +0 -0
  123. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/__init__.py +0 -0
  124. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/sqlite_analytics.py +0 -0
  125. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/sqlite_artifacts.py +0 -0
  126. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/sqlite_common.py +0 -0
  127. {dhee-7.2.3 → dhee-7.2.5}/dhee/db/sqlite_domains.py +0 -0
  128. {dhee-7.2.3 → dhee-7.2.5}/dhee/debugger_api.py +0 -0
  129. {dhee-7.2.3 → dhee-7.2.5}/dhee/demo.py +0 -0
  130. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/__init__.py +0 -0
  131. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/base.py +0 -0
  132. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/gemini.py +0 -0
  133. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/nvidia.py +0 -0
  134. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/ollama.py +0 -0
  135. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/openai.py +0 -0
  136. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/qwen.py +0 -0
  137. {dhee-7.2.3 → dhee-7.2.5}/dhee/embeddings/simple.py +0 -0
  138. {dhee-7.2.3 → dhee-7.2.5}/dhee/exceptions.py +0 -0
  139. {dhee-7.2.3 → dhee-7.2.5}/dhee/fs/__init__.py +0 -0
  140. {dhee-7.2.3 → dhee-7.2.5}/dhee/fs/mounts.py +0 -0
  141. {dhee-7.2.3 → dhee-7.2.5}/dhee/fs/types.py +0 -0
  142. {dhee-7.2.3 → dhee-7.2.5}/dhee/fs/uri.py +0 -0
  143. {dhee-7.2.3 → dhee-7.2.5}/dhee/fs/workspace.py +0 -0
  144. {dhee-7.2.3 → dhee-7.2.5}/dhee/graph_projection_hardening.py +0 -0
  145. {dhee-7.2.3 → dhee-7.2.5}/dhee/graph_proof_bundle.py +0 -0
  146. {dhee-7.2.3 → dhee-7.2.5}/dhee/harness/__init__.py +0 -0
  147. {dhee-7.2.3 → dhee-7.2.5}/dhee/harness/base.py +0 -0
  148. {dhee-7.2.3 → dhee-7.2.5}/dhee/harness/claude_code.py +0 -0
  149. {dhee-7.2.3 → dhee-7.2.5}/dhee/harness/codex.py +0 -0
  150. {dhee-7.2.3 → dhee-7.2.5}/dhee/harness/install.py +0 -0
  151. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/__init__.py +0 -0
  152. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/__init__.py +0 -0
  153. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/__main__.py +0 -0
  154. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/assembler.py +0 -0
  155. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/chunker.py +0 -0
  156. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/ingest.py +0 -0
  157. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/install.py +0 -0
  158. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/migrate.py +0 -0
  159. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/privacy.py +0 -0
  160. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/claude_code/renderer.py +0 -0
  161. {dhee-7.2.3 → dhee-7.2.5}/dhee/hooks/scene_world.py +0 -0
  162. {dhee-7.2.3 → dhee-7.2.5}/dhee/incremental_context.py +0 -0
  163. {dhee-7.2.3 → dhee-7.2.5}/dhee/install_cleanup.py +0 -0
  164. {dhee-7.2.3 → dhee-7.2.5}/dhee/integrations/__init__.py +0 -0
  165. {dhee-7.2.3 → dhee-7.2.5}/dhee/integrations/context_sources.py +0 -0
  166. {dhee-7.2.3 → dhee-7.2.5}/dhee/integrations/hermes.py +0 -0
  167. {dhee-7.2.3 → dhee-7.2.5}/dhee/integrations/hermes_provider/__init__.py +0 -0
  168. {dhee-7.2.3 → dhee-7.2.5}/dhee/integrations/hermes_provider/provider.py +0 -0
  169. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/__init__.py +0 -0
  170. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/anthropic.py +0 -0
  171. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/base.py +0 -0
  172. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/dhee.py +0 -0
  173. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/gemini.py +0 -0
  174. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/mock.py +0 -0
  175. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/ollama.py +0 -0
  176. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/openai.py +0 -0
  177. {dhee-7.2.3 → dhee-7.2.5}/dhee/llms/teacher_logger.py +0 -0
  178. {dhee-7.2.3 → dhee-7.2.5}/dhee/mcp_registry.py +0 -0
  179. {dhee-7.2.3 → dhee-7.2.5}/dhee/mcp_server.py +0 -0
  180. {dhee-7.2.3 → dhee-7.2.5}/dhee/mcp_slim.py +0 -0
  181. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/__init__.py +0 -0
  182. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/admission.py +0 -0
  183. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/base.py +0 -0
  184. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/core.py +0 -0
  185. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/cost.py +0 -0
  186. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/episodic.py +0 -0
  187. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/narrative_scene.py +0 -0
  188. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/orchestration.py +0 -0
  189. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/parallel.py +0 -0
  190. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/projects.py +0 -0
  191. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/reranker.py +0 -0
  192. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/retrieval_helpers.py +0 -0
  193. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/scene_profile.py +0 -0
  194. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/scoping.py +0 -0
  195. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/search_pipeline.py +0 -0
  196. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/smart.py +0 -0
  197. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/tasks.py +0 -0
  198. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/utils.py +0 -0
  199. {dhee-7.2.3 → dhee-7.2.5}/dhee/memory/vectors.py +0 -0
  200. {dhee-7.2.3 → dhee-7.2.5}/dhee/mini/__init__.py +0 -0
  201. {dhee-7.2.3 → dhee-7.2.5}/dhee/mini/karma_evaluator.py +0 -0
  202. {dhee-7.2.3 → dhee-7.2.5}/dhee/mini/progressive_trainer.py +0 -0
  203. {dhee-7.2.3 → dhee-7.2.5}/dhee/mini/replay_gate.py +0 -0
  204. {dhee-7.2.3 → dhee-7.2.5}/dhee/observability.py +0 -0
  205. {dhee-7.2.3 → dhee-7.2.5}/dhee/patch_families.py +0 -0
  206. {dhee-7.2.3 → dhee-7.2.5}/dhee/plugin.py +0 -0
  207. {dhee-7.2.3 → dhee-7.2.5}/dhee/profiles/__init__.py +0 -0
  208. {dhee-7.2.3 → dhee-7.2.5}/dhee/profiles/elevenlabs.py +0 -0
  209. {dhee-7.2.3 → dhee-7.2.5}/dhee/profiles/gemini.py +0 -0
  210. {dhee-7.2.3 → dhee-7.2.5}/dhee/profiles/openai.py +0 -0
  211. {dhee-7.2.3 → dhee-7.2.5}/dhee/protocol/__init__.py +0 -0
  212. {dhee-7.2.3 → dhee-7.2.5}/dhee/protocol/v1.py +0 -0
  213. {dhee-7.2.3 → dhee-7.2.5}/dhee/providers/__init__.py +0 -0
  214. {dhee-7.2.3 → dhee-7.2.5}/dhee/providers/base.py +0 -0
  215. {dhee-7.2.3 → dhee-7.2.5}/dhee/providers/elevenlabs.py +0 -0
  216. {dhee-7.2.3 → dhee-7.2.5}/dhee/providers/gemini.py +0 -0
  217. {dhee-7.2.3 → dhee-7.2.5}/dhee/providers/openai.py +0 -0
  218. {dhee-7.2.3 → dhee-7.2.5}/dhee/release_hygiene.py +0 -0
  219. {dhee-7.2.3 → dhee-7.2.5}/dhee/replay_branching.py +0 -0
  220. {dhee-7.2.3 → dhee-7.2.5}/dhee/repo_intelligence.py +0 -0
  221. {dhee-7.2.3 → dhee-7.2.5}/dhee/repo_link.py +0 -0
  222. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/__init__.py +0 -0
  223. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/agent_digest.py +0 -0
  224. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/bash_digest.py +0 -0
  225. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/bootstrap.py +0 -0
  226. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/critical_surface.py +0 -0
  227. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/digest.py +0 -0
  228. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/edit_ledger.py +0 -0
  229. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/grep_digest.py +0 -0
  230. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/install.py +0 -0
  231. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/intent.py +0 -0
  232. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/policy.py +0 -0
  233. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/pre_tool_gate.py +0 -0
  234. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/ptr_store.py +0 -0
  235. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/quality_report.py +0 -0
  236. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/stats.py +0 -0
  237. {dhee-7.2.3 → dhee-7.2.5}/dhee/router/tune.py +0 -0
  238. {dhee-7.2.3 → dhee-7.2.5}/dhee/runtime.py +0 -0
  239. {dhee-7.2.3 → dhee-7.2.5}/dhee/runtime_daemon.py +0 -0
  240. {dhee-7.2.3 → dhee-7.2.5}/dhee/runtime_io.py +0 -0
  241. {dhee-7.2.3 → dhee-7.2.5}/dhee/schemas/__init__.py +0 -0
  242. {dhee-7.2.3 → dhee-7.2.5}/dhee/schemas/narrative.py +0 -0
  243. {dhee-7.2.3 → dhee-7.2.5}/dhee/schemas/scene_card.py +0 -0
  244. {dhee-7.2.3 → dhee-7.2.5}/dhee/secret_store.py +0 -0
  245. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/__init__.py +0 -0
  246. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/discovery.py +0 -0
  247. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/executor.py +0 -0
  248. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/hashing.py +0 -0
  249. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/miner.py +0 -0
  250. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/outcomes.py +0 -0
  251. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/schema.py +0 -0
  252. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/store.py +0 -0
  253. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/structure.py +0 -0
  254. {dhee-7.2.3 → dhee-7.2.5}/dhee/skills/trajectory.py +0 -0
  255. {dhee-7.2.3 → dhee-7.2.5}/dhee/task_contracts.py +0 -0
  256. {dhee-7.2.3 → dhee-7.2.5}/dhee/temporal_fact_integration.py +0 -0
  257. {dhee-7.2.3 → dhee-7.2.5}/dhee/temporal_fact_ledger.py +0 -0
  258. {dhee-7.2.3 → dhee-7.2.5}/dhee/temporal_scenes.py +0 -0
  259. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/__init__.py +0 -0
  260. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/data_formatter.py +0 -0
  261. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/karma.py +0 -0
  262. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/nididhyasana.py +0 -0
  263. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/smrti.py +0 -0
  264. {dhee-7.2.3 → dhee-7.2.5}/dhee/training/train.py +0 -0
  265. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/__init__.py +0 -0
  266. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/cli.py +0 -0
  267. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/server.py +0 -0
  268. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/dist/assets/CanvasView-Cl1HxIK0.js +0 -0
  269. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/dist/assets/index-BboZhdsv.js +0 -0
  270. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/dist/assets/index-CIsLOp4u.css +0 -0
  271. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/dist/dhee-logo.png +0 -0
  272. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/dist/index.html +0 -0
  273. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/index.html +0 -0
  274. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/package-lock.json +0 -0
  275. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/package.json +0 -0
  276. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/public/dhee-logo.png +0 -0
  277. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/App.js +0 -0
  278. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/App.tsx +0 -0
  279. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/api.js +0 -0
  280. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/api.ts +0 -0
  281. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/AssetDrawer.js +0 -0
  282. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/AssetDrawer.tsx +0 -0
  283. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ChatMessage.js +0 -0
  284. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ChatMessage.tsx +0 -0
  285. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/FirstRunPanel.js +0 -0
  286. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/FirstRunPanel.tsx +0 -0
  287. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/LinePanel.js +0 -0
  288. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/LinePanel.tsx +0 -0
  289. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/NavRail.js +0 -0
  290. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/NavRail.tsx +0 -0
  291. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/OrgDrawer.js +0 -0
  292. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/OrgDrawer.tsx +0 -0
  293. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/TopBar.js +0 -0
  294. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/TopBar.tsx +0 -0
  295. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/TweaksPanel.js +0 -0
  296. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/TweaksPanel.tsx +0 -0
  297. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/WorkspaceManagerModal.js +0 -0
  298. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/WorkspaceManagerModal.tsx +0 -0
  299. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/CanvasControls.js +0 -0
  300. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/CanvasControls.tsx +0 -0
  301. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/CanvasSkeleton.js +0 -0
  302. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/CanvasSkeleton.tsx +0 -0
  303. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/DirectionHints.js +0 -0
  304. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/DirectionHints.tsx +0 -0
  305. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/Minimap.js +0 -0
  306. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/Minimap.tsx +0 -0
  307. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/NodeCard.js +0 -0
  308. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/NodeCard.tsx +0 -0
  309. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/forceLayout.js +0 -0
  310. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/forceLayout.ts +0 -0
  311. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/layout.js +0 -0
  312. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/layout.ts +0 -0
  313. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/treeLayout.js +0 -0
  314. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/treeLayout.ts +0 -0
  315. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/useInfiniteCanvas.js +0 -0
  316. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/canvas/useInfiniteCanvas.ts +0 -0
  317. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/cards/Cards.js +0 -0
  318. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/cards/Cards.tsx +0 -0
  319. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/graph/CanvasNodeCard.js +0 -0
  320. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/graph/CanvasNodeCard.tsx +0 -0
  321. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/DecayBar.js +0 -0
  322. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/DecayBar.tsx +0 -0
  323. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/Markdown.js +0 -0
  324. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/Markdown.tsx +0 -0
  325. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/SectionHeader.js +0 -0
  326. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/SectionHeader.tsx +0 -0
  327. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/StatPill.js +0 -0
  328. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/StatPill.tsx +0 -0
  329. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/TierBadge.js +0 -0
  330. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/components/ui/TierBadge.tsx +0 -0
  331. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/main.js +0 -0
  332. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/main.tsx +0 -0
  333. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/styles.css +0 -0
  334. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/types.js +0 -0
  335. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/types.ts +0 -0
  336. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/CanvasView.js +0 -0
  337. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/CanvasView.tsx +0 -0
  338. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ChannelView.js +0 -0
  339. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ChannelView.tsx +0 -0
  340. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ConflictView.js +0 -0
  341. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ConflictView.tsx +0 -0
  342. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ContextView.js +0 -0
  343. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ContextView.tsx +0 -0
  344. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/EvolutionView.js +0 -0
  345. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/EvolutionView.tsx +0 -0
  346. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/LaunchView.js +0 -0
  347. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/LaunchView.tsx +0 -0
  348. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/MemoryView.js +0 -0
  349. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/MemoryView.tsx +0 -0
  350. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/NotepadView.js +0 -0
  351. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/NotepadView.tsx +0 -0
  352. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/OrgCanvas.js +0 -0
  353. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/OrgCanvas.tsx +0 -0
  354. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ProductViews.js +0 -0
  355. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/ProductViews.tsx +0 -0
  356. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/RouterView.js +0 -0
  357. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/RouterView.tsx +0 -0
  358. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/TasksView.js +0 -0
  359. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/TasksView.tsx +0 -0
  360. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/WorkspaceView.js +0 -0
  361. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/src/views/WorkspaceView.tsx +0 -0
  362. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/tsconfig.json +0 -0
  363. {dhee-7.2.3 → dhee-7.2.5}/dhee/ui/web/vite.config.ts +0 -0
  364. {dhee-7.2.3 → dhee-7.2.5}/dhee/update_capsules.py +0 -0
  365. {dhee-7.2.3 → dhee-7.2.5}/dhee/utils/__init__.py +0 -0
  366. {dhee-7.2.3 → dhee-7.2.5}/dhee/utils/factory.py +0 -0
  367. {dhee-7.2.3 → dhee-7.2.5}/dhee/utils/math.py +0 -0
  368. {dhee-7.2.3 → dhee-7.2.5}/dhee/utils/prompts.py +0 -0
  369. {dhee-7.2.3 → dhee-7.2.5}/dhee/utils/repo_identity.py +0 -0
  370. {dhee-7.2.3 → dhee-7.2.5}/dhee/vector_stores/__init__.py +0 -0
  371. {dhee-7.2.3 → dhee-7.2.5}/dhee/vector_stores/base.py +0 -0
  372. {dhee-7.2.3 → dhee-7.2.5}/dhee/vector_stores/memory.py +0 -0
  373. {dhee-7.2.3 → dhee-7.2.5}/dhee/vector_stores/sqlite_vec.py +0 -0
  374. {dhee-7.2.3 → dhee-7.2.5}/dhee/vector_stores/zvec_store.py +0 -0
  375. {dhee-7.2.3 → dhee-7.2.5}/dhee/verifier_engine.py +0 -0
  376. {dhee-7.2.3 → dhee-7.2.5}/dhee/webhooks/__init__.py +0 -0
  377. {dhee-7.2.3 → dhee-7.2.5}/dhee/webhooks/elevenlabs.py +0 -0
  378. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/__init__.py +0 -0
  379. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/capture_store.py +0 -0
  380. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/causal_graph.py +0 -0
  381. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/encoder.py +0 -0
  382. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/gem_extractor.py +0 -0
  383. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/predictor.py +0 -0
  384. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/schema.py +0 -0
  385. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/service.py +0 -0
  386. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/session_graph.py +0 -0
  387. {dhee-7.2.3 → dhee-7.2.5}/dhee/world_memory/store.py +0 -0
  388. {dhee-7.2.3 → dhee-7.2.5}/dhee.egg-info/dependency_links.txt +0 -0
  389. {dhee-7.2.3 → dhee-7.2.5}/dhee.egg-info/entry_points.txt +0 -0
  390. {dhee-7.2.3 → dhee-7.2.5}/dhee.egg-info/requires.txt +0 -0
  391. {dhee-7.2.3 → dhee-7.2.5}/dhee.egg-info/top_level.txt +0 -0
  392. {dhee-7.2.3 → dhee-7.2.5}/dhee_shared/__init__.py +0 -0
  393. {dhee-7.2.3 → dhee-7.2.5}/dhee_shared/model_paths.py +0 -0
  394. {dhee-7.2.3 → dhee-7.2.5}/engram/__init__.py +0 -0
  395. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/__init__.py +0 -0
  396. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/bus.py +0 -0
  397. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/pubsub.py +0 -0
  398. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/server.py +0 -0
  399. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/store.py +0 -0
  400. {dhee-7.2.3 → dhee-7.2.5}/engram-bus/engram_bus/workspace.py +0 -0
  401. {dhee-7.2.3 → dhee-7.2.5}/setup.cfg +0 -0
  402. {dhee-7.2.3 → dhee-7.2.5}/tests/test_accel.py +0 -0
  403. {dhee-7.2.3 → dhee-7.2.5}/tests/test_accel_benchmark.py +0 -0
  404. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_digest.py +0 -0
  405. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_provider_examples.py +0 -0
  406. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_runtime_before.py +0 -0
  407. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_runtime_http_auth.py +0 -0
  408. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_runtime_lifecycle.py +0 -0
  409. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_runtime_tool.py +0 -0
  410. {dhee-7.2.3 → dhee-7.2.5}/tests/test_agent_runtime_voice_policy.py +0 -0
  411. {dhee-7.2.3 → dhee-7.2.5}/tests/test_artifacts.py +0 -0
  412. {dhee-7.2.3 → dhee-7.2.5}/tests/test_auto_lifecycle.py +0 -0
  413. {dhee-7.2.3 → dhee-7.2.5}/tests/test_backward_compat.py +0 -0
  414. {dhee-7.2.3 → dhee-7.2.5}/tests/test_batch.py +0 -0
  415. {dhee-7.2.3 → dhee-7.2.5}/tests/test_belief_debugger.py +0 -0
  416. {dhee-7.2.3 → dhee-7.2.5}/tests/test_causal_scene_memory.py +0 -0
  417. {dhee-7.2.3 → dhee-7.2.5}/tests/test_claude_code_hooks.py +0 -0
  418. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cli_config.py +0 -0
  419. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cli_harness_commands.py +0 -0
  420. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cli_onboard_update.py +0 -0
  421. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cli_pretty.py +0 -0
  422. {dhee-7.2.3 → dhee-7.2.5}/tests/test_codex_stream.py +0 -0
  423. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cognition_evals.py +0 -0
  424. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cognition_kernel.py +0 -0
  425. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cognition_v3.py +0 -0
  426. {dhee-7.2.3 → dhee-7.2.5}/tests/test_context_state.py +0 -0
  427. {dhee-7.2.3 → dhee-7.2.5}/tests/test_contract_runtime_recovery.py +0 -0
  428. {dhee-7.2.3 → dhee-7.2.5}/tests/test_core_memory.py +0 -0
  429. {dhee-7.2.3 → dhee-7.2.5}/tests/test_cosine_similarity.py +0 -0
  430. {dhee-7.2.3 → dhee-7.2.5}/tests/test_decades_eval.py +0 -0
  431. {dhee-7.2.3 → dhee-7.2.5}/tests/test_dedup.py +0 -0
  432. {dhee-7.2.3 → dhee-7.2.5}/tests/test_demo.py +0 -0
  433. {dhee-7.2.3 → dhee-7.2.5}/tests/test_dhee_init.py +0 -0
  434. {dhee-7.2.3 → dhee-7.2.5}/tests/test_dhee_model_paths.py +0 -0
  435. {dhee-7.2.3 → dhee-7.2.5}/tests/test_dheefs.py +0 -0
  436. {dhee-7.2.3 → dhee-7.2.5}/tests/test_distillation.py +0 -0
  437. {dhee-7.2.3 → dhee-7.2.5}/tests/test_e2e_all_features.py +0 -0
  438. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_cli.py +0 -0
  439. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_correction_memory.py +0 -0
  440. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_no_secret_storage.py +0 -0
  441. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_profile.py +0 -0
  442. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_two_call_memory.py +0 -0
  443. {dhee-7.2.3 → dhee-7.2.5}/tests/test_elevenlabs_webhook.py +0 -0
  444. {dhee-7.2.3 → dhee-7.2.5}/tests/test_engram_tiering.py +0 -0
  445. {dhee-7.2.3 → dhee-7.2.5}/tests/test_engram_tiering_promotion.py +0 -0
  446. {dhee-7.2.3 → dhee-7.2.5}/tests/test_evolution_meta_loop.py +0 -0
  447. {dhee-7.2.3 → dhee-7.2.5}/tests/test_evolution_session_gate.py +0 -0
  448. {dhee-7.2.3 → dhee-7.2.5}/tests/test_forgetting.py +0 -0
  449. {dhee-7.2.3 → dhee-7.2.5}/tests/test_gemini_provider.py +0 -0
  450. {dhee-7.2.3 → dhee-7.2.5}/tests/test_graph_proof_bundle.py +0 -0
  451. {dhee-7.2.3 → dhee-7.2.5}/tests/test_gstack_adapter.py +0 -0
  452. {dhee-7.2.3 → dhee-7.2.5}/tests/test_handoff_snapshot.py +0 -0
  453. {dhee-7.2.3 → dhee-7.2.5}/tests/test_harness_adapters.py +0 -0
  454. {dhee-7.2.3 → dhee-7.2.5}/tests/test_harness_install.py +0 -0
  455. {dhee-7.2.3 → dhee-7.2.5}/tests/test_hashing.py +0 -0
  456. {dhee-7.2.3 → dhee-7.2.5}/tests/test_hermes_provider.py +0 -0
  457. {dhee-7.2.3 → dhee-7.2.5}/tests/test_hippocamp_benchmark.py +0 -0
  458. {dhee-7.2.3 → dhee-7.2.5}/tests/test_incremental_context.py +0 -0
  459. {dhee-7.2.3 → dhee-7.2.5}/tests/test_install_cleanup.py +0 -0
  460. {dhee-7.2.3 → dhee-7.2.5}/tests/test_intent.py +0 -0
  461. {dhee-7.2.3 → dhee-7.2.5}/tests/test_karma_evaluator.py +0 -0
  462. {dhee-7.2.3 → dhee-7.2.5}/tests/test_learnings.py +0 -0
  463. {dhee-7.2.3 → dhee-7.2.5}/tests/test_locomo_plus_runner.py +0 -0
  464. {dhee-7.2.3 → dhee-7.2.5}/tests/test_log_parser.py +0 -0
  465. {dhee-7.2.3 → dhee-7.2.5}/tests/test_longmemeval_config.py +0 -0
  466. {dhee-7.2.3 → dhee-7.2.5}/tests/test_mcp_artifact_tools.py +0 -0
  467. {dhee-7.2.3 → dhee-7.2.5}/tests/test_mcp_tools_slim.py +0 -0
  468. {dhee-7.2.3 → dhee-7.2.5}/tests/test_memory_admission.py +0 -0
  469. {dhee-7.2.3 → dhee-7.2.5}/tests/test_memory_os_service.py +0 -0
  470. {dhee-7.2.3 → dhee-7.2.5}/tests/test_memory_types.py +0 -0
  471. {dhee-7.2.3 → dhee-7.2.5}/tests/test_meta_buddhi_group_relative.py +0 -0
  472. {dhee-7.2.3 → dhee-7.2.5}/tests/test_migration.py +0 -0
  473. {dhee-7.2.3 → dhee-7.2.5}/tests/test_miner.py +0 -0
  474. {dhee-7.2.3 → dhee-7.2.5}/tests/test_narrative_scene_intelligence.py +0 -0
  475. {dhee-7.2.3 → dhee-7.2.5}/tests/test_nvidia_embedder.py +0 -0
  476. {dhee-7.2.3 → dhee-7.2.5}/tests/test_openai_provider.py +0 -0
  477. {dhee-7.2.3 → dhee-7.2.5}/tests/test_openclaw.py +0 -0
  478. {dhee-7.2.3 → dhee-7.2.5}/tests/test_orchestration_core.py +0 -0
  479. {dhee-7.2.3 → dhee-7.2.5}/tests/test_oss_61_regressions.py +0 -0
  480. {dhee-7.2.3 → dhee-7.2.5}/tests/test_parallel.py +0 -0
  481. {dhee-7.2.3 → dhee-7.2.5}/tests/test_patch_families.py +0 -0
  482. {dhee-7.2.3 → dhee-7.2.5}/tests/test_plugin_learnings.py +0 -0
  483. {dhee-7.2.3 → dhee-7.2.5}/tests/test_portability_eval.py +0 -0
  484. {dhee-7.2.3 → dhee-7.2.5}/tests/test_power_packages.py +0 -0
  485. {dhee-7.2.3 → dhee-7.2.5}/tests/test_presets.py +0 -0
  486. {dhee-7.2.3 → dhee-7.2.5}/tests/test_profile.py +0 -0
  487. {dhee-7.2.3 → dhee-7.2.5}/tests/test_progressive_trainer.py +0 -0
  488. {dhee-7.2.3 → dhee-7.2.5}/tests/test_projects.py +0 -0
  489. {dhee-7.2.3 → dhee-7.2.5}/tests/test_protocol_v1.py +0 -0
  490. {dhee-7.2.3 → dhee-7.2.5}/tests/test_provider_runtime_profiles.py +0 -0
  491. {dhee-7.2.3 → dhee-7.2.5}/tests/test_query_cache.py +0 -0
  492. {dhee-7.2.3 → dhee-7.2.5}/tests/test_release_hygiene.py +0 -0
  493. {dhee-7.2.3 → dhee-7.2.5}/tests/test_replay_branching.py +0 -0
  494. {dhee-7.2.3 → dhee-7.2.5}/tests/test_replay_corpus_export.py +0 -0
  495. {dhee-7.2.3 → dhee-7.2.5}/tests/test_replay_gate.py +0 -0
  496. {dhee-7.2.3 → dhee-7.2.5}/tests/test_repo_intelligence.py +0 -0
  497. {dhee-7.2.3 → dhee-7.2.5}/tests/test_repo_link.py +0 -0
  498. {dhee-7.2.3 → dhee-7.2.5}/tests/test_reranker_defaults.py +0 -0
  499. {dhee-7.2.3 → dhee-7.2.5}/tests/test_router.py +0 -0
  500. {dhee-7.2.3 → dhee-7.2.5}/tests/test_router_replay.py +0 -0
  501. {dhee-7.2.3 → dhee-7.2.5}/tests/test_router_stats_agents.py +0 -0
  502. {dhee-7.2.3 → dhee-7.2.5}/tests/test_runtime.py +0 -0
  503. {dhee-7.2.3 → dhee-7.2.5}/tests/test_runtime_hardening.py +0 -0
  504. {dhee-7.2.3 → dhee-7.2.5}/tests/test_scene.py +0 -0
  505. {dhee-7.2.3 → dhee-7.2.5}/tests/test_scene_world_hook.py +0 -0
  506. {dhee-7.2.3 → dhee-7.2.5}/tests/test_secret_store.py +0 -0
  507. {dhee-7.2.3 → dhee-7.2.5}/tests/test_session_tracker.py +0 -0
  508. {dhee-7.2.3 → dhee-7.2.5}/tests/test_shared_tasks.py +0 -0
  509. {dhee-7.2.3 → dhee-7.2.5}/tests/test_simple_zero_config.py +0 -0
  510. {dhee-7.2.3 → dhee-7.2.5}/tests/test_skills.py +0 -0
  511. {dhee-7.2.3 → dhee-7.2.5}/tests/test_smart_memory.py +0 -0
  512. {dhee-7.2.3 → dhee-7.2.5}/tests/test_sqlite_connection_pool.py +0 -0
  513. {dhee-7.2.3 → dhee-7.2.5}/tests/test_sqlite_vec.py +0 -0
  514. {dhee-7.2.3 → dhee-7.2.5}/tests/test_structural.py +0 -0
  515. {dhee-7.2.3 → dhee-7.2.5}/tests/test_structured_resolution.py +0 -0
  516. {dhee-7.2.3 → dhee-7.2.5}/tests/test_task_contracts.py +0 -0
  517. {dhee-7.2.3 → dhee-7.2.5}/tests/test_tasks.py +0 -0
  518. {dhee-7.2.3 → dhee-7.2.5}/tests/test_temporal_fact_integration.py +0 -0
  519. {dhee-7.2.3 → dhee-7.2.5}/tests/test_temporal_fact_ledger.py +0 -0
  520. {dhee-7.2.3 → dhee-7.2.5}/tests/test_temporal_scenes.py +0 -0
  521. {dhee-7.2.3 → dhee-7.2.5}/tests/test_thread_state.py +0 -0
  522. {dhee-7.2.3 → dhee-7.2.5}/tests/test_traces.py +0 -0
  523. {dhee-7.2.3 → dhee-7.2.5}/tests/test_trajectory.py +0 -0
  524. {dhee-7.2.3 → dhee-7.2.5}/tests/test_ui.py +0 -0
  525. {dhee-7.2.3 → dhee-7.2.5}/tests/test_unified_enrichment.py +0 -0
  526. {dhee-7.2.3 → dhee-7.2.5}/tests/test_update_capsules.py +0 -0
  527. {dhee-7.2.3 → dhee-7.2.5}/tests/test_vector_store_factory.py +0 -0
  528. {dhee-7.2.3 → dhee-7.2.5}/tests/test_verification_runner.py +0 -0
  529. {dhee-7.2.3 → dhee-7.2.5}/tests/test_verifier_engine.py +0 -0
  530. {dhee-7.2.3 → dhee-7.2.5}/tests/test_workspace_line_agent_emit.py +0 -0
  531. {dhee-7.2.3 → dhee-7.2.5}/tests/test_workspace_line_bus.py +0 -0
  532. {dhee-7.2.3 → dhee-7.2.5}/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.5
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.5"
54
54
  __all__ = [
55
55
  # Memory classes
56
56
  "Engram",
@@ -1,4 +1,5 @@
1
1
  import os
2
+ from pathlib import Path
2
3
  from typing import Any, Dict, List, Optional
3
4
 
4
5
  from pydantic import BaseModel, Field, field_validator
@@ -12,12 +13,17 @@ from dhee.provider_defaults import (
12
13
  )
13
14
 
14
15
 
16
+ def resolve_dhee_data_dir(path: str | os.PathLike[str]) -> str:
17
+ """Return an absolute Dhee data directory with user markers expanded."""
18
+ return os.path.abspath(os.path.expanduser(os.fspath(path)))
19
+
20
+
15
21
  def _dhee_data_dir() -> str:
16
22
  """Resolve data directory: DHEE_DATA_DIR > ~/.dhee."""
17
23
  env = os.environ.get("DHEE_DATA_DIR")
18
24
  if env:
19
- return env
20
- return os.path.join(os.path.expanduser("~"), ".dhee")
25
+ return resolve_dhee_data_dir(env)
26
+ return resolve_dhee_data_dir(Path.home() / ".dhee")
21
27
 
22
28
 
23
29
  _VALID_VECTOR_PROVIDERS = {"memory", "sqlite_vec", "zvec"}
@@ -180,7 +186,7 @@ class SceneConfig(BaseModel):
180
186
  scene_topic_threshold: float = 0.55 # cosine sim below this = topic shift
181
187
  auto_close_inactive_minutes: int = 120
182
188
  max_scene_memories: int = 50
183
- use_llm_summarization: bool = False
189
+ use_llm_summarization: bool = True
184
190
  summary_regenerate_threshold: int = 5
185
191
 
186
192
 
@@ -741,17 +741,14 @@ def guard_router_call(tool_name: str, arguments: Dict[str, Any]) -> Dict[str, An
741
741
  "repo": str(repo_root),
742
742
  })
743
743
  if mode == "deny":
744
- # Even in deny mode a supervisor outage must leave a recovery
745
- # path open: read-only tools cannot violate a contract, and the
746
- # dhee CLI is how the agent repairs the runtime state.
747
744
  command = str(arguments.get("command") or "").strip()
748
- recoverable = tool_name in _READ_TOOL_NAMES or tool_name in _GREP_TOOL_NAMES or (
749
- tool_name in _BASH_TOOL_NAMES and command.startswith("dhee ")
745
+ recoverable = tool_name in {"Read", "Grep"} or (
746
+ tool_name == "Bash" and command.startswith("dhee ")
750
747
  )
751
748
  if recoverable:
752
749
  warning = (
753
750
  "Contract supervisor unavailable; deny mode allowed this "
754
- "read-only/remediation call."
751
+ "native read-only/remediation call."
755
752
  )
756
753
  _record_enforcement_warning(
757
754
  repo_root,
@@ -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 = []
@@ -229,16 +229,10 @@ class SceneProcessor:
229
229
 
230
230
  # Generate summary (LLM when enabled, otherwise deterministic extractive fallback).
231
231
  memories = self.db.get_scene_memories(scene_id)
232
- summary = None
233
- if self.use_llm_summarization and self.llm:
234
- summary = self._summarize_scene(scene, memories)
235
- if not summary:
236
- summary = self._extractive_scene_summary(memories)
232
+ summary = self._generate_scene_summary(scene, memories)
237
233
  if summary:
238
234
  updates["summary"] = summary
239
- # Derive title from summary
240
- title = summary.split(".")[0][:120]
241
- updates["title"] = title
235
+ updates["title"] = self._title_from_summary(summary)
242
236
 
243
237
  if updates:
244
238
  self.db.update_scene(scene_id, updates)
@@ -270,6 +264,77 @@ class SceneProcessor:
270
264
  # Summarization
271
265
  # ------------------------------------------------------------------
272
266
 
267
+ def summarize_scene(self, scene_id: str, *, force: bool = False) -> Optional[str]:
268
+ """Generate and persist a summary for an existing scene."""
269
+ scene = self.db.get_scene(scene_id)
270
+ if not scene:
271
+ return None
272
+ existing = str(scene.get("summary") or "").strip()
273
+ if existing and not force:
274
+ return existing
275
+
276
+ memories = self.db.get_scene_memories(scene_id)
277
+ summary = self._generate_scene_summary(scene, memories)
278
+ if not summary:
279
+ return None
280
+ self.db.update_scene(
281
+ scene_id,
282
+ {
283
+ "summary": summary,
284
+ "title": self._title_from_summary(summary),
285
+ },
286
+ )
287
+ return summary
288
+
289
+ def summarize_unsummarized(
290
+ self,
291
+ *,
292
+ user_id: Optional[str] = None,
293
+ limit: int = 100,
294
+ ) -> Dict[str, Any]:
295
+ """Fill missing scene summaries for a bounded maintenance slice."""
296
+ bounded_limit = max(1, min(int(limit), 2_000))
297
+ scenes = self.db.get_scenes(user_id=user_id, limit=bounded_limit)
298
+ summarized: List[Dict[str, Any]] = []
299
+ skipped_existing = 0
300
+ skipped_empty = 0
301
+
302
+ for scene in scenes:
303
+ if str(scene.get("summary") or "").strip():
304
+ skipped_existing += 1
305
+ continue
306
+ summary = self.summarize_scene(str(scene["id"]), force=True)
307
+ if not summary:
308
+ skipped_empty += 1
309
+ continue
310
+ summarized.append(
311
+ {
312
+ "id": scene.get("id"),
313
+ "title": self._title_from_summary(summary),
314
+ }
315
+ )
316
+
317
+ return {
318
+ "scanned_count": len(scenes),
319
+ "summarized_count": len(summarized),
320
+ "skipped_existing": skipped_existing,
321
+ "skipped_empty": skipped_empty,
322
+ "summaries": summarized[:50],
323
+ "truncated_summaries": max(0, len(summarized) - 50),
324
+ }
325
+
326
+ def _generate_scene_summary(
327
+ self,
328
+ scene: Dict[str, Any],
329
+ memories: List[Dict[str, Any]],
330
+ ) -> Optional[str]:
331
+ summary = None
332
+ if self.use_llm_summarization and self.llm:
333
+ summary = self._summarize_scene(scene, memories)
334
+ if not summary:
335
+ summary = self._extractive_scene_summary(memories)
336
+ return summary
337
+
273
338
  def _summarize_scene(
274
339
  self, scene: Dict[str, Any], memories: List[Dict[str, Any]]
275
340
  ) -> Optional[str]:
@@ -319,6 +384,14 @@ class SceneProcessor:
319
384
  return None
320
385
  return " | ".join(snippets)
321
386
 
387
+ @staticmethod
388
+ def _title_from_summary(summary: str) -> str:
389
+ cleaned = " ".join(str(summary or "").split())
390
+ if not cleaned:
391
+ return "Untitled scene"
392
+ first_sentence = cleaned.split(".")[0].strip()
393
+ return (first_sentence or cleaned)[:120]
394
+
322
395
  # ------------------------------------------------------------------
323
396
  # Search
324
397
  # ------------------------------------------------------------------
@@ -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')."""
@@ -49,6 +49,7 @@ class DoctorReport:
49
49
  generated_at: float = 0.0
50
50
  core: dict[str, Any] = field(default_factory=dict)
51
51
  runtime: dict[str, Any] = field(default_factory=dict)
52
+ provider_health: dict[str, Any] = field(default_factory=dict)
52
53
  router: dict[str, Any] = field(default_factory=dict)
53
54
  context: dict[str, Any] = field(default_factory=dict)
54
55
  cognition: dict[str, Any] = field(default_factory=dict)
@@ -62,6 +63,7 @@ class DoctorReport:
62
63
  "generated_at": self.generated_at,
63
64
  "core": self.core,
64
65
  "runtime": self.runtime,
66
+ "provider_health": self.provider_health,
65
67
  "router": self.router,
66
68
  "context": self.context,
67
69
  "cognition": self.cognition,
@@ -123,6 +125,61 @@ def _runtime_section() -> dict[str, Any]:
123
125
  return {"error": f"{type(exc).__name__}: {exc}"}
124
126
 
125
127
 
128
+ def _provider_health_section() -> dict[str, Any]:
129
+ try:
130
+ from dhee.cli_config import get_api_key, load_config
131
+ from dhee.provider_defaults import provider_defaults
132
+ except Exception as exc:
133
+ return {"ok": False, "status": "config_error", "error": f"{type(exc).__name__}: {exc}"}
134
+
135
+ config = load_config()
136
+ provider = str(config.get("provider") or "nvidia").strip().lower()
137
+ defaults = provider_defaults(provider)
138
+ model = str(config.get("llm_model") or defaults.get("llm_model") or "").strip()
139
+ if provider != "nvidia":
140
+ return {
141
+ "ok": None,
142
+ "status": "not_implemented",
143
+ "provider": provider,
144
+ "model": model,
145
+ }
146
+
147
+ api_key = get_api_key(provider)
148
+ if not api_key:
149
+ return {
150
+ "ok": False,
151
+ "status": "missing_api_key",
152
+ "provider": provider,
153
+ "model": model,
154
+ "required_env": defaults.get("env_var"),
155
+ }
156
+
157
+ try:
158
+ from dhee.llms.nvidia import NvidiaLLM
159
+
160
+ llm = NvidiaLLM(
161
+ {
162
+ "api_key": api_key,
163
+ "model": model,
164
+ "temperature": 0,
165
+ "max_tokens": 2,
166
+ "timeout": 8,
167
+ "max_retries": 0,
168
+ "app_retries": 1,
169
+ }
170
+ )
171
+ return llm.ping()
172
+ except Exception as exc:
173
+ return {
174
+ "ok": False,
175
+ "status": "unavailable",
176
+ "provider": provider,
177
+ "model": model,
178
+ "error_type": type(exc).__name__,
179
+ "error": str(exc),
180
+ }
181
+
182
+
126
183
  def _context_section() -> dict[str, Any]:
127
184
  out: dict[str, Any] = {}
128
185
  try:
@@ -597,6 +654,7 @@ def build_report() -> DoctorReport:
597
654
 
598
655
  core = _core_section()
599
656
  runtime = _runtime_section()
657
+ provider_health = _provider_health_section()
600
658
  router = _router_section()
601
659
  context = _context_section()
602
660
  cognition = _cognition_section()
@@ -609,6 +667,7 @@ def build_report() -> DoctorReport:
609
667
  generated_at=time.time(),
610
668
  core=core,
611
669
  runtime=runtime,
670
+ provider_health=provider_health,
612
671
  router=router,
613
672
  context=context,
614
673
  cognition=cognition,
@@ -627,6 +686,7 @@ def format_human(report: DoctorReport) -> str:
627
686
  lines: list[str] = []
628
687
  core = report.core
629
688
  runtime = report.runtime
689
+ provider_health = report.provider_health
630
690
  router = report.router
631
691
  context = report.context
632
692
  cog = report.cognition
@@ -674,6 +734,17 @@ def format_human(report: DoctorReport) -> str:
674
734
  lines.append(f" runtime dir: {paths.get('runtime_dir')}")
675
735
  lines.append("")
676
736
 
737
+ # Provider health
738
+ lines.append("[ provider health ]")
739
+ lines.append(f" provider: {provider_health.get('provider', '?')}")
740
+ lines.append(f" model: {provider_health.get('model', '?')}")
741
+ lines.append(f" status: {provider_health.get('status', '?')}")
742
+ if provider_health.get("latency_ms") is not None:
743
+ lines.append(f" latency: {provider_health.get('latency_ms')} ms")
744
+ if provider_health.get("error_type"):
745
+ lines.append(f" error: {provider_health.get('error_type')}: {provider_health.get('error')}")
746
+ lines.append("")
747
+
677
748
  # Router
678
749
  lines.append("[ router ]")
679
750
  if "error" in router:
@@ -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
 
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import os
3
3
  import time
4
- from typing import Optional
4
+ from typing import Any, Dict, Optional
5
5
 
6
6
  from dhee.llms.base import BaseLLM
7
7
  from dhee.provider_defaults import DEFAULT_NVIDIA_LLM_MODEL
@@ -59,6 +59,40 @@ class NvidiaLLM(BaseLLM):
59
59
  self.top_p = self.config.get("top_p", 0.7)
60
60
  self.enable_thinking = self.config.get("enable_thinking", False)
61
61
 
62
+ def ping(self) -> Dict[str, Any]:
63
+ """Check that the configured NVIDIA model accepts a minimal chat call."""
64
+ started = time.perf_counter()
65
+ try:
66
+ response = self.client.chat.completions.create(
67
+ model=self.model,
68
+ messages=[{"role": "user", "content": "Reply with OK."}],
69
+ temperature=0,
70
+ top_p=1,
71
+ max_tokens=2,
72
+ stream=False,
73
+ )
74
+ content = ""
75
+ if getattr(response, "choices", None):
76
+ content = str(response.choices[0].message.content or "").strip()
77
+ return {
78
+ "ok": True,
79
+ "status": "ready",
80
+ "provider": "nvidia",
81
+ "model": self.model,
82
+ "latency_ms": round((time.perf_counter() - started) * 1000, 2),
83
+ "response_preview": content[:20],
84
+ }
85
+ except Exception as exc:
86
+ return {
87
+ "ok": False,
88
+ "status": "unavailable",
89
+ "provider": "nvidia",
90
+ "model": self.model,
91
+ "latency_ms": round((time.perf_counter() - started) * 1000, 2),
92
+ "error_type": type(exc).__name__,
93
+ "error": str(exc),
94
+ }
95
+
62
96
  def generate(self, prompt: str) -> str:
63
97
  from openai import APITimeoutError, APIConnectionError
64
98