hy-memory 2.0.2__tar.gz → 2.0.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 (140) hide show
  1. {hy_memory-2.0.2/hy_memory.egg-info → hy_memory-2.0.4}/PKG-INFO +9 -9
  2. {hy_memory-2.0.2 → hy_memory-2.0.4}/README.md +8 -8
  3. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/extractor.py +2 -0
  4. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/llm_provider.py +35 -20
  5. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/reconciler.py +2 -0
  6. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/extractor.py +1 -0
  7. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/fact_reconciler.py +2 -0
  8. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/judge.py +11 -3
  9. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/reconciler.py +1 -0
  10. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/config.py +8 -1
  11. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/core/embed_service.py +14 -4
  12. hy_memory-2.0.4/hy_memory/utils/model_call_context.py +24 -0
  13. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/pipeline_log_writer.py +5 -1
  14. {hy_memory-2.0.2 → hy_memory-2.0.4/hy_memory.egg-info}/PKG-INFO +9 -9
  15. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory.egg-info/SOURCES.txt +1 -0
  16. {hy_memory-2.0.2 → hy_memory-2.0.4}/pyproject.toml +1 -1
  17. {hy_memory-2.0.2 → hy_memory-2.0.4}/LICENSE +0 -0
  18. {hy_memory-2.0.2 → hy_memory-2.0.4}/MANIFEST.in +0 -0
  19. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/__init__.py +0 -0
  20. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/__init__.py +0 -0
  21. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/abstractor.py +0 -0
  22. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/emotion_analyzer.py +0 -0
  23. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/episode_summary.py +0 -0
  24. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/intention_detector.py +0 -0
  25. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/mem_agent.py +0 -0
  26. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/prompts_zh.py +0 -0
  27. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/reflector.py +0 -0
  28. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/tools/__init__.py +0 -0
  29. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/tools/base.py +0 -0
  30. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/agent/tools/basic_profile.py +0 -0
  31. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/client.py +0 -0
  32. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/__init__.py +0 -0
  33. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/chain_store.py +0 -0
  34. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/lexical.py +0 -0
  35. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/preproc.py +0 -0
  36. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/prompts_zh.py +0 -0
  37. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/store.py +0 -0
  38. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/types.py +0 -0
  39. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/coding/writer.py +0 -0
  40. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/core/__init__.py +0 -0
  41. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/core/merger.py +0 -0
  42. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/core/scorer.py +0 -0
  43. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/core/workload.py +0 -0
  44. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/__init__.py +0 -0
  45. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/cache.py +0 -0
  46. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/cache_base.py +0 -0
  47. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/cache_mysql.py +0 -0
  48. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/cache_sqlite.py +0 -0
  49. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/graph_store.py +0 -0
  50. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/graph_store_base.py +0 -0
  51. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/graph_store_kuzu.py +0 -0
  52. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/graph_store_neo4j.py +0 -0
  53. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/history_store.py +0 -0
  54. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/kv_store.py +0 -0
  55. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/rdb.py +0 -0
  56. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/vector_store.py +0 -0
  57. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/vector_store_base.py +0 -0
  58. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/vector_store_chroma.py +0 -0
  59. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/vector_store_faiss.py +0 -0
  60. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/data/vector_store_qdrant.py +0 -0
  61. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/inspector.py +0 -0
  62. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/metrics.py +0 -0
  63. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/models/__init__.py +0 -0
  64. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/models/memory.py +0 -0
  65. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/models/requests.py +0 -0
  66. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/__init__.py +0 -0
  67. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/__init__.py +0 -0
  68. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/projector.py +0 -0
  69. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/rerank.py +0 -0
  70. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/topic_summary.py +0 -0
  71. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/__init__.py +0 -0
  72. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/bm25.py +0 -0
  73. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/bm25_fastembed.py +0 -0
  74. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/candidate_guards.py +0 -0
  75. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/config.py +0 -0
  76. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/date_view.py +0 -0
  77. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/dedup.py +0 -0
  78. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/diversity.py +0 -0
  79. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/entities.py +0 -0
  80. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/entity_store.py +0 -0
  81. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/evolution.py +0 -0
  82. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/hierarchy_bundle.py +0 -0
  83. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/intent.py +0 -0
  84. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/intention.py +0 -0
  85. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/lemmatize.py +0 -0
  86. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/local_rerank.py +0 -0
  87. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/memory_format.py +0 -0
  88. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/multi_seed_bundle.py +0 -0
  89. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/ner.py +0 -0
  90. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/profile_evidence.py +0 -0
  91. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/profile_owner_gate.py +0 -0
  92. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/query_expand.py +0 -0
  93. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/reconcile_retrieval.py +0 -0
  94. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/record_date_view.py +0 -0
  95. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/retrieval_clauses.py +0 -0
  96. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/rrf.py +0 -0
  97. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/scoring.py +0 -0
  98. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/series_tail_guard.py +0 -0
  99. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/session_episode.py +0 -0
  100. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/strength.py +0 -0
  101. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/supplemental_propositions.py +0 -0
  102. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/tag_index.py +0 -0
  103. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/temporal.py +0 -0
  104. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/topic_candidates.py +0 -0
  105. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/trace.py +0 -0
  106. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/underflow.py +0 -0
  107. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/user_level_l0.py +0 -0
  108. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/balanced_catalog.py +0 -0
  109. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/base.py +0 -0
  110. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/cross_domain_sweeper.py +0 -0
  111. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/reader.py +0 -0
  112. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/reader_base.py +0 -0
  113. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/reader_hybrid.py +0 -0
  114. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/reader_legacy.py +0 -0
  115. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/registry.py +0 -0
  116. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/specific_supplement.py +0 -0
  117. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/system2_agent.py +0 -0
  118. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/system2_tools.py +0 -0
  119. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/system2_writer.py +0 -0
  120. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/user_profile_scope.py +0 -0
  121. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/pipelines/writer.py +0 -0
  122. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/runtime.py +0 -0
  123. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/server.py +0 -0
  124. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/structure.py +0 -0
  125. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/async_executor.py +0 -0
  126. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/clone_references.py +0 -0
  127. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/keyword_ties.py +0 -0
  128. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/lang_detect.py +0 -0
  129. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/log_setup.py +0 -0
  130. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/metrics.py +0 -0
  131. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/pipeline_observability.py +0 -0
  132. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/source_filter.py +0 -0
  133. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/time_window.py +0 -0
  134. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/token_count.py +0 -0
  135. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/trace_file_writer.py +0 -0
  136. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory/utils/tracer.py +0 -0
  137. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory.egg-info/dependency_links.txt +0 -0
  138. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory.egg-info/requires.txt +0 -0
  139. {hy_memory-2.0.2 → hy_memory-2.0.4}/hy_memory.egg-info/top_level.txt +0 -0
  140. {hy_memory-2.0.2 → hy_memory-2.0.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hy-memory
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: HY Memory - Industrial-grade dual-system cognitive memory framework
5
5
  Author: alvinfei
6
6
  License-Expression: Apache-2.0
@@ -83,7 +83,7 @@ English | [中文](README.zh.md)
83
83
 
84
84
  ## Latest News
85
85
 
86
- * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.1`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.1/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
86
+ * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.3`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.3/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
87
87
  * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Open-sourced** **[Hy-Memory-30B-A3B](https://huggingface.co/tencent/Hy-Memory-30B-A3B)** on Hugging Face along with its [technical report](https://arxiv.org/abs/2610.22196) on attributed reinforcement learning for long-term memory writing!
88
88
  * *<mark>[new]</mark>* 🔥🔥 **[2026-09]**: 📊 **Released** **[CMB: A Coding Memory Benchmark for Long-Horizon and Interleaved Coding Agents](docs/papers/CMB_A_Coding_Memory_Benchmark_for_Long_Horizon_and_Interleaved_Coding_Agents.pdf)** (submitted to **ICLR 2027**).
89
89
  * *<mark>[new]</mark>* 🔥🔥 **[2026-08]**: 🎉 **Accepted** at **EMNLP 2026**: **[Memory Beyond Recall: A Dual-Process Cognitive Memory System for Self-Evolving LLM Agents](https://arxiv.org/abs/2606.09483)**!
@@ -114,13 +114,13 @@ Welcome to the **Hy Memory Research Family**, covering cognitive chat memory, lo
114
114
  ### 1. Installation
115
115
 
116
116
  ```bash
117
- pip install hy-memory==2.0.1 # core (includes ChromaDB and Kuzu)
118
- pip install "hy-memory[qdrant]==2.0.1" # + Qdrant
119
- pip install "hy-memory[faiss]==2.0.1" # + FAISS
120
- pip install "hy-memory[graph]==2.0.1" # + Neo4j
121
- pip install "hy-memory[mysql]==2.0.1" # + MySQL cache
122
- pip install "hy-memory[rerank]==2.0.1" # + local multilingual cross-encoder rerank
123
- pip install "hy-memory[all]==2.0.1" # everything
117
+ pip install hy-memory==2.0.3 # core (includes ChromaDB and Kuzu)
118
+ pip install "hy-memory[qdrant]==2.0.3" # + Qdrant
119
+ pip install "hy-memory[faiss]==2.0.3" # + FAISS
120
+ pip install "hy-memory[graph]==2.0.3" # + Neo4j
121
+ pip install "hy-memory[mysql]==2.0.3" # + MySQL cache
122
+ pip install "hy-memory[rerank]==2.0.3" # + local multilingual cross-encoder rerank
123
+ pip install "hy-memory[all]==2.0.3" # everything
124
124
  ```
125
125
 
126
126
  ### 2. Configuration
@@ -32,7 +32,7 @@ English | [中文](README.zh.md)
32
32
 
33
33
  ## Latest News
34
34
 
35
- * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.1`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.1/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
35
+ * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.3`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.3/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
36
36
  * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Open-sourced** **[Hy-Memory-30B-A3B](https://huggingface.co/tencent/Hy-Memory-30B-A3B)** on Hugging Face along with its [technical report](https://arxiv.org/abs/2610.22196) on attributed reinforcement learning for long-term memory writing!
37
37
  * *<mark>[new]</mark>* 🔥🔥 **[2026-09]**: 📊 **Released** **[CMB: A Coding Memory Benchmark for Long-Horizon and Interleaved Coding Agents](docs/papers/CMB_A_Coding_Memory_Benchmark_for_Long_Horizon_and_Interleaved_Coding_Agents.pdf)** (submitted to **ICLR 2027**).
38
38
  * *<mark>[new]</mark>* 🔥🔥 **[2026-08]**: 🎉 **Accepted** at **EMNLP 2026**: **[Memory Beyond Recall: A Dual-Process Cognitive Memory System for Self-Evolving LLM Agents](https://arxiv.org/abs/2606.09483)**!
@@ -63,13 +63,13 @@ Welcome to the **Hy Memory Research Family**, covering cognitive chat memory, lo
63
63
  ### 1. Installation
64
64
 
65
65
  ```bash
66
- pip install hy-memory==2.0.1 # core (includes ChromaDB and Kuzu)
67
- pip install "hy-memory[qdrant]==2.0.1" # + Qdrant
68
- pip install "hy-memory[faiss]==2.0.1" # + FAISS
69
- pip install "hy-memory[graph]==2.0.1" # + Neo4j
70
- pip install "hy-memory[mysql]==2.0.1" # + MySQL cache
71
- pip install "hy-memory[rerank]==2.0.1" # + local multilingual cross-encoder rerank
72
- pip install "hy-memory[all]==2.0.1" # everything
66
+ pip install hy-memory==2.0.3 # core (includes ChromaDB and Kuzu)
67
+ pip install "hy-memory[qdrant]==2.0.3" # + Qdrant
68
+ pip install "hy-memory[faiss]==2.0.3" # + FAISS
69
+ pip install "hy-memory[graph]==2.0.3" # + Neo4j
70
+ pip install "hy-memory[mysql]==2.0.3" # + MySQL cache
71
+ pip install "hy-memory[rerank]==2.0.3" # + local multilingual cross-encoder rerank
72
+ pip install "hy-memory[all]==2.0.3" # everything
73
73
  ```
74
74
 
75
75
  ### 2. Configuration
@@ -1123,6 +1123,7 @@ class Extractor:
1123
1123
  max_tokens=self._llm_config.agent_max_tokens,
1124
1124
  tools=None,
1125
1125
  tool_choice=None,
1126
+ audit_stage="extract",
1126
1127
  )
1127
1128
  self._call_count += 1
1128
1129
  total_tokens += response.tokens_used
@@ -1233,6 +1234,7 @@ class Extractor:
1233
1234
  max_tokens=self._llm_config.agent_max_tokens,
1234
1235
  tools=None,
1235
1236
  tool_choice=None,
1237
+ audit_stage="extract",
1236
1238
  )
1237
1239
  self._call_count += 1
1238
1240
  total_tokens += response.tokens_used
@@ -34,6 +34,7 @@ import os
34
34
  import weakref
35
35
 
36
36
  from ..config import MemoryConfig
37
+ from ..utils.model_call_context import model_call_stage
37
38
  from ..core.workload import llm_slot
38
39
 
39
40
  logger = logging.getLogger(__name__)
@@ -348,6 +349,7 @@ class LLMProvider:
348
349
  stop: List[str] = None,
349
350
  tools: Optional[List[Dict[str, Any]]] = None,
350
351
  tool_choice: Optional[Any] = None,
352
+ audit_stage: Optional[str] = None,
351
353
  **kwargs
352
354
  ) -> LLMResponse:
353
355
  """
@@ -386,15 +388,16 @@ class LLMProvider:
386
388
  len(prompt), _content_fingerprint(prompt),
387
389
  )
388
390
 
389
- response = await self._call_llm(
390
- prompt=prompt,
391
- max_tokens=max_tokens,
392
- temperature=temperature,
393
- stop=stop,
394
- tools=tools,
395
- tool_choice=tool_choice,
396
- **kwargs
397
- )
391
+ with model_call_stage(audit_stage):
392
+ response = await self._call_llm(
393
+ prompt=prompt,
394
+ max_tokens=max_tokens,
395
+ temperature=temperature,
396
+ stop=stop,
397
+ tools=tools,
398
+ tool_choice=tool_choice,
399
+ **kwargs
400
+ )
398
401
 
399
402
  self._total_calls += 1
400
403
  self._total_tokens += response.tokens_used
@@ -496,11 +499,21 @@ class LLMProvider:
496
499
  clients = self._clients.setdefault(loop, {})
497
500
  client = clients.get(client_key)
498
501
  if client is None:
502
+ client_options: Dict[str, Any] = {
503
+ "api_key": base_api_key,
504
+ "base_url": base_url,
505
+ "timeout": self._llm_config.timeout,
506
+ "max_retries": 0,
507
+ }
508
+ transport_factory = getattr(self.config, "http_transport_factory", None)
509
+ if callable(transport_factory):
510
+ import httpx
511
+
512
+ client_options["http_client"] = httpx.AsyncClient(
513
+ transport=transport_factory()
514
+ )
499
515
  client = AsyncOpenAI(
500
- api_key=base_api_key,
501
- base_url=base_url,
502
- timeout=self._llm_config.timeout,
503
- max_retries=0,
516
+ **client_options,
504
517
  )
505
518
  clients[client_key] = client
506
519
 
@@ -585,6 +598,7 @@ class LLMProvider:
585
598
  temperature: Optional[float] = None,
586
599
  tools: Optional[List[Dict[str, Any]]] = None,
587
600
  tool_choice: Optional[Any] = None,
601
+ audit_stage: Optional[str] = None,
588
602
  ) -> LLMResponse:
589
603
  """
590
604
  多轮 messages 调用(支持 tool results 回传)。
@@ -612,13 +626,14 @@ class LLMProvider:
612
626
  f"msgs={len(messages)} tools={len(tools) if tools else 0}"
613
627
  )
614
628
 
615
- response = await self._chat_completions(
616
- messages,
617
- max_tokens=max_tokens,
618
- temperature=temperature,
619
- tools=tools,
620
- tool_choice=tool_choice,
621
- )
629
+ with model_call_stage(audit_stage):
630
+ response = await self._chat_completions(
631
+ messages,
632
+ max_tokens=max_tokens,
633
+ temperature=temperature,
634
+ tools=tools,
635
+ tool_choice=tool_choice,
636
+ )
622
637
 
623
638
  self._total_calls += 1
624
639
  self._total_tokens += response.tokens_used
@@ -669,6 +669,7 @@ class MemoryReconciler:
669
669
  response = await llm.complete(
670
670
  prompt=prompt,
671
671
  max_tokens=500,
672
+ audit_stage="reconcile",
672
673
  )
673
674
  text = response.content.strip()
674
675
  if "```json" in text:
@@ -1383,6 +1384,7 @@ class MemoryReconciler:
1383
1384
  response = await llm.complete(
1384
1385
  prompt=prompt,
1385
1386
  max_tokens=dyn_max_tokens,
1387
+ audit_stage="reconcile",
1386
1388
  )
1387
1389
  except Exception as e:
1388
1390
  # LLM 彻底不可用(provider 已按 max_retries 重试过,网关 500 /
@@ -919,6 +919,7 @@ class CodingMemoryExtractor:
919
919
  resp = await self.llm_provider.complete(
920
920
  prompt=prompt,
921
921
  max_tokens=self.max_tokens,
922
+ audit_stage="coding_extract",
922
923
  )
923
924
  except Exception as e:
924
925
  logger.warning(f"[coding-extract] LLM call failed: {e}")
@@ -571,6 +571,7 @@ class WorkingFactReconciler:
571
571
  resp = await self.llm_provider.complete(
572
572
  prompt=prompt,
573
573
  max_tokens=self.max_tokens,
574
+ audit_stage="coding_fact_reconcile",
574
575
  )
575
576
  return self._parse_ops(resp.content)
576
577
 
@@ -637,6 +638,7 @@ class WorkingFactReconciler:
637
638
  resp = await self.llm_provider.complete(
638
639
  prompt=prompt,
639
640
  max_tokens=_CHAIN_SUMMARY_MAX_TOKENS,
641
+ audit_stage="coding_fact_summary",
640
642
  )
641
643
  except Exception as e:
642
644
  logger.warning(f"[fact-reconcile] chain summary failed: {e}")
@@ -29,6 +29,9 @@ logger = logging.getLogger(__name__)
29
29
 
30
30
  _JUDGE_MAX_TURNS = 20
31
31
  _JUDGE_HEAD_TURNS = 5
32
+ _JUDGE_USER_CONTENT_LIMIT = 1_000
33
+ _JUDGE_USER_CONTENT_HEAD = 200
34
+ _JUDGE_USER_CONTENT_TAIL = 200
32
35
  _JUDGE_MAX_QUERY_CHARS = 300
33
36
  _JUDGE_MAX_QUERIES = 20
34
37
 
@@ -186,6 +189,7 @@ async def classify_messages_scene(
186
189
  prompt=prompt,
187
190
  max_tokens=max_tokens,
188
191
  temperature=temperature,
192
+ audit_stage="coding_judge",
189
193
  )
190
194
  _elapsed = round((time.perf_counter() - _t0) * 1000, 2)
191
195
  result = _parse_scene_json(resp.content)
@@ -631,9 +635,13 @@ def _format_turns(summary: List[Dict[str, Any]]) -> str:
631
635
  rows = []
632
636
  for t in summary:
633
637
  user = t.get("user", "") or ""
634
- # 单 turn 用户文本截到 200 字符
635
- if len(user) > 200:
636
- user = user[:200] + "..."
638
+ if len(user) > _JUDGE_USER_CONTENT_LIMIT:
639
+ omitted = len(user) - _JUDGE_USER_CONTENT_HEAD - _JUDGE_USER_CONTENT_TAIL
640
+ user = (
641
+ user[:_JUDGE_USER_CONTENT_HEAD]
642
+ + f"\n[...{omitted} chars omitted...]\n"
643
+ + user[-_JUDGE_USER_CONTENT_TAIL:]
644
+ )
637
645
  tools = t.get("tools", []) or []
638
646
  rows.append(
639
647
  f"- turn {t.get('turn', '?')}: user={user!r}, tools={tools}"
@@ -310,6 +310,7 @@ class CodingMemoryReconciler:
310
310
  resp = await self.llm_provider.complete(
311
311
  prompt=prompt,
312
312
  max_tokens=self.max_tokens,
313
+ audit_stage="coding_reconcile",
313
314
  )
314
315
  return self._parse_ops(resp.content), prompt, resp.content, resp
315
316
 
@@ -6,7 +6,7 @@ Agent Memory - 配置管理
6
6
 
7
7
  import os
8
8
  from dataclasses import dataclass, field
9
- from typing import Optional, Dict, Any, List
9
+ from typing import Optional, Dict, Any, Callable, List
10
10
  from pathlib import Path
11
11
 
12
12
 
@@ -1252,6 +1252,13 @@ class MemoryConfig:
1252
1252
  enable_agent: bool = False
1253
1253
  debug: bool = False
1254
1254
  metrics_enabled: bool = True
1255
+ # Runtime-only HTTP transport factory. MemHub uses this for request-cost
1256
+ # budgeting without restricting the embedded SDK's local store access.
1257
+ http_transport_factory: Optional[Callable[[], Any]] = field(
1258
+ default=None,
1259
+ repr=False,
1260
+ compare=False,
1261
+ )
1255
1262
 
1256
1263
  def __post_init__(self):
1257
1264
  # enable_graph 跟随 mode 走:mode=ultra 时自动启用,无需独立环境变量
@@ -356,11 +356,21 @@ class EmbedService:
356
356
  key = self._client_cache_key(base_url, api_key, timeout)
357
357
  client = self._client_cache.get(key)
358
358
  if client is None:
359
+ client_options = {
360
+ "api_key": api_key,
361
+ "base_url": base_url or None,
362
+ "timeout": timeout,
363
+ "max_retries": 0,
364
+ }
365
+ transport_factory = getattr(self.config, "http_transport_factory", None)
366
+ if callable(transport_factory):
367
+ import httpx
368
+
369
+ client_options["http_client"] = httpx.AsyncClient(
370
+ transport=transport_factory()
371
+ )
359
372
  client = AsyncOpenAI(
360
- api_key=api_key,
361
- base_url=base_url or None,
362
- timeout=timeout,
363
- max_retries=0,
373
+ **client_options,
364
374
  )
365
375
  self._client_cache[key] = client
366
376
  return client
@@ -0,0 +1,24 @@
1
+ """Context propagated to host-provided HTTP transports for cost accounting."""
2
+
3
+ from collections.abc import Iterator
4
+ from contextlib import contextmanager
5
+ from contextvars import ContextVar, Token
6
+
7
+ _model_call_stage: ContextVar[str] = ContextVar(
8
+ "hy_memory_model_call_stage",
9
+ default="other",
10
+ )
11
+
12
+
13
+ def current_model_call_stage() -> str:
14
+ return _model_call_stage.get()
15
+
16
+
17
+ @contextmanager
18
+ def model_call_stage(stage: str | None) -> Iterator[None]:
19
+ normalized = (stage or "other").strip().lower() or "other"
20
+ token: Token[str] = _model_call_stage.set(normalized)
21
+ try:
22
+ yield
23
+ finally:
24
+ _model_call_stage.reset(token)
@@ -80,7 +80,11 @@ class PipelineLogWriter:
80
80
  split_namespace_user,
81
81
  )
82
82
 
83
- tokens = (prompt_tokens or 0) + (completion_tokens or 0) + (total_tokens or 0)
83
+ # Providers define total_tokens as prompt+completion. Adding all
84
+ # three fields doubled every cost estimate in this JSONL.
85
+ tokens = (total_tokens or 0) or (
86
+ (prompt_tokens or 0) + (completion_tokens or 0)
87
+ )
84
88
  namespace, uid = split_namespace_user(user_id or "")
85
89
  if not is_llm_content_logging_enabled():
86
90
  prompt = redact_content(prompt)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hy-memory
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: HY Memory - Industrial-grade dual-system cognitive memory framework
5
5
  Author: alvinfei
6
6
  License-Expression: Apache-2.0
@@ -83,7 +83,7 @@ English | [中文](README.zh.md)
83
83
 
84
84
  ## Latest News
85
85
 
86
- * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.1`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.1/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
86
+ * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Released** **Hy Memory 2.0 (`hy-memory==2.0.3`)** on [PyPI](https://pypi.org/project/hy-memory/2.0.3/) and open-sourced the **Hy-Memory** monorepo together with **[MemHub](memhub/README.md)**!
87
87
  * *<mark>[new]</mark>* 🔥🔥🔥 **[2026-10]**: 🚀 **Open-sourced** **[Hy-Memory-30B-A3B](https://huggingface.co/tencent/Hy-Memory-30B-A3B)** on Hugging Face along with its [technical report](https://arxiv.org/abs/2610.22196) on attributed reinforcement learning for long-term memory writing!
88
88
  * *<mark>[new]</mark>* 🔥🔥 **[2026-09]**: 📊 **Released** **[CMB: A Coding Memory Benchmark for Long-Horizon and Interleaved Coding Agents](docs/papers/CMB_A_Coding_Memory_Benchmark_for_Long_Horizon_and_Interleaved_Coding_Agents.pdf)** (submitted to **ICLR 2027**).
89
89
  * *<mark>[new]</mark>* 🔥🔥 **[2026-08]**: 🎉 **Accepted** at **EMNLP 2026**: **[Memory Beyond Recall: A Dual-Process Cognitive Memory System for Self-Evolving LLM Agents](https://arxiv.org/abs/2606.09483)**!
@@ -114,13 +114,13 @@ Welcome to the **Hy Memory Research Family**, covering cognitive chat memory, lo
114
114
  ### 1. Installation
115
115
 
116
116
  ```bash
117
- pip install hy-memory==2.0.1 # core (includes ChromaDB and Kuzu)
118
- pip install "hy-memory[qdrant]==2.0.1" # + Qdrant
119
- pip install "hy-memory[faiss]==2.0.1" # + FAISS
120
- pip install "hy-memory[graph]==2.0.1" # + Neo4j
121
- pip install "hy-memory[mysql]==2.0.1" # + MySQL cache
122
- pip install "hy-memory[rerank]==2.0.1" # + local multilingual cross-encoder rerank
123
- pip install "hy-memory[all]==2.0.1" # everything
117
+ pip install hy-memory==2.0.3 # core (includes ChromaDB and Kuzu)
118
+ pip install "hy-memory[qdrant]==2.0.3" # + Qdrant
119
+ pip install "hy-memory[faiss]==2.0.3" # + FAISS
120
+ pip install "hy-memory[graph]==2.0.3" # + Neo4j
121
+ pip install "hy-memory[mysql]==2.0.3" # + MySQL cache
122
+ pip install "hy-memory[rerank]==2.0.3" # + local multilingual cross-encoder rerank
123
+ pip install "hy-memory[all]==2.0.3" # everything
124
124
  ```
125
125
 
126
126
  ### 2. Configuration
@@ -128,6 +128,7 @@ hy_memory/utils/keyword_ties.py
128
128
  hy_memory/utils/lang_detect.py
129
129
  hy_memory/utils/log_setup.py
130
130
  hy_memory/utils/metrics.py
131
+ hy_memory/utils/model_call_context.py
131
132
  hy_memory/utils/pipeline_log_writer.py
132
133
  hy_memory/utils/pipeline_observability.py
133
134
  hy_memory/utils/source_filter.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hy-memory"
7
- version = "2.0.2"
7
+ version = "2.0.4"
8
8
  description = "HY Memory - Industrial-grade dual-system cognitive memory framework"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes
File without changes
File without changes
File without changes
File without changes