hy-memory 2.0.3__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.3/hy_memory.egg-info → hy_memory-2.0.4}/PKG-INFO +1 -1
  2. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/extractor.py +2 -0
  3. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/llm_provider.py +21 -16
  4. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/reconciler.py +2 -0
  5. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/extractor.py +1 -0
  6. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/fact_reconciler.py +2 -0
  7. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/judge.py +11 -3
  8. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/reconciler.py +1 -0
  9. hy_memory-2.0.4/hy_memory/utils/model_call_context.py +24 -0
  10. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/pipeline_log_writer.py +5 -1
  11. {hy_memory-2.0.3 → hy_memory-2.0.4/hy_memory.egg-info}/PKG-INFO +1 -1
  12. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory.egg-info/SOURCES.txt +1 -0
  13. {hy_memory-2.0.3 → hy_memory-2.0.4}/pyproject.toml +1 -1
  14. {hy_memory-2.0.3 → hy_memory-2.0.4}/LICENSE +0 -0
  15. {hy_memory-2.0.3 → hy_memory-2.0.4}/MANIFEST.in +0 -0
  16. {hy_memory-2.0.3 → hy_memory-2.0.4}/README.md +0 -0
  17. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/__init__.py +0 -0
  18. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/__init__.py +0 -0
  19. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/abstractor.py +0 -0
  20. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/emotion_analyzer.py +0 -0
  21. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/episode_summary.py +0 -0
  22. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/intention_detector.py +0 -0
  23. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/mem_agent.py +0 -0
  24. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/prompts_zh.py +0 -0
  25. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/reflector.py +0 -0
  26. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/tools/__init__.py +0 -0
  27. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/tools/base.py +0 -0
  28. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/agent/tools/basic_profile.py +0 -0
  29. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/client.py +0 -0
  30. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/__init__.py +0 -0
  31. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/chain_store.py +0 -0
  32. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/lexical.py +0 -0
  33. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/preproc.py +0 -0
  34. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/prompts_zh.py +0 -0
  35. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/store.py +0 -0
  36. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/types.py +0 -0
  37. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/coding/writer.py +0 -0
  38. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/config.py +0 -0
  39. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/core/__init__.py +0 -0
  40. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/core/embed_service.py +0 -0
  41. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/core/merger.py +0 -0
  42. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/core/scorer.py +0 -0
  43. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/core/workload.py +0 -0
  44. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/__init__.py +0 -0
  45. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/cache.py +0 -0
  46. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/cache_base.py +0 -0
  47. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/cache_mysql.py +0 -0
  48. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/cache_sqlite.py +0 -0
  49. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/graph_store.py +0 -0
  50. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/graph_store_base.py +0 -0
  51. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/graph_store_kuzu.py +0 -0
  52. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/graph_store_neo4j.py +0 -0
  53. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/history_store.py +0 -0
  54. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/kv_store.py +0 -0
  55. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/rdb.py +0 -0
  56. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/vector_store.py +0 -0
  57. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/vector_store_base.py +0 -0
  58. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/vector_store_chroma.py +0 -0
  59. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/vector_store_faiss.py +0 -0
  60. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/data/vector_store_qdrant.py +0 -0
  61. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/inspector.py +0 -0
  62. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/metrics.py +0 -0
  63. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/models/__init__.py +0 -0
  64. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/models/memory.py +0 -0
  65. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/models/requests.py +0 -0
  66. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/__init__.py +0 -0
  67. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/__init__.py +0 -0
  68. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/projector.py +0 -0
  69. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/rerank.py +0 -0
  70. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_graph/topic_summary.py +0 -0
  71. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/__init__.py +0 -0
  72. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/bm25.py +0 -0
  73. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/bm25_fastembed.py +0 -0
  74. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/candidate_guards.py +0 -0
  75. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/config.py +0 -0
  76. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/date_view.py +0 -0
  77. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/dedup.py +0 -0
  78. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/diversity.py +0 -0
  79. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/entities.py +0 -0
  80. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/entity_store.py +0 -0
  81. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/evolution.py +0 -0
  82. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/hierarchy_bundle.py +0 -0
  83. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/intent.py +0 -0
  84. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/intention.py +0 -0
  85. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/lemmatize.py +0 -0
  86. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/local_rerank.py +0 -0
  87. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/memory_format.py +0 -0
  88. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/multi_seed_bundle.py +0 -0
  89. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/ner.py +0 -0
  90. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/profile_evidence.py +0 -0
  91. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/profile_owner_gate.py +0 -0
  92. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/query_expand.py +0 -0
  93. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/reconcile_retrieval.py +0 -0
  94. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/record_date_view.py +0 -0
  95. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/retrieval_clauses.py +0 -0
  96. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/rrf.py +0 -0
  97. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/scoring.py +0 -0
  98. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/series_tail_guard.py +0 -0
  99. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/session_episode.py +0 -0
  100. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/strength.py +0 -0
  101. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/supplemental_propositions.py +0 -0
  102. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/tag_index.py +0 -0
  103. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/temporal.py +0 -0
  104. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/topic_candidates.py +0 -0
  105. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/trace.py +0 -0
  106. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/underflow.py +0 -0
  107. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/_retrieval/user_level_l0.py +0 -0
  108. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/balanced_catalog.py +0 -0
  109. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/base.py +0 -0
  110. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/cross_domain_sweeper.py +0 -0
  111. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/reader.py +0 -0
  112. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/reader_base.py +0 -0
  113. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/reader_hybrid.py +0 -0
  114. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/reader_legacy.py +0 -0
  115. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/registry.py +0 -0
  116. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/specific_supplement.py +0 -0
  117. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/system2_agent.py +0 -0
  118. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/system2_tools.py +0 -0
  119. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/system2_writer.py +0 -0
  120. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/user_profile_scope.py +0 -0
  121. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/pipelines/writer.py +0 -0
  122. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/runtime.py +0 -0
  123. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/server.py +0 -0
  124. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/structure.py +0 -0
  125. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/async_executor.py +0 -0
  126. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/clone_references.py +0 -0
  127. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/keyword_ties.py +0 -0
  128. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/lang_detect.py +0 -0
  129. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/log_setup.py +0 -0
  130. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/metrics.py +0 -0
  131. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/pipeline_observability.py +0 -0
  132. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/source_filter.py +0 -0
  133. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/time_window.py +0 -0
  134. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/token_count.py +0 -0
  135. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/trace_file_writer.py +0 -0
  136. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory/utils/tracer.py +0 -0
  137. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory.egg-info/dependency_links.txt +0 -0
  138. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory.egg-info/requires.txt +0 -0
  139. {hy_memory-2.0.3 → hy_memory-2.0.4}/hy_memory.egg-info/top_level.txt +0 -0
  140. {hy_memory-2.0.3 → 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.3
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
@@ -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
@@ -595,6 +598,7 @@ class LLMProvider:
595
598
  temperature: Optional[float] = None,
596
599
  tools: Optional[List[Dict[str, Any]]] = None,
597
600
  tool_choice: Optional[Any] = None,
601
+ audit_stage: Optional[str] = None,
598
602
  ) -> LLMResponse:
599
603
  """
600
604
  多轮 messages 调用(支持 tool results 回传)。
@@ -622,13 +626,14 @@ class LLMProvider:
622
626
  f"msgs={len(messages)} tools={len(tools) if tools else 0}"
623
627
  )
624
628
 
625
- response = await self._chat_completions(
626
- messages,
627
- max_tokens=max_tokens,
628
- temperature=temperature,
629
- tools=tools,
630
- tool_choice=tool_choice,
631
- )
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
+ )
632
637
 
633
638
  self._total_calls += 1
634
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
 
@@ -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.3
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
@@ -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.3"
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
File without changes
File without changes